Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00011 #ifdef __ZTC__
00012 #include <conio.h>
00013 #endif
00014
00015 #include "fvar.hpp"
00016
00017 #if defined(_WIN32)
00018 #include <conio.h>
00019 #endif
00020
00021 #include <ctype.h>
00022 #include <stdlib.h>
00023
00024 #ifndef OPT_LIB
00025 #include <cassert>
00026 #include <climits>
00027 #endif
00028
00029 int derchflag=0;
00030 double derch_stepsize=0.0;
00031
00032 static ofstream* pofs=0;
00033
00038 void derch(const double& _f, const independent_variables & _x,
00039 const dvector& _gg, int n, const int & _ireturn)
00040 {
00041 dvector& gg=(dvector&) _gg;
00042 double& f=(double&) _f;
00043 int& ireturn = (int&) _ireturn;
00044 independent_variables& x= (independent_variables&) _x;
00045 static int i, n1 ,n2,ii;
00046 static double fsave;
00047 static int order_flag;
00048 static double s, f1, f2, g2, xsave;
00049 static int j = 1;
00050 static int si;
00051 si=gg.indexmax();
00052 static dvector g(1,si);
00053 static dvector index(1,si);
00054
00055 if (ireturn == 4 ) goto label4;
00056 else if (ireturn == 5) goto label5;
00057 g=gg;
00058 {
00059 int maxind = g.indexmin();
00060 double maxg=fabs(g(maxind));
00061 dmatrix tmp(1,3,g.indexmin(),g.indexmax());
00062 tmp(1).fill_seqadd(1,1);
00063 tmp(2)=g;
00064 tmp(3)=-fabs(g);
00065 ofstream ofs("derivatives");
00066 dmatrix dtmp=sort(trans(tmp),3);
00067 ofs << dtmp << endl;
00068 for (int i=g.indexmin();i<=g.indexmax();i++)
00069 {
00070 if (fabs(g(i))>maxg)
00071 {
00072 maxg=fabs(g(i));
00073 maxind=i;
00074 }
00075 }
00076 cout << "maxind = " << maxind << " maxg = " << maxg << endl;
00077 index=column(dtmp,1);
00078 }
00079 while (j > 0)
00080 {
00081 cout << "\nEntering derivative checker.\n";
00082 cout << " Enter index (1 ... "<< n <<") of derivative to check.\n";
00083 cout << " To check all derivatives, enter 0;\n";
00084 cout << " To quit enter -1: ";
00085 flush(cout);
00086 cin >> j;
00087 if (j == -1)
00088 {
00089 ireturn = -1;
00090 return;
00091 }
00092 else if (j == 0)
00093 {
00094 cout << "\n Checking all derivatives. Press X to terminate checking.\n";
00095 flush(cout);
00096 pofs=new ofstream("ders.dat");
00097 (*pofs) << " index analytical finite % error " << endl;
00098 (*pofs) << " difference " << endl;
00099 n1 = 1;
00100 n2 = n;
00101 }
00102 else if (j >= 1 && j <= n)
00103 {
00104 n1 = j;
00105 n2 = j;
00106 }
00107 else
00108 {
00109 cout << "Error: Invalid derivative index \"" << j
00110 << "\" entered which is not in range (1 ... "<< n <<").\n";
00111 ad_exit(1);
00112 }
00113 cout << "\n Enter step size.\n";
00114 cout << " To quit derivative checker enter -1;\n";
00115 cout << " to check for uninitialized variables enter 0): ";
00116 flush(cout);
00117 #if defined(__BORLANDC__)
00118 char mystring[1000];
00119 cin >> mystring;
00120 s=atof(mystring);
00121 #else
00122 cin >> s;
00123 #endif
00124 if (s < 0) ad_exit(0);
00125
00126 if (j==0)
00127 {
00128 cout << "\n If you want the derivatives approximated in order\n"
00129 << " of decreasing magnitude enter 1;\n"
00130 << " else enter 0: ";
00131 flush(cout);
00132 int tmpint=0;
00133 cin >> tmpint;
00134 if (tmpint==1)
00135 order_flag=1;
00136 else
00137 order_flag=0;
00138 }
00139 if (s != 0)
00140 {
00141 cout <<
00142 "\n X Function Analytical Finite Diff ; Index"
00143 << endl;
00144 }
00145
00146 for (ii=n1; ii<=n2; ii++)
00147 {
00148 i = ii;
00149 if (order_flag==1)
00150 {
00151 int count = 0;
00152 for (int _ii = index.indexmin(); _ii <= index.indexmax(); ++_ii)
00153 {
00154 #ifdef OPT_LIB
00155 int idx = (int)index(_ii);
00156 #else
00157 double _idx = index(_ii);
00158 assert(_idx <= (double)INT_MAX);
00159 int idx = (int)_idx;
00160 #endif
00161 if (x.indexmin() <= idx && idx <= x.indexmax())
00162 {
00163 ++count;
00164 }
00165 if (count == ii)
00166 {
00167 i = idx;
00168 break;
00169 }
00170 }
00171 }
00172 derch_stepsize=s;
00173 derchflag=1;
00174 xsave=x(i);
00175 x(i)=xsave+s;
00176 fsave = f;
00177 ireturn = 4;
00178 return;
00179
00180 label4:
00181 derch_stepsize=s;
00182 derchflag=-1;
00183 f1 = f;
00184 x(i)=xsave-s;
00185 ireturn= 5;
00186 return;
00187
00188 label5:
00189 f2 = f;
00190 f = fsave;
00191 x(i)=xsave;
00192 if (s==0.0)
00193 {
00194 if (fabs(f1-f2)>0.0)
00195 {
00196 cout << "There appear to be uninitialized variables in "
00197 << "the objective function " << endl
00198 << " f1 = " << setprecision(15) << f1
00199 << " f2 = " << setprecision(15) << f2 << endl;
00200 }
00201 else
00202 {
00203 cout << "There do not appear to be uninitialized variables in" << endl
00204 << "the objective function " << endl;
00205 }
00206 }
00207 else
00208 {
00209 g2=(f1-f2)/(2.*s);
00210 derchflag=0;
00211 double perr= fabs(g2-g(i))/(fabs(g(i))+1.e-6);
00212
00213 if (pofs)
00214 {
00215 if (perr > 1.e-3)
00216 (*pofs) << " ** ";
00217 else
00218 (*pofs) << " ";
00219 (*pofs) << " " << setw(4) << i
00220 << " " << setw(12) << g(i)
00221 << " " << setw(12) << g2
00222 << " " << setw(12) << perr
00223 << endl;
00224 }
00225 if (ad_printf)
00226 {
00227 (*ad_printf)(" %12.5e %12.5e %12.5e %12.5e ; %5d \n",
00228 x(i), f, g(i), g2, i);
00229 fflush(stdout);
00230 }
00231 }
00232 #if defined(_MSC_VER)
00233 if ( kbhit() )
00234 {
00235 int c = toupper(getch());
00236 if ( c == 'X')
00237 {
00238 cout << " Exiting derivative checker by user interrupt.\n";
00239 ad_exit(0);
00240 }
00241 }
00242 #endif
00243 }
00244 }
00245
00246 ad_exit(0);
00247 }