| 393 | } |
| 394 | |
| 395 | HighsStatus Highs::addColsInterface( |
| 396 | HighsInt ext_num_new_col, const double* ext_col_cost, |
| 397 | const double* ext_col_lower, const double* ext_col_upper, |
| 398 | HighsInt ext_num_new_nz, const HighsInt* ext_a_start, |
| 399 | const HighsInt* ext_a_index, const double* ext_a_value) { |
| 400 | HighsStatus return_status = HighsStatus::kOk; |
| 401 | HighsOptions& options = options_; |
| 402 | if (ext_num_new_col < 0) return HighsStatus::kError; |
| 403 | if (ext_num_new_nz < 0) return HighsStatus::kError; |
| 404 | if (ext_num_new_col == 0) return HighsStatus::kOk; |
| 405 | if (ext_num_new_col > 0) |
| 406 | if (isColDataNull(options.log_options, ext_col_cost, ext_col_lower, |
| 407 | ext_col_upper)) |
| 408 | return HighsStatus::kError; |
| 409 | if (ext_num_new_nz > 0) |
| 410 | if (isMatrixDataNull(options.log_options, ext_a_start, ext_a_index, |
| 411 | ext_a_value)) |
| 412 | return HighsStatus::kError; |
| 413 | |
| 414 | HighsLp& lp = model_.lp_; |
| 415 | HighsBasis& basis = basis_; |
| 416 | HighsScale& scale = lp.scale_; |
| 417 | bool& useful_basis = basis.useful; |
| 418 | bool& lp_has_scaling = lp.scale_.has_scaling; |
| 419 | |
| 420 | // Check that if nonzeros are to be added then the model has a positive number |
| 421 | // of rows |
| 422 | if (lp.num_row_ <= 0 && ext_num_new_nz > 0) return HighsStatus::kError; |
| 423 | |
| 424 | // Record the new number of columns |
| 425 | HighsInt newNumCol = lp.num_col_ + ext_num_new_col; |
| 426 | |
| 427 | HighsIndexCollection index_collection; |
| 428 | index_collection.dimension_ = ext_num_new_col; |
| 429 | index_collection.is_interval_ = true; |
| 430 | index_collection.from_ = 0; |
| 431 | index_collection.to_ = ext_num_new_col - 1; |
| 432 | |
| 433 | // Take a copy of the cost and bounds that can be normalised |
| 434 | std::vector<double> local_colCost{ext_col_cost, |
| 435 | ext_col_cost + ext_num_new_col}; |
| 436 | std::vector<double> local_colLower{ext_col_lower, |
| 437 | ext_col_lower + ext_num_new_col}; |
| 438 | std::vector<double> local_colUpper{ext_col_upper, |
| 439 | ext_col_upper + ext_num_new_col}; |
| 440 | |
| 441 | bool local_has_infinite_cost = false; |
| 442 | return_status = interpretCallStatus( |
| 443 | options_.log_options, |
| 444 | assessCosts(options, lp.num_col_, index_collection, local_colCost, |
| 445 | local_has_infinite_cost, options.infinite_cost), |
| 446 | return_status, "assessCosts"); |
| 447 | if (return_status == HighsStatus::kError) return return_status; |
| 448 | // Assess the column bounds |
| 449 | return_status = interpretCallStatus( |
| 450 | options_.log_options, |
| 451 | assessBounds(options, "Col", lp.num_col_, index_collection, |
| 452 | local_colLower, local_colUpper, options.infinite_bound), |
nothing calls this directly
no test coverage detected