PlayaObjectiveBase.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                 Playa: Programmable Linear Algebra
00005 //                 Copyright 2012 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 
00042 
00043 #include "PlayaObjectiveBase.hpp"
00044 #include "PlayaOut.hpp"
00045 #include "PlayaTabs.hpp"
00046 #include "PlayaGhostView.hpp"
00047 #include "PlayaLinearCombinationImpl.hpp"
00048 
00049 
00050 
00051 namespace Playa
00052 {
00053 using std::endl;
00054 using std::ostream;
00055 using std::setw;
00056 
00057 bool ObjectiveBase::fdCheck(const Vector<double>& xIn,
00058   double tol,
00059   int verbosity) const 
00060 {
00061   double f0, fPlus, fMinus;
00062   /* get a FD step appropriate to this problem */
00063   double h = fdStep();
00064 
00065   PLAYA_MSG1(verbosity, "running fdCheck with stepsize=" << h);
00066 
00067   Vector<double> x = xIn.copy();
00068   Vector<double> x0 = x.copy();
00069   Vector<double> gf = x.copy();
00070   evalGrad(xIn, f0, gf);
00071 
00072   int nTot = x.space().dim();
00073   int n = x.space().numLocalElements();
00074   int lowestIndex = x.space().baseGlobalNaturalIndex();
00075 
00076   Array<double> df_dx(n);
00077 
00078   for (int globalIndex=0; globalIndex<nTot; globalIndex++)
00079   {
00080     double tmp=0.0;
00081     bool isLocal = globalIndex >= lowestIndex 
00082       && globalIndex < (lowestIndex+n);
00083     int localIndex = globalIndex - lowestIndex;
00084     /* set point to xPlus */
00085     if (isLocal)
00086     {
00087       tmp = x[localIndex];
00088       x[localIndex] = tmp + h;
00089     }
00090 
00091     /** eval at xPlus*/
00092     eval(x, fPlus);
00093 
00094     /* set point to xMinus */
00095     if (isLocal)
00096     {
00097       x[localIndex] = tmp - h;
00098     }
00099 
00100     /* eval at xMinus */
00101     eval(x, fMinus);
00102       
00103     /* check error */
00104     if (isLocal)
00105     {
00106       df_dx[localIndex] = (fPlus - fMinus)/2.0/h;
00107       PLAYA_MSG2(verbosity,
00108         "g=" << setw(5) << globalIndex << ", l=" << setw(5) << localIndex 
00109         << " f0=" << setw(12) << f0 
00110          << " fPlus=" << setw(12) << fPlus 
00111         << " fMinus=" << setw(12) << fMinus << " df_dx="
00112         << setw(12) << df_dx[localIndex]);
00113       PLAYA_MSG3(verbosity, "i " << globalIndex << " x_i=" << tmp 
00114         << " f(x)=" << f0 
00115         << " f(x+h)=" << fPlus 
00116         << " f(x-h)=" << fMinus
00117         );
00118       /* restore point */
00119       x[localIndex] = tmp;
00120     }
00121   }
00122   
00123   double localMaxErr = 0.0;
00124 
00125   VectorSpace<double> space = x.space();
00126   for (int i=0; i<space.numLocalElements(); i++)
00127   {
00128     double num =  fabs(df_dx[i]-gf[i]);
00129     double den = fabs(df_dx[i]) + fabs(gf[i]) + 1.0e-14;
00130     double r = 0.0;
00131     if (fabs(den) > 1.0e-16) r = num/den;
00132     else r = 1.0;
00133     PLAYA_MSG2(verbosity, "i=" << setw(5) << i
00134       << " FD=" << setw(16) << df_dx[i] 
00135       << " grad=" << setw(16) << gf[i]
00136       << " r=" << setw(16) << r);
00137     if (localMaxErr < r) localMaxErr = r;
00138   }
00139   PLAYA_MSG2(verbosity, "local max error = " << localMaxErr);
00140   double maxErr = localMaxErr;
00141   PLAYA_MSG1(verbosity, "fd check: max error = " << maxErr);
00142   return maxErr <= tol;
00143 }
00144 
00145 }

Site Contact