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