/home/coin/SVN-release/OS-2.4.2/Couenne/src/convex/operators/trigNewton.cpp

Go to the documentation of this file.
00001 /* $Id: trigNewton.cpp 490 2011-01-14 16:07:12Z pbelotti $
00002  *
00003  * Name:    trigNewton.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: numerically find tangents to (co)sines
00006  *
00007  * (C) Carnegie-Mellon University, 2006. 
00008  * This file is licensed under the Eclipse Public License (EPL)
00009  */
00010 
00011 #include <math.h>
00012 #include <stdlib.h>
00013 #include <stdio.h>
00014 #include "CouenneTypes.hpp"
00015 
00016 namespace Couenne {
00017 
00018 #define MAX_ITER 1000
00019 #define COU_TRIG_TOLERANCE 1e-12
00020 
00021 CouNumber trigNewton (CouNumber a, CouNumber l, CouNumber u) {
00022 
00023   // Find a zero to the function
00024   //
00025   // F(x) = cos x - (sin x - sin a) / (x - a)
00026   // 
00027   // whose derivative is
00028   //
00029   // F'(x) = - sin x - cos x / (x-a) + (sin x - sin a) / (x - a)^2
00030 
00031   if (l>u) {
00032     register CouNumber swap = l;
00033     l = u;
00034     u = swap;
00035   }
00036 
00037   register CouNumber xk = 0.5 * (u+l);
00038 
00039   CouNumber sina  = sin (a),
00040             sinxk = sin (xk),
00041             cosxk = cos (xk),
00042             dy    = sinxk - sina,
00043             dx    = xk - a,
00044             dydx  = dy/dx,
00045             F     = cosxk - dydx;
00046 
00047   // Newton loop. Tolerance is set above
00048   for (register int k = MAX_ITER; (fabs (F) > COU_TRIG_TOLERANCE) && k--;) {
00049 
00050     CouNumber Fp = sinxk + (cosxk - dydx) / dx;
00051 
00052     xk += F/Fp;
00053 
00054     if      (xk < l) xk = l;
00055     else if (xk > u) xk = u;
00056 
00057     sinxk = sin (xk);
00058     cosxk = cos (xk);
00059     dy    = sinxk - sina;
00060     dx    = xk - a;
00061     dydx  = dy/dx;
00062     F     = cosxk - dydx;
00063   }
00064 
00065   return xk;
00066 }
00067 
00068 }
00069 
00070 /*
00071 int main (int argc, char **argv) {
00072 
00073   CouNumber a = atof (argv [1]),
00074             l = atof (argv [2]),
00075             u = atof (argv [3]), r;
00076 
00077   for (register int i=100000; i--;)
00078     r = trigNewton (a, l, u);
00079 
00080   printf ("b0 = %.14f: slope %.15f, derivative %.15f\n", 
00081           r, (sin (r) - sin (a)) / (r-a), cos (r));
00082 
00083   return 0;
00084 }
00085 */

Generated on Wed Nov 30 03:03:59 2011 by  doxygen 1.4.7