File: VirtualChiro.hh

package info (click to toggle)
topcom 1.2.0~beta%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 148,596 kB
  • sloc: cpp: 40,956; sh: 4,663; makefile: 679; ansic: 55
file content (325 lines) | stat: -rw-r--r-- 9,710 bytes parent folder | download
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
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
////////////////////////////////////////////////////////////////////////////////
// 
// VirtualChiro.hh 
//
//    produced: 19 Nov 1999 jr
//
////////////////////////////////////////////////////////////////////////////////
#ifndef VIRTUALCHIRO_HH
#define VIRTUALCHIRO_HH

#include <assert.h>
#include <iostream>
#include <queue>
#include <mutex>

#ifdef USE_SPARSEINTSET
#include "SparseIntegerSet.hh"
#else
#include "LabelSet.hh"
#endif
#include "HashMap.hh"

#include "CommandlineOptions.hh"

#include "StairCaseMatrix.hh"
#include "PointConfiguration.hh"
#include "Permutation.hh"
#include "RealChiro.hh"

namespace topcom {

  class VirtualChiro {
    const   PointConfiguration*    _pointsptr;
    mutable RealChiro              _chiro;
    mutable bool                   _complete;
    mutable std::mutex             _mutex;
    mutable std::queue<basis_type> _known_bases;
  public:
    // constructors:
    inline VirtualChiro();
    inline VirtualChiro(const VirtualChiro&);
    inline VirtualChiro(const PointConfiguration&, const bool = true);
    // destructor:
    inline ~VirtualChiro();
    // assignment:
    inline VirtualChiro& operator=(const VirtualChiro& chiro) {
      if (this == &chiro) {
	return *this;
      }
      _pointsptr = chiro._pointsptr;
      _chiro     = chiro._chiro;
      _complete  = chiro._complete;
      return *this;
    }
    // complete chiro:
    inline void complete() const {
      if (!_complete) {
	_chiro = RealChiro(*_pointsptr);
	_complete = true;
      }
    }
    // accessors:
    inline parameter_type no()   const { return _chiro.no(); }
    inline parameter_type rank() const { return _chiro.rank(); };
    inline Field det(const basis_type& basis) const;
    inline Field det(const Permutation& basisperm) const;
    
    // operators:
    inline const bool operator==(const VirtualChiro& chiro) const;
    inline const bool operator!=(const VirtualChiro& chiro) const;
    inline const int operator()(const basis_type& basis) const;
    inline const int operator()(const Permutation& perm) const;

    // find the sign of prebasis and the lexicographic extension 
    // corresponding to the permutation perm (all signs positive):
    const int operator()(const basis_type&  prebasis,
			 const Permutation& perm) const;
    inline const int operator()(const Permutation& prebasis_perm,
				const Permutation& perm) const {
      assert(prebasis_perm.n() == no());
      assert(prebasis_perm.k() == rank());
      const basis_type basis(prebasis_perm);
      return perm.sign() * (*this)(basis, perm);
    }
    inline const int operator[](const basis_type& basis) const { 
      return (*this)(basis); 
    }
    inline const int operator[](const Permutation& perm) const { 
      return (*this)(perm);
    }
    // functions:
    const basis_type find_non_deg_basis() const;
    inline VirtualChiro dual() const {
      VirtualChiro result;
      complete();
      result._chiro = _chiro.dual();
      result._complete = true;
      return result;
    };
    // stream output/input:
    inline Message& print_string(Message& msg) const {
      complete();
      return _chiro.print_string(msg);
    }
    inline Message& print_dualstring(Message& msg) const {
      complete();
      return _chiro.print_dualstring(msg);
    }
    inline std::istream& read_string(std::istream& ist) {
      _complete = true;
      return _chiro.read_string(ist);
    }
    // stream output/input:
    inline friend std::ostream& operator<<(std::ostream& ost, const VirtualChiro& chiro) {
      chiro.complete();
      return (ost << chiro._chiro);
    }
    inline friend std::istream& operator>>(std::istream& ist, VirtualChiro& chiro) {
      chiro._complete = true;
      return (ist >> chiro._chiro);
    }
    const bool _recursive_find_non_deg_basis(const StairCaseMatrix&    current,
					     const basis_type&         basis,
					     const parameter_type      start,
					     const parameter_type      step,
					     basis_type&               result) const;
  };

  inline const int VirtualChiro::operator()(const basis_type& basis) const {
      if (_complete) {
	return _chiro(basis);
      }
      bool basis_known = false;
#ifdef TOPCOM_CHIROTOPE
      {
	std::lock_guard<std::mutex> lock(_mutex);
	basis_known = _chiro.member(basis);
	if (basis_known) {
	  return _chiro(basis);
	}
      }
#else
      {
	std::lock_guard<std::mutex> lock(_mutex);
	chirotope_data::const_iterator finder = _chiro.find(basis);
	if (finder != _chiro.end()) {
	  return finder->second.first;
	}
      }
#endif
	
#ifdef INDEX_CHECK
      assert(_pointsptr != 0);
      MessageStreams::debug() << message::lock
			      << "computing new chirotope value ..." << std::endl
			      << message::unlock;
#endif
      StairCaseMatrix basis_matrix;
      for (basis_type::const_iterator iter = basis.begin();
	   iter != basis.end();
	   ++iter) {
	basis_matrix.augment((*_pointsptr)[*iter]);
      }
      const Field result_det = basis_matrix.det();
      const int result_sign(sign(result_det));
      if (CommandlineOptions::memopt()) {
	if (CommandlineOptions::chirocache() > 0) {
	  std::lock_guard<std::mutex> lock(_mutex);
	  if (CommandlineOptions::chirocache() < _chiro.size() + 1) {
	    _chiro.erase(_known_bases.front()); // FIFO caching
	    _known_bases.pop();
	  }
	  _chiro[basis] = std::pair<int, Field>(result_sign, result_det);
	  _known_bases.push(basis);
	}
      }
      else {
	std::lock_guard<std::mutex> lock(_mutex);
	_chiro[basis] = std::pair<int, Field>(result_sign, result_det);
      }
#ifdef INDEX_CHECK
      MessageStreams::debug() << message::lock
			      << "... done: " << result << std::endl
			      << message::unlock;
#endif
      return result_sign;
    }

  inline const int VirtualChiro::operator()(const Permutation& perm) const { 
    assert(perm.n() == no());
    assert(perm.k() == rank());
    const basis_type basis(perm);    
    return perm.sign() * (*this)(basis);
  }

  inline Field VirtualChiro::det(const basis_type& basis) const {
    if (_complete && _chiro.has_dets()) {
      return _chiro.det(basis);
    }
    bool basis_known = false;
#ifdef TOPCOM_CHIROTOPE
    {
      std::lock_guard<std::mutex> lock(_mutex);
      basis_known = _chiro.member(basis);
      if (basis_known) {
	return _chiro.det(basis);
      }
    }
#else
    {
      std::lock_guard<std::mutex> lock(_mutex);
      chirotope_data::const_iterator finder = _chiro.find(basis);
      if (finder != _chiro.end()) {
	return finder->second.second;
      }
    }
#endif
    
#ifdef INDEX_CHECK
    assert(_pointsptr != 0);
    MessageStreams::debug() << message::lock
			    << "computing new chirotope value ..." << std::endl
			    << message::unlock;
#endif
    StairCaseMatrix basis_matrix;
    for (basis_type::const_iterator iter = basis.begin();
	 iter != basis.end();
	 ++iter) {
      basis_matrix.augment((*_pointsptr)[*iter]);
    }
    const Field result_det = basis_matrix.det();
    const int result_sign(sign(result_det));
    if (CommandlineOptions::memopt()) {
      if (CommandlineOptions::chirocache() > 0) {
	std::lock_guard<std::mutex> lock(_mutex);
	if (CommandlineOptions::chirocache() < _chiro.size() + 1) {
	  _chiro.erase(_known_bases.front()); // FIFO caching
	  _known_bases.pop();
	}
	_chiro[basis] = std::pair<int, Field>(result_sign, result_det);
	_known_bases.push(basis);
      }
    }
    else {
      std::lock_guard<std::mutex> lock(_mutex);
      _chiro[basis] = std::pair<int, Field>(result_sign, result_det);
    }
#ifdef INDEX_CHECK
    MessageStreams::debug() << message::lock
			    << "... done: " << result << std::endl
			    << message::unlock;
#endif
    return result_det;
  }
  
  inline Field VirtualChiro::det(const Permutation& basisperm) const {
    if (_complete && _chiro.has_dets()) {
      return _chiro.det(basisperm);
    }
    int permsign = basisperm.sign();
    if (permsign > 0) {
      return det(basis_type(basisperm));
    }
    else {
      return -det(basis_type(basisperm));
    }
  }
  
  inline const bool VirtualChiro::operator==(const VirtualChiro& chiro) const {
    if (this->_pointsptr && chiro._pointsptr) {

      // if we have actual points, we can compare those:
      return (*(this->_pointsptr) == *(chiro._pointsptr));
    }
    else {

      // otherwise the chirotope must be stored completely in _chiro,
      // and we can compare that structure:
      return (this->_chiro == chiro._chiro);
    }
  }

  inline const bool VirtualChiro::operator!=(const VirtualChiro& chiro) const {
    return !operator==(chiro);
  }

  inline VirtualChiro::VirtualChiro() : 
    _pointsptr(0), _chiro(), _complete(false) {}

  inline VirtualChiro::VirtualChiro(const VirtualChiro& chiro) : 
    _pointsptr(chiro._pointsptr), 
    _chiro(chiro._chiro) {}

  inline VirtualChiro::VirtualChiro(const PointConfiguration& points,
				    const bool                immediate) : 
    _pointsptr(&points), 
    _chiro(points.no(), points.rank(), true),
    _complete(false) {
    if (immediate && !CommandlineOptions::memopt()) {
      MessageStreams::verbose() << message::lock
				<< "preprocessing chirotope with "
				<< global::binomial(_chiro.no(), _chiro.rank()) << " signs ..." << std::endl
				<< message::unlock;
      _chiro = RealChiro(points);
      MessageStreams::verbose() << message::lock
				<< "... done." << std::endl
				<< message::unlock;
      _complete = true;
    }
  }

  inline VirtualChiro::~VirtualChiro() {
#ifdef CONSTRUCTOR_DEBUG
    MessageStreams::debug() << message::lock
			    << "VirtualChiro::~VirtualChiro(): destructor called" << std::endl
			    << message::unlock;
#endif
  }

};  // namespace topcom


#endif

// eof VirtualChiro.hh