| 20 | } |
| 21 | |
| 22 | bool checkRayDirection(const HighsInt dim, const vector<double>& ray_value, |
| 23 | const vector<double>& expected_ray_value) { |
| 24 | bool ray_ok = true; |
| 25 | HighsInt from_ix = -1; |
| 26 | for (HighsInt ix = 0; ix < dim; ix++) { |
| 27 | if (fabs(expected_ray_value[ix]) > zero_ray_value_tolerance) { |
| 28 | // Found a nonzero in the expected ray values |
| 29 | from_ix = ix; |
| 30 | break; |
| 31 | } else { |
| 32 | // Found a zero in the expected ray values, so make sure that |
| 33 | // the ray value is also zero |
| 34 | if (fabs(ray_value[ix]) > zero_ray_value_tolerance) { |
| 35 | ray_ok = false; |
| 36 | break; |
| 37 | } |
| 38 | } |
| 39 | } |
| 40 | if (!ray_ok) return ray_ok; |
| 41 | if (from_ix < 0) return ray_ok; |
| 42 | double scale = ray_value[from_ix] / expected_ray_value[from_ix]; |
| 43 | for (HighsInt ix = from_ix + 1; ix < dim; ix++) { |
| 44 | double scaled_expected_ray_value = expected_ray_value[ix] * scale; |
| 45 | if (fabs(ray_value[ix] - scaled_expected_ray_value) > |
| 46 | zero_ray_value_tolerance) { |
| 47 | ray_ok = false; |
| 48 | break; |
| 49 | } |
| 50 | } |
| 51 | return ray_ok; |
| 52 | } |
| 53 | |
| 54 | bool checkDualUnboundednessDirection( |
| 55 | Highs& highs, const vector<double>& dual_unboundedness_direction_value) { |