File: RegularityCheck.hh

package info (click to toggle)
topcom 1.1.2%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 31,784 kB
  • sloc: cpp: 37,616; sh: 4,262; makefile: 497; ansic: 49
file content (251 lines) | stat: -rw-r--r-- 6,762 bytes parent folder | download | duplicates (2)
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
////////////////////////////////////////////////////////////////////////////////
// 
// RegularityCheck.hh 
//
//    produced: 2001/10/20 jr
// last change: 2001/10/20 jr
//
////////////////////////////////////////////////////////////////////////////////
#ifndef REGULARITYCHECK_HH
#define REGULARITYCHECK_HH

#include <thread>
#include <mutex>

#include "Vector.hh"
#include "Matrix.hh"
#include "PointConfiguration.hh"
#include "LabelSet.hh"
#include "SimplicialComplex.hh"
#include "Flip.hh"

#include "CommandlineOptions.hh"

#include "Chirotope.hh"
#include "Incidences.hh"

#include "LPinterface.hh"
#include "SPXinterface.hh"

#ifdef USE_QSO
#include "QSOinterface.hh"
#endif

namespace topcom {

#ifdef REGULARITY_CACHE
  typedef std::pair<Simplex, Simplex> constraint_conf_type;

  class ConstraintCacheEntry : public constraint_conf_type {
  public:
    inline ConstraintCacheEntry() = delete;
    inline ConstraintCacheEntry(const Simplex& unionsimp, const Simplex& intersection) :
      constraint_conf_type(unionsimp, intersection) {}
  public:
    size_type keysize() const { return 2; }
    size_type key(const size_type n) const {
      if (n == 0) {
	return first.key(0);
      }
      else {
	return second.key(0);
      }
    }
  };

  typedef std::unordered_map<ConstraintCacheEntry, Vector, Hash<ConstraintCacheEntry> > constraint_cache_data;
  
  class ConstraintCache : public constraint_cache_data {
  };
#endif

  class RegularityCheck {
  public:
    static size_type cnt_calls;
  private:
    Vector                    _heights;
    Matrix                    _coeffs;
    const PointConfiguration* _pointsptr;
    const Chirotope*          _chiroptr;
    const SimplicialComplex*  _triangptr;
    const Incidences*         _incidencesptr;

#ifdef REGULARITY_CACHE
  private:
    // thread-local caching (map a union of two simplices and their common face
    // to the coefficients of the corresponding folding form:
    static ConstraintCache    _cache;
#endif

  private:
    // multithreading:
    static std::mutex         _reg_mutex;
  private:
    RegularityCheck() = delete;
  public:
    // constructors:
    RegularityCheck(const PointConfiguration&, 
		    const Chirotope&,
		    const Incidences&, 
		    const SimplicialComplex&);
    inline RegularityCheck(const RegularityCheck&);
    inline RegularityCheck(const RegularityCheck&, const Flip&);
    // destructor:
    inline ~RegularityCheck();
    // assignments:
    inline RegularityCheck& operator=(const RegularityCheck&);
    // accessors:
    inline const Vector     heights()  const { return _heights; }   
    inline const Matrix     coeffs()   const { return _coeffs; }
    inline const Chirotope* chiroptr() const { return _chiroptr; }
    // init/term the solver:
    inline static void init();
    inline static void term();
    // functions:
    inline const bool is_regular();  // changes "_heights"
  };

  // constructors:

  inline RegularityCheck::RegularityCheck(const RegularityCheck&) {
    std::cerr << "RegularityCheck::RegularityCheck(const RegularityCheck&): not yet implemented!" << std::endl;
  }

  inline RegularityCheck::RegularityCheck(const RegularityCheck&, const Flip&){
    std::cerr << "RegularityCheck::RegularityCheck(const RegularityCheck&, const Flip&): not yet implemented!" << std::endl;
  }

  // destructor:
  inline RegularityCheck::~RegularityCheck() {
#ifdef CONSTRUCTOR_DEBUG
    std::cerr << "destroying coefficients of RegularityCheck " << this->_coeffs << std::endl;
#endif
  }

  // assignment:
  inline RegularityCheck& RegularityCheck::operator=(const RegularityCheck& rc) {
    if (this == &rc) {
      return *this;
    }
    _heights       = rc._heights;
    _coeffs        = rc._coeffs;
    _pointsptr     = rc._pointsptr;
    _chiroptr      = rc._chiroptr;
    _triangptr     = rc._triangptr;
    _incidencesptr = rc._incidencesptr;
    return *this;
  }

  // functions:
  inline const bool RegularityCheck::is_regular() {
    {
      std::lock_guard<std::mutex> lock(_reg_mutex);
      ++cnt_calls;
    }
    // do not interrupt computation because user may want heights!
    // if (_chiroptr->rank() < 3) {
    //   return true;
    // }

    if (_coeffs.coldim() == 0) {
      if (CommandlineOptions::output_heights()) {

	// take a height vector that is ZERO on all used points and ONE otherwise:
	const LabelSet support(_triangptr->support());
	const parameter_type no(_chiroptr->no());
	for (size_type i = 0; i < no; ++i) {
	  if (!support.contains(i)) {
	    _heights.at(i) = FieldConstants::ONE;
	  }
	}
      }
      return true;
    }

#ifdef HAVE_LIBSOPLEX
    if (CommandlineOptions::use_soplex()) {
      SPXinterface LP(_coeffs, _triangptr->support());
      const bool regular(LP.has_interior_point(&_heights));
      if (CommandlineOptions::debug()) {
	LPinterface LP(_coeffs, _triangptr->support());
	const bool double_check_regular(LP.has_interior_point(&_heights));
	if (regular != double_check_regular) {
	  std::cerr << "RegularityCheck::is_regular() const: wrong result, exiting;" << std::endl
		    << "please inspect soplex.lp." << std::endl;
	  exit(1);
	}
      }
      return regular;
    }
    else {
#endif
#ifdef USE_QSO
      if (CommandlineOptions::use_qsopt_ex()) {
	// qsopt_ex cannot run in a multi-threaded environment
	// because of its memory management(?);
	// even locking does not suffice,
	// thus parallel enumeration is
	// not supported with qsopt_ex from the start:
	QSOinterface LP(_coeffs, _triangptr->support());
	const bool result = LP.has_interior_point(&_heights);
	return result;
      }
      else
#endif
	{
	// with the patched version of cddlib with TLS
	// we can run the cdd lp solver lock-free:
	LPinterface LP(_coeffs, _triangptr->support());
	const bool result = LP.has_interior_point(&_heights);
	return result;
      }
#ifdef HAVE_LIBSOPLEX
    }
#endif
  }

  // init/term the solver:
  inline void RegularityCheck::init() {
#ifdef USE_QSO
    if (CommandlineOptions::use_qsopt_ex()) {
      QSOinterface::init();
    }
    else
#endif
#ifdef HAVE_LIBSOPLEX
    if (CommandlineOptions::use_soplex()) {
      SPXinterface::init();
    } else
#endif
    {
      LPinterface::init();
    }
  }

  inline void RegularityCheck::term() {
#if USE_QSO
    if (CommandlineOptions::use_qsopt_ex()) {
      QSOinterface::term();
    }
    else
#endif
#ifdef HAVE_LIBSOPLEX
    if (CommandlineOptions::use_soplex()) {
      SPXinterface::term();
    }
    else
#endif
    {
      LPinterface::term();
    }
    if (CommandlineOptions::verbose()) {
      std::lock_guard<std::mutex> lock(IO_sync::mutex);
      std::cerr << cnt_calls << " calls of RegularityCheck in total" << std::endl;
    }
  }

}; // namespace topcom

#endif

// eof RegularityCheck.hh