-
Notifications
You must be signed in to change notification settings - Fork 1
/
test.cpp
141 lines (134 loc) · 5.32 KB
/
test.cpp
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
#include "catch.hpp"
#include "FunctionalUtilities.h"
#include <iostream>
#include "FangOost.h"
#include <complex>
//u is k*pi/(b-a)
template<typename Number, typename Index>
auto VkCDF(const Number& x, const Number& u, const Number& a, const Number& b, const Index& k){
//auto constant=(b-a)/(k*M_PI);
return k==0?x-a:sin((x-a)*u)/u;
}
TEST_CASE("Test computeXRange", "[FangOost]"){
REQUIRE(fangoost::computeXRange(5, 0.0, 1.0)==std::vector<double>({0, .25, .5, .75, 1.0}));
}
TEST_CASE("Test computeInv", "[FangOost]"){
const double mu=2;
const double sigma=1;
const int numX=5;
const int numU=256;
const double xMin=-3;
const double xMax=7;
auto normCF=[&](const auto& u){ //normal distribution's CF
return exp(u*mu+.5*u*u*sigma*sigma);
};
std::vector<double> referenceNormal=fangoost::computeXRange(numX, xMin, xMax);
referenceNormal=futilities::for_each(std::move(referenceNormal), [&](double x, double index){
return exp(-pow(x-mu, 2)/(2*sigma*sigma))/(sqrt(2*M_PI)*sigma);
});
auto myInverse=fangoost::computeInv(numX, numU, xMin, xMax, normCF);
for(int i=0; i<numX; ++i){
REQUIRE(myInverse[i]==Approx(referenceNormal[i]));
}
}
TEST_CASE("Test computeInvDiscrete", "[FangOost]"){
const double mu=2;
const double sigma=1;
const int numX=5;
const int numU=256;
const double xMin=-3;
const double xMax=7;
auto normCF=[&](const auto& u){ //normal distribution's CF
return exp(u*mu+.5*u*u*sigma*sigma);
};
std::vector<double> referenceNormal=fangoost::computeXRange(numX, xMin, xMax);
referenceNormal=futilities::for_each(std::move(referenceNormal), [&](double x, double index){
return exp(-pow(x-mu, 2)/(2*sigma*sigma))/(sqrt(2*M_PI)*sigma);
});
auto du=fangoost::computeDU(xMin, xMax);
auto cp=fangoost::computeCP(du);
auto discreteCF=futilities::for_each_parallel(0, numU, [&](const auto& index){
return fangoost::formatCFReal(fangoost::getComplexU(fangoost::getU(du, index)), xMin, cp, normCF);
});
auto myInverse=fangoost::computeInvDiscrete(numX, xMin, xMax, std::move(discreteCF));
for(int i=0; i<numX; ++i){
REQUIRE(myInverse[i]==Approx(referenceNormal[i]));
}
}
TEST_CASE("Test computeInvDiscrete for two gaussian added", "[FangOost]"){
const double mu=2;
const double sigma=1;
const double combinedMu=2*mu;
const double combinedSig=sqrt(sigma*2);
const int numX=5;
const int numU=256;
const double xMin=-4;
const double xMax=12;
auto normCF=[&](const auto& u){ //normal distribution's CF
return u*mu+.5*u*u*sigma*sigma;
};
std::vector<double> referenceNormal=fangoost::computeXRange(numX, xMin, xMax);
std::vector<double> xRange=fangoost::computeXRange(numX, xMin, xMax);
referenceNormal=futilities::for_each(std::move(referenceNormal), [&](double x, double index){
return exp(-pow(x-combinedMu, 2)/(2*combinedSig*combinedSig))/(sqrt(2*M_PI)*combinedSig);
});
auto du=fangoost::computeDU(xMin, xMax);
//
auto discreteCF=futilities::for_each_parallel(0, numU, [&](const auto& index){
return normCF(fangoost::getComplexU(fangoost::getU(du, index)));
});
for(auto& val:discreteCF){
val=2.0*val;
}
auto myInverse=fangoost::computeInvDiscreteLog(numX, xMin, xMax, std::move(discreteCF));
for(int i=0; i<numX; ++i){
REQUIRE(myInverse[i]==Approx(referenceNormal[i]));
}
}
TEST_CASE("Test CDF", "[FangOost]"){
const double mu=2;
const double sigma=5;
const int numX=55;
const int numU=256;
const double xMin=-20;
const double xMax=25;
auto normCF=[&](const auto& u){ //normal distribution's CF
return exp(u*mu+.5*u*u*sigma*sigma);
};
std::vector<double> referenceNormal=fangoost::computeXRange(numX, xMin, xMax);
referenceNormal=futilities::for_each(std::move(referenceNormal), [&](double x, double index){
return .5*erfc(-((x-mu)/sigma)/sqrt(2.0));
//return exp(-pow(x-mu, 2)/(2*sigma*sigma))/(sqrt(2*M_PI)*sigma);
});
auto myCDF=fangoost::computeExpectation(numX, numU, xMin, xMax, normCF, [&](const auto& u, const auto& x, const auto& k){
return VkCDF(x, u, xMin, xMax, k);
});
for(int i=0; i<numX; ++i){
//std::cout<<myCDF[i]<<", "<<referenceNormal[i]<<std::endl;
REQUIRE(myCDF[i]==Approx(referenceNormal[i]));
}
}
TEST_CASE("Test computeExpectationVector", "FangOost"){
int numX=100;
int numU=100;
double xmin=-5;
double xmax=5;
const double mu=2;
const double sigma=1;
auto normCF=[&](const auto& u){ //normal distribution's CF
return u*mu+.5*u*u*sigma*sigma;
};
auto vk=[&](const auto& u, const auto& x, const auto& k){
return cos(u*(x-xmin));
};
auto result1=fangoost::computeExpectation(numX, numU, xmin, xmax, normCF, vk);
double dx=fangoost::computeDX(numX, xmin, xmax);
auto xArray=futilities::for_each_parallel(0, numX, [&](const auto& index){
return fangoost::getX(xmin, dx, index);
});
auto result2=fangoost::computeExpectationVector(xArray, numU, normCF, vk);
for(int i=0; i<numX; ++i){
REQUIRE(result1[i]==Approx(result2[i]));
}
}