@@ -1048,12 +1048,22 @@ void HighsPostsolveStack::DuplicateColumn::undoFix(
10481048 }
10491049 };
10501050
1051+ auto computeValue = [mergeValue, scale](double value) {
1052+ return static_cast <double >((static_cast <HighsCDouble>(mergeValue) - value) /
1053+ scale);
1054+ };
1055+
1056+ auto computeInvValue = [mergeValue, scale](double value) {
1057+ return static_cast <double >(static_cast <HighsCDouble>(mergeValue) -
1058+ static_cast <HighsCDouble>(value) * scale);
1059+ };
1060+
10511061 auto findValue = [&](double & z_value, double z_0, double z_1, double z_delta,
10521062 double & other_value, double other_lower,
10531063 double other_upper, bool other_int) {
10541064 const double eps = 1e-8 ;
10551065 for (z_value = z_0;; z_value += z_delta) {
1056- other_value = double (( HighsCDouble (mergeValue) - z_value) / scale );
1066+ other_value = computeValue ( z_value);
10571067 if (isFeasible (other_lower, other_value, other_upper) &&
10581068 (!other_int || isInteger (other_value)))
10591069 return true ;
@@ -1063,6 +1073,16 @@ void HighsPostsolveStack::DuplicateColumn::undoFix(
10631073 return false ;
10641074 };
10651075
1076+ auto setXValue = [&](double value) {
1077+ x_v = value;
1078+ y_v = computeValue (value);
1079+ };
1080+
1081+ auto setYValue = [&](double value) {
1082+ y_v = value;
1083+ x_v = computeInvValue (value);
1084+ };
1085+
10661086 if (x_int) {
10671087 double x_0;
10681088 double x_d;
@@ -1096,14 +1116,12 @@ void HighsPostsolveStack::DuplicateColumn::undoFix(
10961116 if (y_lo <= -kHighsInf ) {
10971117 v_m_a_ylo = scale > 0 ? kHighsInf : -kHighsInf ;
10981118 } else {
1099- v_m_a_ylo =
1100- double ((HighsCDouble (mergeValue) - HighsCDouble (y_lo) * scale));
1119+ v_m_a_ylo = computeInvValue (y_lo);
11011120 }
11021121 if (y_up >= kHighsInf ) {
11031122 v_m_a_yup = scale > 0 ? -kHighsInf : kHighsInf ;
11041123 } else {
1105- v_m_a_yup =
1106- double ((HighsCDouble (mergeValue) - HighsCDouble (y_up) * scale));
1124+ v_m_a_yup = computeInvValue (y_up);
11071125 }
11081126 // Need to ensure that y puts x in [x_l, x_u]
11091127 if (scale > 0 ) {
@@ -1118,16 +1136,13 @@ void HighsPostsolveStack::DuplicateColumn::undoFix(
11181136 if (kAllowDeveloperAssert )
11191137 assert (x_up + primal_feasibility_tolerance >= v_m_a_yup);
11201138 // This assignment is OK unless x_v < x_lo-eps
1121- y_v = y_up;
1122- x_v = v_m_a_yup;
1139+ setYValue (y_up);
11231140 if (x_v < x_lo - primal_feasibility_tolerance) {
11241141 // Try y_v corresponding to x_lo
1125- x_v = x_lo;
1126- y_v = double ((HighsCDouble (mergeValue) - x_v) / scale);
1142+ setXValue (x_lo);
11271143 if (y_v < y_lo - primal_feasibility_tolerance) {
11281144 // Very tight: use x_v on its margin and hope!
1129- x_v = x_lo - primal_feasibility_tolerance;
1130- y_v = double ((HighsCDouble (mergeValue) - x_v) / scale);
1145+ setXValue (x_lo - primal_feasibility_tolerance);
11311146 }
11321147 }
11331148 } else if (y_lo > -kHighsInf ) {
@@ -1137,52 +1152,38 @@ void HighsPostsolveStack::DuplicateColumn::undoFix(
11371152 if (kAllowDeveloperAssert )
11381153 assert (x_lo - primal_feasibility_tolerance <= v_m_a_ylo);
11391154 // This assignment is OK unless x_v > x_up-eps
1140- y_v = y_lo;
1141- x_v = v_m_a_ylo;
1155+ setYValue (y_lo);
11421156 if (x_v > x_up + primal_feasibility_tolerance) {
11431157 // Try y_v corresponding to x_up
1144- // if (kAllowDeveloperAssert) assert(1==102);
1145- x_v = x_up;
1146- y_v = double ((HighsCDouble (mergeValue) - x_v) / scale);
1158+ setXValue (x_up);
11471159 if (y_v > y_up + primal_feasibility_tolerance) {
11481160 // Very tight: use x_v on its margin and hope!
1149- if (debug_report) printf (" DuplicateColumn::undoFix 2==102\n " );
1150- if (kAllowDeveloperAssert ) assert (2 == 102 );
1151- x_v = x_up + primal_feasibility_tolerance;
1152- y_v = double ((HighsCDouble (mergeValue) - x_v) / scale);
1161+ setXValue (x_up + primal_feasibility_tolerance);
11531162 }
11541163 }
11551164 } else {
11561165 // y is free, so use x_v = max(0, x_lo)
1157- x_v = std::max (0.0 , x_lo);
1158- y_v = double ((HighsCDouble (mergeValue) - x_v) / scale);
1166+ setXValue (std::max (0.0 , x_lo));
11591167 }
11601168 } else { // scale < 0
11611169 if (debug_report)
11621170 printf (" DuplicateColumn::undo [V-a(y_l), V-a(y_u)] == [%g, %g]\n " ,
11631171 v_m_a_ylo, v_m_a_yup);
11641172 // V-ay is in [V-a(y_l), V-a(y_u)] == [v_m_a_ylo, v_m_a_yup]
1165- //
11661173 if (y_lo > -kHighsInf ) {
11671174 // If v_m_a_ylo is right of x_up+eps then [v_m_a_ylo, v_m_a_yup] is
11681175 // right of [x_lo-eps, x_up+eps] so there's no solution. [Could
11691176 // try v_m_a_ylo computed from y_up+eps.]
11701177 if (kAllowDeveloperAssert )
11711178 assert (x_up + primal_feasibility_tolerance >= v_m_a_ylo);
11721179 // This assignment is OK unless x_v < x_lo-eps
1173- y_v = y_lo;
1174- x_v = v_m_a_ylo;
1180+ setYValue (y_lo);
11751181 if (x_v < x_lo - primal_feasibility_tolerance) {
11761182 // Try y_v corresponding to x_lo
1177- // if (kAllowDeveloperAssert) assert(11==101);
1178- x_v = x_lo;
1179- y_v = double ((HighsCDouble (mergeValue) - x_v) / scale);
1183+ setXValue (x_lo);
11801184 if (y_v > y_up + primal_feasibility_tolerance) {
11811185 // Very tight: use x_v on its margin and hope!
1182- if (debug_report) printf (" DuplicateColumn::undoFix 12==101\n " );
1183- if (kAllowDeveloperAssert ) assert (12 == 101 );
1184- x_v = x_lo - primal_feasibility_tolerance;
1185- y_v = double ((HighsCDouble (mergeValue) - x_v) / scale);
1186+ setXValue (x_lo - primal_feasibility_tolerance);
11861187 }
11871188 }
11881189 } else if (y_up < kHighsInf ) {
@@ -1192,25 +1193,18 @@ void HighsPostsolveStack::DuplicateColumn::undoFix(
11921193 if (kAllowDeveloperAssert )
11931194 assert (x_lo - primal_feasibility_tolerance <= v_m_a_yup);
11941195 // This assignment is OK unless x_v < x_lo-eps
1195- y_v = y_up;
1196- x_v = v_m_a_yup;
1196+ setYValue (y_up);
11971197 if (x_v > x_up + primal_feasibility_tolerance) {
11981198 // Try y_v corresponding to x_up
1199- // if (kAllowDeveloperAssert) assert(11==102);
1200- x_v = x_up;
1201- y_v = double ((HighsCDouble (mergeValue) - x_v) / scale);
1199+ setXValue (x_up);
12021200 if (y_v < y_lo - primal_feasibility_tolerance) {
12031201 // Very tight: use x_v on its margin and hope!
1204- if (debug_report) printf (" DuplicateColumn::undoFix 12==102\n " );
1205- if (kAllowDeveloperAssert ) assert (12 == 102 );
1206- x_v = x_up + primal_feasibility_tolerance;
1207- y_v = double ((HighsCDouble (mergeValue) - x_v) / scale);
1202+ setXValue (x_up + primal_feasibility_tolerance);
12081203 }
12091204 }
12101205 } else {
12111206 // y is free, so use x_v = max(0, x_lo)
1212- x_v = std::max (0.0 , x_lo);
1213- y_v = double ((HighsCDouble (mergeValue) - x_v) / scale);
1207+ setXValue (std::max (0.0 , x_lo));
12141208 }
12151209 }
12161210 }
0 commit comments