00001
00002
00003
00004
00005
00006
00011 #include "fvar.hpp"
00012
00013
00014
00015
00016 #define USE_BARD_PEN
00017
00018 #include <stdlib.h>
00019 #include <stdio.h>
00020 #include <math.h>
00021
00022 double dmin(double,double);
00023 double dmax(double, double);
00024
00029 dvariable dfatan1(dvariable x, double fmin, double fmax, const prevariable& _fpen)
00030 {
00031 prevariable& fpen=(prevariable&) _fpen;
00032 dvariable t;
00033
00034 t= (atan(x)/PI);
00035 t=( t +.5 );
00036 t= t *( fmax-fmin ) + fmin;
00037 t=( (atan(x)/PI) +.5 )*( fmax-fmin ) + fmin;
00038
00039 if (x < -12.)
00040 {
00041 fpen+=.1*(x+12.)*(x+12.);
00042 }
00043
00044 if (x > 12.)
00045 {
00046 fpen+=.1*(x-12.)*(x-12.);
00047 }
00048 return(t);
00049 }
00050
00055 double dftinv(double x, double fmin, double fmax)
00056 {
00057 double tinv;
00058 if (x <= fmin)
00059 {
00060 if (ad_printf) (*ad_printf)("variable out of bounds in dftinv\nvariable = %lg", x);
00061 if (ad_printf) (*ad_printf)("lower bound = %lg", fmin);
00062 if (ad_printf) (*ad_printf)("upper bound = %lg\n", fmax);
00063
00064 x=dmin(fmin+.001,fmin+.01*(fmax-fmin));
00065 }
00066
00067 tinv=tan( ((x-fmin)/(fmax-fmin) -.5) * PI);
00068 return(tinv);
00069 }
00070
00075 dvariable boundp(const prevariable& x, double fmin, double fmax,const prevariable& _fpen,double s)
00076 {
00077 return boundp(x/s,fmin,fmax,_fpen);
00078 }
00079
00084 dvariable boundp(const prevariable& x, double fmin, double fmax,const prevariable& _fpen)
00085 {
00086 if (gradient_structure::Hybrid_bounded_flag==0)
00087 {
00088 prevariable& fpen=(prevariable&) _fpen;
00089 dvariable t,y;
00090 double diff=fmax-fmin;
00091 const double l4=log(4.0);
00092 dvariable ss=0.4999999999999999*sin(x*1.57079632679489661)+0.50;
00093 t=fmin + diff*ss;
00094
00095 #ifdef USE_BARD_PEN
00096 double pen=.000001/diff;
00097 fpen-=pen*(log(ss+1.e-40)+log((1.0-ss)+1.e-40)+l4);
00098 #else
00099 if (x < -.9999)
00100 {
00101 fpen+=cube(-0.9999-x);
00102 if (x < -1.)
00103 {
00104 fpen+=1.e+6*cube(-1.0-x);
00105 if (x < -1.02)
00106 {
00107 fpen+=1.e+10*cube(-1.02-x);
00108 }
00109 }
00110 }
00111 if (x > 0.9999)
00112 {
00113 fpen+=cube(x-0.9999);
00114 if (x > 1.)
00115 {
00116 fpen+=1.e+6*cube(x-1.);
00117 if (x > 1.02)
00118 {
00119 fpen+=1.e+10*cube(x-1.02);
00120 }
00121 }
00122 }
00123 #endif
00124 return(t);
00125 }
00126 else
00127 {
00128 double diff=fmax-fmin;
00129 dvariable t,y;
00130 if (x>-20)
00131 {
00132 y=1.0/(1+exp(-x));
00133 }
00134 else
00135 {
00136 dvariable u=exp(x);
00137 y=u/(1.0+u);
00138 }
00139 t=fmin + diff*y;
00140 return(t);
00141 }
00142 }
00143 void xxjunk10(double){;}
00144
00149 dvariable dfboundp(const prevariable& x, double fmin,double fmax)
00150 {
00151 if (gradient_structure::Hybrid_bounded_flag==0)
00152 {
00153 return (fmax-fmin)*0.499999999999999*1.57079632679489661
00154 *cos(x*1.57079632679489661);
00155 }
00156 else
00157 {
00158 double diff=fmax-fmin;
00159 dvariable dfy;
00160 if (x>-20)
00161 {
00162 dvariable u=exp(-x);
00163
00164 dfy=u/square(1.0+u);
00165 }
00166 else
00167 {
00168 dvariable u=exp(x);
00169
00170 dfy=u/square(1.0+u);
00171 }
00172 if (dfy==0)
00173 {
00174 cout << "error in dfboundp" << endl;
00175 }
00176 return diff*dfy;
00177 }
00178 }
00179
00184 double ndfboundp( double x, double fmin, double fmax,const double& fpen)
00185 {
00186 if (gradient_structure::Hybrid_bounded_flag==0)
00187 {
00188 return (fmax-fmin)*0.499999999999999*1.57079632679489661
00189 *cos(x*1.57079632679489661);
00190 }
00191 else
00192 {
00193 double diff=fmax-fmin;
00194 double dfy;
00195 if (x>-20)
00196 {
00197 double u=exp(-x);
00198
00199 dfy=u/square(1.0+u);
00200 }
00201 else
00202 {
00203 double u=exp(x);
00204
00205 dfy=u/square(1.0+u);
00206 }
00207 return diff*dfy;
00208 }
00209 }
00210
00215 double boundp(double x, double fmin, double fmax)
00216 {
00217 if (gradient_structure::Hybrid_bounded_flag==0)
00218 {
00219 double t;
00220 double diff=fmax-fmin;
00221 double ss=0.49999999999999999*sin(x*1.57079632679489661)+0.50;
00222 t=fmin + diff*ss;
00223 return(t);
00224 }
00225 else
00226 {
00227 double diff=fmax-fmin;
00228 double t,y;
00229 if (x>-20)
00230 {
00231 y=1.0/(1+exp(-x));
00232 }
00233 else
00234 {
00235 double u=exp(x);
00236 y=u/(1.0+u);
00237 }
00238 t=fmin + diff*y;
00239 return(t);
00240 }
00241 }
00242
00247 double nd2fboundp( double x, double fmin, double fmax,const double& fpen)
00248 {
00249 if (x<-0.99999)
00250 {
00251 return (boundp(x,fmin,fmax,fpen)-2.*boundp(x+1.e-6,fmin,fmax,fpen)
00252 +boundp(x+2.e-6,fmin,fmax,fpen))/1.e-12;
00253 }
00254 else if (x>0.99999)
00255 {
00256 return (boundp(x-2.e-6,fmin,fmax,fpen)-2.*boundp(x-1.e-6,fmin,fmax,fpen)
00257 +boundp(x,fmin,fmax,fpen))/1.e-12;
00258 }
00259 else
00260 {
00261 return (boundp(x+1.e-6,fmin,fmax,fpen)-2.*boundp(x,fmin,fmax,fpen)
00262 +boundp(x-1.e-6,fmin,fmax,fpen))/1.e-12;
00263 }
00264 }
00265
00270 double boundp( double x, double fmin, double fmax,const double& _fpen)
00271 {
00272 if (gradient_structure::Hybrid_bounded_flag==0)
00273 {
00274 double t;
00275 double& fpen=(double&) _fpen;
00276 double diff=fmax-fmin;
00277 const double l4=log(4.0);
00278 double ss=0.499999999999999*sin(x*1.57079632679489661)+0.50;
00279 t=fmin + diff*ss;
00280 #ifdef USE_BARD_PEN
00281 double pen=.001/diff;
00282 fpen-=pen*(log(ss+1.e-40)+log((1.0-ss)+1.e-40)+l4);
00283 #else
00284 if (x < -.9999)
00285 {
00286 fpen+=(x+0.9999)*(x+0.9999);
00287 if (x < -1.)
00288 {
00289 fpen+=1.e+6*(x+1.)*(x+1.);
00290 if (x < -1.02)
00291 {
00292 fpen+=1.e+10*(x+1.02)*(x+1.02);
00293 }
00294 }
00295 }
00296 if (x > 0.9999)
00297 {
00298 fpen+=(x-0.9999)*(x-0.9999);
00299 if (x > 1.)
00300 {
00301 fpen+=1.e+6*(x-1.)*(x-1.);
00302 if (x > 1.02)
00303 {
00304 fpen+=1.e+10*(x-1.02)*(x-1.02);
00305 }
00306 }
00307 }
00308 #endif
00309 return(t);
00310 }
00311 else
00312 {
00313 double diff=fmax-fmin;
00314 double t,y;
00315 if (x>-20)
00316 {
00317 y=1.0/(1+exp(-x));
00318 }
00319 else
00320 {
00321 double u=exp(x);
00322 y=u/(1.0+u);
00323 }
00324 t=fmin + diff*y;
00325 return(t);
00326 }
00327 }
00328
00333 double boundpin(double x, double fmin, double fmax,double s)
00334 {
00335 return s*boundpin(x,fmin,fmax);
00336 }
00337
00342 double boundpin(double x, double fmin, double fmax)
00343 {
00344 double tinv;
00345
00346 if (x < fmin)
00347 {
00348 if (ad_printf) (*ad_printf)("variable out of bounds in boundpin: variable = %lg", x);
00349 if (ad_printf) (*ad_printf)("; min = %lg", fmin);
00350 if (ad_printf) (*ad_printf)("; max = %lg\n", fmax);
00351
00352 x=dmin(fmin+.001,fmin+.01*(fmax-fmin));
00353 }
00354
00355 if (x > fmax)
00356 {
00357 if (ad_printf) (*ad_printf)("variable out of bounds in boundpin: variable = %lg", x);
00358 if (ad_printf) (*ad_printf)("; min = %lg", fmin);
00359 if (ad_printf) (*ad_printf)("; max = %lg\n", fmax);
00360
00361 x=dmax(fmax-.001,fmax-.01*(fmax-fmin));
00362 }
00363
00364 if (gradient_structure::Hybrid_bounded_flag==0)
00365 {
00366 tinv=::asin(2.*(x-fmin)/(fmax-fmin)-1.)/1.57079632679489661;
00367 }
00368 else
00369 {
00370
00371
00372 double y=1.e-20+(fmax-x)/(1.e-20+(x-fmin));
00373 tinv=-log(y);
00374 }
00375 return(tinv);
00376 }
00377
00382 double boundpin(const prevariable& x, double fmin, double fmax,double s)
00383 {
00384 return s*boundpin(x,fmin,fmax);
00385 }
00386
00391 double boundpin(const prevariable& xx, double fmin, double fmax)
00392 {
00393 double tinv;
00394 double x=value(xx);
00395
00396 if (x < fmin)
00397 {
00398 if (ad_printf) (*ad_printf)("variable out of bounds in boundpin: variable = %lg", x);
00399 if (ad_printf) (*ad_printf)("; min = %lg", fmin);
00400 if (ad_printf) (*ad_printf)("; max = %lg\n", fmax);
00401
00402 x=dmin(fmin+.001,fmin+.01*(fmax-fmin));
00403 }
00404
00405 if (x > fmax)
00406 {
00407 if (ad_printf) (*ad_printf)("variable out of bounds in boundpin: variable = %lg", x);
00408 if (ad_printf) (*ad_printf)("; min = %lg", fmin);
00409 if (ad_printf) (*ad_printf)("; max = %lg\n", fmax);
00410
00411 x=dmax(fmax-.001,fmax-.01*(fmax-fmin));
00412 }
00413 if (gradient_structure::Hybrid_bounded_flag==0)
00414 {
00415 tinv=::asin(2.*(x-fmin)/(fmax-fmin)-1.)/1.57079632679489661;
00416 }
00417 else
00418 {
00419
00420
00421
00422 double y=1.e-20+(fmax-x)/(1.e-20+(x-fmin));
00423 tinv=-log(y);
00424 }
00425
00426 return(tinv);
00427 }
00428
00433 double dmin(double x, double y)
00434 {
00435 if (x<y)
00436 {
00437 return (x);
00438 }
00439 else
00440 {
00441 return(y);
00442 }
00443 }
00444
00449 double dmax(double x, double y)
00450 {
00451 if (x>y)
00452 {
00453 return (x);
00454 }
00455 else
00456 {
00457 return(y);
00458 }
00459 }
00460