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: 418346
1
/*
2
* NormalizInterface: GAP wrapper for Normaliz
3
* Copyright (C) 2014 Sebastian Gutsche, Max Horn, Christof Söger
4
*
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
9
*
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
*/
19
20
/*
21
#! @Chapter Functions
22
#! @Section YOU FORGOT TO SET A SECTION
23
*/
24
25
#include <gmp.h>
26
27
extern "C" {
28
#include "src/compiled.h" /* GAP headers */
29
}
30
#include "libnormaliz/cone.h"
31
#include <assert.h>
32
33
34
#include "libnormaliz/map_operations.h"
35
36
#include <vector>
37
#include <iostream>
38
39
#include <csignal>
40
using std::signal;
41
42
typedef void (*sighandler_t)(int);
43
44
// the TNUM used for NormalizInterface objects,
45
extern UInt T_NORMALIZ;
46
47
// old versions of libnormaliz (before 2.99.1) did not include such a define
48
#if !defined(NMZ_RELEASE) || NMZ_RELEASE < 30400
49
#error Your Normaliz version is to old! Update to 3.4.0 or newer.
50
#endif
51
52
#define FUNC_BEGIN try {
53
54
#define FUNC_END \
55
} catch (std::exception& e) { \
56
ErrorQuit(e.what(),0,0); \
57
return Fail; \
58
} catch (const char* a) { \
59
ErrorQuit(a,0,0); \
60
return Fail; \
61
}
62
63
#define SIGNAL_HANDLER_BEGIN \
64
sighandler_t current_interpreter_sigint_handler = signal( SIGINT, signal_handler ); \
65
try{
66
67
#define SIGNAL_HANDLER_END \
68
} catch (libnormaliz::InterruptException& e ) {\
69
signal(SIGINT,current_interpreter_sigint_handler);\
70
libnormaliz::nmz_interrupted = false; \
71
ErrorQuit( "computation interrupted", 0, 0 ); \
72
return 0; \
73
} catch (...) { \
74
signal(SIGINT,current_interpreter_sigint_handler);\
75
throw;\
76
} \
77
signal(SIGINT,current_interpreter_sigint_handler);
78
79
extern Obj TheTypeNormalizCone;
80
81
#define IS_CONE(o) (TNUM_OBJ(o) == T_NORMALIZ)
82
83
84
// Paranoia check
85
#ifdef SYS_IS_64_BIT
86
#if GMP_LIMB_BITS != 64
87
#error GAP compiled in 64 bit mode, but GMP limbs are not 64 bit
88
#endif
89
#else
90
#if GMP_LIMB_BITS != 32
91
#error GAP compiled in 32 bit mode, but GMP limbs are not 32 bit
92
#endif
93
#endif
94
95
96
using libnormaliz::Cone;
97
//using libnormaliz::ConeProperty;
98
using libnormaliz::ConeProperties;
99
using libnormaliz::Sublattice_Representation;
100
using libnormaliz::Type::InputType;
101
102
using std::map;
103
using std::vector;
104
using std::string;
105
using std::pair;
106
107
using std::cerr;
108
using std::endl;
109
110
void signal_handler(int signal)
111
{
112
libnormaliz::nmz_interrupted = true;
113
}
114
115
116
Obj TheTypeNormalizCone;
117
118
UInt T_NORMALIZ = 0;
119
120
template<typename Integer>
121
inline void SET_CONE(Obj o, libnormaliz::Cone<Integer>* p) {
122
ADDR_OBJ(o)[0] = reinterpret_cast<Obj>(p);
123
}
124
125
template<typename Integer>
126
inline libnormaliz::Cone<Integer>* GET_CONE(Obj o) {
127
return reinterpret_cast<libnormaliz::Cone<Integer>*>(ADDR_OBJ(o)[0]);
128
}
129
130
Obj NewCone(Cone<mpz_class>* C)
131
{
132
Obj o;
133
o = NewBag(T_NORMALIZ, 1 * sizeof(Obj));
134
SET_CONE<mpz_class>(o, C);
135
return o;
136
}
137
138
Obj NewProxyCone(Cone<mpz_class>* C, Obj parentCone)
139
{
140
Obj o;
141
o = NewBag(T_NORMALIZ, 2 * sizeof(Obj) );
142
SET_CONE<mpz_class>(o, C);
143
ADDR_OBJ(o)[1] = parentCone;
144
return o;
145
}
146
147
#define IS_PROXY_CONE(o) (SIZE_OBJ(o) == 2)
148
149
/* Free function */
150
void NormalizFreeFunc(Obj o)
151
{
152
if (!IS_PROXY_CONE(o)) {
153
delete GET_CONE<mpz_class>(o);
154
}
155
}
156
157
/* Type object function for the object */
158
Obj NormalizTypeFunc(Obj o)
159
{
160
return TheTypeNormalizCone;
161
}
162
163
Obj NormalizCopyFunc(Obj o, Int mut)
164
{
165
// Cone objects are mathematically immutable, so
166
// we don't need to do anything,
167
return o;
168
}
169
170
void NormalizCleanFunc(Obj o)
171
{
172
}
173
174
Int NormalizIsMutableObjFuncs(Obj o)
175
{
176
// Cone objects are mathematically immutable.
177
return 0L;
178
}
179
180
181
static Obj MpzToGAP(const mpz_t x)
182
{
183
Obj res;
184
Int size = x->_mp_size;
185
int sign;
186
if (size == 0) {
187
return INTOBJ_INT(0);
188
} else if (size < 0) {
189
size = -size;
190
sign = -1;
191
} else {
192
sign = +1;
193
}
194
if (size == 1) {
195
res = ObjInt_UInt(x->_mp_d[0]);
196
if (sign < 0)
197
res = AInvInt(res);
198
} else {
199
size = sizeof(mp_limb_t) * size;
200
if (sign > 0)
201
res = NewBag(T_INTPOS, size);
202
else
203
res = NewBag(T_INTNEG, size);
204
memcpy(ADDR_INT(res), x->_mp_d, size);
205
}
206
return res;
207
}
208
209
static inline Obj MpzClassToGAP(const mpz_class& x)
210
{
211
return MpzToGAP(x.get_mpz_t());
212
}
213
214
static Obj MpqClassToGAP(const mpq_class& x)
215
{
216
Obj num = MpzClassToGAP(x.get_num());
217
Obj den = MpzClassToGAP(x.get_den());
218
return QUO(num, den);
219
}
220
221
template<typename Number>
222
Obj NmzNumberToGAP(Number x)
223
{
224
return Number::unimplemented_function;
225
}
226
227
template<>
228
Obj NmzNumberToGAP(libnormaliz::key_t x) // key_t = unsigned int
229
{
230
return ObjInt_UInt(x);
231
}
232
233
#ifdef SYS_IS_64_BIT
234
template<>
235
Obj NmzNumberToGAP(size_t x) // size_t = unsigned long
236
{
237
return ObjInt_UInt(x);
238
}
239
#endif
240
241
template<>
242
Obj NmzNumberToGAP(long x)
243
{
244
return ObjInt_Int(x);
245
}
246
247
template<>
248
Obj NmzNumberToGAP(mpz_class x)
249
{
250
return MpzClassToGAP(x);
251
}
252
253
template<>
254
Obj NmzNumberToGAP(double x)
255
{
256
return NEW_MACFLOAT(x);
257
}
258
259
260
template<typename Integer>
261
bool GAPIntToNmz(Obj x, Integer &out)
262
{
263
return Integer::unimplemented_function;
264
}
265
266
template<>
267
bool GAPIntToNmz(Obj x, long &out)
268
{
269
if (IS_INTOBJ(x)) {
270
out = INT_INTOBJ(x);
271
return true;
272
} else if (TNUM_OBJ(x) == T_INTPOS || TNUM_OBJ(x) == T_INTNEG) {
273
UInt size = SIZE_INT(x);
274
if (size == 1) {
275
out = *ADDR_INT(x);
276
if (out < 0)
277
return false; // overflow
278
if (TNUM_OBJ(x) == T_INTNEG)
279
out = -out;
280
return true;
281
}
282
}
283
return false;
284
}
285
286
template<>
287
bool GAPIntToNmz(Obj x, mpz_class &out)
288
{
289
mpz_ptr m = out.get_mpz_t();
290
291
if (IS_INTOBJ(x)) {
292
mpz_realloc2(m, 1 * GMP_NUMB_BITS);
293
294
if (INT_INTOBJ(x) == 0) {
295
mpz_set_ui(m, 0);
296
} else if (INT_INTOBJ(x) >= 0) {
297
m->_mp_d[0] = INT_INTOBJ(x);
298
m->_mp_size = 1;
299
} else {
300
m->_mp_d[0] = -INT_INTOBJ(x);
301
m->_mp_size = -1;
302
}
303
304
return true;
305
} else if (TNUM_OBJ(x) == T_INTPOS || TNUM_OBJ(x) == T_INTNEG) {
306
UInt size = SIZE_INT(x);
307
mpz_realloc2(m, size * GMP_NUMB_BITS);
308
memcpy(m->_mp_d, ADDR_INT(x), sizeof(mp_limb_t) * size);
309
m->_mp_size = (TNUM_OBJ(x) == T_INTPOS) ? (Int)size : - (Int)size;
310
return true;
311
}
312
return false;
313
}
314
315
template<typename Integer>
316
static bool GAPIntVectorToNmz(vector<Integer>& out, Obj V)
317
{
318
if (!IS_PLIST(V) || !IS_DENSE_LIST(V))
319
return false;
320
const int n = LEN_PLIST(V);
321
out.resize(n);
322
for (int i = 0; i < n; ++i) {
323
Obj tmp = ELM_PLIST(V, i+1);
324
if (!GAPIntToNmz(tmp, out[i]))
325
return false;
326
}
327
return true;
328
}
329
330
template<typename Integer>
331
static bool GAPIntMatrixToNmz(vector< vector<Integer> >& out, Obj M)
332
{
333
if (!IS_PLIST(M) || !IS_DENSE_LIST(M))
334
return false;
335
const int nr = LEN_PLIST(M);
336
out.resize(nr);
337
for (int i = 0; i < nr; ++i) {
338
bool okay = GAPIntVectorToNmz(out[i], ELM_PLIST(M, i+1));
339
if (!okay)
340
return false;
341
}
342
return true;
343
}
344
345
template<typename Number>
346
static Obj NmzVectorToGAP(const vector<Number>& in)
347
{
348
Obj M;
349
const size_t n = in.size();
350
M = NEW_PLIST((n > 0) ? T_PLIST_CYC : T_PLIST, n);
351
SET_LEN_PLIST(M, n);
352
for (size_t i = 0; i < n; ++i) {
353
SET_ELM_PLIST(M, i+1, NmzNumberToGAP(in[i]));
354
CHANGED_BAG( M );
355
}
356
return M;
357
}
358
359
template<typename Number>
360
static Obj NmzMatrixToGAP(const vector< vector<Number> >& in)
361
{
362
Obj M;
363
const size_t n = in.size();
364
M = NEW_PLIST(T_PLIST, n);
365
SET_LEN_PLIST(M, n);
366
for (size_t i = 0; i < n; ++i) {
367
SET_ELM_PLIST(M, i+1, NmzVectorToGAP(in[i]));
368
CHANGED_BAG( M );
369
}
370
CHANGED_BAG( M );
371
return M;
372
}
373
374
static Obj NmzBoolMatrixToGAP(const vector< vector<bool> >& in)
375
{
376
Obj M;
377
Obj N;
378
const size_t m = in.size();
379
size_t n;
380
// TODO: Use BLIST instead
381
M = NEW_PLIST(T_PLIST, m);
382
SET_LEN_PLIST(M, m);
383
for (size_t i = 0; i < m; ++i) {
384
n = in[i].size();
385
N = NEW_PLIST( T_PLIST, n );
386
SET_LEN_PLIST( N, n );
387
for( size_t j = 0; j < n; ++j ){
388
SET_ELM_PLIST(N, j+1, in[i][j] ? True : False );
389
}
390
SET_ELM_PLIST( M, i+1, N );
391
CHANGED_BAG( M );
392
}
393
CHANGED_BAG( M );
394
return M;
395
}
396
397
/* TODO: HSOP
398
* There are two representations for Hilbert series in Normaliz, standard and HSOP.
399
* Currently, only the standard representation is returned.
400
*/
401
static Obj NmzHilbertSeriesToGAP(const libnormaliz::HilbertSeries& HS)
402
{
403
Obj ret;
404
ret = NEW_PLIST(T_PLIST, 3);
405
SET_LEN_PLIST(ret, 3);
406
AssPlist(ret, 1, NmzVectorToGAP(HS.getNum()));
407
AssPlist(ret, 2, NmzVectorToGAP(libnormaliz::to_vector(HS.getDenom())));
408
AssPlist(ret, 3, NmzNumberToGAP(HS.getShift()));
409
return ret;
410
}
411
412
template<typename Integer>
413
static Obj NmzWeightedEhrhartSeriesToGAP(const std::pair<libnormaliz::HilbertSeries,Integer>& HS)
414
{
415
Obj ret;
416
ret = NEW_PLIST(T_PLIST, 4);
417
SET_LEN_PLIST(ret, 4);
418
AssPlist(ret, 1, NmzVectorToGAP(HS.first.getNum()));
419
AssPlist(ret, 2, NmzVectorToGAP(libnormaliz::to_vector(HS.first.getDenom())));
420
AssPlist(ret, 3, NmzNumberToGAP(HS.first.getShift()));
421
AssPlist(ret, 4, NmzNumberToGAP(HS.second));
422
return ret;
423
}
424
425
static Obj NmzHilbertQuasiPolynomialToGAP(const libnormaliz::HilbertSeries& HS)
426
{
427
Obj ret;
428
vector< vector<mpz_class> > HQ = HS.getHilbertQuasiPolynomial();
429
const size_t n = HS.getPeriod();
430
ret = NEW_PLIST(T_PLIST, n+1);
431
SET_LEN_PLIST(ret, n+1);
432
433
for (size_t i = 0; i < n; ++i) {
434
SET_ELM_PLIST(ret, i+1, NmzVectorToGAP(HQ[i]));
435
CHANGED_BAG( ret );
436
}
437
AssPlist(ret, n+1, NmzNumberToGAP(HS.getHilbertQuasiPolynomialDenom()));
438
return ret;
439
}
440
441
static Obj NmzWeightedEhrhartQuasiPolynomialToGAP(const libnormaliz::IntegrationData& int_data)
442
{
443
Obj ret;
444
vector< vector<mpz_class> > ehrhart_qp = int_data.getWeightedEhrhartQuasiPolynomial();
445
const size_t n = ehrhart_qp.size();
446
ret = NEW_PLIST(T_PLIST, n+1);
447
for (size_t i = 0; i < n; ++i) {
448
SET_ELM_PLIST(ret, i+1 , NmzVectorToGAP(ehrhart_qp[i]));
449
CHANGED_BAG( ret );
450
}
451
AssPlist(ret, n+1, NmzNumberToGAP(int_data.getWeightedEhrhartQuasiPolynomialDenom()));
452
return ret;
453
}
454
455
template<typename Integer>
456
static Obj NmzTriangleListToGAP(const vector< pair<vector<libnormaliz::key_t>, Integer> >& in)
457
{
458
Obj M;
459
const size_t n = in.size();
460
M = NEW_PLIST(T_PLIST, n);
461
SET_LEN_PLIST(M, n);
462
for (size_t i = 0; i < n; ++i) {
463
// convert the pair
464
Obj pair = NEW_PLIST(T_PLIST, 2);
465
SET_LEN_PLIST(pair, 2);
466
SET_ELM_PLIST(pair, 1, NmzVectorToGAP<libnormaliz::key_t>(in[i].first));
467
SET_ELM_PLIST(pair, 2, NmzNumberToGAP(in[i].second));
468
CHANGED_BAG( pair );
469
470
SET_ELM_PLIST(M, i+1, pair);
471
CHANGED_BAG( M );
472
}
473
CHANGED_BAG( M );
474
return M;
475
}
476
477
478
template<typename Integer>
479
static Obj _NmzConeIntern(Obj input_list)
480
{
481
bool has_polynomial_input = false;
482
string polynomial;
483
map <InputType, vector< vector<Integer> > > input;
484
const int n = LEN_PLIST(input_list);
485
if (n&1) {
486
throw std::runtime_error("Input list must have even number of elements");
487
}
488
for (int i = 0; i < n; i += 2) {
489
Obj type = ELM_PLIST(input_list, i+1);
490
if (!IS_STRING_REP(type)) {
491
throw std::runtime_error("Element " + std::to_string(i+1) + " of the input list must be a type string");
492
}
493
string type_str(CSTR_STRING(type));
494
Obj M = ELM_PLIST(input_list, i+2);
495
if (type_str.compare("polynomial") == 0) {
496
if (!IS_STRING_REP(M)) {
497
throw std::runtime_error("Element " + std::to_string(i+2) + " of the input list must be a string");
498
}
499
polynomial = string(CSTR_STRING(M));
500
has_polynomial_input = true;
501
continue;
502
}
503
vector<vector<Integer> > Mat;
504
bool okay = GAPIntMatrixToNmz(Mat, M);
505
if (!okay) {
506
throw std::runtime_error("Element " + std::to_string(i+2) + " of the input list must integer matrix");
507
}
508
509
input[libnormaliz::to_type(type_str)] = Mat;
510
}
511
512
Cone<Integer>* C = new Cone<Integer>(input);
513
if (has_polynomial_input) {
514
C->setPolynomial(polynomial);
515
}
516
Obj Cone = NewCone(C);
517
return Cone;
518
519
}
520
521
Obj _NmzCone(Obj self, Obj input_list)
522
{
523
if (!IS_PLIST(input_list) || !IS_DENSE_LIST(input_list))
524
ErrorQuit("Input argument must be a list", 0, 0);
525
526
FUNC_BEGIN
527
return _NmzConeIntern<mpz_class>(input_list);
528
FUNC_END
529
}
530
531
Obj _NmzCompute(Obj self, Obj cone, Obj to_compute)
532
{
533
if (!IS_CONE(cone))
534
ErrorQuit("<cone> must be a Normaliz cone", 0, 0);
535
if (!IS_PLIST(to_compute) || !IS_DENSE_LIST(to_compute))
536
ErrorQuit("<props> must be a list of strings", 0, 0);
537
538
FUNC_BEGIN
539
ConeProperties propsToCompute;
540
// we have a list
541
const int n = LEN_PLIST(to_compute);
542
543
for (int i = 0; i < n; ++i) {
544
Obj prop = ELM_PLIST(to_compute, i+1);
545
if (!IS_STRING_REP(prop)) {
546
throw std::runtime_error("Element " + std::to_string(i+1) + " of the input list must be a type string");
547
}
548
string prop_str(CSTR_STRING(prop));
549
propsToCompute.set( libnormaliz::toConeProperty(prop_str) );
550
}
551
552
Cone<mpz_class>* C = GET_CONE<mpz_class>(cone);
553
554
ConeProperties notComputed;
555
SIGNAL_HANDLER_BEGIN
556
notComputed = C->compute(propsToCompute);
557
SIGNAL_HANDLER_END
558
559
// Cone.compute returns the not computed properties
560
// we return a bool, true when everything requested was computed
561
return notComputed.none() ? True : False;
562
FUNC_END
563
}
564
565
566
/*
567
#! @Section Use a NmzCone
568
#! @Arguments cone property
569
#! @Returns whether the cone has already computed the given property
570
#! @Description
571
#! See <Ref Func="NmzConeProperty"/> for a list of recognized properties.
572
#!
573
#! @InsertChunk NmzHasConeProperty example
574
DeclareGlobalFunction("NmzHasConeProperty");
575
*/
576
Obj NmzHasConeProperty(Obj self, Obj cone, Obj prop)
577
{
578
if (!IS_CONE(cone))
579
ErrorQuit("<cone> must be a Normaliz cone", 0, 0);
580
if (!IS_STRING_REP(prop))
581
ErrorQuit("<prop> must be a string", 0, 0);
582
583
FUNC_BEGIN
584
585
libnormaliz::ConeProperty::Enum p = libnormaliz::toConeProperty(CSTR_STRING(prop));
586
587
Cone<mpz_class>* C = GET_CONE<mpz_class>(cone);
588
return C->isComputed(p) ? True : False;
589
590
FUNC_END
591
}
592
593
/*
594
#! @Section Use a NmzCone
595
#! @Arguments cone
596
#! @Returns a list of strings representing the known (computed) cone properties
597
#! @Description
598
#! Given a Normaliz cone object, return a list of all properties already
599
#! computed for the cone.
600
#!
601
#! @InsertChunk NmzKnownConeProperties example
602
DeclareGlobalFunction("NmzKnownConeProperties");
603
*/
604
Obj NmzKnownConeProperties(Obj self, Obj cone)
605
{
606
if (!IS_CONE(cone))
607
ErrorQuit("<cone> must be a Normaliz cone", 0, 0);
608
609
FUNC_BEGIN
610
611
size_t n = 0;
612
Obj M = NEW_PLIST(T_PLIST, libnormaliz::ConeProperty::EnumSize);
613
614
// FIXME: This code could be a lot simpler if there was
615
// a Cone method for reading the value of is_Computed.
616
for (int i = 0; i < libnormaliz::ConeProperty::EnumSize; ++i) {
617
libnormaliz::ConeProperty::Enum p = (libnormaliz::ConeProperty::Enum)i;
618
619
Cone<mpz_class>* C = GET_CONE<mpz_class>(cone);
620
bool isComputed = C->isComputed(p);
621
622
if (isComputed) {
623
string prop_name(libnormaliz::toString(p));
624
625
Obj prop_name_gap;
626
C_NEW_STRING(prop_name_gap, prop_name.size(), prop_name.c_str());
627
628
n++; // Increment counter
629
SET_ELM_PLIST(M, n, prop_name_gap);
630
CHANGED_BAG(M);
631
if (p == libnormaliz::ConeProperty::HilbertSeries) {
632
Cone<mpz_class>* C = GET_CONE<mpz_class>(cone);
633
C->getHilbertSeries().computeHilbertQuasiPolynomial();
634
isComputed = C->getHilbertSeries().isHilbertQuasiPolynomialComputed();
635
636
if (isComputed) {
637
string prop_name("HilbertQuasiPolynomial");
638
639
Obj prop_name_gap;
640
C_NEW_STRING(prop_name_gap, prop_name.size(), prop_name.c_str());
641
642
n++; // Increment counter
643
SET_ELM_PLIST(M, n, prop_name_gap);
644
CHANGED_BAG(M);
645
}
646
}
647
}
648
}
649
SET_LEN_PLIST(M, n);
650
return M;
651
652
FUNC_END
653
}
654
655
template<typename Integer>
656
static Obj _NmzConePropertyImpl(Obj cone, Obj prop)
657
{
658
Cone<Integer>* C = GET_CONE<Integer>(cone);
659
660
libnormaliz::ConeProperty::Enum p = libnormaliz::toConeProperty(CSTR_STRING(prop));
661
ConeProperties notComputed;
662
SIGNAL_HANDLER_BEGIN
663
notComputed = C->compute(ConeProperties(p));
664
SIGNAL_HANDLER_END
665
if (notComputed.any()) {
666
return Fail;
667
}
668
669
switch (p) {
670
case libnormaliz::ConeProperty::Generators:
671
return NmzMatrixToGAP(C->getGenerators());
672
673
case libnormaliz::ConeProperty::ExtremeRays:
674
return NmzMatrixToGAP(C->getExtremeRays());
675
676
case libnormaliz::ConeProperty::VerticesOfPolyhedron:
677
return NmzMatrixToGAP(C->getVerticesOfPolyhedron());
678
679
case libnormaliz::ConeProperty::SupportHyperplanes:
680
return NmzMatrixToGAP(C->getSupportHyperplanes());
681
682
case libnormaliz::ConeProperty::TriangulationSize:
683
return ObjInt_UInt(C->getTriangulationSize());
684
685
case libnormaliz::ConeProperty::TriangulationDetSum:
686
return NmzNumberToGAP(C->getTriangulationDetSum());
687
688
case libnormaliz::ConeProperty::Triangulation:
689
return NmzTriangleListToGAP<Integer>(C->getTriangulation());
690
691
case libnormaliz::ConeProperty::Multiplicity:
692
{
693
mpq_class mult = C->getMultiplicity();
694
return MpqClassToGAP(mult);
695
}
696
697
case libnormaliz::ConeProperty::Integral:
698
return MpqClassToGAP(C->getIntegral());
699
700
case libnormaliz::ConeProperty::VirtualMultiplicity:
701
return MpqClassToGAP(C->getVirtualMultiplicity());
702
703
case libnormaliz::ConeProperty::RecessionRank:
704
return NmzNumberToGAP(C->getRecessionRank());
705
706
case libnormaliz::ConeProperty::AffineDim:
707
return NmzNumberToGAP(C->getAffineDim());
708
709
case libnormaliz::ConeProperty::ModuleRank:
710
return NmzNumberToGAP(C->getModuleRank());
711
712
case libnormaliz::ConeProperty::HilbertBasis:
713
return NmzMatrixToGAP(C->getHilbertBasis());
714
715
case libnormaliz::ConeProperty::MaximalSubspace:
716
return NmzMatrixToGAP(C->getMaximalSubspace());
717
718
case libnormaliz::ConeProperty::ModuleGenerators:
719
return NmzMatrixToGAP(C->getModuleGenerators());
720
721
case libnormaliz::ConeProperty::Deg1Elements:
722
return NmzMatrixToGAP(C->getDeg1Elements());
723
724
case libnormaliz::ConeProperty::HilbertSeries:
725
return NmzHilbertSeriesToGAP(C->getHilbertSeries());
726
break;
727
728
case libnormaliz::ConeProperty::Grading:
729
{
730
vector<Integer> grad = C->getGrading();
731
grad.push_back(C->getGradingDenom());
732
return NmzVectorToGAP(grad);
733
}
734
735
case libnormaliz::ConeProperty::GradingDenom:
736
return NmzNumberToGAP( C->getGradingDenom() );
737
738
case libnormaliz::ConeProperty::IsPointed:
739
return C->isPointed() ? True : False;
740
741
case libnormaliz::ConeProperty::IsDeg1ExtremeRays:
742
return C->isDeg1ExtremeRays() ? True : False;
743
744
case libnormaliz::ConeProperty::IsDeg1HilbertBasis:
745
return C->isDeg1HilbertBasis() ? True : False;
746
747
case libnormaliz::ConeProperty::IsIntegrallyClosed:
748
return C->isIntegrallyClosed() ? True : False;
749
750
case libnormaliz::ConeProperty::OriginalMonoidGenerators:
751
return NmzMatrixToGAP(C->getOriginalMonoidGenerators());
752
753
case libnormaliz::ConeProperty::IsReesPrimary:
754
return C->isReesPrimary() ? True : False;
755
756
case libnormaliz::ConeProperty::ReesPrimaryMultiplicity:
757
return NmzNumberToGAP(C->getReesPrimaryMultiplicity());
758
759
// StanleyDec is special and we do not support the required conversion at
760
// this time. If you really need this, contact the developers.
761
case libnormaliz::ConeProperty::StanleyDec:
762
//C->getStanleyDec();
763
break;
764
765
case libnormaliz::ConeProperty::ExcludedFaces:
766
return NmzMatrixToGAP(C->getExcludedFaces());
767
768
case libnormaliz::ConeProperty::Dehomogenization:
769
return NmzVectorToGAP(C->getDehomogenization());
770
771
case libnormaliz::ConeProperty::InclusionExclusionData:
772
return NmzTriangleListToGAP<long>(C->getInclusionExclusionData());
773
774
case libnormaliz::ConeProperty::ClassGroup:
775
return NmzVectorToGAP(C->getClassGroup());
776
777
case libnormaliz::ConeProperty::IsInhomogeneous:
778
return C->isInhomogeneous() ? True : False;
779
780
case libnormaliz::ConeProperty::Equations:
781
return NmzMatrixToGAP(C->getSublattice().getEquations());
782
783
case libnormaliz::ConeProperty::Congruences:
784
return NmzMatrixToGAP(C->getSublattice().getCongruences());
785
786
case libnormaliz::ConeProperty::EmbeddingDim:
787
return NmzNumberToGAP(C->getEmbeddingDim());
788
789
case libnormaliz::ConeProperty::Rank:
790
return NmzNumberToGAP(C->getRank());
791
792
case libnormaliz::ConeProperty::Sublattice:
793
return _NmzBasisChangeIntern(C);
794
795
case libnormaliz::ConeProperty::IntegerHull:
796
{
797
Cone<Integer>* int_hull = &(C->getIntegerHullCone());
798
return NewProxyCone( int_hull, cone );
799
}
800
801
case libnormaliz::ConeProperty::HilbertQuasiPolynomial:
802
return NmzHilbertQuasiPolynomialToGAP(C->getHilbertSeries());
803
804
case libnormaliz::ConeProperty::WeightedEhrhartQuasiPolynomial:
805
return NmzWeightedEhrhartQuasiPolynomialToGAP(C->getIntData());
806
807
case libnormaliz::ConeProperty::IsTriangulationNested:
808
return C->isTriangulationNested() ? True : False;
809
810
case libnormaliz::ConeProperty::IsTriangulationPartial:
811
return C->isTriangulationPartial() ? True : False;
812
813
case libnormaliz::ConeProperty::ConeDecomposition:
814
return NmzBoolMatrixToGAP(C->getOpenFacets());
815
816
case libnormaliz::ConeProperty::ExternalIndex:
817
return NmzNumberToGAP(C->getSublattice().getExternalIndex());
818
819
case libnormaliz::ConeProperty::InternalIndex:
820
return NmzNumberToGAP(C->getIndex());
821
822
case libnormaliz::ConeProperty::WitnessNotIntegrallyClosed:
823
return NmzVectorToGAP(C->getWitnessNotIntegrallyClosed());
824
825
case libnormaliz::ConeProperty::UnitGroupIndex:
826
return NmzNumberToGAP(C->getUnitGroupIndex());
827
828
case libnormaliz::ConeProperty::WeightedEhrhartSeries:
829
return NmzWeightedEhrhartSeriesToGAP(C->getWeightedEhrhartSeries());
830
831
case libnormaliz::ConeProperty::IsGorenstein:
832
return C->isGorenstein() ? True : False;
833
834
case libnormaliz::ConeProperty::GeneratorOfInterior:
835
return NmzVectorToGAP( C->getGeneratorOfInterior() );
836
837
case libnormaliz::ConeProperty::VerticesFloat:
838
return NmzMatrixToGAP( C->getVerticesFloat() );
839
840
// the following properties are compute options and do not return anything
841
case libnormaliz::ConeProperty::DefaultMode:
842
case libnormaliz::ConeProperty::Approximate:
843
case libnormaliz::ConeProperty::BottomDecomposition:
844
case libnormaliz::ConeProperty::KeepOrder:
845
case libnormaliz::ConeProperty::NoBottomDec:
846
case libnormaliz::ConeProperty::PrimalMode:
847
case libnormaliz::ConeProperty::Symmetrize:
848
case libnormaliz::ConeProperty::NoSymmetrization:
849
case libnormaliz::ConeProperty::BigInt:
850
case libnormaliz::ConeProperty::NoNestedTri:
851
case libnormaliz::ConeProperty::HSOP:
852
case libnormaliz::ConeProperty::Projection:
853
case libnormaliz::ConeProperty::NoProjection:
854
case libnormaliz::ConeProperty::ProjectionFloat:
855
case libnormaliz::ConeProperty::SCIP:
856
case libnormaliz::ConeProperty::NoPeriodBound:
857
throw "cone property is input-only";
858
859
default:
860
throw "unknown cone property";
861
}
862
863
return Fail;
864
}
865
866
Obj _NmzConeProperty(Obj self, Obj cone, Obj prop)
867
{
868
if (!IS_CONE(cone))
869
ErrorQuit("<cone> must be a Normaliz cone", 0, 0);
870
if (!IS_STRING_REP(prop))
871
ErrorQuit("<prop> must be a string", 0, 0);
872
873
FUNC_BEGIN
874
return _NmzConePropertyImpl<mpz_class>(cone, prop);
875
FUNC_END
876
}
877
878
879
880
/*
881
#! @Section Use a NmzCone
882
#! @Arguments verboseFlag
883
#! @Returns the previous verbosity
884
#! @Description
885
#! Set the global default verbosity state in libnormaliz.
886
#! This will influence all NmzCone created afterwards, but not any existing ones.
887
#!
888
#! See also <Ref Func="NmzSetVerbose"/>
889
DeclareGlobalFunction("NmzSetVerboseDefault");
890
*/
891
Obj NmzSetVerboseDefault(Obj self, Obj value)
892
{
893
if (value != True && value != False)
894
ErrorQuit("<value> must be a boolean value", 0, 0);
895
FUNC_BEGIN
896
return libnormaliz::setVerboseDefault(value == True) ? True : False;
897
FUNC_END
898
}
899
/*
900
#! @Arguments cone verboseFlag
901
#! @Returns the previous verbosity
902
#! @Description
903
#! Set the verbosity state for a cone.
904
#!
905
#! See also <Ref Func="NmzSetVerboseDefault"/>
906
DeclareGlobalFunction("NmzSetVerbose");
907
*/
908
Obj NmzSetVerbose(Obj self, Obj cone, Obj value)
909
{
910
if (!IS_CONE(cone))
911
ErrorQuit("<cone> must be a Normaliz cone", 0, 0);
912
if (value != True && value != False)
913
ErrorQuit("<value> must be a boolean value", 0, 0);
914
bool old_value;
915
916
FUNC_BEGIN
917
Cone<mpz_class>* C = GET_CONE<mpz_class>(cone);
918
old_value = C->setVerbose(value == True);
919
return old_value ? True : False;
920
FUNC_END
921
}
922
923
/*
924
#! @Section Cone properties
925
*/
926
927
928
template<typename Integer>
929
static Obj _NmzBasisChangeIntern(Cone<Integer>* C)
930
{
931
Sublattice_Representation<Integer> bc;
932
SIGNAL_HANDLER_BEGIN
933
bc = C->getSublattice();
934
SIGNAL_HANDLER_END
935
936
Obj res = NEW_PLIST(T_PLIST, 3);
937
SET_LEN_PLIST(res, 3);
938
AssPlist(res, 1, NmzMatrixToGAP(bc.getEmbedding()));
939
AssPlist(res, 2, NmzMatrixToGAP(bc.getProjection()));
940
AssPlist(res, 3, NmzNumberToGAP(bc.getAnnihilator()));
941
// Dim, Rank, Equations and Congruences are already covered by special functions
942
// The index is not always computed and not so relevant
943
return res;
944
}
945
946
947
typedef Obj (* GVarFuncType)(/*arguments*/);
948
949
#define GVAR_FUNC_TABLE_ENTRY(srcfile, name, nparam, params) \
950
{#name, nparam, \
951
params, \
952
(GVarFuncType)name, \
953
srcfile ":Func" #name }
954
955
// Table of functions to export
956
static StructGVarFunc GVarFuncs[] = {
957
GVAR_FUNC_TABLE_ENTRY("normaliz.cc", _NmzCone, 1, "list"),
958
959
GVAR_FUNC_TABLE_ENTRY("normaliz.cc", _NmzCompute, 2, "cone, props"),
960
GVAR_FUNC_TABLE_ENTRY("normaliz.cc", NmzSetVerboseDefault, 1, "value"),
961
GVAR_FUNC_TABLE_ENTRY("normaliz.cc", NmzSetVerbose, 2, "cone, value"),
962
963
GVAR_FUNC_TABLE_ENTRY("normaliz.cc", NmzHasConeProperty, 2, "cone, prop"),
964
GVAR_FUNC_TABLE_ENTRY("normaliz.cc", _NmzConeProperty, 2, "cone, prop"),
965
GVAR_FUNC_TABLE_ENTRY("normaliz.cc", NmzKnownConeProperties, 1, "cone"),
966
967
{ 0 } /* Finish with an empty entry */
968
969
};
970
971
/******************************************************************************
972
*F InitKernel( <module> ) . . . . . . . . initialise kernel data structures
973
*/
974
static Int InitKernel( StructInitInfo *module )
975
{
976
/* init filters and functions */
977
InitHdlrFuncsFromTable( GVarFuncs );
978
979
InitCopyGVar( "TheTypeNormalizCone", &TheTypeNormalizCone );
980
981
T_NORMALIZ = RegisterPackageTNUM("NormalizCone", NormalizTypeFunc);
982
983
InitMarkFuncBags(T_NORMALIZ, &MarkAllSubBags);
984
InitFreeFuncBag(T_NORMALIZ, &NormalizFreeFunc);
985
986
CopyObjFuncs[ T_NORMALIZ ] = &NormalizCopyFunc;
987
CleanObjFuncs[ T_NORMALIZ ] = &NormalizCleanFunc;
988
IsMutableObjFuncs[ T_NORMALIZ ] = &NormalizIsMutableObjFuncs;
989
990
/* return success */
991
return 0;
992
}
993
994
/******************************************************************************
995
*F InitLibrary( <module> ) . . . . . . . initialise library data structures
996
*/
997
static Int InitLibrary( StructInitInfo *module )
998
{
999
/* init filters and functions */
1000
InitGVarFuncsFromTable( GVarFuncs );
1001
1002
/* return success */
1003
return 0;
1004
}
1005
1006
/******************************************************************************
1007
*F InitInfopl() . . . . . . . . . . . . . . . . . table of init functions
1008
*/
1009
static StructInitInfo module = {
1010
#ifdef NORMALIZSTATIC
1011
/* type = */ MODULE_STATIC,
1012
#else
1013
/* type = */ MODULE_DYNAMIC,
1014
#endif
1015
/* name = */ "Normaliz",
1016
/* revision_c = */ 0,
1017
/* revision_h = */ 0,
1018
/* version = */ 0,
1019
/* crc = */ 0,
1020
/* initKernel = */ InitKernel,
1021
/* initLibrary = */ InitLibrary,
1022
/* checkInit = */ 0,
1023
/* preSave = */ 0,
1024
/* postSave = */ 0,
1025
/* postRestore = */ 0
1026
};
1027
1028
#ifndef NORMALIZSTATIC
1029
extern "C"
1030
StructInitInfo * Init__Dynamic ( void )
1031
{
1032
return &module;
1033
}
1034
#endif
1035
1036
extern "C"
1037
StructInitInfo * Init__normaliz ( void )
1038
{
1039
return &module;
1040
}
1041
1042