| 3112 | } |
| 3113 | |
| 3114 | HighsStatus Highs::userUnscale(HighsUserScaleData& data) { |
| 3115 | if (!data.applied) return HighsStatus::kOk; |
| 3116 | // Unscale the incumbent model and solution |
| 3117 | HighsStatus status = HighsStatus::kOk; |
| 3118 | // Flip the scaling sign |
| 3119 | data.user_objective_scale *= -1; |
| 3120 | data.user_bound_scale *= -1; |
| 3121 | HighsStatus unscale_status = this->userScaleModel(data); |
| 3122 | if (unscale_status == HighsStatus::kError) { |
| 3123 | highsLogUser( |
| 3124 | this->options_.log_options, HighsLogType::kError, |
| 3125 | "Unexpected error removing user scaling from the incumbent model\n"); |
| 3126 | assert(unscale_status != HighsStatus::kError); |
| 3127 | } |
| 3128 | const bool update_kkt = true; |
| 3129 | unscale_status = this->userScaleSolution(data, update_kkt); |
| 3130 | highsLogUser(this->options_.log_options, HighsLogType::kInfo, |
| 3131 | "After solving the user-scaled model, the unscaled solution " |
| 3132 | "has objective value %.12g\n", |
| 3133 | this->info_.objective_function_value); |
| 3134 | if (model_status_ == HighsModelStatus::kOptimal && |
| 3135 | unscale_status != HighsStatus::kOk) { |
| 3136 | // KKT errors in the unscaled optimal solution, so log a warning and |
| 3137 | // return |
| 3138 | highsLogUser( |
| 3139 | this->options_.log_options, HighsLogType::kWarning, |
| 3140 | "User scaled problem solved to optimality, but unscaled solution " |
| 3141 | "does not satisfy feasibility and optimality tolerances\n"); |
| 3142 | status = HighsStatus::kWarning; |
| 3143 | } |
| 3144 | return status; |
| 3145 | } |
| 3146 | |
| 3147 | HighsStatus Highs::userScaleModel(HighsUserScaleData& data) { |
| 3148 | // Consider applying user objective and bound scaling to the model |
no test coverage detected