exprSin.cpp
Go to the documentation of this file.
1 /* $Id: exprSin.cpp 748 2011-07-28 16:13:32Z pbelotti $
2  *
3  * Name: exprSin.cpp
4  * Author: Pietro Belotti
5  * Purpose: definition of the sine of a function
6  *
7  * (C) Carnegie-Mellon University, 2006-09.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include <math.h>
12 
13 #include "CouenneExprSin.hpp"
14 #include "CouenneExprClone.hpp"
15 #include "CouenneExprCos.hpp"
16 #include "CouenneExprBSin.hpp"
17 #include "CouenneExprMul.hpp"
18 
19 namespace Couenne {
20 
21 static const CouNumber
22  pi = M_PI,
23  pi2 = M_PI * 2.,
24  pih = M_PI / 2.;
25 
26 // differentiation
27 
29 
30  return new exprMul (new exprCos (new exprClone (argument_)),
31  argument_ -> differentiate (index));
32 }
33 
34 
35 // compute bounds of sin x given bounds of x
37 
38  expression *xl, *xu;
39 
40  argument_ -> getBounds (xl, xu);
41 
42  lb = new exprLBSin (xl, xu);
43  ub = new exprUBSin (new exprClone (xl), new exprClone (xu));
44 }
45 
46 // compute value of bounds of cos x given bounds of x
48 
49  CouNumber l, u;
50  argument_ -> getBounds (l, u);
51 
52  if ((u - l >= pi2) || // 1) interval spans whole cycle
53  (floor (l/pi2 - 0.75) < // 2) there is a pi + 2k pi between l and u
54  floor (u/pi2 - 0.75)))
55  lb = -1.;
56  else lb = CoinMin (sin (l), sin (u));
57 
58  if ((u - l >= pi2) || // 1) interval spans whole cycle
59  (floor (l/pi2 - 0.25) < // 2) there is a 3/2 pi + 2k pi between l and u
60  floor (u/pi2 - 0.25)))
61  ub = 1.;
62  else ub = CoinMax (sin (l), sin (u));
63 }
64 
66 bool trigImpliedBound (enum cou_trig type, int wind, int xind,
67  CouNumber *l, CouNumber *u, t_chg_bounds *chg) {
68 
69  //return false; // !!!
70 
71  CouNumber *xl = l + xind, wl = l [wind],
72  *xu = u + xind, wu = u [wind];
73 
74  bool tighter = false;
75 
76  CouNumber fl, fu, iwl, iwu, displacement;
77 
78  if (type == COU_SINE) {fl = sin (*xl); fu = sin (*xu); displacement = pih;}
79  else {fl = cos (*xl); fu = cos (*xu); displacement = 0.;}
80 
81  iwl = acos (wl);
82  iwu = acos (wu);
83 
84  /*printf ("### [%s] old bd: [%g pi,%g pi] -> [%g,%g] --- w = [%g,%g] -8-> [%g pi, %g pi]\n",
85  type==COU_SINE ? "sin" : "cos",
86  *xl / pi, *xu / pi, fl, fu,
87  wl, wu, iwl/pi, iwu/pi);*/
88 
90 
91  if (wu < fl - COUENNE_EPS) {
92 
93  CouNumber base = displacement + pi2 * floor ((*xl + pi - displacement) / pi2);
94 
95  //printf ("### wu, fl: base = %g pi\n", base / pi);
96 
97  if (updateBound (-1, xl, base + iwu)) {
98  tighter = true;
99  chg [xind]. setLower (t_chg_bounds::CHANGED);
100  }
101  }
102 
103  if (wu < fu - COUENNE_EPS) {
104 
105  CouNumber base = displacement + pi2 * floor ((*xu + pi - displacement) / pi2);
106 
107  //printf ("### wu, fu: base = %g pi\n", base / pi);
108 
109  if (updateBound (+1, xu, base - iwu)) {
110  tighter = true;
111  chg [xind]. setUpper (t_chg_bounds::CHANGED);
112  }
113  }
114 
115  if (wl > fl + COUENNE_EPS) {
116 
117  CouNumber base = displacement + pi2 * floor ((*xl - displacement) / pi2) + pi;
118 
119  //printf ("### wl, fl: base = %g pi\n", base / pi);
120 
121  if (updateBound (-1, xl, base + pi - iwl)) {
122  tighter = true;
123  chg [xind]. setLower (t_chg_bounds::CHANGED);
124  }
125  }
126 
127  if (wl > fu + COUENNE_EPS) {
128 
129  CouNumber base = displacement + pi2 * floor ((*xu - displacement) / pi2) + pi;
130 
131  //printf ("### wl, fu: base = %g pi\n", base / pi);
132 
133  if (updateBound (+1, xu, base - pi + iwl)) {
134  tighter = true;
135  chg [xind]. setUpper (t_chg_bounds::CHANGED);
136  }
137  }
138 
139  //printf ("### new bounds: [%g pi, %g pi]------------------------------\n", *xl/pi, *xu/pi);
140 
141  return tighter;
142 }
143 
144 
147  CouNumber& left, CouNumber& right) const
148 {
149  CouNumber curr = (*varind)() - pih;
150  int period = (int)(curr/pi2);
151  CouNumber curr_noperiod = curr - pi2*period;
152  CouNumber inv = acos((*vardep)());
153 
154  if (curr_noperiod < inv) {
155  left = pi2*period - inv;
156  right = pi2*period + inv;
157  }
158  else if (curr_noperiod < pi2-inv) {
159  left = pi2*period + inv;
160  right = pi2*(period+1) - inv;
161  }
162  else {
163  left = pi2*(period+1) - inv;
164  right = pi2*(period+1) + inv;
165  }
166  left += pih;
167  right += pih;
168 }
169 
170 }
class to compute lower bound of a sine based on the bounds on its arguments
bool updateBound(register int sign, register CouNumber *dst, register CouNumber src)
updates maximum violation.
#define M_PI
class cosine,
status of lower/upper bound of a variable, to be checked/modified in bound tightening ...
void getBounds(expression *&, expression *&)
Get lower and upper bound of an expression (if any)
Definition: exprSin.cpp:36
expression * argument_
single argument taken by this expression
bool trigImpliedBound(enum cou_trig, int, int, CouNumber *, CouNumber *, t_chg_bounds *)
generalized implied bound procedure for sine/cosine
Definition: exprSin.cpp:66
static const CouNumber pih
Definition: exprSin.cpp:24
CouNumber inv(register CouNumber arg)
the operator itself
virtual void closestFeasible(expression *varind, expression *vardep, CouNumber &left, CouNumber &right) const
closest feasible points in function in both directions
Definition: exprSin.cpp:146
class to compute lower bound of a sine based on the bounds on its arguments
expression clone (points to another expression)
#define COUENNE_EPS
static int
Definition: OSdtoa.cpp:2173
static const CouNumber pi
Definition: exprSin.cpp:22
cou_trig
specify which trigonometric function is dealt with in trigEnvelope
double CouNumber
main number type in Couenne
Expression base class.
CouExpr & cos(CouExpr &e)
expression * differentiate(int index)
differentiation
Definition: exprSin.cpp:28
CouExpr & sin(CouExpr &e)
static const CouNumber pi2
Definition: exprSin.cpp:23
class for multiplications,