CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

| Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

Views: 418425
1
/*
2
* Normaliz
3
* Copyright (C) 2007-2014 Winfried Bruns, Bogdan Ichim, Christof Soeger
4
* This program is free software: you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation, either version 3 of the License, or
7
* (at your option) any later version.
8
*
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*
14
* You should have received a copy of the GNU General Public License
15
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
*
17
* As an exception, when this program is distributed through (i) the App Store
18
* by Apple Inc.; (ii) the Mac App Store by Apple Inc.; or (iii) Google Play
19
* by Google Inc., then that store may impose any digital rights management,
20
* device limits and/or redistribution restrictions that are required by its
21
* terms of service.
22
*/
23
24
#ifdef NMZ_MIC_OFFLOAD
25
#pragma offload_attribute (push, target(mic))
26
#endif
27
28
#include <vector>
29
#include <string>
30
#include <assert.h>
31
32
#include "libQnormaliz/Qcone_property.h"
33
#include "libQnormaliz/libQnormaliz.h"
34
#include "libQnormaliz/Qnormaliz_exception.h"
35
36
namespace libQnormaliz {
37
using std::bitset;
38
using std::vector;
39
using std::string;
40
using std::endl;
41
42
43
/* Constructors */
44
ConeProperties::ConeProperties() {
45
CPs = bitset<ConeProperty::EnumSize>();
46
}
47
ConeProperties::ConeProperties(ConeProperty::Enum p1) {
48
CPs = bitset<ConeProperty::EnumSize>();
49
CPs.set(p1);
50
}
51
ConeProperties::ConeProperties(ConeProperty::Enum p1, ConeProperty::Enum p2) {
52
CPs = bitset<ConeProperty::EnumSize>();
53
CPs.set(p1);
54
CPs.set(p2);
55
}
56
ConeProperties::ConeProperties(ConeProperty::Enum p1, ConeProperty::Enum p2,
57
ConeProperty::Enum p3) {
58
CPs = bitset<ConeProperty::EnumSize>();
59
CPs.set(p1);
60
CPs.set(p2);
61
CPs.set(p3);
62
}
63
ConeProperties::ConeProperties(const bitset<ConeProperty::EnumSize>& props){
64
CPs = props;
65
}
66
67
/* set Properties */
68
ConeProperties& ConeProperties::set(ConeProperty::Enum p1, bool value) {
69
CPs.set(p1, value);
70
return *this;
71
}
72
ConeProperties& ConeProperties::set(ConeProperty::Enum p1, ConeProperty::Enum p2) {
73
CPs.set(p1);
74
CPs.set(p2);
75
return *this;
76
}
77
ConeProperties& ConeProperties::set(const ConeProperties& ConeProps) {
78
CPs ^= ConeProps.CPs;
79
return *this;
80
}
81
82
ConeProperties& ConeProperties::set(const std::string s, bool value) {
83
CPs.set(toConeProperty(s), value);
84
return *this;
85
}
86
87
/* reset (=unset) properties */
88
ConeProperties& ConeProperties::reset(ConeProperty::Enum Property) {
89
CPs.set(Property, false);
90
return *this;
91
}
92
ConeProperties& ConeProperties::reset(const ConeProperties& ConeProps) {
93
CPs &= ~ConeProps.CPs;
94
return *this;
95
}
96
97
ConeProperties& ConeProperties::reset_compute_options() {
98
CPs.set(ConeProperty::Approximate, false);
99
CPs.set(ConeProperty::BottomDecomposition, false);
100
CPs.set(ConeProperty::NoBottomDec, false);
101
CPs.set(ConeProperty::DefaultMode, false);
102
CPs.set(ConeProperty::DualMode, false);
103
CPs.set(ConeProperty::KeepOrder, false);
104
CPs.set(ConeProperty::HSOP, false);
105
CPs.set(ConeProperty::Symmetrize, false);
106
CPs.set(ConeProperty::NoSymmetrization, false);
107
CPs.set(ConeProperty::PrimalMode, false);
108
CPs.set(ConeProperty::BigInt, false);
109
return *this;
110
}
111
112
/* return a new ConeProperties object with only the goals/options set,
113
* which are set in this object
114
*/
115
ConeProperties ConeProperties::goals() {
116
ConeProperties ret(*this);
117
ret.reset_compute_options();
118
return ret;
119
}
120
ConeProperties ConeProperties::options() {
121
ConeProperties ret;
122
ret.set(ConeProperty::Approximate, CPs.test(ConeProperty::Approximate));
123
ret.set(ConeProperty::BottomDecomposition, CPs.test(ConeProperty::BottomDecomposition));
124
ret.set(ConeProperty::BottomDecomposition, CPs.test(ConeProperty::NoBottomDec));
125
ret.set(ConeProperty::DefaultMode, CPs.test(ConeProperty::DefaultMode));
126
ret.set(ConeProperty::DualMode, CPs.test(ConeProperty::DualMode));
127
ret.set(ConeProperty::KeepOrder, CPs.test(ConeProperty::KeepOrder));
128
ret.set(ConeProperty::HSOP, CPs.test(ConeProperty::HSOP));
129
ret.set(ConeProperty::Symmetrize, CPs.test(ConeProperty::Symmetrize));
130
ret.set(ConeProperty::NoSymmetrization, CPs.test(ConeProperty::NoSymmetrization));
131
ret.set(ConeProperty::PrimalMode, CPs.test(ConeProperty::PrimalMode));
132
return ret;
133
}
134
135
/* test which/how many properties are set */
136
bool ConeProperties::test(ConeProperty::Enum Property) const {
137
return CPs.test(Property);
138
}
139
bool ConeProperties::any() const {
140
return CPs.any();
141
}
142
bool ConeProperties::none() const {
143
return CPs.none();
144
}
145
size_t ConeProperties::count() const {
146
return CPs.count();
147
}
148
149
150
/* add preconditions */
151
void ConeProperties::set_preconditions() {
152
if (CPs.test(ConeProperty::WitnessNotIntegrallyClosed))
153
CPs.set(ConeProperty::IsIntegrallyClosed);
154
155
if (CPs.test(ConeProperty::IsDeg1HilbertBasis)) {
156
CPs.set(ConeProperty::HilbertBasis);
157
CPs.set(ConeProperty::Grading);
158
}
159
if (CPs.test(ConeProperty::IsDeg1ExtremeRays)) {
160
CPs.set(ConeProperty::ExtremeRays);
161
CPs.set(ConeProperty::Grading);
162
}
163
if (CPs.test(ConeProperty::Grading))
164
CPs.set(ConeProperty::Generators);
165
166
if (CPs.test(ConeProperty::IsPointed))
167
CPs.set(ConeProperty::ExtremeRays);
168
169
if (CPs.test(ConeProperty::ExtremeRays))
170
CPs.set(ConeProperty::SupportHyperplanes);
171
172
if (CPs.test(ConeProperty::HSOP)){
173
CPs.set(ConeProperty::SupportHyperplanes);
174
CPs.set(ConeProperty::HilbertSeries);
175
}
176
// inhomogenous preconditions
177
if (CPs.test(ConeProperty::VerticesOfPolyhedron))
178
CPs.set(ConeProperty::ExtremeRays);
179
180
if(CPs.test(ConeProperty::ModuleGeneratorsOverOriginalMonoid))
181
CPs.set(ConeProperty::HilbertBasis);
182
183
if (CPs.test(ConeProperty::ModuleGenerators))
184
CPs.set(ConeProperty::HilbertBasis);
185
186
if (CPs.test(ConeProperty::MaximalSubspace))
187
CPs.set(ConeProperty::SupportHyperplanes);
188
189
// always
190
191
if (CPs.test(ConeProperty::ExtremeRays))
192
CPs.set(ConeProperty::SupportHyperplanes);
193
}
194
195
/* removes ignored compute options and sets implications */
196
void ConeProperties::prepare_compute_options(bool inhomogeneous) {
197
if (CPs.test(ConeProperty::NumberHull)){
198
if(inhomogeneous){
199
CPs.set(ConeProperty::HilbertBasis);
200
}
201
else{
202
CPs.set(ConeProperty::Deg1Elements);
203
}
204
}
205
// -d without -1 means: compute Hilbert basis in dual mode
206
if (CPs.test(ConeProperty::DualMode) && !CPs.test(ConeProperty::Deg1Elements)){
207
CPs.set(ConeProperty::HilbertBasis);
208
}
209
210
if(CPs.test(ConeProperty::ModuleGeneratorsOverOriginalMonoid)) // can't be computed in dual mode
211
CPs.reset(ConeProperty::DualMode);
212
213
// dual mode has priority, approximation makes no sense if HB is computed
214
if(CPs.test(ConeProperty::DualMode) || CPs.test(ConeProperty::HilbertBasis))
215
CPs.reset(ConeProperty::Approximate);
216
217
if ((CPs.test(ConeProperty::DualMode) || CPs.test(ConeProperty::Approximate))
218
&& (CPs.test(ConeProperty::HilbertSeries) || CPs.test(ConeProperty::StanleyDec))
219
&& !CPs.test(ConeProperty::HilbertBasis)){
220
CPs.reset(ConeProperty::DualMode); //it makes no sense to compute only deg 1 elements in dual mode
221
CPs.reset(ConeProperty::Approximate); // or by approximation if the
222
} // Stanley decomposition must be computed anyway
223
if (CPs.test(ConeProperty::Approximate)
224
&& !CPs.test(ConeProperty::Deg1Elements)) {
225
errorOutput() << "WARNING: Approximate is ignored since Deg1Elements is not set."<< std::endl;
226
}
227
if (CPs.test(ConeProperty::ConeDecomposition))
228
CPs.set(ConeProperty::Triangulation);
229
230
if (CPs.test(ConeProperty::GradingDenom))
231
CPs.reset(ConeProperty::Grading);
232
233
if(CPs.test(ConeProperty::UnitGroupIndex))
234
CPs.set(ConeProperty::HilbertBasis);
235
236
if(CPs.test(ConeProperty::Equations) || CPs.test(ConeProperty::Congruences) || CPs.test(ConeProperty::ExternalIndex))
237
CPs.set(ConeProperty::Sublattice);
238
239
if(CPs.test(ConeProperty::Rank))
240
CPs.set(ConeProperty::Sublattice);
241
242
if(CPs.test(ConeProperty::HilbertQuasiPolynomial))
243
CPs.set(ConeProperty::HilbertSeries);
244
245
if(inhomogeneous && CPs.test(ConeProperty::SupportHyperplanes))
246
CPs.set(ConeProperty::AffineDim);
247
248
if(CPs.test(ConeProperty::DefaultMode)){
249
CPs.set(ConeProperty::HilbertBasis);
250
CPs.set(ConeProperty::HilbertSeries);
251
if(!inhomogeneous)
252
CPs.set(ConeProperty::ClassGroup);
253
CPs.set(ConeProperty::SupportHyperplanes);
254
}
255
}
256
257
void ConeProperties::check_Q_permissible() {
258
ConeProperties copy(*this);
259
copy.reset(ConeProperty::SupportHyperplanes);
260
copy.reset(ConeProperty::ExtremeRays);
261
copy.reset(ConeProperty::VerticesOfPolyhedron);
262
copy.reset(ConeProperty::KeepOrder);
263
copy.reset(ConeProperty::Triangulation);
264
copy.reset(ConeProperty::ConeDecomposition);
265
copy.reset(ConeProperty::DefaultMode);
266
copy.reset(ConeProperty::Generators);
267
copy.reset(ConeProperty::Sublattice);
268
copy.reset(ConeProperty::MaximalSubspace);
269
copy.reset(ConeProperty::Equations);
270
copy.reset(ConeProperty::Dehomogenization);
271
copy.reset(ConeProperty::Rank);
272
copy.reset(ConeProperty::EmbeddingDim);
273
copy.reset(ConeProperty::IsPointed);
274
copy.reset(ConeProperty::IsInhomogeneous);
275
copy.reset(ConeProperty::DefaultMode);
276
277
//bvverboseOutput() << copy << endl;
278
if(copy.any())
279
throw BadInputException("Cone Property not allowd for field coefficients");
280
}
281
282
283
void ConeProperties::check_sanity(bool inhomogeneous) {
284
ConeProperty::Enum prop;
285
if(
286
(CPs.test(ConeProperty::BottomDecomposition) && CPs.test(ConeProperty::NoBottomDec))
287
|| (CPs.test(ConeProperty::DualMode) && CPs.test(ConeProperty::PrimalMode))
288
|| (CPs.test(ConeProperty::Symmetrize) && CPs.test(ConeProperty::NoSymmetrization))
289
)
290
throw BadInputException("Contradictory algorithmic variants in options.");
291
292
if(CPs.test(ConeProperty::IsTriangulationNested) || CPs.test(ConeProperty::IsTriangulationPartial))
293
throw BadInputException("ConeProperty not allowed in compute().");
294
295
for (size_t i=0; i<ConeProperty::EnumSize; i++) {
296
if (CPs.test(i)) {
297
prop = static_cast<ConeProperty::Enum>(i);
298
if (inhomogeneous) {
299
if ( prop == ConeProperty::Deg1Elements
300
|| prop == ConeProperty::StanleyDec
301
|| prop == ConeProperty::Triangulation
302
|| prop == ConeProperty::ConeDecomposition
303
|| prop == ConeProperty::IsIntegrallyClosed
304
|| prop == ConeProperty::WitnessNotIntegrallyClosed
305
|| prop == ConeProperty::Approximate
306
|| prop == ConeProperty::ClassGroup
307
|| prop == ConeProperty::Symmetrize
308
|| prop == ConeProperty::NoSymmetrization
309
|| prop == ConeProperty::InclusionExclusionData
310
|| prop == ConeProperty::ExcludedFaces
311
|| prop == ConeProperty::UnitGroupIndex
312
|| prop == ConeProperty::ReesPrimaryMultiplicity
313
|| prop == ConeProperty::IsReesPrimary
314
|| prop == ConeProperty::IsDeg1HilbertBasis
315
|| prop == ConeProperty::IsDeg1ExtremeRays
316
// || prop == ConeProperty::ModuleGeneratorsOverOriginalMonoid
317
) {
318
throw BadInputException(toString(prop) + " not computable in the inhomogeneous case.");
319
}
320
} else { // homgeneous
321
if ( prop == ConeProperty::VerticesOfPolyhedron
322
|| prop == ConeProperty::ModuleRank
323
|| prop == ConeProperty::ModuleGenerators ) {
324
throw BadInputException(toString(prop) + " only computable in the inhomogeneous case.");
325
}
326
}
327
} //end if test(i)
328
}
329
}
330
331
332
/* conversion */
333
namespace {
334
// only to initialize the CPN in ConePropertyNames
335
vector<string> initializeCPN() {
336
vector<string> CPN(ConeProperty::EnumSize);
337
CPN.at(ConeProperty::Generators) = "Generators";
338
CPN.at(ConeProperty::ExtremeRays) = "ExtremeRays";
339
CPN.at(ConeProperty::VerticesOfPolyhedron) = "VerticesOfPolyhedron";
340
CPN.at(ConeProperty::SupportHyperplanes) = "SupportHyperplanes";
341
CPN.at(ConeProperty::TriangulationSize) = "TriangulationSize";
342
CPN.at(ConeProperty::TriangulationDetSum) = "TriangulationDetSum";
343
CPN.at(ConeProperty::Triangulation) = "Triangulation";
344
CPN.at(ConeProperty::Multiplicity) = "Multiplicity";
345
CPN.at(ConeProperty::RecessionRank) = "RecessionRank";
346
CPN.at(ConeProperty::AffineDim) = "AffineDim";
347
CPN.at(ConeProperty::ModuleRank) = "ModuleRank";
348
CPN.at(ConeProperty::HilbertBasis) = "HilbertBasis";
349
CPN.at(ConeProperty::ModuleGenerators) = "ModuleGenerators";
350
CPN.at(ConeProperty::Deg1Elements) = "Deg1Elements";
351
CPN.at(ConeProperty::HilbertSeries) = "HilbertSeries";
352
CPN.at(ConeProperty::Grading) = "Grading";
353
CPN.at(ConeProperty::IsPointed) = "IsPointed";
354
CPN.at(ConeProperty::IsDeg1ExtremeRays) = "IsDeg1ExtremeRays";
355
CPN.at(ConeProperty::IsDeg1HilbertBasis) = "IsDeg1HilbertBasis";
356
CPN.at(ConeProperty::IsIntegrallyClosed) = "IsIntegrallyClosed";
357
CPN.at(ConeProperty::WitnessNotIntegrallyClosed) = "WitnessNotIntegrallyClosed";
358
CPN.at(ConeProperty::OriginalMonoidGenerators) = "OriginalMonoidGenerators";
359
CPN.at(ConeProperty::IsReesPrimary) = "IsReesPrimary";
360
CPN.at(ConeProperty::ReesPrimaryMultiplicity) = "ReesPrimaryMultiplicity";
361
CPN.at(ConeProperty::StanleyDec) = "StanleyDec";
362
CPN.at(ConeProperty::ExcludedFaces) = "ExcludedFaces";
363
CPN.at(ConeProperty::Dehomogenization) = "Dehomogenization";
364
CPN.at(ConeProperty::InclusionExclusionData) = "InclusionExclusionData";
365
CPN.at(ConeProperty::Sublattice) = "Sublattice";
366
CPN.at(ConeProperty::ClassGroup) = "ClassGroup";
367
CPN.at(ConeProperty::ModuleGeneratorsOverOriginalMonoid) = "ModuleGeneratorsOverOriginalMonoid";
368
// the following are more compute options than real properties of the cone
369
CPN.at(ConeProperty::Approximate) = "Approximate";
370
CPN.at(ConeProperty::BottomDecomposition) = "BottomDecomposition";
371
CPN.at(ConeProperty::DefaultMode) = "DefaultMode";
372
CPN.at(ConeProperty::DualMode) = "DualMode";
373
CPN.at(ConeProperty::KeepOrder) = "KeepOrder";
374
CPN.at(ConeProperty::NumberHull) = "NumberHull";
375
CPN.at(ConeProperty::MaximalSubspace) = "MaximalSubspace";
376
CPN.at(ConeProperty::ConeDecomposition) = "ConeDecomposition";
377
CPN.at(ConeProperty::HSOP) = "HSOP";
378
CPN.at(ConeProperty::NoBottomDec) = "NoBottomDec";
379
380
CPN.at(ConeProperty::PrimalMode) = "PrimalMode";
381
CPN.at(ConeProperty::Symmetrize) = "Symmetrize";
382
CPN.at(ConeProperty::NoSymmetrization) = "NoSymmetrization";
383
CPN.at(ConeProperty::EmbeddingDim) = "EmbeddingDim";
384
CPN.at(ConeProperty::Rank) = "Rank";
385
CPN.at(ConeProperty::InternalIndex) = "InternalIndex";
386
CPN.at(ConeProperty::IsInhomogeneous) = "IsInhomogeneous";
387
CPN.at(ConeProperty::UnitGroupIndex) = "UnitGroupIndex";
388
CPN.at(ConeProperty::GradingDenom) = "GradingDenom";
389
CPN.at(ConeProperty::Equations) = "Equations";
390
CPN.at(ConeProperty::Congruences) = "Congruences";
391
CPN.at(ConeProperty::ExternalIndex) = "ExernalIndex";
392
CPN.at(ConeProperty::HilbertQuasiPolynomial) = "HilbertQuasiPolynomial";
393
CPN.at(ConeProperty::IsTriangulationNested) = "IsTriangulationNested";
394
CPN.at(ConeProperty::IsTriangulationPartial) = "IsTriangulationPartial";
395
CPN.at(ConeProperty::BigInt) = "BigInt";
396
397
// detect changes in size of Enum, to remember to update CPN!
398
static_assert (ConeProperty::EnumSize == 57,
399
"ConeProperties Enum size does not fit! Update cone_property.cpp!");
400
// assert all fields contain an non-empty string
401
for (size_t i=0; i<ConeProperty::EnumSize; i++) {
402
assert(CPN.at(i).size() > 0);
403
}
404
return CPN;
405
}
406
407
const vector<string>& ConePropertyNames() {
408
static const vector<string> CPN(initializeCPN());
409
return CPN;
410
}
411
}
412
413
bool isConeProperty(ConeProperty::Enum& cp, const std::string& s) {
414
const vector<string>& CPN = ConePropertyNames();
415
for (size_t i=0; i<ConeProperty::EnumSize; i++) {
416
if (CPN[i] == s) {
417
cp = static_cast<ConeProperty::Enum>(i);
418
return true;
419
}
420
}
421
return false;
422
}
423
424
ConeProperty::Enum toConeProperty(const std::string& s) {
425
ConeProperty::Enum cp;
426
if (isConeProperty(cp, s)) return cp;
427
throw BadInputException("Unknown ConeProperty string \"" + s + "\"");
428
}
429
430
const std::string& toString(ConeProperty::Enum cp) {
431
return ConePropertyNames()[cp];
432
}
433
434
/* print it in a nice way */
435
std::ostream& operator<< (std::ostream& out, const ConeProperties& CP){
436
for (size_t i=0; i<ConeProperty::EnumSize; i++) {
437
if (CP.CPs.test(i)) out << toString(static_cast<ConeProperty::Enum>(i)) << " ";
438
}
439
return out;
440
}
441
442
443
} /* end namespace libQnormaliz */
444
445
#ifdef NMZ_MIC_OFFLOAD
446
#pragma offload_attribute (pop)
447
#endif
448
449