Go to the documentation of this file.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
00029
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
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 }