fix problems with import_sage

This commit is contained in:
Maria 2021-07-15 13:48:37 +02:00
parent 30d1f40670
commit 8c8654c456
13 changed files with 696 additions and 15 deletions

View File

@ -45,9 +45,9 @@ So we can work in the following steps:
from .utility import import_sage
import os
package = __name__.split('.')[0]
path = os.path.dirname(__file__)
import_sage('signature', package=package, path=path)
#
# package = __name__.split('.')[0]
# path = os.path.dirname(__file__)
# import_sage('signature', package=package, path=path)
# import_sage('cable_signature', package=package, path=path)
# import_sage('main', package=package, path=path)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -8,9 +8,12 @@ from typing import Iterable
from collections import Counter
from sage.arith.functions import LCM_list
import importlib
from .utility import import_sage, mod_one
from .utility import import_sage
from . import signature as sig
SIGMA = 0
SIGNATURE = 1

5
gaknot/clean.sh Executable file
View File

@ -0,0 +1,5 @@
#!/bin/bash
rm cable_signature.py
rm signature.py
rm main.py

278
gaknot/main.py Normal file
View File

@ -0,0 +1,278 @@
# This file was *autogenerated* from the file /home/maria/signature_function/gaknot/main.sage
from sage.all_cmdline import * # import sage library
_sage_const_0 = Integer(0); _sage_const_1 = Integer(1); _sage_const_2 = Integer(2); _sage_const_3 = Integer(3); _sage_const_5 = Integer(5); _sage_const_7 = Integer(7); _sage_const_11 = Integer(11); _sage_const_13 = Integer(13); _sage_const_10 = Integer(10)#!/usr/bin/env sage -python
# TBD: read about Factory Method, variable in docstring, sage documentation,
# print calc. to output file
# decide about printing option
# make __main__?
import os
import sys
import itertools as it
import re
import numpy as np
import importlib
from .utility import import_sage
# from . import signature as sig
# from . import cable_signature as cs
package = __name__.split('.')[_sage_const_0 ]
path = os.path.dirname(__file__)
print(path)
sg = import_sage('signature', package='gaknot', path=path)
cs = import_sage('cable_signature', package='gaknot', path=path)
# class Config:
# def __init__(self):
# self.f_results = os.path.join(os.getcwd(), "results.out")
class Schemas:
# knot_formula = "[[k[0], k[1], k[2]],\
# [ k[3], k[4]],\
# [-k[0], -k[3], -k[4]],\
# [ -k[1], -k[2]]]"
#
# knot_formula = "[[k[0], k[1], k[2]],\
# [ k[3]],\
# [-k[0], -k[1], -k[3]],\
# [ -k[2]]]"
short_3_layers_a = "[[ k[5], k[3]], " + \
"[ -k[1], -k[3]], " + \
"[ k[3]], " + \
"[ -k[4], -k[6], -k[3]]]"
short_3_layers_b = "[[k[4], k[1], k[7]], " + \
"[ -k[7]], " + \
"[ k[6], k[7]], " + \
"[ -k[5], -k[7]]]"
schema_short1 = "[ [k[5], k[3]], " + \
"[ -k[1], -k[3]], " + \
"[ k[3]], " + \
"[ -k[6], -k[3]]]"
schema_short2 = "[[ k[1], k[7]], " + \
"[ -k[7]], " + \
"[ k[6], k[7]], " + \
"[ -k[5], -k[7]]]"
schema_short = "[[ k[5], k[3]], " + \
"[ -k[1], -k[3]], " + \
"[ k[3]], " + \
"[ -k[6], -k[3]], " + \
"[ k[1], k[7]], " + \
"[ -k[7]], " + \
"[ k[6], k[7]], " + \
"[ -k[5], -k[7]]]"
# two_summands_schema = "[ [k[0], k[1], k[4]], [-k[1], -k[3]],\
# [k[2], k[3]], [-k[0], -k[2], -k[4]] ]"
# two_small_summands_schema = "[[k[3]], [-k[3]],\
# [k[3]], [-k[3]] ]"
#
# four_summands_schema = "[[k[3], k[2], k[0]],\
# [ -k[2], -k[0]],\
# [ k[1], k[0]],\
# [-k[3], -k[1], -k[0]]]"
#
four_summands_schema = "[[ k[0], k[1], k[3]]," + \
"[ -k[1], -k[3]]," + \
"[ k[2], k[3]]," + \
"[ -k[0], -k[2], -k[3]]]"
# formula_1 = "[[ k[0], k[5], k[3]], " + \
# "[ -k[1], -k[3]], " + \
# "[ k[2], k[3]], " + \
# "[ -k[0], -k[2], -k[3]]]"
#
# formula_2 = "[[ k[4], k[1], k[7]], " + \
# "[ -k[5], -k[7]], " + \
# "[ k[6], k[7]], " + \
# "[ -k[4], -k[6], -k[7]]]"
#
# formula_1 = "[[ k[0], k[5], k[3]], " + \
# "[ -k[5], -k[3]], " + \
# "[ k[2], k[3]], " + \
# "[-k[4], -k[2], -k[3]]]"
#
# formula_2 = "[[ k[4], k[1], k[7]], " + \
# "[ -k[1], -k[7]], " + \
# "[ k[6], k[7]], " + \
# "[-k[0], -k[6], -k[7]]]"
def main(arg=None):
try:
limit = int(arg[_sage_const_1 ])
except (IndexError, TypeError):
limit = None
conf = Config()
cable_loop_with_details(conf)
def print_sigma_for_cable(verbose=True, Schemas=None):
schema_short1 = Schemas.schema_short1
schema_short2 = Schemas.schema_short2
schema_short = Schemas.schema_short
schema_four = Schemas.four_summands_schema
cable_template = cs.CableTemplate(knot_formula=schema_short)
cable_template.fill_q_vector()
q_v = cable_template.q_vector
print(q_v)
print(cable_template.cable.knot_description)
cable1 = cs.CableTemplate(knot_formula=schema_short1,
verbose=verbose,
q_vector=q_v
).cable
cable2 = cs.CableTemplate(knot_formula=schema_short2,
verbose=verbose,
q_vector=q_v
).cable
cable = cs.CableTemplate(knot_formula=schema_short1,
verbose=verbose,
q_vector=q_v
).cable
cable.plot_sigma_for_summands()
# cable1.plot_sigma_for_summands()
# cable2.plot_sigma_for_summands()
def cable_loop_with_details(verbose=True):
# verbose = False
schema_short1 = Schemas.schema_short1
schema_short2 = Schemas.schema_short2
schema_short = Schemas.schema_short
cable_template = cs.CableTemplate(knot_formula=schema_short)
list_of_q_vectors = []
# for el in [2, 3, 5, 7, 11, 13]:
for el in [_sage_const_2 ]:
cable_template.fill_q_vector(lowest_number=el)
q_v = cable_template.q_vector
print(q_v)
print(cable_template.cable.knot_description)
cable1 = cs.CableTemplate(knot_formula=schema_short1,
verbose=verbose,
q_vector=q_v
).cable
cable2 = cs.CableTemplate(knot_formula=schema_short2,
verbose=verbose,
q_vector=q_v
).cable
# print("\n")
# print(cable1.knot_description)
is_1 = cable1.is_function_big_for_all_metabolizers(invariant=cs.SIGMA)
is_2 = cable2.is_function_big_for_all_metabolizers(invariant=cs.SIGMA)
if is_1 and is_2:
print("sigma is big for all metabolizers")
else:
print("sigma is not big for all metabolizers")
print("\n" * _sage_const_3 )
def few_cable_without_calc(verbose=False):
schema_short1 = Schemas.schema_short1
schema_short2 = Schemas.schema_short2
schema_short = Schemas.schema_short
cable_template = cs.CableTemplate(knot_formula=schema_short)
list_of_q_vectors = []
for el in [_sage_const_2 , _sage_const_3 , _sage_const_5 , _sage_const_7 , _sage_const_11 , _sage_const_13 ]:
cable_template.fill_q_vector(lowest_number=el)
q_v = cable_template.q_vector
print(q_v)
print(cable_template.cable.knot_description)
cable1 = cs.CableTemplate(knot_formula=schema_short1,
verbose=verbose,
q_vector=q_v
).cable
cable2 = cs.CableTemplate(knot_formula=schema_short2,
verbose=verbose,
q_vector=q_v
).cable
is_1 = cable1.is_function_big_for_all_metabolizers(invariant=sigma)
is_2 = cable2.is_function_big_for_all_metabolizers(invariant=sigma)
if is_1 and is_2:
print("sigma is big for all metabolizers")
else:
print("sigma is not big for all metabolizers")
print("\n" * _sage_const_3 )
def smallest_cable(verbose=True):
schema_short1 = Schemas.schema_short1
schema_short2 = Schemas.schema_short2
schema_short = Schemas.schema_short
cable_template = cs.CableTemplate(knot_formula=schema_short)
q_v = cable_template.q_vector
print(q_v)
cable1 = cs.CableTemplate(knot_formula=schema_short1,
verbose=verbose,
q_vector=q_v).cable
cable2 = cs.CableTemplate(knot_formula=schema_short2,
verbose=verbose,
q_vector=q_v).cable
cable1.is_function_big_for_all_metabolizers(invariant=sigma)
cable2.is_function_big_for_all_metabolizers(invariant=sigma)
def plot_many_untwisted_signature_functions(range_tuple=(_sage_const_1 , _sage_const_10 )):
P = Primes()
for i in range(*range_tuple):
q = P.unrank(i)
a = cs.CableSummand.get_untwisted_signature_function(q=q)
a.plot()
if __name__ == '__main__':
if '__file__' in globals():
# skiped in interactive mode as __file__ is not defined
main(sys.argv)
else:
pass
# main()
# formula_long = "[[k[0], k[5], k[3]], " + \
# "[-k[5], -k[3]], " + \
# "[k[2], k[3]], " + \
# "[-k[4], -k[2], -k[3]]" + \
# "[k[4], k[1], k[7]], " + \
# "[-k[1], -k[7]], " + \
# "[k[6], k[7]], " + \
# "[-k[0], -k[6], -k[7]]]"
#
#
# formula_1 = "[[k[0], k[5], k[3]], " + \
# "[-k[1], -k[3]], " + \
# "[ k[3]], " + \
# "[-k[4], -k[6], -k[3]]]"
#
# formula_2 = "[[k[4], k[1], k[7]], " + \
# "[ -k[7]], " + \
# "[k[6], k[7]], " + \
# "[-k[0], -k[5], -k[7]]]"
#
#

View File

@ -12,12 +12,20 @@ import itertools as it
import re
import numpy as np
import importlib
from .utility import import_sage
from . import signature as sig
from . import cable_signature as cs
package = __name__.split('.')[0]
path = os.path.dirname(__file__)
if __name__ == '__main__':
from utility import import_sage
package = None
path = ''
else:
from .utility import import_sage
package = os.path.join( __name__.split('.')[0])
path = '../'
sg = import_sage('signature', package=package, path=path)
cs = import_sage('cable_signature', package=package, path=path)

385
gaknot/signature.py Normal file
View File

@ -0,0 +1,385 @@
# This file was *autogenerated* from the file /home/maria/signature_function/gaknot/signature.sage
from sage.all_cmdline import * # import sage library
_sage_const_0 = Integer(0); _sage_const_1 = Integer(1); _sage_const_2 = Integer(2); _sage_const_36 = Integer(36); _sage_const_10 = Integer(10); _sage_const_5 = Integer(5); _sage_const_0p3 = RealNumber('0.3'); _sage_const_0p7 = RealNumber('0.7'); _sage_const_0p05 = RealNumber('0.05'); _sage_const_4 = Integer(4); _sage_const_3 = Integer(3)#!/usr/bin/env sage -python
from collections import Counter
import matplotlib.pyplot as plt
import inspect
from PIL import Image
from pathlib import Path
import warnings
from .utility import mod_one
# 9.11 (9.8)
# 9.15 (9.9)
import sys
import os
JUPYTER = 'ipykernel'
IPy_TERMINAL = 'IPython'
def get_ipython_info():
if JUPYTER in sys.modules:
return JUPYTER
elif IPy_TERMINAL in sys.modules:
return IPy_TERMINAL
return False
global ipython_info
ipython_info = get_ipython_info()
class SignatureFunction:
def __init__(self, values=None, counter=None, plot_title=''):
# counter of signature jumps
if counter is None:
counter = Counter()
values = values or []
for k, v in values:
counter[k] += v
counter = Counter({k : v for k, v in counter.items() if v != _sage_const_0 })
if any(k >= _sage_const_1 for k in counter.keys()):
msg = "Signature function is defined on the interval [0, 1)."
raise ValueError(msg)
counter[_sage_const_0 ] += _sage_const_0
counter[_sage_const_1 ] += _sage_const_0
self.jumps_counter = counter
self.plot_title = plot_title
def __rshift__(self, shift):
# A shift of the signature functions corresponds to the rotation.
counter = Counter({mod_one(k + shift) : v \
for k, v in self.jumps_counter.items()})
return SignatureFunction(counter=counter)
def __lshift__(self, shift):
return self.__rshift__(-shift)
def __neg__(self):
counter = Counter()
counter.subtract(self.jumps_counter)
return SignatureFunction(counter=counter)
def __add__(self, other):
counter = copy(self.jumps_counter)
counter.update(other.jumps_counter)
if self.plot_title and other.plot_title:
title = self.plot_title + " + " + other.plot_title
else:
title = self.plot_title or other.plot_title
return SignatureFunction(counter=counter, plot_title=title)
def __sub__(self, other):
counter = copy(self.jumps_counter)
counter.subtract(other.jumps_counter)
return SignatureFunction(counter=counter)
def __mul__(self, number):
# scalar multiplication
counter = Counter({k : number * v \
for k, v in self.jumps_counter.items()})
return SignatureFunction(counter=counter)
def __rmul__(self, number):
return(self.__mul__(number))
def __eq__(self, other):
return self.jumps_counter == other.jumps_counter
def __str__(self):
result = ''.join([str(jump_arg) + ": " + str(jump) + "\n"
for jump_arg, jump in sorted(self.jumps_counter.items())])
return result
def __repr__(self):
result = ''.join([str(jump_arg) + ": " + str(jump) + ", "
for jump_arg, jump in sorted(self.jumps_counter.items())])
return result[:-_sage_const_2 ] + "."
def __call__(self, arg):
# return the value of the signature function at the point arg, i.e.
# sum of all signature jumps that occur before arg
items = self.jumps_counter.items()
result = [jump for jump_arg, jump in items if jump_arg < mod_one(arg)]
return _sage_const_2 * sum(result) + self.jumps_counter[arg]
def double_cover(self):
# to read values for t^2
items = self.jumps_counter.items()
counter = Counter({(_sage_const_1 + k) / _sage_const_2 : v for k, v in items})
counter.update(Counter({k / _sage_const_2 : v for k, v in items}))
return SignatureFunction(counter=counter)
def square_root(self):
# to read values for t^(1/2)
counter = Counter()
for jump_arg, jump in self.jumps_counter.items():
if jump_arg < _sage_const_1 /_sage_const_2 :
counter[_sage_const_2 * jump_arg] = jump
return SignatureFunction(counter=counter)
def minus_square_root(self):
# to read values for t^(1/2)
items = self.jumps_counter.items()
counter = Counter({mod_one(_sage_const_2 * k) : v for k, v in items if k >= _sage_const_1 /_sage_const_2 })
return SignatureFunction(counter=counter)
def is_zero_everywhere(self):
return not any(self.jumps_counter.values())
def extremum(self, limit=math.inf):
max_point = (_sage_const_0 , _sage_const_0 )
current = _sage_const_0
items = sorted(self.jumps_counter.items())
for arg, jump in items:
current += _sage_const_2 * jump
assert current == self(arg) + jump
if abs(current) > abs(max_point[_sage_const_1 ]):
max_point = (arg, current)
if abs(current) > limit:
break
return max_point
def total_sign_jump(self):
# Total signature jump is the sum of all jumps.
return sum([j[_sage_const_1 ] for j in sorted(self.jumps_counter.items())])
def plot(self, *args, **kargs):
SignaturePloter.plot(self, *args, **kargs)
class SignaturePloter:
@classmethod
def plot_many(cls, *sf_list, save_path=None, title='', cols=None):
axes_num = len(sf_list)
if axes_num > _sage_const_36 :
sf_list = sf_list[_sage_const_36 ]
axes_num = _sage_const_36
msg = "To many functions for the plot were given. "
msg += "Only 36 can be plotted "
warnings.warn(msg)
# print war, set val in conf
cols = cols or ceil(sqrt(axes_num))
rows = ceil(axes_num/cols)
fig, axes_matrix = plt.subplots(rows, cols,
sharex='col', sharey='row',
gridspec_kw={'hspace': _sage_const_0 , 'wspace': _sage_const_0 },
# sharey=True,
# sharex=True,
)
for i, sf in enumerate(sf_list):
col = i % cols
row = (i - col)/cols
sf.plot(subplot=True,
ax=axes_matrix[row][col],
title=sf.plot_title)
fig.suptitle(title)
plt.tight_layout()
cls.show_and_save(save_path)
@classmethod
def plot_sum_of_two(cls, sf1, sf2, save_path=None, title=''):
sf = sf1 + sf2
fig, axes_matrix = plt.subplots(_sage_const_2 , _sage_const_2 , sharey=True, figsize=(_sage_const_10 ,_sage_const_5 ))
sf1.plot(subplot=True,
ax=axes_matrix[_sage_const_0 ][_sage_const_1 ])
sf2.plot(subplot=True,
ax=axes_matrix[_sage_const_1 ][_sage_const_0 ],
color='red',
linestyle='dotted')
sf.plot(subplot=True,
ax=axes_matrix[_sage_const_0 ][_sage_const_0 ],
color='black')
sf1.plot(subplot=True,
ax=axes_matrix[_sage_const_1 ][_sage_const_1 ],
alpha=_sage_const_0p3 )
sf2.plot(subplot=True,
ax=axes_matrix[_sage_const_1 ][_sage_const_1 ],
color='red', alpha=_sage_const_0p3 ,
linestyle='dotted')
sf.plot(subplot=True,
ax=axes_matrix[_sage_const_1 ][_sage_const_1 ],
color='black',
alpha=_sage_const_0p7 ,)
fig.suptitle(title)
plt.tight_layout()
cls.show_and_save(save_path)
@classmethod
def plot(cls, sf, subplot=False, ax=None,
save_path=None,
title='',
alpha=_sage_const_1 ,
color='blue',
linestyle='solid',
special_point=None,
special_label='',
extraticks=None,
ylabel=''):
if ax is None:
fig, ax = plt.subplots(_sage_const_1 , _sage_const_1 )
keys = sorted(sf.jumps_counter.keys())
y = [(sf(k) + sf.jumps_counter[k]) for k in keys[:-_sage_const_1 ]]
xmax = keys[_sage_const_1 :]
xmin = keys[:-_sage_const_1 ]
ax.set(ylabel=ylabel)
ax.set(title=title)
ax.hlines(y, xmin, xmax, color=color, linestyle=linestyle, alpha=alpha)
if special_point is not None:
arg, val = special_point
extraticks = extraticks or []
plt.xticks(list(plt.xticks()[_sage_const_0 ]) + extraticks)
ext = sf.extremum()[_sage_const_1 ]
ytext = ext/_sage_const_2 + _sage_const_1 /_sage_const_2
xtext = arg + _sage_const_1 /_sage_const_5
ax.annotate(special_label, xy=(arg, val), xytext=(xtext, ytext),
arrowprops=dict(facecolor='black', shrink=_sage_const_0p05 ,
alpha=_sage_const_0p7 , width=_sage_const_2 ),)
if subplot:
return ax
cls.show_and_save(save_path)
@staticmethod
def show_and_save(save_path):
if save_path is not None:
save_path = Path(save_path)
save_path = save_path.with_suffix('.png')
plt.savefig(save_path)
if ipython_info == JUPYTER:
plt.show()
elif True: # save_path is None:
plt.savefig('tmp.png')
plt.close()
image = Image.open('tmp.png')
image.show()
# msg = "For interactive shell set save_path."
# warnings.warn(msg)
@staticmethod
def step_function_data(sf):
# Transform the signature jump data to a format understandable
# by the plot function.
result = [(k, sf.sf(k) + sf.jumps_counter[k])
for k in sorted(sf.jumps_counter.keys())]
return result
@staticmethod
def tikz_plot(sf, save_as):
plt_sin = plot(sin(x), (x, _sage_const_0 , _sage_const_2 *pi))
# plt_sin.show()
plt_sin.save("MyPic.pdf")
return
# Draw the graph of the signature and transform it into TiKz.
# header of the LaTeX file
head = inspect.cleandoc(
r"""
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
""")
body = \
r"""
%A piecewise linear function is drawn over the interval.
\draw (5,0) -- (6,-4);
%The axes are drawn.
\draw[latex-latex] ($(0,{-4*(2/5)}) +(0pt,-12.5pt)$) --
($(0,{4*(2/5)}) +(0pt,12.5pt)$) node[above right]{$y$};
\draw[latex-latex] ($({-4*(2/5)},0) +(-12.5pt,0pt)$) --
($({12*(2/5)},0) +(12.5pt,0pt)$) node[below right]{$x$};
"""
tail = \
r"""
\end{tikzpicture}
\end{document}
"""
tikzpicture = re.sub(r' +', ' ', ''.join([head, body, tail]))
tikzpicture = re.sub(r'\n ', '\n', tikzpicture)
with open("tmp.tex", "w") as f:
f.write(tikzpicture)
data = self.step_function_data()
with open(save_as, "w") as f:
head = \
r"""
\documentclass[tikz]{{standalone}}
%\usepackage{{tikz}}
\usetikzlibrary{{datavisualization}}
\usetikzlibrary{{datavisualization.formats.functions}}
%\usetikzlibrary{{calc}}
\begin{{document}}
\begin{{tikzpicture}}
\datavisualization[scientific axes, visualize as smooth line,
x axis={{ticks={{none,major={{at={{, {arg0} " as \\( {val0} \\
%]
""".format(arg0=str(N(data[_sage_const_0 ][_sage_const_0 ] ,digits=_sage_const_4 )), val0=str(data[_sage_const_0 ][_sage_const_0 ]))
f.write(head)
# f.write(", " + str(N(data[0][0],digits=4)) + " as \\(" + \
# str(data[0][0]) + "\\)")
for jump_arg, jump in data[_sage_const_1 :_sage_const_3 ]:
f.write(", " + str(N(jump_arg,digits=_sage_const_4 )) +
" as \\(" + str(jump_arg) + "\\)")
f.write("}}}}\n")
f.write(" ]\n")
f.write("data [format=function]{\n")
f.write("var x : interval [0:1];\n")
f.write("func y = \\value x;\n")
f.write("};\n")
# close LaTeX enviroments
tail = \
r"""
%};
\end{tikzpicture}
\end{document}
"""
f.write(tail)
SignatureFunction.__doc__ = \
"""
This simple class encodes twisted and untwisted signature functions
of knots. Since the signature function is entirely encoded by its signature
jump, the class stores only information about signature jumps
in a dictionary self.jumps_counter.
The dictionary stores data of the signature jump as a key/values pair,
where the key is the argument at which the functions jumps
and value encodes the value of the jump. Remember that we treat
signature functions as defined on the interval [0,1).
"""

View File

@ -1,5 +1,8 @@
#!/usr/bin/env sage -python
import sys
import os
from collections import Counter
import matplotlib.pyplot as plt
import inspect
@ -8,11 +11,6 @@ from pathlib import Path
import warnings
from .utility import mod_one
# 9.11 (9.8)
# 9.15 (9.9)
import sys
import os
JUPYTER = 'ipykernel'
IPy_TERMINAL = 'IPython'
@ -27,6 +25,10 @@ def get_ipython_info():
global ipython_info
ipython_info = get_ipython_info()
# 9.11 (9.8)
# 9.15 (9.9)
class SignatureFunction: