Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

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

563621 views
1
/***************************************************************************
2
*
3
* Include
4
*
5
***************************************************************************/
6
7
#include <Python.h>
8
using namespace std;
9
10
#include <iostream>
11
using std::cout;
12
using std::cerr;
13
using std::endl;
14
15
#include <string>
16
using std::string;
17
18
#include <libnormaliz/cone.h>
19
#include <libnormaliz/map_operations.h>
20
21
using libnormaliz::Cone;
22
//using libnormaliz::ConeProperty;
23
using libnormaliz::ConeProperties;
24
using libnormaliz::Sublattice_Representation;
25
using libnormaliz::Type::InputType;
26
27
#include <vector>
28
using std::map;
29
using std::vector;
30
using std::pair;
31
32
#include<csignal>
33
34
typedef int py_size_t;
35
36
/***************************************************************************
37
*
38
* Macros for exception handling
39
*
40
***************************************************************************/
41
42
#define FUNC_BEGIN try {
43
44
#define FUNC_END \
45
} catch (libnormaliz::InterruptException& e ) {\
46
PyOS_setsig(SIGINT,current_interpreter_sigint_handler);\
47
libnormaliz::nmz_interrupted = false; \
48
PyErr_SetInterrupt(); \
49
PyErr_CheckSignals(); \
50
return NULL; \
51
} catch (libnormaliz::NormalizException& e) { \
52
PyOS_setsig(SIGINT,current_interpreter_sigint_handler);\
53
PyErr_SetString( NormalizError, e.what() ); \
54
return NULL; \
55
} catch( exception& e ) { \
56
PyOS_setsig(SIGINT,current_interpreter_sigint_handler);\
57
PyErr_SetString( PyNormaliz_cppError, e.what() ); \
58
return NULL; \
59
}
60
61
/***************************************************************************
62
*
63
* Signal handling
64
*
65
***************************************************************************/
66
67
void signal_handler( int signal ){
68
libnormaliz::nmz_interrupted = true;
69
}
70
71
/***************************************************************************
72
*
73
* Static objects
74
*
75
***************************************************************************/
76
77
78
static PyObject * NormalizError;
79
static PyObject * PyNormaliz_cppError;
80
static const char* cone_name = "Cone";
81
static const char* cone_name_long = "Cone<long long>";
82
static string cone_name_str( cone_name );
83
static string cone_name_str_long( cone_name_long );
84
85
static PyOS_sighandler_t current_interpreter_sigint_handler;
86
87
/***************************************************************************
88
*
89
* Compiler version control
90
*
91
***************************************************************************/
92
93
#if PY_MAJOR_VERSION >= 3
94
#define string_check PyUnicode_Check
95
#else
96
#define string_check PyString_Check
97
#endif
98
99
// Hacky 64-bit check. Works for windows and gcc, probably not clang.
100
// Check windows
101
#if _WIN32 || _WIN64
102
#if _WIN64
103
#define ENVIRONMENT64
104
#else
105
#define ENVIRONMENT32
106
#endif
107
#endif
108
109
// Check GCC
110
#if __GNUC__
111
#if __x86_64__ || __ppc64__ || __aarch64__
112
#define ENVIRONMENT64
113
#else
114
#define ENVIRONMENT32
115
#endif
116
#endif
117
118
#ifndef NMZ_RELEASE
119
static_assert(false,
120
"Your Normaliz version (unknown) is to old! Update to 3.2.0 or newer.");
121
#endif
122
#if NMZ_RELEASE < 30400
123
static_assert(false, "Your Normaliz version is to old! Update to 3.3.1 or newer.");
124
#endif
125
126
/***************************************************************************
127
*
128
* Python-C data conversion functions
129
*
130
***************************************************************************/
131
132
string PyUnicodeToString( PyObject* in ){
133
#if PY_MAJOR_VERSION >= 3
134
string out = "";
135
int length = PyUnicode_GET_SIZE( in );
136
for( int i = 0; i < length; i++ ){
137
out += PyUnicode_READ_CHAR( in, i );
138
}
139
return out;
140
#else
141
char* out = PyString_AsString( in );
142
return string(out);
143
#endif
144
}
145
146
PyObject * StringToPyUnicode( string in ){
147
#if PY_MAJOR_VERSION >= 3
148
return PyUnicode_FromString( in.c_str() );
149
#else
150
return PyString_FromString( in.c_str() );
151
#endif
152
}
153
154
// Boolean conversion
155
156
inline PyObject* BoolToPyBool( bool in ){
157
return in ? Py_True : Py_False;
158
}
159
160
// Converting MPZ's to PyLong and back via strings. Worst possible solution ever.
161
162
bool PyNumberToNmz( PyObject * in, mpq_class& out ){
163
if( PyFloat_Check( in ) ){
164
mpq_class temp(PyFloat_AsDouble(in));
165
out.swap(temp);
166
return true;
167
}
168
PyObject * in_as_string = PyObject_Str( in );
169
const char* in_as_c_string = PyUnicodeToString( in_as_string ).c_str();
170
out.set_str( in_as_c_string, 10 );
171
return true;
172
}
173
174
PyObject* NmzToPyNumber( mpz_class in ){
175
string mpz_as_string = in.get_str();
176
char* mpz_as_c_string = const_cast<char*>(mpz_as_string.c_str());
177
char * pend;
178
PyObject* ret_val = PyLong_FromString( mpz_as_c_string, &pend, 10 );
179
return ret_val;
180
}
181
182
PyObject* NmzToPyList( mpq_class in ){
183
PyObject* out_list = PyList_New( 2 );
184
PyList_SetItem( out_list, 0, NmzToPyNumber( in.get_num() ) );
185
PyList_SetItem( out_list, 1, NmzToPyNumber( in.get_den() ) );
186
return out_list;
187
}
188
189
bool PyNumberToNmz( PyObject* in, long long & out ){
190
191
int overflow;
192
out = PyLong_AsLongLongAndOverflow( in, &overflow );
193
if( overflow == -1 )
194
return false;
195
return true;
196
197
}
198
199
PyObject* NmzToPyNumber( long long in ){
200
201
return PyLong_FromLongLong( in );
202
203
}
204
205
PyObject* NmzToPyNumber( libnormaliz::key_t in ){
206
207
return PyLong_FromLong( in );
208
209
}
210
211
#ifdef ENVIRONMENT64
212
PyObject* NmzToPyNumber( size_t in ){
213
214
return PyLong_FromLong( in );
215
216
}
217
#endif
218
219
PyObject* NmzToPyNumber( long in ){
220
221
return PyLong_FromLong( in );
222
223
}
224
225
PyObject* NmzToPyNumber( double in ){
226
227
return PyFloat_FromDouble( in );
228
229
}
230
231
template<typename Integer>
232
bool PyNumberToNmz(Integer& x, Integer &out){
233
234
return Integer::unimplemented_function;
235
236
}
237
238
template<typename Integer>
239
PyObject* NmzToPyNumber(Integer &in){
240
241
return Integer::unimplemented_function;
242
243
}
244
245
template<typename Integer>
246
static bool PyListToNmz( vector<Integer>& out, PyObject* in ){
247
if (!PyList_Check(in))
248
return false;
249
const int n = PyList_Size(in);
250
out.resize(n);
251
for (int i = 0; i < n; ++i) {
252
PyObject* tmp = PyList_GetItem(in, i);
253
if (!PyNumberToNmz(tmp, out[i]))
254
return false;
255
}
256
return true;
257
}
258
259
template<typename Integer>
260
static bool PyIntMatrixToNmz( vector<vector<Integer> >& out, PyObject* in ){
261
if (!PyList_Check( in ) )
262
return false;
263
const int nr = PyList_Size( in );
264
out.resize(nr);
265
for (int i = 0; i < nr; ++i) {
266
bool okay = PyListToNmz(out[i], PyList_GetItem(in, i));
267
if (!okay)
268
return false;
269
}
270
return true;
271
}
272
273
template<typename Integer>
274
PyObject* NmzVectorToPyList(const vector<Integer>& in)
275
{
276
PyObject* vector;
277
const size_t n = in.size();
278
vector = PyList_New(n);
279
for (size_t i = 0; i < n; ++i) {
280
PyList_SetItem(vector, i, NmzToPyNumber(in[i]));
281
}
282
return vector;
283
}
284
285
PyObject* NmzBoolVectorToPyList(const vector<bool>& in)
286
{
287
PyObject* vector;
288
const size_t n = in.size();
289
vector = PyList_New(n);
290
for (size_t i = 0; i < n; ++i) {
291
PyList_SetItem(vector, i, BoolToPyBool(in[i]));
292
}
293
return vector;
294
}
295
296
PyObject* NmzBoolMatrixToPyList(const vector< vector<bool> >& in)
297
{
298
PyObject* matrix;
299
const size_t n = in.size();
300
matrix = PyList_New( n );
301
for (size_t i = 0; i < n; ++i) {
302
PyList_SetItem(matrix, i, NmzBoolVectorToPyList(in[i]));
303
}
304
return matrix;
305
}
306
307
template<typename Integer>
308
PyObject* NmzMatrixToPyList(const vector< vector<Integer> >& in)
309
{
310
PyObject* matrix;
311
const size_t n = in.size();
312
matrix = PyList_New( n );
313
for (size_t i = 0; i < n; ++i) {
314
PyList_SetItem(matrix, i, NmzVectorToPyList(in[i]));
315
}
316
return matrix;
317
}
318
319
PyObject* NmzHilbertSeriesToPyList(const libnormaliz::HilbertSeries& HS, bool is_HSOP)
320
{
321
PyObject* return_list = PyList_New( 3 );
322
if(is_HSOP){
323
PyList_SetItem(return_list, 0, NmzVectorToPyList(HS.getHSOPNum()));
324
PyList_SetItem(return_list, 1, NmzVectorToPyList(libnormaliz::to_vector(HS.getHSOPDenom())));
325
PyList_SetItem(return_list, 2, NmzToPyNumber(HS.getShift()));
326
}else{
327
PyList_SetItem(return_list, 0, NmzVectorToPyList(HS.getNum()));
328
PyList_SetItem(return_list, 1, NmzVectorToPyList(libnormaliz::to_vector(HS.getDenom())));
329
PyList_SetItem(return_list, 2, NmzToPyNumber(HS.getShift()));
330
}
331
return return_list;
332
}
333
334
template<typename Integer>
335
PyObject* NmzWeightedEhrhartSeriesToPyList(const std::pair<libnormaliz::HilbertSeries,Integer>& HS)
336
{
337
PyObject* return_list = PyList_New( 4 );
338
PyList_SetItem(return_list, 0, NmzVectorToPyList(HS.first.getNum()));
339
PyList_SetItem(return_list, 1, NmzVectorToPyList(libnormaliz::to_vector(HS.first.getDenom())));
340
PyList_SetItem(return_list, 2, NmzToPyNumber(HS.first.getShift()));
341
PyList_SetItem(return_list, 3, NmzToPyNumber(HS.second) );
342
return return_list;
343
}
344
345
template<typename Integer>
346
PyObject* NmzHilbertQuasiPolynomialToPyList(const libnormaliz::HilbertSeries& HS)
347
{
348
vector< vector<Integer> > HQ = HS.getHilbertQuasiPolynomial();
349
const size_t n = HS.getPeriod();
350
PyObject* return_list = PyList_New(n+1);
351
for (size_t i = 0; i < n; ++i) {
352
PyList_SetItem(return_list, i, NmzVectorToPyList(HQ[i]));
353
}
354
PyList_SetItem(return_list, n, NmzToPyNumber(HS.getHilbertQuasiPolynomialDenom()));
355
return return_list;
356
}
357
358
template<typename Integer>
359
PyObject* NmzWeightedEhrhartQuasiPolynomialToPyList(const libnormaliz::IntegrationData& int_data)
360
{
361
vector< vector<Integer> > ehrhart_qp = int_data.getWeightedEhrhartQuasiPolynomial();
362
const size_t n = ehrhart_qp.size();
363
PyObject* return_list = PyList_New(n+1);
364
for (size_t i = 0; i < n; ++i) {
365
PyList_SetItem(return_list, i, NmzVectorToPyList(ehrhart_qp[i]));
366
}
367
PyList_SetItem(return_list, n, NmzToPyNumber(int_data.getWeightedEhrhartQuasiPolynomialDenom()));
368
return return_list;
369
}
370
371
template<typename Integer>
372
PyObject* NmzTriangleListToPyList(const vector< pair<vector<libnormaliz::key_t>, Integer> >& in)
373
{
374
const size_t n = in.size();
375
PyObject* M = PyList_New( n );
376
for (size_t i = 0; i < n; ++i) {
377
// convert the pair
378
PyObject* pair = PyList_New(2);
379
PyList_SetItem(pair, 0, NmzVectorToPyList<libnormaliz::key_t>(in[i].first));
380
PyList_SetItem(pair, 1, NmzToPyNumber(in[i].second));
381
PyList_SetItem(M, i, pair);
382
}
383
return M;
384
}
385
386
template<typename Integer>
387
PyObject* NmzStanleyDataToPyList(const libnormaliz::STANLEYDATA<Integer>& StanleyData)
388
{
389
PyObject* pair = PyList_New(2);
390
PyList_SetItem(pair, 0, NmzVectorToPyList<libnormaliz::key_t>(StanleyData.key));
391
PyList_SetItem(pair, 1, NmzMatrixToPyList(StanleyData.offsets.get_elements()));
392
return pair;
393
}
394
395
template<typename Integer>
396
PyObject* NmzStanleyDecToPyList(const list<libnormaliz::STANLEYDATA<Integer> >& StanleyDec)
397
{
398
const size_t n = StanleyDec.size();
399
PyObject* M = PyList_New( n );
400
typename list<libnormaliz::STANLEYDATA<Integer> >::const_iterator S = StanleyDec.begin();
401
for (size_t i = 0; i < n; ++i) {
402
PyList_SetItem(M, i,NmzStanleyDataToPyList(*S) );
403
++S;
404
}
405
return M;
406
}
407
408
template<typename Integer>
409
static PyObject* _NmzBasisChangeIntern(Cone<Integer>* C)
410
{
411
Sublattice_Representation<Integer> bc = C->getSublattice();
412
413
PyObject* res = PyList_New( 3 );
414
PyList_SetItem(res, 0, NmzMatrixToPyList(bc.getEmbedding()));
415
PyList_SetItem(res, 1, NmzMatrixToPyList(bc.getProjection()));
416
PyList_SetItem(res, 2, NmzToPyNumber(bc.getAnnihilator()));
417
// Dim, Rank, Equations and Congruences are already covered by special functions
418
// ditto ExternalIndex
419
return res;
420
}
421
422
/***************************************************************************
423
*
424
* PyCapsule handler functions
425
*
426
***************************************************************************/
427
428
void delete_cone_mpz( PyObject* cone ){
429
Cone<mpz_class> * cone_ptr = reinterpret_cast<Cone<mpz_class>* >( PyCapsule_GetPointer( cone, cone_name ) );
430
delete cone_ptr;
431
}
432
433
void delete_cone_long( PyObject* cone ){
434
Cone<long long> * cone_ptr = reinterpret_cast<Cone<long long>* >( PyCapsule_GetPointer( cone, cone_name_long ) );
435
delete cone_ptr;
436
}
437
438
Cone<long long>* get_cone_long( PyObject* cone ){
439
return reinterpret_cast<Cone<long long>*>( PyCapsule_GetPointer( cone, cone_name_long ) );
440
}
441
442
Cone<mpz_class>* get_cone_mpz( PyObject* cone ){
443
return reinterpret_cast<Cone<mpz_class>*>( PyCapsule_GetPointer( cone, cone_name ) );
444
}
445
446
447
PyObject* pack_cone( Cone<mpz_class>* C ){
448
return PyCapsule_New( reinterpret_cast<void*>( C ), cone_name, &delete_cone_mpz );
449
}
450
451
PyObject* pack_cone( Cone<long long>* C ){
452
return PyCapsule_New( reinterpret_cast<void*>( C ), cone_name_long, &delete_cone_long );
453
}
454
455
bool is_cone( PyObject* cone ){
456
if( PyCapsule_CheckExact( cone ) ){
457
// compare as string
458
return cone_name_str == string(PyCapsule_GetName( cone )) || cone_name_str_long == string(PyCapsule_GetName( cone ));
459
}
460
return false;
461
}
462
463
/***************************************************************************
464
*
465
* Cone property list
466
*
467
***************************************************************************/
468
469
static PyObject* NmzListConeProperties(PyObject* args)
470
{
471
FUNC_BEGIN
472
473
PyObject* return_list = PyList_New( 2 );
474
475
ConeProperties props;
476
for(int i=0; i < libnormaliz::ConeProperty::EnumSize;i++){
477
props.set( static_cast<libnormaliz::ConeProperty::Enum>(i) );
478
}
479
480
ConeProperties goals = props.goals();
481
ConeProperties options = props.options();
482
483
int number_goals = goals.count();
484
int number_options = options.count();
485
486
PyObject* goal_list = PyList_New( number_goals );
487
PyObject* option_list = PyList_New( number_options );
488
489
PyList_SetItem( return_list, 0, goal_list );
490
PyList_SetItem( return_list, 1, option_list );
491
492
int list_position = 0;
493
for(int i=0; i < libnormaliz::ConeProperty::EnumSize;i++){
494
if(goals.test(static_cast<libnormaliz::ConeProperty::Enum>(i))){
495
string name = libnormaliz::toString(static_cast<libnormaliz::ConeProperty::Enum>(i));
496
PyList_SetItem( goal_list, list_position, StringToPyUnicode( name ) );
497
list_position++;
498
}
499
}
500
501
list_position = 0;
502
for(int i=0; i < libnormaliz::ConeProperty::EnumSize;i++){
503
if(options.test(static_cast<libnormaliz::ConeProperty::Enum>(i))){
504
string name = libnormaliz::toString(static_cast<libnormaliz::ConeProperty::Enum>(i));
505
PyList_SetItem( option_list, list_position, StringToPyUnicode( name ) );
506
list_position++;
507
}
508
}
509
510
return return_list;
511
512
FUNC_END
513
514
}
515
516
/***************************************************************************
517
*
518
* NmzCone
519
*
520
***************************************************************************/
521
522
template<typename Integer>
523
static PyObject* _NmzConeIntern(PyObject * args)
524
{
525
map <InputType, vector< vector<mpq_class> > > input;
526
527
PyObject* input_list;
528
529
bool grading_polynomial = false;
530
string polynomial;
531
532
if( PyTuple_Size(args)==1 ){
533
input_list = PyTuple_GetItem( args, 0 );
534
if( ! PyList_Check( input_list ) ){
535
PyErr_SetString( PyNormaliz_cppError, "Single argument must be a list" );
536
return NULL;
537
}
538
input_list = PyList_AsTuple( input_list );
539
}else{
540
input_list = args;
541
}
542
543
const int n = PyTuple_Size(input_list);
544
if (n&1) {
545
PyErr_SetString( PyNormaliz_cppError, "Number of arguments must be even" );
546
return NULL;
547
}
548
for (int i = 0; i < n; i += 2) {
549
PyObject* type = PyTuple_GetItem(input_list, i);
550
if (!string_check(type)) {
551
PyErr_SetString( PyNormaliz_cppError, "Odd entries must be strings" );
552
return NULL;
553
}
554
555
string type_str = PyUnicodeToString( type );
556
557
if( type_str.compare( "polynomial" ) == 0 ){
558
PyObject* M = PyTuple_GetItem(input_list, i+1);
559
polynomial = PyUnicodeToString( M );
560
grading_polynomial = true;
561
continue;
562
}
563
564
PyObject* M = PyTuple_GetItem(input_list, i+1);
565
vector<vector<mpq_class> > Mat;
566
bool okay = PyIntMatrixToNmz(Mat, M);
567
if (!okay) {
568
PyErr_SetString( PyNormaliz_cppError, "Even entries must be matrices" );
569
return NULL;
570
}
571
572
input[libnormaliz::to_type(type_str)] = Mat;
573
}
574
575
Cone<Integer>* C = new Cone<Integer>(input);
576
577
if( grading_polynomial ){
578
C->setPolynomial( polynomial );
579
}
580
581
PyObject* return_container = pack_cone( C );
582
583
return return_container;
584
}
585
586
PyObject* _NmzCone(PyObject* self, PyObject* args, PyObject* keywds)
587
{
588
FUNC_BEGIN
589
590
static const char* string_for_keyword_argument = "CreateAsLongLong";
591
PyObject* create_as_long_long;
592
593
#if PY_MAJOR_VERSION >= 3
594
PyObject* key = PyUnicode_FromString( string_for_keyword_argument );
595
#else
596
PyObject* key = PyString_FromString( const_cast<char*>(string_for_keyword_argument) );
597
#endif
598
599
if( keywds != NULL && PyDict_Contains( keywds, key ) == 1 ){
600
create_as_long_long = PyDict_GetItem( keywds, key );
601
}else{
602
create_as_long_long = Py_False;
603
}
604
605
if( create_as_long_long!=Py_True ){
606
return _NmzConeIntern<mpz_class>(args);
607
}else{
608
return _NmzConeIntern<long long>(args);
609
}
610
611
FUNC_END
612
}
613
614
/***************************************************************************
615
*
616
* NmzHilbertSeries
617
*
618
***************************************************************************/
619
620
template<typename Integer>
621
PyObject* NmzHilbertSeries(Cone<Integer>* C, PyObject* args)
622
{
623
FUNC_BEGIN
624
625
const int arg_len = PyTuple_Size(args);
626
627
if(arg_len==1){
628
bool is_HSOP = C->isComputed(libnormaliz::ConeProperty::HSOP);
629
return NmzHilbertSeriesToPyList(C->getHilbertSeries(),is_HSOP);
630
}
631
632
PyObject* is_HSOP = PyTuple_GetItem( args, 1 );
633
634
if( is_HSOP == Py_True ){
635
if (!C->isComputed(libnormaliz::ConeProperty::HSOP)) C->compute(libnormaliz::ConeProperty::HSOP);
636
return NmzHilbertSeriesToPyList(C->getHilbertSeries(),true);
637
}else{
638
return NmzHilbertSeriesToPyList(C->getHilbertSeries(),false);
639
}
640
641
FUNC_END
642
}
643
644
645
PyObject* NmzHilbertSeries_Outer(PyObject* self, PyObject* args){
646
647
FUNC_BEGIN
648
649
PyObject* cone = PyTuple_GetItem( args, 0 );
650
651
if( !is_cone(cone) ){
652
PyErr_SetString( PyNormaliz_cppError, "First argument must be a cone" );
653
return NULL;
654
}
655
656
current_interpreter_sigint_handler = PyOS_setsig(SIGINT,signal_handler);
657
658
if( cone_name_str == string(PyCapsule_GetName(cone)) ){
659
Cone<mpz_class>* cone_ptr = get_cone_mpz(cone);
660
PyObject* return_value = NmzHilbertSeries(cone_ptr, args);
661
PyOS_setsig( SIGINT, current_interpreter_sigint_handler );
662
return return_value;
663
}else{
664
Cone<long long>* cone_ptr = get_cone_long(cone);
665
PyObject* return_value = NmzHilbertSeries(cone_ptr,args);
666
PyOS_setsig( SIGINT, current_interpreter_sigint_handler );
667
return return_value;
668
}
669
670
FUNC_END
671
672
}
673
674
/***************************************************************************
675
*
676
* NmzCompute
677
*
678
***************************************************************************/
679
680
template<typename Integer>
681
PyObject* _NmzCompute(Cone<Integer>* C, PyObject* args)
682
{
683
FUNC_BEGIN
684
685
const int arg_len = PyTuple_Size(args);
686
687
PyObject* to_compute;
688
689
if(arg_len==2){
690
PyObject* first_arg = PyTuple_GetItem(args,1);
691
if(PyList_CheckExact( first_arg )){
692
to_compute = first_arg;
693
}else{
694
to_compute = PyList_New( 1 );
695
int result = PyList_SetItem( to_compute, 0, first_arg );
696
if(result!=0){
697
PyErr_SetString( PyNormaliz_cppError, "List could not be created" );
698
return NULL;
699
}
700
}
701
}else{
702
to_compute = PyList_New( arg_len - 1 );
703
for( int i = 1;i<arg_len;i++){
704
PyList_SetItem( to_compute, i, PyTuple_GetItem( args, i ) );
705
}
706
}
707
708
ConeProperties propsToCompute;
709
const int n = PyList_Size(to_compute);
710
711
for (int i = 0; i < n; ++i) {
712
PyObject* prop = PyList_GetItem(to_compute, i);
713
if (!string_check(prop)) {
714
PyErr_SetString( PyNormaliz_cppError, "All elements must be strings" );
715
return NULL;
716
}
717
string prop_str(PyUnicodeToString(prop));
718
propsToCompute.set( libnormaliz::toConeProperty(prop_str) );
719
}
720
721
ConeProperties notComputed = C->compute(propsToCompute);
722
723
// Cone.compute returns the not computed properties
724
// we return a bool, true when everything requested was computed
725
return notComputed.none() ? Py_True : Py_False;
726
FUNC_END
727
}
728
729
730
PyObject* _NmzCompute_Outer(PyObject* self, PyObject* args){
731
732
FUNC_BEGIN
733
734
current_interpreter_sigint_handler = PyOS_setsig(SIGINT,signal_handler);
735
736
PyObject* cone = PyTuple_GetItem( args, 0 );
737
738
PyObject* result;
739
740
if( !is_cone(cone) ){
741
PyErr_SetString( PyNormaliz_cppError, "First argument must be a cone" );
742
return NULL;
743
}
744
745
if( cone_name_str == string(PyCapsule_GetName(cone)) ){
746
Cone<mpz_class>* cone_ptr = get_cone_mpz(cone);
747
result = _NmzCompute(cone_ptr, args);
748
}else{
749
Cone<long long>* cone_ptr = get_cone_long(cone);
750
result = _NmzCompute(cone_ptr,args);
751
}
752
753
PyOS_setsig(SIGINT,current_interpreter_sigint_handler);
754
755
return result;
756
757
FUNC_END
758
759
}
760
761
/***************************************************************************
762
*
763
* NmzIsComputed
764
*
765
***************************************************************************/
766
767
template<typename Integer>
768
PyObject* NmzIsComputed(Cone<Integer>* C, PyObject* prop)
769
{
770
FUNC_BEGIN
771
772
libnormaliz::ConeProperty::Enum p = libnormaliz::toConeProperty(PyUnicodeToString( prop ) );
773
774
return C->isComputed(p) ? Py_True : Py_False;
775
776
FUNC_END
777
}
778
779
PyObject* NmzIsComputed_Outer(PyObject* self, PyObject* args)
780
{
781
FUNC_BEGIN
782
783
PyObject* cone = PyTuple_GetItem( args, 0 );
784
PyObject* to_compute = PyTuple_GetItem( args, 1 );
785
786
if( !is_cone(cone) ){
787
PyErr_SetString( PyNormaliz_cppError, "First argument must be a cone" );
788
return NULL;
789
}
790
791
if( cone_name_str == string(PyCapsule_GetName(cone)) ){
792
Cone<mpz_class>* cone_ptr = get_cone_mpz(cone);
793
return NmzIsComputed(cone_ptr, to_compute);
794
}else{
795
Cone<long long>* cone_ptr = get_cone_long(cone);
796
return NmzIsComputed(cone_ptr,to_compute);
797
}
798
799
FUNC_END
800
}
801
802
/***************************************************************************
803
*
804
* NmzResult
805
*
806
***************************************************************************/
807
808
template<typename Integer>
809
PyObject* _NmzResultImpl(Cone<Integer>* C, PyObject* prop_obj)
810
{
811
812
string prop = PyUnicodeToString( prop_obj );
813
814
libnormaliz::ConeProperty::Enum p = libnormaliz::toConeProperty(prop);
815
816
current_interpreter_sigint_handler = PyOS_setsig(SIGINT,signal_handler);
817
ConeProperties notComputed = C->compute(ConeProperties(p));
818
PyOS_setsig(SIGINT, current_interpreter_sigint_handler );
819
820
if (notComputed.any()) {
821
return Py_None;
822
}
823
824
switch (p) {
825
case libnormaliz::ConeProperty::Generators:
826
return NmzMatrixToPyList(C->getGenerators());
827
828
case libnormaliz::ConeProperty::ExtremeRays:
829
return NmzMatrixToPyList(C->getExtremeRays());
830
831
case libnormaliz::ConeProperty::VerticesOfPolyhedron:
832
return NmzMatrixToPyList(C->getVerticesOfPolyhedron());
833
834
case libnormaliz::ConeProperty::SupportHyperplanes:
835
return NmzMatrixToPyList(C->getSupportHyperplanes());
836
837
case libnormaliz::ConeProperty::TriangulationSize:
838
return NmzToPyNumber(C->getTriangulationSize());
839
840
case libnormaliz::ConeProperty::TriangulationDetSum:
841
return NmzToPyNumber(C->getTriangulationDetSum());
842
843
case libnormaliz::ConeProperty::Triangulation:
844
return NmzTriangleListToPyList<Integer>(C->getTriangulation());
845
846
case libnormaliz::ConeProperty::Multiplicity:
847
return NmzToPyList(C->getMultiplicity());
848
849
case libnormaliz::ConeProperty::Integral:
850
return NmzToPyList(C->getIntegral());
851
852
case libnormaliz::ConeProperty::VirtualMultiplicity:
853
return NmzToPyList(C->getVirtualMultiplicity());
854
855
case libnormaliz::ConeProperty::RecessionRank:
856
return NmzToPyNumber(C->getRecessionRank());
857
858
case libnormaliz::ConeProperty::AffineDim:
859
return NmzToPyNumber(C->getAffineDim());
860
861
case libnormaliz::ConeProperty::ModuleRank:
862
return NmzToPyNumber(C->getModuleRank());
863
864
case libnormaliz::ConeProperty::HilbertBasis:
865
return NmzMatrixToPyList(C->getHilbertBasis());
866
867
case libnormaliz::ConeProperty::MaximalSubspace:
868
return NmzMatrixToPyList(C->getMaximalSubspace());
869
870
case libnormaliz::ConeProperty::ModuleGenerators:
871
return NmzMatrixToPyList(C->getModuleGenerators());
872
873
case libnormaliz::ConeProperty::Deg1Elements:
874
return NmzMatrixToPyList(C->getDeg1Elements());
875
876
case libnormaliz::ConeProperty::HilbertSeries:
877
{
878
bool is_HSOP = C->isComputed(libnormaliz::ConeProperty::HSOP);
879
return NmzHilbertSeriesToPyList(C->getHilbertSeries(),is_HSOP);
880
}
881
882
case libnormaliz::ConeProperty::WeightedEhrhartSeries:
883
return NmzWeightedEhrhartSeriesToPyList(C->getWeightedEhrhartSeries());
884
885
886
case libnormaliz::ConeProperty::Grading:
887
{
888
vector<Integer> grad = C->getGrading();
889
grad.push_back(C->getGradingDenom());
890
return NmzVectorToPyList(grad);
891
}
892
893
case libnormaliz::ConeProperty::IsPointed:
894
return BoolToPyBool(C->isPointed());
895
896
case libnormaliz::ConeProperty::IsDeg1ExtremeRays:
897
return BoolToPyBool(C->isDeg1ExtremeRays());
898
899
case libnormaliz::ConeProperty::IsDeg1HilbertBasis:
900
return BoolToPyBool(C->isDeg1HilbertBasis());
901
902
case libnormaliz::ConeProperty::IsIntegrallyClosed:
903
return BoolToPyBool(C->isIntegrallyClosed());
904
905
case libnormaliz::ConeProperty::OriginalMonoidGenerators:
906
return NmzMatrixToPyList(C->getOriginalMonoidGenerators());
907
908
case libnormaliz::ConeProperty::IsReesPrimary:
909
return BoolToPyBool(C->isReesPrimary());
910
911
case libnormaliz::ConeProperty::ReesPrimaryMultiplicity:
912
return NmzToPyNumber(C->getReesPrimaryMultiplicity());
913
914
case libnormaliz::ConeProperty::StanleyDec:
915
return NmzStanleyDecToPyList(C->getStanleyDec());
916
917
case libnormaliz::ConeProperty::ExcludedFaces:
918
return NmzMatrixToPyList(C->getExcludedFaces());
919
920
case libnormaliz::ConeProperty::Dehomogenization:
921
return NmzVectorToPyList(C->getDehomogenization());
922
923
case libnormaliz::ConeProperty::InclusionExclusionData:
924
return NmzTriangleListToPyList<long>(C->getInclusionExclusionData());
925
926
case libnormaliz::ConeProperty::ClassGroup:
927
return NmzVectorToPyList(C->getClassGroup());
928
929
case libnormaliz::ConeProperty::IsInhomogeneous:
930
return BoolToPyBool(C->isInhomogeneous());
931
932
/* Sublattice properties */
933
934
case libnormaliz::ConeProperty::Equations:
935
return NmzMatrixToPyList(C->getSublattice().getEquations());
936
937
case libnormaliz::ConeProperty::Congruences:
938
return NmzMatrixToPyList(C->getSublattice().getCongruences());
939
940
case libnormaliz::ConeProperty::EmbeddingDim:
941
return NmzToPyNumber(C->getEmbeddingDim());
942
943
case libnormaliz::ConeProperty::Rank:
944
return NmzToPyNumber(C->getRank());
945
946
case libnormaliz::ConeProperty::Sublattice:
947
return _NmzBasisChangeIntern(C);
948
949
case libnormaliz::ConeProperty::ExternalIndex:
950
return NmzToPyNumber(C->getSublattice().getExternalIndex());
951
952
case libnormaliz::ConeProperty::InternalIndex:
953
return NmzToPyNumber(C->getIndex());
954
955
case libnormaliz::ConeProperty::WitnessNotIntegrallyClosed:
956
return NmzVectorToPyList(C->getWitnessNotIntegrallyClosed());
957
958
959
/* New stuff */
960
961
case libnormaliz::ConeProperty::GradingDenom:
962
return NmzToPyNumber(C->getGradingDenom());
963
964
case libnormaliz::ConeProperty::UnitGroupIndex:
965
return NmzToPyNumber(C->getUnitGroupIndex());
966
967
case libnormaliz::ConeProperty::ModuleGeneratorsOverOriginalMonoid:
968
return NmzMatrixToPyList(C->getModuleGeneratorsOverOriginalMonoid());
969
970
case libnormaliz::ConeProperty::IntegerHull:
971
{
972
Cone<Integer>* hull = new Cone<Integer>( C->getIntegerHullCone() );
973
return pack_cone( hull );
974
}
975
976
case libnormaliz::ConeProperty::HilbertQuasiPolynomial:
977
return NmzHilbertQuasiPolynomialToPyList<mpz_class>(C->getHilbertSeries()); //FIXME: Why is this return value not parametrized, but mpz_class only?
978
979
case libnormaliz::ConeProperty::WeightedEhrhartQuasiPolynomial:
980
return NmzWeightedEhrhartQuasiPolynomialToPyList<mpz_class>(C->getIntData());
981
982
case libnormaliz::ConeProperty::IsTriangulationNested:
983
return BoolToPyBool(C->isTriangulationNested());
984
985
case libnormaliz::ConeProperty::IsTriangulationPartial:
986
return BoolToPyBool(C->isTriangulationPartial());
987
988
case libnormaliz::ConeProperty::ConeDecomposition:
989
return NmzBoolMatrixToPyList(C->getOpenFacets());
990
991
case libnormaliz::ConeProperty::IsGorenstein:
992
return BoolToPyBool(C->isGorenstein());
993
994
case libnormaliz::ConeProperty::GeneratorOfInterior:
995
return NmzVectorToPyList(C->getGeneratorOfInterior());
996
997
case libnormaliz::ConeProperty::VerticesFloat:
998
return NmzMatrixToPyList(C->getVerticesFloat());
999
1000
// the following properties are compute options and do not return anything
1001
case libnormaliz::ConeProperty::DualMode:
1002
case libnormaliz::ConeProperty::DefaultMode:
1003
case libnormaliz::ConeProperty::Approximate:
1004
case libnormaliz::ConeProperty::BottomDecomposition:
1005
case libnormaliz::ConeProperty::KeepOrder:
1006
case libnormaliz::ConeProperty::NoBottomDec:
1007
case libnormaliz::ConeProperty::PrimalMode:
1008
case libnormaliz::ConeProperty::Symmetrize:
1009
case libnormaliz::ConeProperty::NoSymmetrization:
1010
case libnormaliz::ConeProperty::BigInt:
1011
case libnormaliz::ConeProperty::NoNestedTri:
1012
case libnormaliz::ConeProperty::HSOP:
1013
case libnormaliz::ConeProperty::Projection:
1014
case libnormaliz::ConeProperty::NoProjection:
1015
case libnormaliz::ConeProperty::ProjectionFloat:
1016
case libnormaliz::ConeProperty::SCIP:
1017
case libnormaliz::ConeProperty::NoPeriodBound:
1018
PyErr_SetString( PyNormaliz_cppError, "ConeProperty is input-only" );
1019
return NULL;
1020
#if NMZ_RELEASE >= 30200
1021
case libnormaliz::ConeProperty::NoSubdivision:
1022
PyErr_SetString( PyNormaliz_cppError, "ConeProperty is input-only" );
1023
return NULL;
1024
#endif
1025
default:
1026
PyErr_SetString( PyNormaliz_cppError, "Unknown cone property" );
1027
return NULL;
1028
break;
1029
}
1030
1031
return Py_None;
1032
}
1033
1034
PyObject* _NmzResult( PyObject* self, PyObject* args ){
1035
1036
FUNC_BEGIN
1037
PyObject* cone = PyTuple_GetItem( args, 0 );
1038
PyObject* prop = PyTuple_GetItem( args, 1 );
1039
1040
if( !is_cone( cone ) ){
1041
PyErr_SetString( PyNormaliz_cppError, "First argument must be a cone" );
1042
return NULL;
1043
}
1044
1045
if( !string_check( prop ) ){
1046
PyErr_SetString( PyNormaliz_cppError, "Second argument must be a unicode string" );
1047
return NULL;
1048
}
1049
1050
if( cone_name_str == string(PyCapsule_GetName(cone)) ){
1051
Cone<mpz_class>* cone_ptr = get_cone_mpz(cone);
1052
return _NmzResultImpl(cone_ptr, prop);
1053
}else{
1054
Cone<long long>* cone_ptr = get_cone_long(cone);
1055
return _NmzResultImpl(cone_ptr, prop);
1056
}
1057
1058
FUNC_END
1059
}
1060
1061
/***************************************************************************
1062
*
1063
* Python verbosity
1064
*
1065
***************************************************************************/
1066
1067
PyObject* NmzSetVerboseDefault( PyObject* self, PyObject* args)
1068
{
1069
FUNC_BEGIN
1070
PyObject * value = PyTuple_GetItem( args, 0 );
1071
if (value != Py_True && value != Py_False){
1072
PyErr_SetString( PyNormaliz_cppError, "Argument must be True or False" );
1073
return NULL;
1074
}
1075
return BoolToPyBool(libnormaliz::setVerboseDefault(value == Py_True));
1076
FUNC_END
1077
}
1078
1079
template<typename Integer>
1080
PyObject* NmzSetVerbose(Cone<Integer>* C, PyObject* value)
1081
{
1082
FUNC_BEGIN
1083
bool old_value;
1084
old_value = C->setVerbose(value == Py_True);
1085
return BoolToPyBool(old_value);
1086
FUNC_END
1087
}
1088
1089
PyObject* NmzSetVerbose_Outer(PyObject* self, PyObject* args)
1090
{
1091
FUNC_BEGIN
1092
1093
PyObject* cone = PyTuple_GetItem( args, 0 );
1094
1095
if( !is_cone( cone ) ){
1096
PyErr_SetString( PyNormaliz_cppError, "First argument must be a cone" );
1097
return NULL;
1098
}
1099
1100
PyObject* value = PyTuple_GetItem( args, 1 );
1101
if (value != Py_True && value != Py_False){
1102
PyErr_SetString( PyNormaliz_cppError, "Second argument must be True or False" );
1103
return NULL;
1104
}
1105
1106
if( cone_name_str == string(PyCapsule_GetName(cone)) ){
1107
Cone<mpz_class>* cone_ptr = get_cone_mpz(cone);
1108
return NmzSetVerbose(cone_ptr, value);
1109
}else{
1110
Cone<long long>* cone_ptr = get_cone_long(cone);
1111
return NmzSetVerbose(cone_ptr, value);
1112
}
1113
1114
FUNC_END
1115
1116
}
1117
1118
/***************************************************************************
1119
*
1120
* Get Polynomial
1121
*
1122
***************************************************************************/
1123
1124
PyObject* NmzGetPolynomial(PyObject* self, PyObject* args ){
1125
1126
FUNC_BEGIN
1127
1128
PyObject* cone = PyTuple_GetItem( args, 0 );
1129
1130
if( !is_cone( cone ) ){
1131
PyErr_SetString( PyNormaliz_cppError, "First argument must be a cone" );
1132
return NULL;
1133
}
1134
1135
current_interpreter_sigint_handler = PyOS_setsig(SIGINT,signal_handler);
1136
1137
if( cone_name_str == string(PyCapsule_GetName(cone)) ){
1138
Cone<mpz_class>* cone_ptr = get_cone_mpz(cone);
1139
PyObject* return_value = StringToPyUnicode( (cone_ptr->getIntData()).getPolynomial() );
1140
PyOS_setsig( SIGINT, current_interpreter_sigint_handler );
1141
return return_value;
1142
}else{
1143
Cone<long long>* cone_ptr = get_cone_long(cone);
1144
PyObject* return_value = StringToPyUnicode( (cone_ptr->getIntData()).getPolynomial() );
1145
PyOS_setsig( SIGINT, current_interpreter_sigint_handler );
1146
return return_value;
1147
}
1148
1149
FUNC_END
1150
1151
}
1152
1153
/***************************************************************************
1154
*
1155
* NrCoeffQuasiPol
1156
*
1157
***************************************************************************/
1158
1159
PyObject* NmzSetNrCoeffQuasiPol( PyObject* self, PyObject* args ){
1160
1161
FUNC_BEGIN
1162
1163
PyObject* cone = PyTuple_GetItem( args, 0 );
1164
1165
if( !is_cone( cone ) ){
1166
PyErr_SetString( PyNormaliz_cppError, "First argument must be a cone" );
1167
return NULL;
1168
}
1169
1170
PyObject* bound_py = PyTuple_GetItem( args, 1 );
1171
1172
int overflow;
1173
long bound = PyLong_AsLongLongAndOverflow( bound_py, &overflow );
1174
if( cone_name_str == string(PyCapsule_GetName(cone)) ){
1175
Cone<mpz_class>* cone_ptr = get_cone_mpz(cone);
1176
cone_ptr->setNrCoeffQuasiPol(bound);
1177
return Py_True;
1178
}else{
1179
Cone<long long>* cone_ptr = get_cone_long(cone);
1180
cone_ptr->setNrCoeffQuasiPol(bound);
1181
return Py_True;
1182
}
1183
1184
FUNC_END
1185
1186
}
1187
1188
/***************************************************************************
1189
*
1190
* Get Symmetrized cone
1191
*
1192
***************************************************************************/
1193
1194
PyObject* NmzSymmetrizedCone(PyObject* self, PyObject* args ){
1195
1196
FUNC_BEGIN
1197
1198
PyObject* cone = PyTuple_GetItem( args, 0 );
1199
1200
if( !is_cone( cone ) ){
1201
PyErr_SetString( PyNormaliz_cppError, "First argument must be a cone" );
1202
return NULL;
1203
}
1204
1205
current_interpreter_sigint_handler = PyOS_setsig(SIGINT,signal_handler);
1206
1207
if( cone_name_str == string(PyCapsule_GetName(cone)) ){
1208
Cone<mpz_class>* cone_ptr = get_cone_mpz(cone);
1209
Cone<mpz_class>* symm_cone = &(cone_ptr->getSymmetrizedCone());
1210
PyOS_setsig( SIGINT, current_interpreter_sigint_handler );
1211
if( symm_cone==0 ){
1212
return Py_None;
1213
}
1214
symm_cone = new Cone<mpz_class>( *symm_cone );
1215
return pack_cone( symm_cone );
1216
}else{
1217
Cone<long long>* cone_ptr = get_cone_long(cone);
1218
Cone<long long>* symm_cone = &(cone_ptr->getSymmetrizedCone());
1219
PyOS_setsig( SIGINT, current_interpreter_sigint_handler );
1220
if( symm_cone==0 ){
1221
return Py_None;
1222
}
1223
symm_cone = new Cone<long long>( *symm_cone );
1224
return pack_cone( symm_cone );
1225
}
1226
1227
FUNC_END
1228
1229
}
1230
1231
/***************************************************************************
1232
*
1233
* Set number of threads
1234
*
1235
***************************************************************************/
1236
1237
PyObject* NmzSetNumberOfNormalizThreads(PyObject* self, PyObject* args ){
1238
1239
FUNC_BEGIN
1240
1241
PyObject* num_treads = PyTuple_GetItem( args, 0 );
1242
1243
if( !PyLong_Check( num_treads ) ){
1244
PyErr_SetString( PyNormaliz_cppError, "First argument must be an integer" );
1245
return NULL;
1246
}
1247
1248
long num_threads_long = PyLong_AsLong( num_treads );
1249
1250
num_threads_long = libnormaliz::set_thread_limit( num_threads_long );
1251
1252
return PyLong_FromLong( num_threads_long );
1253
1254
FUNC_END
1255
1256
}
1257
1258
/***************************************************************************
1259
*
1260
* Python init stuff
1261
*
1262
***************************************************************************/
1263
1264
struct module_state {
1265
PyObject *error;
1266
};
1267
1268
#if PY_MAJOR_VERSION >= 3
1269
#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
1270
#else
1271
#define GETSTATE(m) (&_state)
1272
static struct module_state _state;
1273
#endif
1274
1275
static PyObject * error_out(PyObject *m) {
1276
struct module_state *st = GETSTATE(m);
1277
PyErr_SetString(st->error, "something bad happened");
1278
return NULL;
1279
}
1280
1281
static PyMethodDef PyNormaliz_cppMethods[] = {
1282
{"error_out", (PyCFunction)error_out, METH_NOARGS, NULL},
1283
{"NmzCone", (PyCFunction)_NmzCone, METH_VARARGS|METH_KEYWORDS,
1284
"Create a cone"},
1285
{"NmzCompute", (PyCFunction)_NmzCompute_Outer, METH_VARARGS,
1286
"Compute some stuff"},
1287
{"NmzIsComputed", (PyCFunction)NmzIsComputed_Outer, METH_VARARGS,
1288
"Check if property is computed "},
1289
{"NmzResult", (PyCFunction)_NmzResult, METH_VARARGS,
1290
"Return cone property" },
1291
{ "NmzSetVerboseDefault", (PyCFunction)NmzSetVerboseDefault, METH_VARARGS,
1292
"Set verbosity" },
1293
{ "NmzSetVerbose", (PyCFunction)NmzSetVerbose_Outer, METH_VARARGS,
1294
"Set verbosity of cone" },
1295
{ "NmzListConeProperties", (PyCFunction)NmzListConeProperties,METH_NOARGS,
1296
"List all available properties" },
1297
{ "NmzHilbertSeries", (PyCFunction)NmzHilbertSeries_Outer, METH_VARARGS,
1298
"Returns Hilbert series, either HSOP or not" },
1299
{ "NmzGetPolynomial", (PyCFunction)NmzGetPolynomial, METH_VARARGS,
1300
"Returns grading polynomial" },
1301
{ "NmzSymmetrizedCone", (PyCFunction)NmzSymmetrizedCone, METH_VARARGS,
1302
"Returns symmetrized cone" },
1303
{ "NmzSetNumberOfNormalizThreads", (PyCFunction)NmzSetNumberOfNormalizThreads, METH_VARARGS,
1304
"Sets the Normaliz thread limit" },
1305
{ "NmzSetNrCoeffQuasiPol", (PyCFunction)NmzSetNrCoeffQuasiPol, METH_VARARGS,
1306
"Sets the period bound for the quasi-polynomial" },
1307
{NULL, } /* Sentinel */
1308
};
1309
1310
1311
#if PY_MAJOR_VERSION >= 3
1312
1313
static int PyNormaliz_cpp_traverse(PyObject *m, visitproc visit, void *arg) {
1314
Py_VISIT(GETSTATE(m)->error);
1315
return 0;
1316
}
1317
1318
static int PyNormaliz_cpp_clear(PyObject *m) {
1319
Py_CLEAR(GETSTATE(m)->error);
1320
return 0;
1321
}
1322
1323
1324
static struct PyModuleDef moduledef = {
1325
PyModuleDef_HEAD_INIT,
1326
"PyNormaliz_cpp",
1327
NULL,
1328
sizeof(struct module_state),
1329
PyNormaliz_cppMethods,
1330
NULL,
1331
PyNormaliz_cpp_traverse,
1332
PyNormaliz_cpp_clear,
1333
NULL
1334
};
1335
1336
#define INITERROR return NULL
1337
1338
PyMODINIT_FUNC PyInit_PyNormaliz_cpp(void)
1339
1340
#else
1341
#define INITERROR return
1342
1343
extern "C" void initPyNormaliz_cpp(void)
1344
#endif
1345
{
1346
#if PY_MAJOR_VERSION >= 3
1347
PyObject *module = PyModule_Create(&moduledef);
1348
#else
1349
PyObject *module = Py_InitModule("PyNormaliz_cpp", PyNormaliz_cppMethods);
1350
#endif
1351
1352
if (module == NULL)
1353
INITERROR;
1354
struct module_state *st = GETSTATE(module);
1355
1356
st->error = PyErr_NewException(const_cast<char*>("PyNormaliz_cpp.INITError"), NULL, NULL);
1357
if (st->error == NULL) {
1358
Py_DECREF(module);
1359
INITERROR;
1360
}
1361
1362
NormalizError = PyErr_NewException(const_cast<char*>("Normaliz.error"), NULL, NULL );
1363
Py_INCREF( NormalizError );
1364
PyNormaliz_cppError = PyErr_NewException(const_cast<char*>("Normaliz.interface_error"), NULL, NULL );
1365
Py_INCREF( PyNormaliz_cppError );
1366
1367
PyModule_AddObject( module, "error", NormalizError );
1368
PyModule_AddObject( module, "error", PyNormaliz_cppError );
1369
1370
current_interpreter_sigint_handler = PyOS_getsig( SIGINT );
1371
1372
#if PY_MAJOR_VERSION >= 3
1373
return module;
1374
#endif
1375
}
1376
1377
1378