gradtest.hh

Go to the documentation of this file.
00001 /*************************************************************************
00002 
00003 Copyright Rice University, 2004, 2005, 2006
00004 All rights reserved.
00005 
00006 Permission is hereby granted, free of charge, to any person obtaining a
00007 copy of this software and associated documentation files (the "Software"),
00008 to deal in the Software without restriction, including without limitation
00009 the rights to use, copy, modify, merge, publish, distribute, and/or sell
00010 copies of the Software, and to permit persons to whom the Software is
00011 furnished to do so, provided that the above copyright notice(s) and this
00012 permission notice appear in all copies of the Software and that both the
00013 above copyright notice(s) and this permission notice appear in supporting
00014 documentation.
00015 
00016 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
00019 RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
00020 NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
00021 DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00022 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00023 ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
00024 THIS SOFTWARE.
00025 
00026 Except as contained in this notice, the name of a copyright holder shall
00027 not be used in advertising or otherwise to promote the sale, use or other
00028 dealings in this Software without prior written authorization of the
00029 copyright holder.
00030 
00031 **************************************************************************/
00032 
00033 #ifndef __RVL_GRADTEST
00034 #define __RVL_GRADTEST
00035 
00036 #include "functional.hh"
00037 
00038 namespace RVL {
00039  
00050   template<class Scalar>
00051   bool GradientTest(Functional<Scalar> const & f,
00052             const Vector<Scalar> & y,
00053             const Vector<Scalar> & p,
00054             ostream & str,
00055             int n=11,
00056             Scalar hmin=0.1, 
00057             Scalar hmax=1.0,
00058             Scalar minrat=1.95) {
00059 
00060     try {
00061 
00062       bool success = false;
00063 
00064       if (!y.inSpace(f.getDomain())) {
00065     RVLException e; e<<"Error in GradientTest: \n";
00066     e<<"base vector is not in Domain\n";
00067     throw e;
00068       }
00069       if (!p.inSpace(f.getDomain())) {
00070     RVLException e; e<<"Error in GradientTest: \n";
00071     e<<"direction vector is not in Domain\n";
00072     throw e;
00073       }
00074 
00075       if (hmax <= hmin) {
00076     Scalar temp = hmax;
00077     hmax = hmin;
00078     hmin = temp;
00079       }
00080       if (hmin <= 0.0) {
00081     hmin = 0.1;
00082     hmax = 1.0;
00083       }
00084       if (n < 2) { 
00085     RVLException e;
00086     e<<"RVL::GradientTest:\n";
00087     e<<"  test not performed because number of samples = "<<n<<" too small\n";
00088     throw e;
00089       }
00090 
00091       Scalar hlimit1;
00092       Scalar hlimit2;
00093       hlimit1 = f.getMaxStep(y,p);
00094 
00095       {
00096     Vector<Scalar> ptemp(f.getDomain());
00097     Scalar one = ScalarFieldTraits<Scalar>::One();
00098     ptemp.scale(-one,p);
00099     hlimit2 = f.getMaxStep(y,ptemp);
00100       }
00101 
00102       Scalar hlimit = min(hlimit1,hlimit2);
00103       if (hlimit <= 0.0) {
00104     RVLException e; e<<"Error in GradientTest:\n";
00105     e<<" direction is not feasible\n";
00106     throw e;
00107       }
00108       if (hmax >= hlimit) {
00109     hmax = 0.99*hlimit;
00110     if (hmin >= hmax) hmin = hmax/n;
00111       }
00112 
00113       Vector<Scalar> x1(f.getDomain());
00114       Vector<Scalar> x2(f.getDomain());
00115       Vector<Scalar> dx(f.getDomain());
00116 
00117       FunctionalEvaluation<Scalar> F1(f,x1);
00118       FunctionalEvaluation<Scalar> F2(f,x2);
00119 
00120       Scalar s = 0.0;
00121       {
00122     FunctionalEvaluation<Scalar> Fy(f,y);
00123         s = (Fy.getGradient()).inner(p);
00124       }
00125 
00126       int nd;
00127       if (numeric_precision<Scalar>()==1) nd = 8;
00128       if (numeric_precision<Scalar>()==2) nd = 16;
00129 
00130       int oldprecision = str.precision(nd);
00131 
00132       int rflag = 1;
00133 
00134       if (abs(s) < numeric_limits<Scalar>::epsilon()) {
00135     rflag = 0;
00136     str << "GradientTest: norm of first "
00137       "variation is too small; displaying absolute error"
00138         << endl;
00139       }
00140 
00141       str<<endl<<"Gradient Computation Check"<<endl<<endl;
00142    
00143       if (rflag)
00144     str << setw(8) << "h" << setw(nd+7) << " norm of diff."
00145         << setw(nd+8) << "rel. error" << setw(nd+6)
00146         << "convg. rate" << endl;
00147       else
00148     str << setw(8) << "h" << setw(nd+7) << " norm of diff."
00149         << setw(nd+6) << "convg. rate" << endl;
00150       int i;
00151       Scalar hstep = (hmax-hmin)/(n-1);
00152       Scalar n1p=1.0;
00153       Scalar tn;
00154 
00155       for(i=n-1;i>=0;i--)  {
00156 
00157     Scalar h = hmin+i*hstep;
00158         x1.copy(y);
00159     x2.copy(y);
00160     x1.linComb(-h,p);
00161     x2.linComb(h,p);
00162     /*
00163     cerr<<"\ny:\n";
00164     y.write(cerr);
00165     cerr<<"\np:\n";
00166     p.write(cerr);
00167     cerr<<"\nx1:\n";
00168     x1.write(cerr);
00169     cerr<<"\nx2:\n";
00170     x2.write(cerr);
00171     cerr<<endl;
00172     */
00173     Scalar ds = (F2.getValue()-F1.getValue())/(2.0*h);
00174     // cerr<<"h = "<<h<<" val1 = "<<F1.getValue()<<" val2 = "<<F2.getValue()<<" ds = "<<ds<<endl;
00175     Scalar n1 = abs(s-ds);
00176     if (i<n-1 && !ProtectedDivision(n1p,n1,tn)) {
00177       Scalar rat = log(tn)/log((h+hstep)/h);
00178       if (rat > minrat) success = true;
00179       if (rflag)
00180         str << setprecision(6) << setw(8) << h << " "
00181         << setprecision(nd) << setw(nd+6) << n1
00182         << setw(nd+8) << n1/abs(s) << setw(nd+6)
00183         << rat << endl;
00184       else
00185         str << setprecision(6) << setw(8) << h << " "
00186         << setprecision(nd) << setw(nd+6) << n1
00187         << setw(nd+6) << rat
00188         << endl;
00189     }
00190     else {
00191       char * jnk = new char[nd];
00192       for (int ii=0;ii<nd;ii++) {
00193         jnk[ii]='-';
00194       }
00195       jnk[nd-1]='\0';
00196       if (rflag)
00197         str << setprecision(6) << setw(8) << h << " "
00198         << setprecision(nd) << setw(nd+6) << n1
00199         << setw(nd+8) << n1/abs(s) << setw(nd+6)
00200         << jnk << endl;
00201       else
00202         str << setprecision(6) << setw(8) << h << " "
00203         << setprecision(nd) << setw(nd+6) << n1 << " "
00204         << setw(nd+6) << jnk  << endl;
00205       delete [] jnk;
00206     }
00207     n1p=n1;
00208 
00209       }
00210       str.precision(oldprecision);
00211       return success;
00212     }
00213     catch (RVLException & e) {
00214       e<<"\ncalled from GradientTest\n";
00215       throw e;
00216     }
00217   }
00218 
00219 }
00220 
00221 #endif

Generated on 5 Jan 2017 for RVL by  doxygen 1.4.7