File: TestHighsGFkSolve.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 (102 lines) | stat: -rw-r--r-- 3,102 bytes parent folder | download | duplicates (6)
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
#include <numeric>

#include "HCheckConfig.h"
#include "catch.hpp"
#include "mip/HighsGFkSolve.h"
#include "util/HighsRandom.h"

const bool dev_run = false;

template <int k>
void testGFkSolve(const std::vector<HighsInt>& Avalue,
                  const std::vector<HighsInt>& Aindex,
                  const std::vector<HighsInt>& Astart, HighsInt numRow) {
  HighsGFkSolve GFkSolve;
  GFkSolve.fromCSC<k>(Avalue, Aindex, Astart, numRow);
  GFkSolve.setRhs<k>(numRow - 1, k - 1);

  HighsInt numCol = Astart.size() - 1;
  HighsInt nnz = Avalue.size();
  for (HighsInt i = 0; i != numCol; ++i) {
    for (HighsInt j = Astart[i]; j != Astart[i + 1]; ++j) {
      HighsInt val = Avalue[j] % k;
      if (val < 0) val += k;
      REQUIRE(val >= 0);
      HighsInt pos = GFkSolve.findNonzero(Aindex[j], i);
      if (val == 0) {
        --nnz;
        REQUIRE(pos == -1);
      } else {
        REQUIRE(pos != -1);
        REQUIRE(GFkSolve.getAvalue()[pos] == (unsigned int)val);
        REQUIRE(GFkSolve.getArow()[pos] == Aindex[j]);
        REQUIRE(GFkSolve.getAcol()[pos] == i);
      }
    }
  }

  REQUIRE(nnz == GFkSolve.numNonzeros());

  GFkSolve.solve<k>(
      [&](const std::vector<HighsGFkSolve::SolutionEntry>& solution,
          int rhsIndex) {
        REQUIRE(rhsIndex == 0);
        HighsInt numSolutionNnz = solution.size();
        if (dev_run)
          printf("solution (k=%d) has %" HIGHSINT_FORMAT " nonzeros\n", k,
                 numSolutionNnz);

        std::vector<unsigned int> solSums(numRow);
        for (const auto& solentry : solution) {
          REQUIRE(solentry.weight > 0);
          REQUIRE(solentry.weight < k);
          for (HighsInt j = Astart[solentry.index];
               j != Astart[solentry.index + 1]; ++j) {
            int64_t val =
                (solSums[Aindex[j]] + (Avalue[j] * (int64_t)solentry.weight)) %
                k;
            if (val < 0) val += k;
            solSums[Aindex[j]] = val;
          }
        }

        for (HighsInt i = 0; i < numRow - 1; ++i) REQUIRE(solSums[i] == 0);

        REQUIRE(solSums[numRow - 1] == k - 1);
      });
}

TEST_CASE("GFkSolve", "[mip]") {
  std::vector<HighsInt> Avalue;
  std::vector<HighsInt> Aindex;
  std::vector<HighsInt> Astart;

  HighsRandom randgen;
  HighsInt numRow = 10;
  HighsInt numCol = 100;

  std::vector<HighsInt> rowInds(numRow);
  std::iota(rowInds.begin(), rowInds.end(), 0);

  Astart.push_back(0);

  for (HighsInt i = 0; i != numCol; ++i) {
    randgen.shuffle(rowInds.data(), rowInds.size());
    HighsInt numentry = randgen.integer(5, 11);

    for (HighsInt j = 0; j != numentry; ++j) {
      HighsInt val = randgen.integer(-10000, 10001);
      if (val == 0) ++val;
      Avalue.push_back(randgen.integer(-10000, 10001));
      Aindex.push_back(rowInds[j]);
    }

    Astart.push_back(Avalue.size());
  }

  testGFkSolve<2>(Avalue, Aindex, Astart, numRow);
  testGFkSolve<3>(Avalue, Aindex, Astart, numRow);
  testGFkSolve<5>(Avalue, Aindex, Astart, numRow);
  testGFkSolve<7>(Avalue, Aindex, Astart, numRow);
  testGFkSolve<11>(Avalue, Aindex, Astart, numRow);
}