ADMB Documentation  11.1.1015
 All Classes Files Functions Variables Typedefs Friends Defines
boundfun.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: boundfun.cpp 542 2012-07-10 21:04:06Z johnoel $
00003  *
00004  * Author: David Fournier
00005  * Copyright (c) 2008-2012 Regents of the University of California
00006  */
00011 #include "fvar.hpp"
00012 //#ifdef __TURBOC__
00013 //#  pragma hdrstop
00014 //#endif
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       //y=1.0/(1+u);
00164       dfy=u/square(1.0+u);
00165     }
00166     else
00167     {
00168       dvariable u=exp(x);
00169       //y=u/(1.0+u);
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       //y=1.0/(1+u);
00199       dfy=u/square(1.0+u);
00200     }
00201     else
00202     {
00203       double u=exp(x);
00204       //y=u/(1.0+u);
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     //double y=(x-fmin)/(fmax-fmin);
00371     //double u=1.e-20+y/(1.e-20+(1.0-y));
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     //double y=(x-fmin)/(fmax-fmin);
00420     //double u=1.e-20+y/(1.e-20+(1.0-y));
00421     //tinv=-log(u);
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