Hello everyone
If we have two normal distribution n1(2, 1) , n2(3, 1) and add this two as result we derive N(5, 2).
but if we take samples of n1 and n2 CDfs, and store them in vectors like:
cdf_samples(n1), cdf_samples(n2)
and apply a convolution on them. we should get the same results as:
cdf_samples(N);
my question is it possible to reconstruct the vector extracted from convolution into normal?
i've done the following so far...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
class normal
{
public:
float mean;
float stddev;
float variance = stddev * stddev;
float left_margin = mean - 4 * stddev;
float right_margin = mean + 4 * stddev;
normal():mean(0), stddev(1){}
normal(float m, float s):mean(m), stddev(s){}
float cdf(float x);
float pdf(float x);
void operator=(normal& rhs)
{mean = rhs.mean; stddev = rhs.stddev;}
};
float normal::pdf(float x)
{
if (x < left_margin || x > right_margin) return 0;
float coefficient = 1 / (float)sqrt(2 * PI * variance);
float x_mean = x - mean;
float result = coefficient * exp(-(x_mean * x_mean) / 2 * variance);
return result;
}
float normal::cdf(float x)
{
if (x <= left_margin) return 0;
if (x >= right_margin) return 1;
float x_mean = x - mean;
float result = (float)(0.5 * (1 + erf((x_mean) / sqrt(2 * variance))));
if (result > 1) return 1;
else return result;
};
normal ADD(normal& N1, normal& N2)
{
float mean = N1.mean + N2.mean;
float stddev = N1.stddev + N2.stddev;
return normal(mean, stddev);
}
vector<float> CDF(normal& X)
{
vector<float> R;
float L = X.left_margin;
while(L <= X.right_margin)
{
R.push_back(X.cdf(L));
L += 0.1;
}
return R;
}
vector<float> CONV(vector<float>& Y, vector<float>& X)
{
if (X.size() < Y.size()) X.resize(Y.size());
else Y.resize(X.size());
int d1_size = X.size();
int d2_size = Y.size();
int R_size = d1_size + d2_size - 1;
vector<float> out(R_size);
//convolution process
for (int i = 0; i < R_size; ++i)
{
int d1_limit = (i < d1_size - 1) ? i : d1_size - 1;
int d2_limit = (i < d2_size - 1) ? 0 : i - (d2_size - 1);
for (int j = d2_limit; j <= d1_limit; ++j)
{
out[i] += (X[j] * Y[i - j]);
}
}
// for (int i = R_size / 2; i < R_size; ++i)
// out.resize(R_size / 2);
return out;
}
normal vec2normal(vector<float>& vec)
{
int mean;
mean = std::find(vec.begin(), vec.end(), 0.5) - vec.begin();
normal N(mean, 1);
return N;
}
|
i've written the vec2normal function for reconstruction but apparently it's not always gives the proper answer...
In other words all i want to say is convolution(v1, v2) and ADD(n1, n2) are functionally the same. and i want to check if these two operators are following the same shifting property or not.
and main function would look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
int main()
{
normal n1(2, 1);
normal n2(3, 1);
normal N = ADD(n1, n2);
vector<float> cdf_add = CDF(N);
vector<float>cdf1 = CDF(n1);
vector<float>cdf2 = CDF(n2);
vector<float>conv = CONV(cdf1, cdf2);
// cdf_add should equals conv not necessarily the same samples
// but same postion of the mean(the same shift)
return 0;
}
|
is there proper way to reconstruct vector to normal?
any suggestions will be greatly appreciated...
regards