00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "numeric/diff.hxx"
00029 #include "numeric/funcobj.hxx"
00030 #include <vector>
00031 #include <string>
00032 #include <iostream>
00033 #include <cmath>
00034 #include <memory>
00035
00036 using ::std::vector;
00037 using ::std::cout;
00038 using ::std::endl;
00039 using ::std::string;
00040 using ::std::auto_ptr;
00041
00042 using namespace scsolver::numeric;
00043
00044 class TestFailed {};
00045
00046 class BaseTestFunc : public BaseFuncObj
00047 {
00048 public:
00049 BaseTestFunc(size_t varIndex) : BaseFuncObj(varIndex)
00050 {
00051 }
00052
00053 virtual ~BaseTestFunc() throw() {}
00054 virtual double evalDef1() const = 0;
00055 virtual double evalDef2() const = 0;
00056
00057 private:
00058 BaseTestFunc();
00059 };
00060
00061 class TestFunc : public BaseTestFunc
00062 {
00063 public:
00064 TestFunc() : BaseTestFunc(1)
00065 {
00066 }
00067
00068 virtual ~TestFunc() throw()
00069 {
00070 }
00071
00072 virtual const string getFuncString() const
00073 {
00074 return string("f(x) = 2x^2 + 5x");
00075 }
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 virtual double eval() const
00094 {
00095
00096 double x = getVar(0);
00097 return (2*x + 5)*x;
00098 }
00099
00100 virtual double evalDef1() const
00101 {
00102
00103 double x = getVar(0);
00104 return 4*x + 5;
00105 }
00106
00107 virtual double evalDef2() const
00108 {
00109 return 4;
00110 }
00111
00112
00113
00114 };
00115
00116 class TestFunc2 : public BaseTestFunc
00117 {
00118 public:
00119 TestFunc2() : BaseTestFunc(1)
00120 {
00121 }
00122
00123 virtual ~TestFunc2() throw()
00124 {
00125 }
00126
00127 virtual const string getFuncString() const
00128 {
00129 return string("f(x) = 2x^3 + 5x^2 - 2x");
00130 }
00131
00132 virtual double eval() const
00133 {
00134
00135
00136 double x = getVar(0);
00137 double f = ((2*x + 5)*x - 2)*x;
00138 return f;
00139 }
00140
00141 virtual double evalDef1() const
00142 {
00143
00144
00145 double x = getVar(0);
00146 double f = (6*x + 10) * x - 2;
00147 return f;
00148 }
00149
00150 virtual double evalDef2() const
00151 {
00152
00153 double x = getVar(0);
00154 return 12*x + 10;
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 };
00176
00177 void checkDelta(double delta)
00178 {
00179 cout << "delta = " << delta << endl;
00180 if (delta > 0.05)
00181 throw TestFailed();
00182 }
00183
00184 void test(BaseTestFunc* pF)
00185 {
00186 static const double vars[] = {0, 1.5, 10.0, 20.5, 50.0};
00187 for (int i = 0; i < 5; ++i)
00188 {
00189 double var = vars[i];
00190 cout << "----------------------------------------" << endl;
00191 cout << " x = " << var << endl;
00192
00193
00194 auto_ptr<NumericalDiffer> pDiff( new NumericalDiffer );
00195
00196 pDiff->setVariable(var);
00197 pDiff->setPrecision(5);
00198 SingleVarFuncObj& rSingleFuncObj = pF->getSingleVarFuncObj(0);
00199 pDiff->setFuncObject(&rSingleFuncObj);
00200 double answer = pDiff->run();
00201 double delta = fabs(answer - pF->evalDef1())/fabs(answer);
00202 checkDelta(delta);
00203
00204 pDiff->setSecondOrder(true);
00205 answer = pDiff->run();
00206 delta = (answer - pF->evalDef2())/answer;
00207 checkDelta(delta);
00208 }
00209 }
00210
00211 int main()
00212 {
00213 try
00214 {
00215 auto_ptr<TestFunc> pF( new TestFunc );
00216 test(pF.get());
00217 auto_ptr<TestFunc2> pF2( new TestFunc2 );
00218 test(pF2.get());
00219 cout << "Test passed!" << endl;
00220 }
00221 catch (const TestFailed& )
00222 {
00223 cout << "Test failed" << endl;
00224 }
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241