1 
2 #ifndef CoinPresolveMonitor_H
3 #define CoinPresolveMonitor_H
4 
5 /*!
6   \brief Monitor a row or column for modification
7 
8   The purpose of this class is to monitor a row or column for modifications
9   during presolve and postsolve. Each object can monitor one row or
10   column. The initial copy of the row or column is loaded by the constructor.
11   Each subsequent call to checkAndTell() compares the current state of the row
12   or column with the stored state and reports any modifications.
13 
14   Internally the row or column is held as a CoinPackedVector so that it's
15   possible to follow a row or column through presolve (CoinPresolveMatrix)
16   and postsolve (CoinPostsolveMatrix).
17 
18   Do not underestimate the amount of work required here. Extracting a row from
19   the CoinPostsolve matrix requires a scan of every element in the matrix.
20   That's one scan by the constructor and one scan with every call to modify.
21   But that's precisely why it's virtually impossible to debug presolve without
22   aids.
23 
24   Parameter overloads for CoinPresolveMatrix and CoinPostsolveMatrix are a
25   little clumsy, but not a problem in use. The alternative is to add methods
26   to the CoinPresolveMatrix and CoinPostsolveMatrix classes that will only be
27   used for debugging. That's not too attractive either.
28 */
29 class CoinPresolveMonitor {
30 public:
31   /*! \brief Default constructor
32 
33     Creates an empty monitor.
34   */
35   CoinPresolveMonitor();
36 
37   /*! \brief Initialise from a CoinPresolveMatrix
38 
39     Load the initial row or column from a CoinPresolveMatrix. Set \p isRow
40     true for a row, false for a column.
41   */
42   CoinPresolveMonitor(const CoinPresolveMatrix *mtx, bool isRow, int k);
43 
44   /*! \brief Initialise from a CoinPostsolveMatrix
45 
46     Load the initial row or column from a CoinPostsolveMatrix. Set \p isRow
47     true for a row, false for a column.
48   */
49   CoinPresolveMonitor(const CoinPostsolveMatrix *mtx, bool isRow, int k);
50 
51   /*! \brief Compare the present row or column against the stored copy and
52   	     report differences.
53 
54     Load the current row or column from a CoinPresolveMatrix and compare.
55     Differences are printed to std::cout.
56   */
57   void checkAndTell(const CoinPresolveMatrix *mtx);
58 
59   /*! \brief Compare the present row or column against the stored copy and
60   	     report differences.
61 
62     Load the current row or column from a CoinPostsolveMatrix and compare.
63     Differences are printed to std::cout.
64   */
65   void checkAndTell(const CoinPostsolveMatrix *mtx);
66 
67 private:
68   /// Extract a row from a CoinPresolveMatrix
69   CoinPackedVector *extractRow(int i, const CoinPresolveMatrix *mtx) const;
70 
71   /// Extract a column from a CoinPresolveMatrix
72   CoinPackedVector *extractCol(int j, const CoinPresolveMatrix *mtx) const;
73 
74   /// Extract a row from a CoinPostsolveMatrix
75   CoinPackedVector *extractRow(int i, const CoinPostsolveMatrix *mtx) const;
76 
77   /// Extract a column from a CoinPostsolveMatrix
78   CoinPackedVector *extractCol(int j, const CoinPostsolveMatrix *mtx) const;
79 
80   /// Worker method underlying the public checkAndTell methods.
81   void checkAndTell(CoinPackedVector *curVec, double lb, double ub);
82 
83   /// True to monitor a row, false to monitor a column
84   bool isRow_;
85 
86   /// Row or column index
87   int ndx_;
88 
89   /*! The original row or column
90 
91     Sorted in increasing order of indices.
92   */
93   CoinPackedVector *origVec_;
94 
95   /// Original row or column lower bound
96   double lb_;
97 
98   /// Original row or column upper bound
99   double ub_;
100 };
101 
102 #endif
103 
104 /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
105 */
106