/home/coin/SVN-release/OS-2.4.2/Couenne/src/util/rootQ.cpp

Go to the documentation of this file.
00001 /* $Id: rootQ.cpp 513 2011-03-03 01:43:48Z pbelotti $
00002  *
00003  * Name:    rootQ.cpp
00004  * Author:  Pietro Belotti
00005  * Purpose: find roots of polynomial Q^k(x) (see Liberti and Pantelides, 2003)
00006  *
00007  * (C) Carnegie-Mellon University, 2006-11.
00008  * This file is licensed under the Eclipse Public License (EPL)
00009  */
00010 
00011 #include <math.h>
00012 #include <stdio.h>
00013 
00014 #include "CouenneTypes.hpp"
00015 #include "CouennePrecisions.hpp"
00016 
00017 namespace Couenne {
00018 
00019 /* compute Q(x) */
00020 
00021 CouNumber Q (register int k, CouNumber x) {
00022 
00023   register CouNumber xp = x, Q = 1.;
00024 
00025   k *= 2;
00026 
00027   for (register int i=2; i<=k; i++) {
00028 
00029     Q += (CouNumber) i * xp;
00030     xp *= x;
00031   }
00032 
00033   return Q;
00034 }
00035 
00036 
00037 /*
00038  * Find roots of polynomial $Q^k(x) = \sum_{i=1}^{2k} i x^{i-1}$. Used
00039  *  in convexification of powers with odd exponent
00040  */
00041 
00042 CouNumber rootQ (int k) {
00043 
00044   if (k==1) return - 0.5; // for x^3, solution is -1/2
00045   else {
00046 
00047     register CouNumber 
00048       l  = - 1.0 + 0.5 / k, 
00049       u  = - 0.5,
00050       /* Ql = Q (k, l), Qu = Q (k, u), */
00051       Qm,
00052       midpoint;
00053     do {
00054 
00055       midpoint = 0.5 * (l+u); /* (- Ql * u + Qu * l) / (Qu - Ql); */
00056       Qm = Q (k, midpoint);
00057 
00058       /*      printf ("[%.4f, %.4f] --> %.4f: %.24f\n", l, u, midpoint, Qm); */
00059 
00060       if (Qm<0) {l = midpoint; /* Ql = Qm; */ Qm = - Qm;} // invert sign to avoid fabs() in termination check
00061       else      {u = midpoint; /* Qu = Qm; */}
00062 
00063     } while (Qm > 1e-15);
00064 
00065     return midpoint;
00066   }
00067 }
00068 
00069 }
00070 
00071 #ifdef DEBUG_ROOTQ
00072 int main () {
00073 
00074   register int k;
00075   CouNumber x, q;
00076 
00077   for (k=6; --k;) {
00078 
00079     printf ("root, %3d -> %.15f\n", 2*k+1, rootQ (k));
00080     /*
00081     printf ("k=%3d: ", 2*k+1);
00082     for (x = -1.0; x < 0.4; x += 0.1) {
00083       //      Q (k, x, &q, NULL, NULL); 
00084       printf ("[%.2f, %.3f] ", x, rootQ);
00085     }
00086     printf ("\n");
00087     */
00088   }
00089 }
00090 
00091 #endif

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