File: TestModelProperties.cpp

package info (click to toggle)
scipy 1.16.3-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 236,092 kB
  • sloc: cpp: 503,720; python: 345,302; ansic: 195,677; javascript: 89,566; fortran: 56,210; cs: 3,081; f90: 1,150; sh: 857; makefile: 792; pascal: 284; csh: 135; lisp: 134; xml: 56; perl: 51
file content (141 lines) | stat: -rw-r--r-- 5,084 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include <cmath>

#include "Highs.h"
#include "catch.hpp"

const bool dev_run = false;
const double inf = kHighsInf;

TEST_CASE("simplest-ill-conditioning", "[highs_model_properties]") {
  Highs highs;
  highs.setOptionValue("output_flag", dev_run);
  HighsLp lp;
  const double epsilon = 1e-4;
  const double ill_conditioning_bound = 1;
  lp.num_col_ = 2;
  lp.num_row_ = 2;
  lp.col_cost_ = {2, 2 + epsilon};
  lp.col_lower_ = {0, 0};
  lp.col_upper_ = {inf, inf};
  lp.row_lower_ = {2, 2 + epsilon};
  lp.row_upper_ = {inf, inf};
  lp.a_matrix_.start_ = {0, 2, 4};
  lp.a_matrix_.index_ = {0, 1, 0, 1};
  lp.a_matrix_.value_ = {1, 1, 1, 1 + epsilon};
  highs.passModel(lp);
  highs.run();
  if (dev_run) highs.writeSolution("", 1);
  HighsIllConditioning ill_conditioning;

  const bool constraint = true;
  highs.getIllConditioning(ill_conditioning, constraint);
  REQUIRE(ill_conditioning.record.size() == 2);
  // Both multipliers should be large
  for (HighsInt iX = 0; iX < 2; iX++) {
    REQUIRE(std::fabs(ill_conditioning.record[iX].multiplier) > 0.45);
    REQUIRE(std::fabs(ill_conditioning.record[iX].multiplier) < 0.55);
  }
  highs.getIllConditioning(ill_conditioning, !constraint);

  REQUIRE(highs.getIllConditioning(ill_conditioning, constraint, 1, 0.1) ==
          HighsStatus::kOk);
  REQUIRE(highs.getIllConditioning(ill_conditioning, constraint, 1,
                                   ill_conditioning_bound) == HighsStatus::kOk);
  REQUIRE(highs.getIllConditioning(ill_conditioning, constraint, 1, 10) ==
          HighsStatus::kOk);
}

TEST_CASE("simple-ill-conditioning", "[highs_model_properties]") {
  Highs highs;
  highs.setOptionValue("output_flag", dev_run);
  HighsLp lp;
  const double epsilon = 1e-4;
  lp.num_col_ = 3;
  lp.num_row_ = 3;
  lp.col_cost_ = {3, 2, 3 + epsilon};
  lp.col_lower_ = {0, 0, 0};
  lp.col_upper_ = {inf, inf, inf};
  lp.row_lower_ = {3, 2, 3 + epsilon};
  lp.row_upper_ = {inf, inf, inf};
  lp.a_matrix_.start_ = {0, 3, 5, 8};
  lp.a_matrix_.index_ = {0, 1, 2, 0, 2, 0, 1, 2};
  lp.a_matrix_.value_ = {1, 1, 1, 1, 1, 1, 1, 1 + epsilon};

  highs.passModel(lp);
  highs.run();
  if (dev_run) highs.writeSolution("", 1);
  HighsIllConditioning ill_conditioning;
  const bool constraint = true;
  highs.getIllConditioning(ill_conditioning, constraint);
  REQUIRE(ill_conditioning.record.size() == 3);
  // First two multipliers should be the large ones
  for (HighsInt iX = 0; iX < 2; iX++) {
    REQUIRE(std::fabs(ill_conditioning.record[iX].multiplier) > 0.45);
    REQUIRE(std::fabs(ill_conditioning.record[iX].multiplier) < 0.55);
  }
  highs.getIllConditioning(ill_conditioning, !constraint);
}

TEST_CASE("afiro-ill-conditioning", "[highs_model_properties]") {
  std::string filename = std::string(HIGHS_DIR) + "/check/instances/afiro.mps";
  Highs highs;
  highs.setOptionValue("output_flag", dev_run);
  highs.readModel(filename);
  const HighsLp& lp = highs.getLp();
  HighsInt num_nz;
  std::vector<HighsInt> index(lp.num_col_);
  std::vector<double> value(lp.num_col_);
  highs.run();
  const HighsBasis& highs_basis = highs.getBasis();
  lp.a_matrix_.getRow(0, num_nz, index.data(), value.data());
  if (dev_run) {
    for (HighsInt iEl = 0; iEl < num_nz; iEl++) {
      HighsInt iCol = index[iEl];
      printf("%s: %d %19.12g (%s)\n", lp.col_names_[iCol].c_str(), int(iCol),
             value[iEl],
             highs.basisStatusToString(highs_basis.col_status[iCol]).c_str());
    }
  }
  value[0] += 1e-4;

  const bool negate_bad_row = false;
  if (negate_bad_row)
    for (HighsInt iEl = 0; iEl < num_nz; iEl++) value[iEl] *= -1;

  highs.addRow(0, 0, num_nz, index.data(), value.data());
  HighsInt bad_row = lp.num_row_ - 1;
  highs.passRowName(bad_row, "R09bad");
  // Find a nonbasic row to replace bad row in the basis
  HighsInt nonbasic_row = -1;
  for (HighsInt iRow = 1; iRow < lp.num_row_; iRow++) {
    if (dev_run) {
      printf("Row %d (%s) has status %s\n", int(iRow),
             lp.row_names_[iRow].c_str(),
             highs.basisStatusToString(highs_basis.row_status[iRow]).c_str());
    }
    if (highs_basis.row_status[iRow] != HighsBasisStatus::kBasic) {
      nonbasic_row = iRow;
      break;
    }
  }
  // Bad row should be basic - since it's been added
  REQUIRE(highs_basis.row_status[bad_row] == HighsBasisStatus::kBasic);
  REQUIRE(nonbasic_row >= 0);
  HighsBasis basis = highs_basis;
  // Make the bad row nonbasic at lower bound - it's FX - and make the
  // nonbasic_row basic
  basis.row_status[bad_row] = HighsBasisStatus::kLower;
  basis.row_status[nonbasic_row] = HighsBasisStatus::kBasic;
  highs.setBasis(basis);
  if (dev_run) {
    for (HighsInt iRow = 0; iRow < lp.num_row_; iRow++) {
      printf("Row %d (%s) has status %s\n", int(iRow),
             lp.row_names_[iRow].c_str(),
             highs.basisStatusToString(highs_basis.row_status[iRow]).c_str());
    }
  }
  HighsIllConditioning ill_conditioning;
  const bool constraint = true;
  highs.getIllConditioning(ill_conditioning, constraint);
  highs.getIllConditioning(ill_conditioning, !constraint);
}