Refact. Add SignatureFunction.plot_title var. Plot many sf at once - function plot_many

This commit is contained in:
Maria Marchwicka 2020-11-06 04:01:54 +01:00
parent 84a4c2a082
commit 4d549c2dcb
3 changed files with 97 additions and 60 deletions

View File

@ -1,13 +1,15 @@
#!/usr/bin/python #!/usr/bin/env sage -python
import numpy as np import numpy as np
import itertools as it import itertools as it
import matplotlib.pyplot as plt
import warnings
import re
import inspect
from typing import Iterable from typing import Iterable
from collections import Counter from collections import Counter
from sage.arith.functions import LCM_list from sage.arith.functions import LCM_list
import warnings
import re
import matplotlib.pyplot as plt
import inspect
# 9.11 (9.8) # 9.11 (9.8)
# 9.15 (9.9) # 9.15 (9.9)
@ -22,7 +24,6 @@ class CableSummand():
self.signature_as_function_of_theta = \ self.signature_as_function_of_theta = \
self.get_summand_signature_as_theta_function() self.get_summand_signature_as_theta_function()
@staticmethod @staticmethod
def get_summand_descrption(knot_as_k_values): def get_summand_descrption(knot_as_k_values):
description = "" description = ""
@ -33,7 +34,6 @@ class CableSummand():
description += "2, " + str(2 * abs(k) + 1) + "; " description += "2, " + str(2 * abs(k) + 1) + "; "
return description[:-2] + ")" return description[:-2] + ")"
@classmethod @classmethod
def get_blanchfield_for_pattern(cls, k_n, theta=0): def get_blanchfield_for_pattern(cls, k_n, theta=0):
@ -45,17 +45,13 @@ class CableSummand():
k = abs(k_n) k = abs(k_n)
assert theta <= k, msg assert theta <= k, msg
results = []
results = []
ksi = 1/(2 * k + 1) ksi = 1/(2 * k + 1)
counter = Counter()
# print("lambda_odd, i.e. (theta + e) % 2 != 0") # print("lambda_odd, i.e. (theta + e) % 2 != 0")
for e in range(1, k + 1): for e in range(1, k + 1):
if (theta + e) % 2 != 0: if (theta + e) % 2 != 0:
counter[e * ksi] = 1 * sgn(k_n)
counter[1 - e * ksi] = -1 * sgn(k_n)
results.append((e * ksi, 1 * sgn(k_n))) results.append((e * ksi, 1 * sgn(k_n)))
results.append((1 - e * ksi, -1 * sgn(k_n))) results.append((1 - e * ksi, -1 * sgn(k_n)))
@ -139,7 +135,18 @@ class CableSummand():
pattern_part = self.get_blanchfield_for_pattern(patt_k, theta) pattern_part = self.get_blanchfield_for_pattern(patt_k, theta)
satellite_part = self.get_satellite_part(*knot_as_k_values, satellite_part = self.get_satellite_part(*knot_as_k_values,
theta=theta) theta=theta)
return pattern_part, satellite_part sf = satellite_part + pattern_part
satellite_part.plot_title = self.knot_description + \
", theta = " + str(theta) + \
", satellite part."
pattern_part.plot_title = self.knot_description + \
", theta = " + str(theta) + \
", pattern part."
sf.plot_title = self.knot_description +\
", theta = " + str(theta)
return pattern_part, satellite_part, sf
get_summand_signture_function.__doc__ = \ get_summand_signture_function.__doc__ = \
get_summand_signture_function_docsting get_summand_signture_function_docsting
@ -156,7 +163,7 @@ class CableSummand():
return name return name
def plot_summand_for_theta(self, theta, save_path=None): def plot_summand_for_theta(self, theta, save_path=None):
pp, sp = self.signature_as_function_of_theta(theta) pp, sp, sf = self.signature_as_function_of_theta(theta)
title = self.knot_description + ", theta = " + str(theta) title = self.knot_description + ", theta = " + str(theta)
if save_path is not None: if save_path is not None:
file_name = self.get_file_name_for_summand_plot(theta) file_name = self.get_file_name_for_summand_plot(theta)
@ -221,7 +228,7 @@ class CableSum():
for i, knot in enumerate(self.knot_summands): for i, knot in enumerate(self.knot_summands):
knot.plot_summand_for_theta(thetas[i], save_path=save_path) knot.plot_summand_for_theta(thetas[i], save_path=save_path)
pp, sp = self.signature_as_function_of_theta(*thetas) pp, sp, sf = self.signature_as_function_of_theta(*thetas)
title = self.knot_description + ", thetas = " + str(thetas) title = self.knot_description + ", thetas = " + str(thetas)
if save_path is not None: if save_path is not None:
file_name = re.sub(r', ', '_', str(thetas)) file_name = re.sub(r', ', '_', str(thetas))
@ -232,9 +239,18 @@ class CableSum():
if save_path is not None: if save_path is not None:
file_path = os.path.join(save_path, "all_" + file_name) file_path = os.path.join(save_path, "all_" + file_name)
sf_list = [knot.signature_as_function_of_theta(thetas[i]) sf_list = [knot.signature_as_function_of_theta(thetas[i])[2]
for i, knot in enumerate(self.knot_summands)] for i, knot in enumerate(self.knot_summands)]
# pp, sp = knot.signature_as_function_of_theta(thetas[i]) sf_list.append(sf_list[-1])
sf_list.append(sf_list[-1])
sf_list.append(sf_list[-1])
sf_list.append(sf_list[-1])
sf_list.append(sf_list[-1])
sf_list.append(sf_list[-1])
# sf_list.append(sf_list[-1])
SignatureFunction.plot_many(*sf_list)
# pp, sp, sf = knot.signature_as_function_of_theta(thetas[i])
# (pp + sp) = sp.plot # (pp + sp) = sp.plot
# #
# pp.plot_sum_with_other(sp, title=title, save_path=file_path) # pp.plot_sum_with_other(sp, title=title, save_path=file_path)
@ -249,7 +265,6 @@ class CableSum():
for knot in self.knot_summands: for knot in self.knot_summands:
knot.plot_summand() knot.plot_summand()
def parse_thetas(self, *thetas): def parse_thetas(self, *thetas):
summands_num = len(self.knot_sum_as_k_valus) summands_num = len(self.knot_sum_as_k_valus)
if not thetas: if not thetas:
@ -302,7 +317,7 @@ class CableSum():
# for each cable knot (summand) in cable sum apply theta # for each cable knot (summand) in cable sum apply theta
for i, knot in enumerate(self.knot_summands): for i, knot in enumerate(self.knot_summands):
sfth = knot.signature_as_function_of_theta sfth = knot.signature_as_function_of_theta
pp, sp = sfth(thetas[i]) pp, sp, _ = sfth(thetas[i])
pattern_part += pp pattern_part += pp
satellite_part += sp satellite_part += sp
sf = pattern_part + satellite_part sf = pattern_part + satellite_part
@ -312,7 +327,7 @@ class CableSum():
print(str(thetas)) print(str(thetas))
print(sf) print(sf)
assert sf.total_sign_jump() == 0 assert sf.total_sign_jump() == 0
return pattern_part, satellite_part return pattern_part, satellite_part, sf
signature_as_function_of_theta.__doc__ =\ signature_as_function_of_theta.__doc__ =\
signature_as_function_of_theta_docstring signature_as_function_of_theta_docstring
@ -340,8 +355,7 @@ class CableSum():
# has a large signature. # has a large signature.
for shift in range(1, self.q_order): for shift in range(1, self.q_order):
shifted_thetas = [shift * th for th in thetas] shifted_thetas = [shift * th for th in thetas]
pp, sp = self.signature_as_function_of_theta(*shifted_thetas) pp, sp, sf= self.signature_as_function_of_theta(*shifted_thetas)
sf = pp + sp
limit = 5 + np.count_nonzero(shifted_thetas) limit = 5 + np.count_nonzero(shifted_thetas)
extremum = abs(sf.extremum(limit=limit)) extremum = abs(sf.extremum(limit=limit))
if shift > 1: if shift > 1:
@ -378,6 +392,7 @@ class CableSum():
print("\nOK") print("\nOK")
return True return True
class CableTemplate(): class CableTemplate():
def __init__(self, knot_formula, q_vector=None, k_vector=None, def __init__(self, knot_formula, q_vector=None, k_vector=None,
@ -421,7 +436,6 @@ class CableTemplate():
self.knot_sum_as_k_valus = eval(self.knot_formula) self.knot_sum_as_k_valus = eval(self.knot_formula)
self._cable = CableSum(self.knot_sum_as_k_valus) self._cable = CableSum(self.knot_sum_as_k_valus)
self._q_vector = [2 * k_val + 1 for k_val in k] self._q_vector = [2 * k_val + 1 for k_val in k]
@property @property
@ -467,7 +481,6 @@ class CableTemplate():
other.knot_formula) other.knot_formula)
return self + CableTemplate(o_formula) return self + CableTemplate(o_formula)
def __add__(self, other): def __add__(self, other):
knot_formula = self.knot_formula[:-1] + ",\n" + other.knot_formula[1:] knot_formula = self.knot_formula[:-1] + ",\n" + other.knot_formula[1:]
return CableTemplate(knot_formula) return CableTemplate(knot_formula)

View File

@ -1,4 +1,4 @@
#!/usr/bin/python #!/usr/bin/env sage -python
# TBD: read about Factory Method, variable in docstring, sage documentation, # TBD: read about Factory Method, variable in docstring, sage documentation,
# print calc. to output file # print calc. to output file
@ -15,13 +15,22 @@ import numpy as np
attach("signature.sage") attach("signature.sage")
attach("cable_signature.sage") attach("cable_signature.sage")
# if not os.path.isfile('signature.py'):
# os.system('sage --preparse cable_signature.sage')
# os.system('mv cable_signature.sage.py cable_signature.py')
# from signature import SignatureFunction
class Config(object): class Config(object):
def __init__(self): def __init__(self):
self.f_results = os.path.join(os.getcwd(), "results.out") self.f_results = os.path.join(os.getcwd(), "results.out")
self.verbose = True
# self.verbose = False
# knot_formula is a schema for knots which signature function # knot_formula is a schema for knots which signature function
# will be calculated # will be calculated
self.knot_formula = "[[k[0], k[1], k[3]], " + \ self.knot_formula = "[[k[0], k[1], k[3]], " + \
@ -42,10 +51,7 @@ class Config(object):
# [-k[0], -k[3], -k[4]], [-k[1], -k[2]]]" # [-k[0], -k[3], -k[4]], [-k[1], -k[2]]]"
# self.knot_formula = "[[k[0], k[1], k[2]], [k[3]],\ # self.knot_formula = "[[k[0], k[1], k[2]], [k[3]],\
# [-k[0], -k[1], -k[3]], [-k[2]]]" # [-k[0], -k[1], -k[3]], [-k[2]]]"
self.limit = 3
self.verbose = True
# self.verbose = False
@ -68,7 +74,7 @@ def main(arg=None):
# knot_formula = config.knot_formula # knot_formula = config.knot_formula
# q_vector = (3, 5, 7, 13) # q_vector = (3, 5, 7, 13)
# q_vector = (3, 5, 7, 11) # q_vector = (3, 5, 7, 11)
return
formula_1 = "[[k[0], k[5], k[3]], " + \ formula_1 = "[[k[0], k[5], k[3]], " + \
"[-k[1], -k[3]], " + \ "[-k[1], -k[3]], " + \
"[k[2], k[3]], " + \ "[k[2], k[3]], " + \
@ -85,11 +91,11 @@ def main(arg=None):
cable_template_1 = CableTemplate(knot_formula=formula_1) cable_template_1 = CableTemplate(knot_formula=formula_1)
cable_template_2 = CableTemplate(knot_formula=formula_2) cable_template_2 = CableTemplate(knot_formula=formula_2)
cable_template = cable_template_1 + cable_template_2 cable_template = cable_template_1 + cable_template_2
cable_with_shift = cable_template_1.add_with_shift(cable_template_2) # cable_with_shift = cable_template_1.add_with_shift(cable_template_2)
print(cable_with_shift.knot_formula) print(cable_with_shift.knot_formula)
cable_template.fill_q_vector() # cable_template.fill_q_vector()
print(cable_template.q_vector) # print(cable_template.q_vector)
print(cable_template.knot_formula) # print(cable_template.knot_formula)
cable = cable_template.cable cable = cable_template.cable
sf = cable(4,4,4,4,0,0,0,0) sf = cable(4,4,4,4,0,0,0,0)
@ -104,7 +110,7 @@ def main(arg=None):
cable_template_2 = CableTemplate(knot_formula=formula_2) cable_template_2 = CableTemplate(knot_formula=formula_2)
cable_template = cable_template_1 + cable_template_2 cable_template = cable_template_1 + cable_template_2
# cable_template.cable.is_signature_big_for_all_metabolizers() # cable_template.cable.is_signature_big_for_all_metabolizers()
# sf = cable_template.cable.signature_as_function_of_theta(4,4,4,4,0,0,0,0) sf = cable_template.cable.signature_as_function_of_theta(4,4,4,4,0,0,0,0)

View File

@ -1,4 +1,4 @@
#!/usr/bin/python #!/usr/bin/env sage -python
import numpy as np import numpy as np
import itertools as it import itertools as it
from typing import Iterable from typing import Iterable
@ -16,13 +16,12 @@ from pathlib import Path
class SignatureFunction(): class SignatureFunction():
def __init__(self, values=None, counter=None): def __init__(self, values=None, counter=None, plot_title=''):
# counter of signature jumps # counter of signature jumps
if counter is None: if counter is None:
counter = Counter() counter = Counter()
if values is None: values = values or []
values = []
for k, v in values: for k, v in values:
counter[k] += v counter[k] += v
@ -34,6 +33,7 @@ class SignatureFunction():
counter[0] += 0 counter[0] += 0
counter[1] += 0 counter[1] += 0
self.jumps_counter = counter self.jumps_counter = counter
self.plot_title = plot_title
def __rshift__(self, shift): def __rshift__(self, shift):
# A shift of the signature functions corresponds to the rotation. # A shift of the signature functions corresponds to the rotation.
@ -52,7 +52,11 @@ class SignatureFunction():
def __add__(self, other): def __add__(self, other):
counter = copy(self.jumps_counter) counter = copy(self.jumps_counter)
counter.update(other.jumps_counter) counter.update(other.jumps_counter)
return SignatureFunction(counter=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): def __sub__(self, other):
counter = copy(self.jumps_counter) counter = copy(self.jumps_counter)
@ -79,9 +83,6 @@ class SignatureFunction():
result = [jump for jump_arg, jump in items if jump_arg < mod_one(arg)] result = [jump for jump_arg, jump in items if jump_arg < mod_one(arg)]
return 2 * sum(result) + self.jumps_counter[arg] return 2 * sum(result) + self.jumps_counter[arg]
def is_zero_everywhere(self):
return not any(self.jumps_counter.values())
def double_cover(self): def double_cover(self):
# to read values for t^2 # to read values for t^2
items = self.jumps_counter.items() items = self.jumps_counter.items()
@ -103,6 +104,11 @@ class SignatureFunction():
counter = Counter({mod_one(2 * k) : v for k, v in items if k >= 1/2}) counter = Counter({mod_one(2 * k) : v for k, v in items if k >= 1/2})
return SignatureFunction(counter=counter) return SignatureFunction(counter=counter)
def is_zero_everywhere(self):
return not any(self.jumps_counter.values())
def extremum(self, limit=None): def extremum(self, limit=None):
max = 0 max = 0
current = 0 current = 0
@ -121,13 +127,36 @@ class SignatureFunction():
# Total signature jump is the sum of all jumps. # Total signature jump is the sum of all jumps.
return sum([j[1] for j in sorted(self.jumps_counter.items())]) return sum([j[1] for j in sorted(self.jumps_counter.items())])
def plot_four(self, sf1, sf2, sf3, save_path=None, title=''): @staticmethod
def plot_many(*sf_list, save_path=None, title='',):
axes_num = len(sf_list)
if axes_num > 36:
sf_list = sf_list[36]
axes_num = 36
# print war, set val in conf
rows = ceil(sqrt(axes_num))
cols = ceil(axes_num/rows)
fig, axes_matrix = plt.subplots(rows, cols,
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)
plt.tight_layout()
save_path = save_path or os.path.join(os.getcwd(),"tmp.png")
save_path = Path(save_path).with_suffix('.png')
plt.savefig(save_path)
plt.close()
image = Image.open(save_path)
image.show()
return
fig, axes_matrix = plt.subplots(2, 2, sharey=True,
figsize=(10,5))
sf0 = self
sf.plot(subplot=True,
ax=axes_matrix[0][1])
sf1.plot(subplot=True, sf1.plot(subplot=True,
ax=axes_matrix[1][0], ax=axes_matrix[1][0],
@ -146,18 +175,13 @@ class SignatureFunction():
plt.tight_layout() plt.tight_layout()
save_path = save_path or os.path.join(os.getcwd(),"tmp.png") save_path = save_path or os.path.join(os.getcwd(),"tmp.png")
save_path = Path(save_path) save_path = Path(save_path).with_suffix('.png')
save_path = save_path.with_suffix('.png')
plt.savefig(save_path) plt.savefig(save_path)
plt.close() plt.close()
image = Image.open(save_path) image = Image.open(save_path)
image.show() image.show()
pass
def plot_sum_with_other(self, other, def plot_sum_with_other(self, other,
save_path=None, title=''): save_path=None, title=''):
tp = self tp = self
@ -209,10 +233,6 @@ class SignatureFunction():
image = Image.open(save_path) image = Image.open(save_path)
image.show() image.show()
pass
def plot(self, subplot=False, ax=None, save_as='sf', def plot(self, subplot=False, ax=None, save_as='sf',
title="", title="",
alpha=1, alpha=1,
@ -241,8 +261,6 @@ class SignatureFunction():
image = Image.open(save_as) image = Image.open(save_as)
image.show() image.show()
def step_function_data(self): def step_function_data(self):
# Transform the signature jump data to a format understandable # Transform the signature jump data to a format understandable
# by the plot function. # by the plot function.