/home/coin/SVN-release/OS-2.1.0/Couenne/src/expression/operators/exprSin.cpp

Go to the documentation of this file.
00001 /* $Id: exprSin.cpp 182 2009-07-01 13:37:04Z pbelotti $
00002  *
00003  * Name:    exprSin.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: definition of the sine of a function
00006  *
00007  * (C) Carnegie-Mellon University, 2006-09.
00008  * This file is licensed under the Common Public License (CPL)
00009  */
00010 
00011 #include <math.h>
00012 
00013 #include "exprSin.hpp"
00014 #include "exprClone.hpp"
00015 #include "exprCos.hpp"
00016 #include "exprBSin.hpp"
00017 #include "exprMul.hpp"
00018 
00019 static const CouNumber 
00020   pi  = M_PI,
00021   pi2 = M_PI * 2.,
00022   pih = M_PI / 2.;
00023 
00024 // differentiation
00025 
00026 expression *exprSin::differentiate (int index) {
00027 
00028   return new exprMul (new exprCos (new exprClone (argument_)),
00029                       argument_ -> differentiate (index));
00030 }
00031 
00032 
00033 // compute bounds of sin x given bounds of x 
00034 void exprSin::getBounds (expression *&lb, expression *&ub) {
00035 
00036   expression *xl, *xu;
00037 
00038   argument_ -> getBounds (xl, xu);
00039 
00040   lb = new exprLBSin (xl, xu);
00041   ub = new exprUBSin (new exprClone (xl), new exprClone (xu));
00042 }
00043 
00044 // compute value of bounds of cos x given bounds of x 
00045 void exprSin::getBounds (CouNumber &lb, CouNumber &ub) {
00046 
00047   CouNumber l, u;
00048   argument_ -> getBounds (l, u);
00049 
00050   if ((u - l > pi2) ||        // 1) interval spans whole cycle
00051       (floor (l/pi2 - 0.75) < // 2) there is a pi + 2k pi between l and u
00052        floor (u/pi2 - 0.75))) 
00053     lb = -1.;
00054   else lb = CoinMin (sin (l), sin (u));
00055 
00056   if ((u - l > pi2) ||        // 1) interval spans whole cycle
00057       (floor (l/pi2 - 0.25) < // 2) there is a 3/2 pi + 2k pi between l and u
00058        floor (u/pi2 - 0.25))) 
00059     ub = 1.;
00060   else ub = CoinMax (sin (l), sin (u));
00061 }
00062 
00064 bool trigImpliedBound (enum cou_trig type, int wind, int xind,
00065                        CouNumber *l, CouNumber *u, t_chg_bounds *chg) {
00066 
00067   //return false; // !!!
00068 
00069   CouNumber *xl = l + xind, wl = l [wind],
00070             *xu = u + xind, wu = u [wind];
00071 
00072   bool tighter = false;
00073 
00074   CouNumber fl, fu, iwl, iwu, displacement;
00075 
00076   if (type == COU_SINE) {fl = sin (*xl); fu = sin (*xu); displacement = pih;} 
00077   else                  {fl = cos (*xl); fu = cos (*xu); displacement = 0.;}
00078 
00079   iwl = acos (wl);
00080   iwu = acos (wu);
00081 
00082   /*printf ("### [%s] old bd: [%g pi,%g pi] -> [%g,%g]  ---  w = [%g,%g] -8-> [%g pi, %g pi]\n", 
00083           type==COU_SINE ? "sin" : "cos", 
00084            *xl / pi, *xu / pi, fl, fu, 
00085            wl, wu, iwl/pi, iwu/pi);*/
00086 
00088 
00089   if (wu < fl - COUENNE_EPS) {
00090 
00091     CouNumber base = displacement + pi2 * floor ((*xl + pi - displacement) / pi2);
00092 
00093     //printf ("### wu, fl: base = %g pi\n", base / pi);
00094 
00095     if (updateBound (-1, xl, base + iwu)) {
00096       tighter = true; 
00097       chg [xind]. setLower (t_chg_bounds::CHANGED);
00098     }
00099   }
00100 
00101   if (wu < fu - COUENNE_EPS) {
00102 
00103     CouNumber base = displacement + pi2 * floor ((*xu + pi - displacement) / pi2);
00104 
00105     //printf ("### wu, fu: base = %g pi\n", base / pi);
00106 
00107     if (updateBound (+1, xu, base - iwu)) {
00108       tighter = true; 
00109       chg [xind]. setUpper (t_chg_bounds::CHANGED);
00110     }
00111   }
00112 
00113   if (wl > fl + COUENNE_EPS) {
00114 
00115     CouNumber base = displacement + pi2 * floor ((*xl - displacement) / pi2) + pi;
00116 
00117     //printf ("### wl, fl: base = %g pi\n", base / pi);
00118 
00119     if (updateBound (-1, xl, base + pi - iwl)) {
00120       tighter = true; 
00121       chg [xind]. setLower (t_chg_bounds::CHANGED);
00122     }
00123   }
00124 
00125   if (wl > fu + COUENNE_EPS) {
00126 
00127     CouNumber base = displacement + pi2 * floor ((*xu - displacement) / pi2) + pi;
00128 
00129     //printf ("### wl, fu: base = %g pi\n", base / pi);
00130 
00131     if (updateBound (+1, xu, base - pi + iwl)) {
00132       tighter = true; 
00133       chg [xind]. setUpper (t_chg_bounds::CHANGED);
00134     }
00135   }
00136 
00137   //printf ("### new bounds: [%g pi, %g pi]------------------------------\n", *xl/pi, *xu/pi);
00138 
00139   return tighter;
00140 }
00141 
00142 
00144 void exprSin::closestFeasible (expression *varind, expression *vardep,
00145                                CouNumber& left, CouNumber& right) const
00146 {
00147   CouNumber curr = (*varind)() - pih;
00148   int period = (int)(curr/pi2);
00149   CouNumber curr_noperiod = curr - pi2*period;
00150   CouNumber inv = acos((*vardep)());
00151 
00152   if (curr_noperiod < inv) {
00153     left = pi2*period - inv;
00154     right = pi2*period + inv;
00155   }
00156   else if (curr_noperiod < pi2-inv) {
00157     left = pi2*period + inv;
00158     right = pi2*(period+1) - inv;
00159   }
00160   else {
00161     left = pi2*(period+1) - inv;
00162     right = pi2*(period+1) + inv;
00163   }
00164   left += pih;
00165   right += pih;
00166 }

Generated on Tue Mar 30 03:04:37 2010 by  doxygen 1.4.7