SundanceStdMathFunctors.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                              Sundance
00005 //                 Copyright (2005) Sandia Corporation
00006 // 
00007 // Copyright (year first published) Sandia Corporation.  Under the terms 
00008 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 
00009 // retains certain rights in this software.
00010 // 
00011 // This library is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Lesser General Public License as
00013 // published by the Free Software Foundation; either version 2.1 of the
00014 // License, or (at your option) any later version.
00015 //  
00016 // This library is distributed in the hope that it will be useful, but
00017 // WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 //                                                                                 
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA                                                                                
00025 // Questions? Contact Kevin Long (krlong@sandia.gov), 
00026 // Sandia National Laboratories, Livermore, California, USA
00027 // 
00028 // ************************************************************************
00029 /* @HEADER@ */
00030 
00031 #include <math.h>
00032 #include "SundanceStdMathFunctors.hpp"
00033 #include "Teuchos_Utils.hpp"
00034 
00035 using namespace Sundance;
00036 using namespace Teuchos;
00037 
00038 
00039 PowerFunctor::PowerFunctor(const double& p) 
00040   : UnaryFunctor("pow("+Teuchos::toString(p)+")"), p_(p)
00041 {;}
00042 
00043 void PowerFunctor::eval1(const double* const x, 
00044                         int nx, 
00045                         double* f, 
00046                         double* df) const
00047 {
00048   if (p_==2)
00049     {
00050       for (int i=0; i<nx; i++) 
00051         {
00052           df[i] = 2.0*x[i];
00053           f[i] = x[i]*x[i];
00054         }
00055     }
00056   else if (p_==1)
00057     {
00058       for (int i=0; i<nx; i++) 
00059         {
00060           df[i] = 0.0;
00061           f[i] = 1.0;
00062         }
00063     }
00064   else if (p_==0)
00065     {
00066       for (int i=0; i<nx; i++) 
00067         {
00068           df[i] = 0.0;
00069           f[i] = 0.0;
00070         }
00071     }
00072   else
00073     {
00074       if (checkResults())
00075         {
00076           for (int i=0; i<nx; i++) 
00077             {
00078               double px = ::pow(x[i], p_-1);
00079               df[i] = p_*px;
00080               f[i] = x[i]*px;
00081               //bvbw tried to include math.h, without success
00082 #ifdef REDDISH_PORT_PROBLEM
00083               TEST_FOR_EXCEPTION(fpclassify(f[i]) != FP_NORMAL 
00084                                  || fpclassify(df[i]) != FP_NORMAL,
00085                                  RuntimeError,
00086                                  "Non-normal floating point result detected in "
00087                                  "evaluation of unary functor " << name());
00088 #endif
00089             }
00090         }
00091       else
00092         {
00093           for (int i=0; i<nx; i++) 
00094             {
00095               double px = ::pow(x[i], p_-1);
00096               df[i] = p_*px;
00097               f[i] = x[i]*px;
00098             }
00099         }
00100     }
00101 }
00102 
00103 void PowerFunctor::eval2(const double* const x, 
00104                         int nx, 
00105                         double* f, 
00106                         double* df,
00107                         double* d2f_dxx) const
00108 {
00109   if (p_==2)
00110     {
00111       for (int i=0; i<nx; i++) 
00112         {
00113           d2f_dxx[i] = 2.0;
00114           df[i] = 2.0*x[i];
00115           f[i] = x[i]*x[i];
00116         }
00117     }
00118   else if (p_==1)
00119     {
00120        for (int i=0; i<nx; i++) 
00121         {
00122           d2f_dxx[i] = 0.0;
00123           df[i] = 1.0;
00124           f[i] = x[i];
00125         }
00126     }
00127   else if (p_==0)
00128     {
00129       for (int i=0; i<nx; i++) 
00130         {
00131           d2f_dxx[i] = 0.0;
00132           df[i] = 0.0;
00133           f[i] = 1.0;
00134         }
00135     }
00136   else
00137     {
00138       if (checkResults())
00139         {
00140           for (int i=0; i<nx; i++) 
00141             {
00142               double px = ::pow(x[i], p_-2);
00143               d2f_dxx[i] = p_ * (p_-1) * px;
00144               df[i] = p_*x[i]*px;
00145               f[i] = x[i]*x[i]*px;
00146 #ifdef REDDISH_PORT_PROBLEM
00147               TEST_FOR_EXCEPTION(fpclassify(f[i]) != FP_NORMAL 
00148                                  || fpclassify(df[i]) != FP_NORMAL,
00149                                  RuntimeError,
00150                                  "Non-normal floating point result detected in "
00151                                  "evaluation of unary functor " << name());
00152 #endif
00153             }
00154         }
00155       else
00156         {
00157           for (int i=0; i<nx; i++) 
00158             {
00159               double px = ::pow(x[i], p_-2);
00160               d2f_dxx[i] = p_ * (p_-1) * px;
00161               df[i] = p_*x[i]*px;
00162               f[i] = x[i]*x[i]*px;
00163             }
00164         }
00165     }
00166 }
00167 
00168 
00169 void PowerFunctor::eval3(const double* const x, 
00170                          int nx, 
00171                          double* f, 
00172                          double* df,
00173                          double* d2f_dxx,
00174                          double* d3f_dxxx) const
00175 {
00176   if (p_==3)
00177     {
00178       for (int i=0; i<nx; i++) 
00179         {
00180           d3f_dxxx[i] = 6.0;
00181           d2f_dxx[i] = 6.0*x[i];
00182           df[i] = 3.0*x[i]*x[i];
00183           f[i] = x[i]*x[i]*x[i];
00184         }
00185     }
00186   else if (p_==2)
00187     {
00188       for (int i=0; i<nx; i++) 
00189         {
00190           d3f_dxxx[i] = 0.0;
00191           d2f_dxx[i] = 2.0;
00192           df[i] = 2.0*x[i];
00193           f[i] = x[i]*x[i];
00194         }
00195     }
00196   else if (p_==1)
00197     {
00198        for (int i=0; i<nx; i++) 
00199         {
00200           d3f_dxxx[i] = 0.0;
00201           d2f_dxx[i] = 0.0;
00202           df[i] = 1.0;
00203           f[i] = x[i];
00204         }
00205     }
00206   else if (p_==0)
00207     {
00208       for (int i=0; i<nx; i++) 
00209         {
00210           d3f_dxxx[i] = 0.0;
00211           d2f_dxx[i] = 0.0;
00212           df[i] = 0.0;
00213           f[i] = 1.0;
00214         }
00215     }
00216   else
00217     {
00218       if (checkResults())
00219         {
00220           for (int i=0; i<nx; i++) 
00221             {
00222               double px = ::pow(x[i], p_-3);
00223               d3f_dxxx[i] = p_ * (p_-1) * (p_-2) * px;
00224               d2f_dxx[i] = p_ * (p_-1) * x[i] * px;
00225               df[i] = p_*x[i]*x[i]*px;
00226               f[i] = x[i]*x[i]*x[i]*px;
00227 #ifdef REDDISH_PORT_PROBLEM
00228               TEST_FOR_EXCEPTION(fpclassify(f[i]) != FP_NORMAL 
00229                                  || fpclassify(df[i]) != FP_NORMAL,
00230                                  RuntimeError,
00231                                  "Non-normal floating point result detected in "
00232                                  "evaluation of unary functor " << name());
00233 #endif
00234             }
00235         }
00236       else
00237         {
00238           for (int i=0; i<nx; i++) 
00239             {
00240               double px = ::pow(x[i], p_-3);
00241               d3f_dxxx[i] = p_ * (p_-1) * (p_-2) * px;
00242               d2f_dxx[i] = p_ * (p_-1) * x[i] * px;
00243               df[i] = p_*x[i]*x[i]*px;
00244               f[i] = x[i]*x[i]*x[i]*px;
00245             }
00246         }
00247     }
00248 }
00249 
00250 void PowerFunctor::eval0(const double* const x, 
00251                         int nx, 
00252                         double* f) const
00253 {
00254   if (checkResults())
00255     {
00256       for (int i=0; i<nx; i++) 
00257         {
00258           f[i] = ::pow(x[i], p_);
00259 #ifdef REDDISH_PORT_PROBLEM
00260           TEST_FOR_EXCEPTION(fpclassify(f[i]) != FP_NORMAL, 
00261                              RuntimeError,
00262                              "Non-normal floating point result detected in "
00263                              "evaluation of unary functor " << name());
00264 #endif
00265         }
00266     }
00267   else
00268     {
00269       for (int i=0; i<nx; i++) 
00270         {
00271           f[i] = ::pow(x[i], p_);
00272         }
00273     }
00274 }

Site Contact