/home/coin/SVN-release/OS-2.4.2/Couenne/src/expression/operators/exprCos.cpp

Go to the documentation of this file.
00001 /* $Id: exprCos.cpp 748 2011-07-28 16:13:32Z pbelotti $ 
00002  *
00003  * Name:    exprCos.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: methods for cosines
00006  *
00007  * (C) Carnegie-Mellon University, 2006-09.
00008  * This file is licensed under the Eclipse Public License (EPL)
00009  */
00010 
00011 #include <math.h>
00012 
00013 #include "CouenneExprCos.hpp"
00014 #include "CouenneExprSin.hpp"
00015 #include "CouenneExprBCos.hpp"
00016 #include "CouenneExprOpp.hpp"
00017 #include "CouenneExprMul.hpp"
00018 #include "CouenneExprClone.hpp"
00019 
00020 using namespace Couenne;
00021 
00022 static const CouNumber 
00023   pi  = M_PI,
00024   pi2 = M_PI * 2.,
00025   pih = M_PI / 2.;
00026 
00027 
00028 // return an expression -sin (argument), the derivative of cos (argument)
00029 expression *exprCos::differentiate (int index) {
00030 
00031   return new exprOpp (new exprMul (new exprSin (new exprClone (argument_)),
00032                                    argument_ -> differentiate (index)));
00033 }
00034 
00035 
00036 // compute bounds of sin x given bounds of x 
00037 void exprCos::getBounds (expression *&lb, expression *&ub) {
00038 
00039   expression *xl, *xu;
00040   argument_ -> getBounds (xl, xu);
00041 
00042   lb = new exprLBCos (xl, xu);
00043   ub = new exprUBCos (new exprClone (xl), new exprClone (xu));
00044 }
00045 
00046 // compute value of bounds of cos x given bounds of x 
00047 void exprCos::getBounds (CouNumber &lb, CouNumber &ub) {
00048 
00049   CouNumber l, u;
00050   argument_ -> getBounds (l, u);
00051 
00052   if ((u - l >= pi2) ||      // 1) interval spans whole cycle
00053       (floor (l/pi2 - 0.5) < // 2) there is a pi + 2k pi between l and u
00054        floor (u/pi2 - 0.5))) 
00055     lb = -1.;
00056   else lb = CoinMin (cos (l), cos (u));
00057 
00058   if ((u - l >= pi2) || // 1) interval spans whole cycle
00059       (floor (l/pi2) <  // 2) there is a 3/2 pi + 2k pi between l and u
00060        floor (u/pi2))) 
00061     ub = 1.;
00062   else ub = CoinMax (cos (l), cos (u));
00063 }
00064 
00065 
00067 void exprCos::closestFeasible (expression *varind, expression *vardep,
00068                                CouNumber& left, CouNumber& right) const
00069 {
00070   CouNumber curr = (*varind)();
00071   int period = (int)(curr/pi2);
00072   CouNumber curr_noperiod = curr - pi2*period;
00073   CouNumber inv = acos((*vardep)());
00074 
00075   if (curr_noperiod < inv) {
00076     left = pi2*period - inv;
00077     right = pi2*period + inv;
00078   }
00079   else if (curr_noperiod < pi2-inv) {
00080     left = pi2*period + inv;
00081     right = pi2*(period+1) - inv;
00082   }
00083   else {
00084     left = pi2*(period+1) - inv;
00085     right = pi2*(period+1) + inv;
00086   }
00087 }

Generated on Wed Nov 30 03:04:02 2011 by  doxygen 1.4.7