00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "CoinHelperFunctions.hpp"
00012
00013 #include "CouenneExprLog.hpp"
00014 #include "CouenneObject.hpp"
00015 #include "CouenneBranchingObject.hpp"
00016 #include "CouenneProjections.hpp"
00017 #include "CouenneFunTriplets.hpp"
00018
00019 using namespace Couenne;
00020
00021 #define SQ_COUENNE_EPS COUENNE_EPS * COUENNE_EPS
00022
00025 CouNumber exprLog::selectBranch (const CouenneObject *obj,
00026 const OsiBranchingInformation *info,
00027 expression *&var,
00028 double * &brpts,
00029 double * &brDist,
00030
00031 int &way) {
00032
00033 brpts = (double *) realloc (brpts, sizeof (double));
00034 brDist = (double *) realloc (brDist, 2*sizeof (double));
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 var = argument_;
00054
00055 int
00056 ind = var -> Index (),
00057 wi = obj -> Reference () -> Index ();
00058
00059 assert ((ind >= 0) && (wi >= 0));
00060
00061 CouNumber
00062 y0 = info -> solution_ [wi],
00063 x0 = info -> solution_ [ind],
00064 l = info -> lower_ [ind],
00065 u = info -> upper_ [ind];
00066
00067 if (u < COUENNE_EPS) {
00068 var = NULL;
00069 return 0.;
00070 }
00071
00072 if (x0 < SQ_COUENNE_EPS)
00073 x0 = SQ_COUENNE_EPS;
00074
00075 if (y0 > log (x0)) {
00076
00077
00078
00079 *brpts = obj -> midInterval (powNewton (x0, y0, log, inv, oppInvSqr), l, u, info);
00080
00081 way = TWO_LEFT;
00082 CouNumber dy = y0 - log (*brpts);
00083 x0 -= *brpts;
00084
00085 return (brDist [0] = brDist [1] = sqrt (x0*x0 + dy*dy));
00086 }
00087
00088
00089
00090 if ((l <= SQ_COUENNE_EPS) &&
00091 (u > COUENNE_INFINITY)) {
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 brpts = (double *) realloc (brpts, sizeof (double));
00110 *brpts = 0.5 * (x0 + exp (y0));
00111 way = TWO_RAND;
00112
00113 return CoinMin (brDist [0] = x0 - exp (y0),
00114 brDist [1] = log (x0) - y0);
00115 }
00116
00117
00118
00119 brpts = (double *) realloc (brpts, sizeof (double));
00120
00121 if (l <= SQ_COUENNE_EPS) {
00122
00123 *brpts = obj -> midInterval (exp (y0), l, u, info);
00124 way = TWO_RIGHT;
00125
00126 brDist [0] = x0 - *brpts;
00127 return (brDist [1] = projectSeg (x0, y0, *brpts, log (*brpts), u, log (u), +1));
00128
00129 }
00130
00131 if (u > COUENNE_INFINITY) {
00132
00133 *brpts = CoinMax (10*x0, obj -> midInterval (x0, l, u, info));
00134 way = TWO_LEFT;
00135
00136 brDist [1] = log (*brpts) - y0;
00137
00138 return (brDist [0] = projectSeg (x0, y0, l, log (l), *brpts, log (*brpts), +1));
00139
00140 }
00141
00142
00143
00144 simpletriplet ft (log, inv, oppInvSqr, inv);
00145
00146 *brpts = obj -> getBrPoint (&ft, x0, l, u, info);
00147
00148
00149
00150
00151
00152
00153
00154 way = TWO_RAND;
00155
00156
00157 return CoinMin (brDist [0] = projectSeg (x0, y0, l, log (l), *brpts, log (*brpts), +1),
00158 brDist [1] = projectSeg (x0, y0, *brpts, log (*brpts), u, log (u), +1));
00159 }