Skip to content

Commit

Permalink
Construction from file, output precomputed, 2.16
Browse files Browse the repository at this point in the history
  • Loading branch information
Winfried Bruns committed Jan 10, 2022
1 parent f0b1ee4 commit ec759eb
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 15 deletions.
160 changes: 155 additions & 5 deletions NormalizModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ using std::vector;

typedef int py_size_t;

#include <fstream>

/***************************************************************************
*
* Macros for exception handling
Expand Down Expand Up @@ -177,11 +179,11 @@ static PyObject* CallPythonFuncOnOneArg(PyObject* function, PyObject* single_arg
#ifndef NMZ_RELEASE
static_assert(
false,
"Your Normaliz version (unknown) is to old! Update to 3.9.0 or newer.");
"Your Normaliz version (unknown) is too old! Update to 3.9.2 or newer.");
#endif
#if NMZ_RELEASE < 30900
#if NMZ_RELEASE < 30902
static_assert(false,
"Your Normaliz version is to old! Update to 3.9.0 or newer.");
"Your Normaliz version is too old! Update to 3.9.2 or newer.");
#endif

/***************************************************************************
Expand Down Expand Up @@ -1097,6 +1099,61 @@ static PyObject* _NmzConeIntern_renf(PyObject* kwargs)
}
#endif

static PyObject* _NmzConeFromFile(PyObject* kwargs)
{

static const char* from_file = "file";
PyObject* create_from_file = StringToPyUnicode(from_file);
PyObject* FileName = PyDict_GetItem(kwargs, create_from_file);
string project(PyUnicodeToString(FileName));

std::string name_in = project + ".in";
const char* file_in = name_in.c_str();

#ifdef ENFNORMALIZ
std::ifstream in;
in.open(file_in, std::ifstream::in);
if (!in.is_open()) {
string message = "error: Failed to open file " + name_in;
throw libnormaliz::BadInputException(message);
}
bool number_field_in_input = false;
std::string poly, var, emb;
std::string test;
while(in.good()){
in >> test;
if(test == "number_field"){
number_field_in_input = true;
libnormaliz::read_number_field_strings(in, poly, var, emb);
break;
}
}
in.close();

if(number_field_in_input){
boost::intrusive_ptr<const renf_class> renf = renf_class::make(poly, var, emb);
const renf_class* my_renf = renf.get();
Cone< renf_elem_class >* C = new Cone< renf_elem_class >(project);
PyObject* return_container = pack_cone(C, my_renf);
return return_container;
}
#endif

static const char* string_for_long_long = "CreateAsLongLong";
PyObject* create_as_long_long = StringToPyUnicode(string_for_long_long);

if (PyDict_Contains(kwargs, create_as_long_long) == 1) {
Cone< long long >* C = new Cone< long long >(project);
PyObject* return_container = pack_cone(C);
return return_container;
}
else{
Cone< mpz_class >* C = new Cone< mpz_class >(project);
PyObject* return_container = pack_cone(C);
return return_container;
}
}

/*
@Name NmzCone
@Arguments <keywords>
Expand All @@ -1112,7 +1169,12 @@ to machine integers instead of arbitrary precision numbers.
static PyObject* _NmzCone(PyObject* self, PyObject* args, PyObject* kwargs)
{
FUNC_BEGIN

static const char* from_file = "file";
PyObject* create_from_file = StringToPyUnicode(from_file);
if (kwargs != NULL && PyDict_Contains(kwargs, create_from_file) == 1) {
return _NmzConeFromFile(kwargs);
}

static const char* string_for_long = "CreateAsLongLong";
PyObject* create_as_long_long = StringToPyUnicode(string_for_long);
#ifdef ENFNORMALIZ
Expand Down Expand Up @@ -2479,7 +2541,50 @@ static PyObject* NmzWriteOutputFile(PyObject* self, PyObject* args)

/***************************************************************************
*
* Get renf precision
* Write file with precomputed data
*
***************************************************************************/

static PyObject* NmzWritePrecompData(PyObject* self, PyObject* args)
{
FUNC_BEGIN

if ((!PyTuple_Check(args)) || (PyTuple_Size(args) != 2)) {
throw PyNormalizInputException(
"The arguments must be a cone and a string");
return NULL;
}

PyObject* cone_py = PyTuple_GetItem(args, 0);
PyObject* filename_py = PyTuple_GetItem(args, 1);

string filename = PyUnicodeToString(filename_py);

if (is_cone_mpz(cone_py)) {
Cone< mpz_class >* cone = get_cone_mpz(cone_py);
cone->write_precomp_for_input(filename);
Py_RETURN_TRUE;
}
if (is_cone_long(cone_py)) {
Cone< long long >* cone = get_cone_long(cone_py);
cone->write_precomp_for_input(filename);
Py_RETURN_TRUE;
}
#ifdef ENFNORMALIZ
if (is_cone_renf(cone_py)) {
Cone< renf_elem_class >* cone = get_cone_renf(cone_py);
cone->write_precomp_for_input(filename);
Py_RETURN_TRUE;
}
#endif
Py_RETURN_FALSE;

FUNC_END
}

/***************************************************************************
*
* Get renf minpoly and precision
*
***************************************************************************/

Expand All @@ -2501,6 +2606,7 @@ static PyObject* NmzGetRenfInfo(PyObject* self, PyObject* args)
);
return NULL;
}

const renf_class* renf = get_cone_renf_renf(cone_py);
std::string minpoly_str;
minpoly_str = fmpq_poly_get_str_pretty(renf->get_renf()->nf->pol, renf->gen_name().c_str());
Expand All @@ -2514,6 +2620,44 @@ static PyObject* NmzGetRenfInfo(PyObject* self, PyObject* args)
FUNC_END
}

/***************************************************************************
*
* Get name of field generator
*
***************************************************************************/

static PyObject* NmzFieldGenName(PyObject* self, PyObject* args)
{
FUNC_BEGIN

if( (!PyTuple_Check(args)) || (PyTuple_Size(args) != 1) ){
throw PyNormalizInputException(
"Only one argument allowed"
);
return NULL;
}
PyObject* cone_py = PyTuple_GetItem(args, 0);

std::string gen_name_string = "";

if (is_cone_mpz(cone_py)) {
return PyUnicode_FromString(gen_name_string.c_str());
}
if (is_cone_long(cone_py)) {
return PyUnicode_FromString(gen_name_string.c_str());
}
#ifdef ENFNORMALIZ
if (is_cone_renf(cone_py)) {
Cone< renf_elem_class >* cone_ptr = get_cone_renf(cone_py);
gen_name_string = cone_ptr->getRenfGenerator();
return PyUnicode_FromString(gen_name_string.c_str());
}

#endif

FUNC_END
}

/***************************************************************************
*
* Python init stuff
Expand Down Expand Up @@ -2598,8 +2742,14 @@ static PyMethodDef PyNormaliz_cppMethods[] = {

{"NmzWriteOutputFile", (PyCFunction)NmzWriteOutputFile, METH_VARARGS,
"Prints the Normaliz cone output into a file"},
{"NmzWritePrecompData", (PyCFunction)NmzWritePrecompData, METH_VARARGS,
"Prints the Normaliz cone precomputed data for further input"},

{"NmzGetRenfInfo", (PyCFunction)NmzGetRenfInfo, METH_VARARGS,
"Outputs info of the number field associated to a renf cone"},
{"NmzFieldGenName", (PyCFunction)NmzFieldGenName, METH_VARARGS,
"Returns name of field generator"},

{"NmzModifyCone", (PyCFunction)_NmzModify_Outer, METH_VARARGS,
"Modifies a given input property of a cone using a new matrix"},
{
Expand Down
19 changes: 10 additions & 9 deletions PyNormaliz.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,25 +296,20 @@ def print_quasipol(poly):

class Cone:

def __init__(self,**kwargs):
def __init__(self,**kwargs):
global name_of_indeterminate
pop_list = []
for entry in kwargs.items():
current_input=entry[1];
key = entry[0]
if type(current_input) == list and len(current_input) > 0 and type(current_input[0]) != list and key != "number_field":
kwargs[key] = [current_input]
if key == "number_field":
if type(current_input) != list or len(current_input) < 3:
raise ValueError("Illegal number_field definition!")
global name_of_indeterminate
name_of_indeterminate = current_input[1]
elif type(current_input) == bool and current_input == True:
if type(current_input) == bool and current_input == True:
kwargs[key] = current_input = [[]]
elif type(current_input) == bool and current_input == False:
poplist = pop_list + [key]
for k in pop_list:
kwargs.pop(k)
self.cone = PyNormaliz_cpp.NmzCone(**kwargs)
name_of_indeterminate = PyNormaliz_cpp.NmzFieldGenName(self.cone)

def ModifyCone(self, *args):
PyNormaliz_cpp.NmzModifyCone(self.cone, *args)
Expand All @@ -341,6 +336,9 @@ def __str__(self):

def __repr__(self):
return "<Normaliz Cone>"

def GetFieldGenName(self):
return PyNormaliz_cpp.NmzFieldGenName(self.cone)

def Compute(self, *args):
return PyNormaliz_cpp.NmzCompute(self.cone, args)
Expand Down Expand Up @@ -408,6 +406,9 @@ def WeightedEhrhartSeriesExpansion(self,degree):
def WriteOutputFile(self, project):
return NmzWriteOutputFile(self.cone, project)

def WritePrecompData(self, project):
return NmzWritePrecompData(self.cone, project)

def NumberFieldData(self):
return NmzGetRenfInfo(self.cone)

Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = PyNormaliz
version = 2.15
version = 2.16
description = An interface to Normaliz
author = Sebastian Gutsche, Richard Sieg
author_email = [email protected]
Expand Down

0 comments on commit ec759eb

Please sign in to comment.