-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcone_chain_element.py
130 lines (109 loc) · 5 KB
/
cone_chain_element.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/usr/bin/env sage
"""ConeChain
This module defines ConeChainElement, an object that will contain experimental data for each cone.
"""
import sage.all
import cone_tools
import experiment_io_tools
import json
class ConeChainElement(object):
""" A data structure to hold a cone and its hilbert basis
and associated experimental data.
Class Attribute:
(currently not used)
num_hilbert_calc (int): Keeps track of the number of times we call
Hilbert basis calculations.
Attributes:
cone (sage.all.Polyhedron): the cone object to be stored
cone_rays_list (list of lists): extremal generators of cone object (mostly for JSON)
generation_step (int): step in the generation process
algorithm_used (str): "i" = initial step
"t" = top down
"b" = bottom up
hilbert_basis (list of lists): Hilbert basis of cone
"""
# MAY NOT BE NECESSARY num_hilbert_calc = 0
def __init__(self,cone,generation_step=0, algorithm_used="i",
hilbert_basis=None, hilbert_basis_size=None,
longest_hilbert_basis_element=None,
longest_hilbert_basis_element_length=None):
self.cone = cone
self.cone_rays_list = cone.rays_list()
self.generation_step = generation_step
self.algorithm_used = algorithm_used
self.hilbert_basis = hilbert_basis
self.hilbert_basis_size = hilbert_basis_size
self.longest_hilbert_basis_element = longest_hilbert_basis_element
self.longest_hilbert_basis_element_length = longest_hilbert_basis_element_length
def get_hilbert_basis(self,forced=False):
""" Retreives the hilbert basis, only calculates once. """
# if the hilbert_basis data is empty, generate it using Normaliz and store it
if self.hilbert_basis == None or forced:
self.hilbert_basis = list(self.cone.integral_points_generators()[1])
self.hilbert_basis_size = len(self.hilbert_basis)
self.longest_hilbert_basis_element = cone_tools.longest_vector(self.hilbert_basis)
self.longest_hilbert_basis_element_length = float(sage.all.vector(self.get_longest_hilbert_basis_element()).norm())
#return the stored value.
return list(self.hilbert_basis)
def get_longest_hilbert_basis_element(self):
if self.longest_hilbert_basis_element == None:
self.longest_hilbert_basis_element = cone_tools.longest_vector(self.get_hilbert_basis())
return self.longest_hilbert_basis_element
def hilbert_graph_data_size(self):
if self.hilbert_basis_size == None:
self.hilbert_basis_size = float(len(self.get_hilbert_basis()))
return self.hilbert_basis_size
def hilbert_graph_data_length(self):
if self.longest_hilbert_basis_element_length == None:
self.longest_hilbert_basis_element_length = float(sage.all.vector(self.get_longest_hilbert_basis_element()).norm())
return self.longest_hilbert_basis_element_length
def rays_list(self):
"""Returns the extremal generators of the cone
self.cone.rays_list() (list of lists): normaliz returns this.
"""
return self.cone_rays_list
def output_details(self):
""" Prints basic details about this particular cone. """
print("rays = {}".format(self.rays_list()))
print("generated on step {} with algorithm {}".format(self.generation_step,self.algorithm_used))
if self.hilbert_basis == None:
L = 0
else:
L = len(self.hilbert_basis)
print("number of elements in hilbert_basis = {}".format(L))
def calculate(self):
if self.hilbert_basis == None:
self.hilbert_basis = list(self.cone.integral_points_generators()[1])
self.longest_hilbert_basis_element = cone_tools.longest_vector(self.hilbert_basis)
class ConeChainElementEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, ConeChainElement):
cone_rays_list_json = cone_tools.rays_list_to_json_array(obj.cone_rays_list)
hilb_basis = cone_tools.rays_list_to_json_array(obj.hilbert_basis)
longest = None if obj.hilbert_basis is None else [int(i) for i in obj.longest_hilbert_basis_element]
return {'cone_rays_list' : cone_rays_list_json,
'generation_step' : obj.generation_step,
'algorithm_used' : obj.algorithm_used,
'hilbert_basis' : hilb_basis,
'hilbert_basis_size': obj.hilbert_graph_data_size(),
'longest_hilbert_basis_element': longest,
'longest_hilbert_basis_element_length': obj.hilbert_graph_data_length()}
return json.JSONEncoder.default(self, obj)
class ConeChainElementDecoder(json.JSONDecoder):
def __init__(self, *args, **kwargs):
json.JSONDecoder.__init__(self, object_hook=self.object_hook, *args, **kwargs)
def object_hook(self, dictionary):
if 'cone_rays_list' in dictionary:
cone = sage.all.Polyhedron(rays=dictionary['cone_rays_list'],backend='normaliz')
if dictionary['hilbert_basis'] == 'null':
return ConeChainElement(cone,
dictionary['generation_step'],
dictionary['algorithm_used'])
else:
return ConeChainElement(cone,
dictionary['generation_step'],
dictionary['algorithm_used'],
[sage.all.vector(v) for v in dictionary['hilbert_basis']],
dictionary['hilbert_basis_size'],
sage.all.vector(dictionary['longest_hilbert_basis_element']),
dictionary['longest_hilbert_basis_element_length'])