first tests for cable with 8 direct summand
This commit is contained in:
parent
4c8df7468e
commit
8ddb06fdb8
@ -3,6 +3,9 @@ import numpy as np
|
|||||||
import itertools as it
|
import itertools as it
|
||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
|
from sage.arith.functions import LCM_list
|
||||||
|
import warnings
|
||||||
|
import re
|
||||||
|
|
||||||
SIGNATURE = 0
|
SIGNATURE = 0
|
||||||
SIGMA = 1
|
SIGMA = 1
|
||||||
@ -36,44 +39,25 @@ class SignatureFunction(object):
|
|||||||
def double_cover(self):
|
def double_cover(self):
|
||||||
# to read values for t^2
|
# to read values for t^2
|
||||||
items = self.cnt_signature_jumps.items()
|
items = self.cnt_signature_jumps.items()
|
||||||
counter = Counter({ (1 + k) / 2 : v for k, v in items})
|
counter = Counter({(1 + k) / 2 : v for k, v in items})
|
||||||
counter.update(Counter({ k / 2 : v for k, v in items}))
|
counter.update(Counter({k / 2 : v for k, v in items}))
|
||||||
new_data = []
|
return SignatureFunction(counter=counter)
|
||||||
for jump_arg, jump in self.cnt_signature_jumps.items():
|
|
||||||
new_data.append((jump_arg/2, jump))
|
|
||||||
new_data.append((1/2 + jump_arg/2, jump))
|
|
||||||
assert SignatureFunction(values=new_data) == SignatureFunction(counter=counter)
|
|
||||||
return SignatureFunction(values=new_data)
|
|
||||||
|
|
||||||
def square_root(self):
|
def square_root(self):
|
||||||
# to read values for t^(1/2)
|
# to read values for t^(1/2)
|
||||||
new_data = []
|
|
||||||
for jump_arg, jump in self.cnt_signature_jumps.items():
|
|
||||||
if jump_arg < 1/2:
|
|
||||||
new_data.append((2 * jump_arg, jump))
|
|
||||||
|
|
||||||
counter = Counter()
|
counter = Counter()
|
||||||
for jump_arg, jump in self.cnt_signature_jumps.items():
|
for jump_arg, jump in self.cnt_signature_jumps.items():
|
||||||
if jump_arg < 1/2:
|
if jump_arg < 1/2:
|
||||||
counter[2 * jump_arg] = jump
|
counter[2 * jump_arg] = jump
|
||||||
assert SignatureFunction(values=new_data) == SignatureFunction(counter=counter)
|
return SignatureFunction(counter=counter)
|
||||||
|
|
||||||
return SignatureFunction(values=new_data)
|
|
||||||
|
|
||||||
def minus_square_root(self):
|
def minus_square_root(self):
|
||||||
# to read values for t^(1/2)
|
# to read values for t^(1/2)
|
||||||
items = self.cnt_signature_jumps.items()
|
items = self.cnt_signature_jumps.items()
|
||||||
|
counter = Counter({mod_one(2 * k) : v for k, v in items if k >= 1/2})
|
||||||
counter = Counter()
|
|
||||||
for jump_arg, jump in self.cnt_signature_jumps.items():
|
|
||||||
if jump_arg >= 1/2:
|
|
||||||
counter[mod_one(2 * jump_arg)] = jump
|
|
||||||
counter2 = Counter({mod_one(2 * k) : v for k, v in items if k >= 1/2 })
|
|
||||||
assert counter2 == counter
|
|
||||||
|
|
||||||
return SignatureFunction(counter=counter)
|
return SignatureFunction(counter=counter)
|
||||||
|
|
||||||
def is_big(self):
|
def extremum(self):
|
||||||
max = 0
|
max = 0
|
||||||
current = 0
|
current = 0
|
||||||
items = sorted(self.cnt_signature_jumps.items())
|
items = sorted(self.cnt_signature_jumps.items())
|
||||||
@ -88,15 +72,8 @@ class SignatureFunction(object):
|
|||||||
|
|
||||||
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.
|
||||||
new_data = []
|
|
||||||
for jump_arg, jump in self.cnt_signature_jumps.items():
|
|
||||||
new_data.append((mod_one(jump_arg + shift), jump))
|
|
||||||
sf = SignatureFunction(values=new_data)
|
|
||||||
|
|
||||||
counter = Counter({mod_one(k + shift) : v \
|
counter = Counter({mod_one(k + shift) : v \
|
||||||
for k,v in self.cnt_signature_jumps.items()})
|
for k, v in self.cnt_signature_jumps.items()})
|
||||||
assert SignatureFunction(counter=counter) == \
|
|
||||||
SignatureFunction(values=new_data)
|
|
||||||
return SignatureFunction(counter=counter)
|
return SignatureFunction(counter=counter)
|
||||||
|
|
||||||
def __lshift__(self, shift):
|
def __lshift__(self, shift):
|
||||||
@ -112,19 +89,19 @@ class SignatureFunction(object):
|
|||||||
counter.update(other.cnt_signature_jumps)
|
counter.update(other.cnt_signature_jumps)
|
||||||
return SignatureFunction(counter=counter)
|
return SignatureFunction(counter=counter)
|
||||||
|
|
||||||
def __eq__(self, other):
|
|
||||||
self_cnt = Counter({ k : v for k, v in self.cnt_signature_jumps.items()
|
|
||||||
if v != 0})
|
|
||||||
other_cnt = Counter({ k : v for k, v in other.cnt_signature_jumps.items()
|
|
||||||
if v != 0})
|
|
||||||
|
|
||||||
return self.cnt_signature_jumps == other.cnt_signature_jumps
|
|
||||||
|
|
||||||
def __sub__(self, other):
|
def __sub__(self, other):
|
||||||
counter = copy(self.cnt_signature_jumps)
|
counter = copy(self.cnt_signature_jumps)
|
||||||
counter.subtract(other.cnt_signature_jumps)
|
counter.subtract(other.cnt_signature_jumps)
|
||||||
return SignatureFunction(counter=counter)
|
return SignatureFunction(counter=counter)
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
self_cnt = Counter({k : v for k, v in self.cnt_signature_jumps.items()
|
||||||
|
if v != 0})
|
||||||
|
other_cnt = Counter({k : v for k, v in other.cnt_signature_jumps.items()
|
||||||
|
if v != 0})
|
||||||
|
return self.cnt_signature_jumps == other.cnt_signature_jumps
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
result = ''.join([str(jump_arg) + ": " + str(jump) + "\n"
|
result = ''.join([str(jump_arg) + ": " + str(jump) + "\n"
|
||||||
for jump_arg, jump in sorted(self.cnt_signature_jumps.items())
|
for jump_arg, jump in sorted(self.cnt_signature_jumps.items())
|
||||||
@ -145,15 +122,11 @@ class SignatureFunction(object):
|
|||||||
|
|
||||||
def total_sign_jump(self):
|
def total_sign_jump(self):
|
||||||
# Total signature jump is the sum of all jumps.
|
# Total signature jump is the sum of all jumps.
|
||||||
result = sum([j[1] for j in self.to_list()])
|
|
||||||
assert result == sum(v for _, v in self.cnt_signature_jumps.items())
|
|
||||||
return sum([j[1] for j in self.to_list()])
|
return sum([j[1] for j in self.to_list()])
|
||||||
|
|
||||||
def to_list(self):
|
def to_list(self):
|
||||||
# Return signature jumps formated as a list
|
# Return signature jumps formated as a list
|
||||||
assert sorted(self.cnt_signature_jumps.items(), key = lambda x: x[0]) == \
|
return sorted(self.cnt_signature_jumps.items())
|
||||||
sorted(self.cnt_signature_jumps.items())
|
|
||||||
return sorted(self.cnt_signature_jumps.items(), key = lambda x: x[0])
|
|
||||||
|
|
||||||
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
|
||||||
@ -187,9 +160,9 @@ class SignatureFunction(object):
|
|||||||
data = sorted(self.step_function_data())
|
data = sorted(self.step_function_data())
|
||||||
print("data")
|
print("data")
|
||||||
print(data)
|
print(data)
|
||||||
f.write(" \\datavisualization[scientific axes, " +
|
f.write("\\datavisualization[scientific axes, " +
|
||||||
"visualize as smooth line,\n")
|
"visualize as smooth line,\n")
|
||||||
f.write(" x axis={ticks={none,major={at={")
|
f.write("x axis={ticks={none,major={at={")
|
||||||
f.write(", " + str(N(data[0][0],digits=4)) + " as \\(" + \
|
f.write(", " + str(N(data[0][0],digits=4)) + " as \\(" + \
|
||||||
str(data[0][0]) + "\\)")
|
str(data[0][0]) + "\\)")
|
||||||
for jump_arg, jump in data:
|
for jump_arg, jump in data:
|
||||||
@ -210,7 +183,6 @@ class TorusCable(object):
|
|||||||
def __init__(self, knot_formula, k_vector=None, q_vector=None):
|
def __init__(self, knot_formula, k_vector=None, q_vector=None):
|
||||||
|
|
||||||
self._knot_formula = knot_formula
|
self._knot_formula = knot_formula
|
||||||
|
|
||||||
# q_i = 2 * k_i + 1
|
# q_i = 2 * k_i + 1
|
||||||
if k_vector is not None:
|
if k_vector is not None:
|
||||||
self.k_vector = k_vector
|
self.k_vector = k_vector
|
||||||
@ -220,7 +192,6 @@ class TorusCable(object):
|
|||||||
msg = "Please give a list of k (k_vector) or q values (q_vector)."
|
msg = "Please give a list of k (k_vector) or q values (q_vector)."
|
||||||
raise ValueError(msg)
|
raise ValueError(msg)
|
||||||
|
|
||||||
# TBD property function
|
|
||||||
self._sigma_function = None
|
self._sigma_function = None
|
||||||
self._signature_as_function_of_theta = None
|
self._signature_as_function_of_theta = None
|
||||||
|
|
||||||
@ -239,9 +210,13 @@ class TorusCable(object):
|
|||||||
self.get_signature_as_function_of_theta()
|
self.get_signature_as_function_of_theta()
|
||||||
return self._signature_as_function_of_theta
|
return self._signature_as_function_of_theta
|
||||||
|
|
||||||
|
# KNOT ENCODING
|
||||||
@property
|
@property
|
||||||
def knot_formula(self):
|
def knot_formula(self):
|
||||||
return self._knot_formula
|
return self._knot_formula
|
||||||
|
# @knot_formula.setter
|
||||||
|
# def knot_formula(self, knot_formula):
|
||||||
|
# self._knot_formula = knot_formula
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def knot_description(self):
|
def knot_description(self):
|
||||||
@ -251,14 +226,33 @@ class TorusCable(object):
|
|||||||
def knot_sum(self):
|
def knot_sum(self):
|
||||||
return self._knot_sum
|
return self._knot_sum
|
||||||
@knot_sum.setter
|
@knot_sum.setter
|
||||||
def knot_sum(self, val):
|
def knot_sum(self, knot_sum):
|
||||||
self._knot_sum = val
|
self._knot_sum = knot_sum
|
||||||
self._knot_description = self.get_knot_descrption(val)
|
self._knot_description = self.get_knot_descrption(knot_sum)
|
||||||
self._number_of_summands = len(val)
|
self._last_k_list = [abs(i[-1]) for i in knot_sum]
|
||||||
|
self._last_q_list = [2 * i + 1 for i in self._last_k_list]
|
||||||
|
if any(n not in Primes() for n in self._last_q_list):
|
||||||
|
msg = "Incorrect q-vector. This implementation assumes that" + \
|
||||||
|
" all last q values are prime numbers.\n" + \
|
||||||
|
str(self._last_q_list)
|
||||||
|
raise ValueError(msg)
|
||||||
|
|
||||||
|
self.q_order = LCM_list(self._last_q_list)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def number_of_summands(self):
|
def last_k_list(self):
|
||||||
return self._number_of_summands
|
return self._last_k_list
|
||||||
|
|
||||||
|
@property
|
||||||
|
def last_q_list(self):
|
||||||
|
return self._last_q_list
|
||||||
|
|
||||||
|
@property
|
||||||
|
def q_order(self):
|
||||||
|
return self._q_order
|
||||||
|
@q_order.setter
|
||||||
|
def q_order(self, val):
|
||||||
|
self._q_order = val
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def k_vector(self):
|
def k_vector(self):
|
||||||
@ -266,6 +260,11 @@ class TorusCable(object):
|
|||||||
@k_vector.setter
|
@k_vector.setter
|
||||||
def k_vector(self, k):
|
def k_vector(self, k):
|
||||||
self._k_vector = k
|
self._k_vector = k
|
||||||
|
if self.extract_max(self.knot_formula) > len(k) - 1:
|
||||||
|
msg = "The vector for knot_formula evaluation is to short!"
|
||||||
|
msg += "\nk_vector " + str(k) + " \nknot_formula " \
|
||||||
|
+ str(self.knot_formula)
|
||||||
|
raise IndexError(msg)
|
||||||
self.knot_sum = eval(self.knot_formula)
|
self.knot_sum = eval(self.knot_formula)
|
||||||
self._q_vector = [2 * k_val + 1 for k_val in k]
|
self._q_vector = [2 * k_val + 1 for k_val in k]
|
||||||
|
|
||||||
@ -277,60 +276,91 @@ class TorusCable(object):
|
|||||||
self.k_vector = [(q - 1)/2 for q in new_q_vector]
|
self.k_vector = [(q - 1)/2 for q in new_q_vector]
|
||||||
|
|
||||||
|
|
||||||
|
def add_with_shift(self, other):
|
||||||
|
# print("*" * 100)
|
||||||
|
# print("BEFORE")
|
||||||
|
# print(self.knot_description)
|
||||||
|
# print(self.knot_sum)
|
||||||
|
# print("*" * 100)
|
||||||
|
# print("BEFORE k_vectors self, other")
|
||||||
|
# print(self.k_vector)
|
||||||
|
# print(other.k_vector)
|
||||||
|
|
||||||
|
shift = len(self.k_vector)
|
||||||
|
formula = re.sub(r'\d+', lambda x: str(int(x.group()) + shift),
|
||||||
|
other.knot_formula)
|
||||||
|
|
||||||
|
knot_formula = self.knot_formula[:-1] + ",\n" + formula[1:]
|
||||||
|
k_vector = self.k_vector + other.k_vector
|
||||||
|
cable = TorusCable(knot_formula, k_vector=k_vector)
|
||||||
|
s_signature_as_function_of_theta = self.signature_as_function_of_theta
|
||||||
|
o_signature_as_function_of_theta = other.signature_as_function_of_theta
|
||||||
|
|
||||||
|
shift = len(self.knot_sum)
|
||||||
|
shift = len(self.knot_sum)
|
||||||
|
def signature_as_function_of_theta(*thetas, **kwargs):
|
||||||
|
result = s_signature_as_function_of_theta(*thetas[shift:]) + \
|
||||||
|
o_signature_as_function_of_theta(*thetas[0:shift])
|
||||||
|
return result
|
||||||
|
cable._signature_as_function_of_theta = signature_as_function_of_theta
|
||||||
|
# print("*" * 100)
|
||||||
|
# print("AFTER")
|
||||||
|
# print(self.knot_description)
|
||||||
|
# print(self.knot_formula)
|
||||||
|
# print(self.knot_sum)
|
||||||
|
# print("*" * 100)
|
||||||
|
# print("AFTER k_vector, q_vector")
|
||||||
|
# print(self.k_vector)
|
||||||
|
# print(self.q_vector)
|
||||||
|
return cable
|
||||||
|
|
||||||
|
def __add__(self, other):
|
||||||
|
if self.k_vector != other.k_vector:
|
||||||
|
msg = "k_vectors are different. k-vector preserving addition is " +\
|
||||||
|
"impossible. The function add_with_shift was called instead"
|
||||||
|
warnings.warn(msg)
|
||||||
|
# print("*" * 100)
|
||||||
|
# print("BEFORE")
|
||||||
|
# print(self.knot_description)
|
||||||
|
# print(self.knot_sum)
|
||||||
|
# print("*" * 100)
|
||||||
|
# print("BEFORE k_vectors self, other")
|
||||||
|
|
||||||
|
knot_formula = self.knot_formula[:-1] + ",\n" + other.knot_formula[1:]
|
||||||
|
cable = TorusCable(knot_formula, k_vector=self.k_vector)
|
||||||
|
s_signature_as_function_of_theta = self.signature_as_function_of_theta
|
||||||
|
o_signature_as_function_of_theta = other.signature_as_function_of_theta
|
||||||
|
# print("FUNCTIONS ")
|
||||||
|
# print(s_signature_as_function_of_theta([1,1,1,2]))
|
||||||
|
# print(o_signature_as_function_of_theta([1,1,1,2]))
|
||||||
|
# print("FUNCTIONS 1111")
|
||||||
|
# print(s_signature_as_function_of_theta([1,1,1,1]))
|
||||||
|
# print(o_signature_as_function_of_theta([1,1,1,1]))
|
||||||
|
|
||||||
|
shift = len(self.knot_sum)
|
||||||
|
def signature_as_function_of_theta(*thetas, **kwargs):
|
||||||
|
result = s_signature_as_function_of_theta(*thetas[shift:]) + \
|
||||||
|
o_signature_as_function_of_theta(*thetas[0:shift])
|
||||||
|
return result
|
||||||
|
cable._signature_as_function_of_theta = signature_as_function_of_theta
|
||||||
|
# print("*" * 100)
|
||||||
|
# print("AFTER")
|
||||||
|
# print(self.knot_description)
|
||||||
|
# print(self.knot_formula)
|
||||||
|
# print(self.knot_sum)
|
||||||
|
# print("*" * 100)
|
||||||
|
# print("AFTER k_vector, q_vector")
|
||||||
|
# print(self.k_vector)
|
||||||
|
# print(self.q_vector)
|
||||||
|
return cable
|
||||||
|
|
||||||
|
|
||||||
def update(self, other):
|
|
||||||
# TBD knot_formula etc.
|
|
||||||
print("*" * 100)
|
|
||||||
print("BEFORE")
|
|
||||||
print(self.knot_description)
|
|
||||||
print(self.knot_formula)
|
|
||||||
print(self.knot_sum)
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
self._knot_formula = self.knot_formula[:-1] + ",\n" + \
|
def extract_max(string):
|
||||||
other.knot_formula[1:]
|
numbers = re.findall(r'\d+', string)
|
||||||
self.knot_sum += other.knot_sum
|
numbers = map(int, numbers)
|
||||||
# self.signature_as_function_of_theta = \
|
return max(numbers)
|
||||||
# self.get_signature_as_function_of_theta() + \
|
|
||||||
# other.get_signature_as_function_of_theta()
|
|
||||||
print("*" * 100)
|
|
||||||
print("AFTER")
|
|
||||||
print(self.knot_description)
|
|
||||||
print(self.knot_formula)
|
|
||||||
print(self.knot_sum)
|
|
||||||
|
|
||||||
|
|
||||||
def get_sigma_function(self):
|
|
||||||
k_1, k_2, k_3, k_4 = [abs(k) for k in self.k_vector]
|
|
||||||
last_q = 2 * k_4 + 1
|
|
||||||
ksi = 1/last_q
|
|
||||||
sigma_q_1 = self.get_untwisted_signature_function(k_1)
|
|
||||||
sigma_q_2 = self.get_untwisted_signature_function(k_2)
|
|
||||||
sigma_q_3 = self.get_untwisted_signature_function(k_3)
|
|
||||||
|
|
||||||
def sigma_function(theta_vector, print_results=False):
|
|
||||||
# "untwisted" part (Levine-Tristram signatures)
|
|
||||||
a_1, a_2, a_3, a_4 = theta_vector
|
|
||||||
untwisted_part = 2 * (sigma_q_2(ksi * a_1) -
|
|
||||||
sigma_q_2(ksi * a_2) +
|
|
||||||
sigma_q_3(ksi * a_3) -
|
|
||||||
sigma_q_3(ksi * a_4) +
|
|
||||||
sigma_q_1(ksi * a_1 * 2) -
|
|
||||||
sigma_q_1(ksi * a_4 * 2))
|
|
||||||
# "twisted" part
|
|
||||||
tp = [0, 0, 0, 0]
|
|
||||||
for i, a in enumerate(theta_vector):
|
|
||||||
if a:
|
|
||||||
tp[i] = -last_q + 2 * a - 2 * (a^2/last_q)
|
|
||||||
twisted_part = tp[0] - tp[1] + tp[2] - tp[3]
|
|
||||||
# if print_results:
|
|
||||||
# self.print_results_LT(theta_vector, untwisted_part)
|
|
||||||
# self.print_results_LT(theta_vector, twisted_part)
|
|
||||||
|
|
||||||
sigma_v = untwisted_part + twisted_part
|
|
||||||
return sigma_v
|
|
||||||
return sigma_function
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_blanchfield_for_pattern(k_n, theta):
|
def get_blanchfield_for_pattern(k_n, theta):
|
||||||
@ -394,10 +424,10 @@ class TorusCable(object):
|
|||||||
# return the signature function of the T_{2,2k+1} torus knot
|
# return the signature function of the T_{2,2k+1} torus knot
|
||||||
k = abs(j)
|
k = abs(j)
|
||||||
q = 2 * k + 1
|
q = 2 * k + 1
|
||||||
w = ([((2 * a + 1)/(2 * q), -1 * sgn(j)) for a in range(k)] +
|
values = ([((2 * a + 1)/(2 * q), -1 * sgn(j)) for a in range(k)] +
|
||||||
[((2 * a + 1)/(2 * q), 1 * sgn(j))
|
[((2 * a + 1)/(2 * q), 1 * sgn(j))
|
||||||
for a in range(k + 1, 2 * k + 1)])
|
for a in range(k + 1, 2 * k + 1)])
|
||||||
return SignatureFunction(values=w)
|
return SignatureFunction(values=values)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_knot_descrption(knot_sum):
|
def get_knot_descrption(knot_sum):
|
||||||
@ -426,19 +456,21 @@ class TorusCable(object):
|
|||||||
# call with no arguments
|
# call with no arguments
|
||||||
if len_t == 0:
|
if len_t == 0:
|
||||||
return signature_as_function_of_theta(*(len_a * [0]))
|
return signature_as_function_of_theta(*(len_a * [0]))
|
||||||
|
|
||||||
if len_t != len_a:
|
if len_t != len_a:
|
||||||
if isinstance(thetas, Iterable) and len(thetas[0]) == len_a:
|
if isinstance(thetas, Iterable):
|
||||||
|
if len(thetas[0]) == len_a:
|
||||||
thetas = thetas[0]
|
thetas = thetas[0]
|
||||||
else:
|
else:
|
||||||
msg = "This function takes exactly " + str(len_a) + \
|
msg = "This function takes exactly " + str(len_a) + \
|
||||||
" arguments or no argument at all (" + str(len_t) + \
|
" arguments or no argument at all (" + str(len_t) + \
|
||||||
" given)."
|
" given)."
|
||||||
raise TypeError(msg)
|
raise TypeError(msg)
|
||||||
|
|
||||||
sf = SignatureFunction()
|
sf = SignatureFunction()
|
||||||
untwisted_part = SignatureFunction()
|
untwisted_part = SignatureFunction()
|
||||||
# for each cable knot in cable sum apply theta
|
# for each cable knot in cable sum apply theta
|
||||||
|
|
||||||
|
# print(self.knot_sum)
|
||||||
|
|
||||||
for i, knot in enumerate(self.knot_sum):
|
for i, knot in enumerate(self.knot_sum):
|
||||||
try:
|
try:
|
||||||
ssf = self.get_summand_signature_as_theta_function(*knot)
|
ssf = self.get_summand_signature_as_theta_function(*knot)
|
||||||
@ -451,15 +483,16 @@ class TorusCable(object):
|
|||||||
print("ValueError: " + str(e.args[0]) +\
|
print("ValueError: " + str(e.args[0]) +\
|
||||||
" Please change " + str(i + 1) + ". parameter.")
|
" Please change " + str(i + 1) + ". parameter.")
|
||||||
return None
|
return None
|
||||||
a = thetas[0]
|
# a = thetas[0]
|
||||||
if all(i == a or i == self.q_vector[-1] - a for i in thetas):
|
# # last_q = abs (2 * self.knot_sum[-1][-1]) + 1
|
||||||
print()
|
# if all(i == thetas[0] for i in thetas):
|
||||||
print("\n" + "*" * 100)
|
# print()
|
||||||
print(self.knot_description)
|
# print("\n" + "*" * 100)
|
||||||
print("one vector " + str(thetas))
|
# print(self.knot_description)
|
||||||
print("max sf " + str(sf.is_big()))
|
# print("one vector " + str(thetas))
|
||||||
print()
|
# print("max sf " + str(sf.extremum()))
|
||||||
# assert untwisted_part.is_zero_everywhere()
|
# print()
|
||||||
|
# # assert untwisted_part.is_zero_everywhere()
|
||||||
|
|
||||||
if verbose:
|
if verbose:
|
||||||
print()
|
print()
|
||||||
@ -478,6 +511,7 @@ class TorusCable(object):
|
|||||||
def get_summand_signature_as_theta_function(self, *knot_as_k_values):
|
def get_summand_signature_as_theta_function(self, *knot_as_k_values):
|
||||||
def get_summand_signture_function(theta):
|
def get_summand_signture_function(theta):
|
||||||
# TBD: another formula (for t^2) description
|
# TBD: another formula (for t^2) description
|
||||||
|
# TBD if theata condition
|
||||||
k_n = knot_as_k_values[-1]
|
k_n = knot_as_k_values[-1]
|
||||||
if theta > 2 * abs(k_n):
|
if theta > 2 * abs(k_n):
|
||||||
msg = "k for the pattern in the cable is " + str(k_n) + \
|
msg = "k for the pattern in the cable is " + str(k_n) + \
|
||||||
@ -491,6 +525,7 @@ class TorusCable(object):
|
|||||||
# untwisted part
|
# untwisted part
|
||||||
# for each knot summand consider k values in reversed order
|
# for each knot summand consider k values in reversed order
|
||||||
# ommit last k = k_n value
|
# ommit last k = k_n value
|
||||||
|
|
||||||
ksi = 1/(2 * abs(k_n) + 1)
|
ksi = 1/(2 * abs(k_n) + 1)
|
||||||
for i, k in enumerate(knot_as_k_values[:-1][::-1]):
|
for i, k in enumerate(knot_as_k_values[:-1][::-1]):
|
||||||
power = 2^i
|
power = 2^i
|
||||||
@ -576,6 +611,41 @@ class TorusCable(object):
|
|||||||
bad_vectors.append(vector)
|
bad_vectors.append(vector)
|
||||||
return good_vectors, bad_vectors
|
return good_vectors, bad_vectors
|
||||||
|
|
||||||
|
|
||||||
|
def is_metaboliser(self, theta):
|
||||||
|
i = 1
|
||||||
|
sum = 0
|
||||||
|
for idx, el in enumerate(theta):
|
||||||
|
to_add = i * el^2
|
||||||
|
# print("i * el^2 " + str(i * el^2))
|
||||||
|
to_add /= self.last_q_list[idx]
|
||||||
|
sum += to_add
|
||||||
|
# print("i * el^2 % q_4: " + str(to_add))
|
||||||
|
# print("sum ", sum)
|
||||||
|
i *= -1
|
||||||
|
# if sum is integer
|
||||||
|
# continue
|
||||||
|
# if all(a in [1, last_q - 1] for a in vector):
|
||||||
|
# pass
|
||||||
|
# else:
|
||||||
|
# continue
|
||||||
|
# print(theta, end=" ")
|
||||||
|
# print(sum)
|
||||||
|
if sum.is_integer():
|
||||||
|
print("#" * 100)
|
||||||
|
print(theta)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
# if self.is_value_for_vector_class_big(vector, sigma_or_sign):
|
||||||
|
# good_vectors.append(vector)
|
||||||
|
# else:
|
||||||
|
# # print(vector)
|
||||||
|
# bad_vectors.append(vector)
|
||||||
|
# return good_vectors, bad_vectors
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# searching for signature == 0
|
# searching for signature == 0
|
||||||
def eval_cable_for_null_signature(self, print_results=False, verbose=False):
|
def eval_cable_for_null_signature(self, print_results=False, verbose=False):
|
||||||
# search for zero combinations
|
# search for zero combinations
|
||||||
@ -600,8 +670,8 @@ class TorusCable(object):
|
|||||||
# for all v = s * [a_1, a_2, a_3, a_4] for s in [1, last_q - 1]
|
# for all v = s * [a_1, a_2, a_3, a_4] for s in [1, last_q - 1]
|
||||||
def is_value_for_vector_class_big(self, theta_vector, sigma_or_sign):
|
def is_value_for_vector_class_big(self, theta_vector, sigma_or_sign):
|
||||||
[a_1, a_2, a_3, a_4] = theta_vector
|
[a_1, a_2, a_3, a_4] = theta_vector
|
||||||
q_4 = self.q_vector[-1]
|
k_4 = self.knot_sum[-1][-1]
|
||||||
k_4 = self.k_vector[-1]
|
q_4 = 2 * k_4 + 1
|
||||||
|
|
||||||
max_sigma = 0
|
max_sigma = 0
|
||||||
|
|
||||||
@ -616,7 +686,7 @@ class TorusCable(object):
|
|||||||
[a_1, a_2, a_3, a_4]]
|
[a_1, a_2, a_3, a_4]]
|
||||||
if sigma_or_sign == SIGNATURE:
|
if sigma_or_sign == SIGNATURE:
|
||||||
sf = f(shifted_theta)
|
sf = f(shifted_theta)
|
||||||
sig_v = sf.is_big()
|
sig_v = sf.extremum()
|
||||||
else:
|
else:
|
||||||
sig_v = f(shifted_theta)
|
sig_v = f(shifted_theta)
|
||||||
print(sig_v, end=" ")
|
print(sig_v, end=" ")
|
||||||
@ -641,8 +711,47 @@ class TorusCable(object):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# sigma function
|
# sigma function
|
||||||
|
|
||||||
|
def get_sigma_function(self):
|
||||||
|
if len(self.k_vector) != 4:
|
||||||
|
msg = "This function is not implemented for k_vectors " +\
|
||||||
|
"with len other than 4."
|
||||||
|
raise IndexError(msg)
|
||||||
|
k_1, k_2, k_3, k_4 = [abs(k) for k in self.k_vector]
|
||||||
|
last_q = 2 * k_4 + 1
|
||||||
|
ksi = 1/last_q
|
||||||
|
sigma_q_1 = self.get_untwisted_signature_function(k_1)
|
||||||
|
sigma_q_2 = self.get_untwisted_signature_function(k_2)
|
||||||
|
sigma_q_3 = self.get_untwisted_signature_function(k_3)
|
||||||
|
|
||||||
|
def sigma_function(theta_vector, print_results=False):
|
||||||
|
# "untwisted" part (Levine-Tristram signatures)
|
||||||
|
a_1, a_2, a_3, a_4 = theta_vector
|
||||||
|
untwisted_part = 2 * (sigma_q_2(ksi * a_1) -
|
||||||
|
sigma_q_2(ksi * a_2) +
|
||||||
|
sigma_q_3(ksi * a_3) -
|
||||||
|
sigma_q_3(ksi * a_4) +
|
||||||
|
sigma_q_1(ksi * a_1 * 2) -
|
||||||
|
sigma_q_1(ksi * a_4 * 2))
|
||||||
|
# "twisted" part
|
||||||
|
tp = [0, 0, 0, 0]
|
||||||
|
for i, a in enumerate(theta_vector):
|
||||||
|
if a:
|
||||||
|
tp[i] = -last_q + 2 * a - 2 * (a^2/last_q)
|
||||||
|
twisted_part = tp[0] - tp[1] + tp[2] - tp[3]
|
||||||
|
# if print_results:
|
||||||
|
# self.print_results_LT(theta_vector, untwisted_part)
|
||||||
|
# self.print_results_LT(theta_vector, twisted_part)
|
||||||
|
|
||||||
|
sigma_v = untwisted_part + twisted_part
|
||||||
|
return sigma_v
|
||||||
|
return sigma_function
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def print_results_LT(self, theta_vector, untwisted_part):
|
def print_results_LT(self, theta_vector, untwisted_part):
|
||||||
knot_description = self.knot_description
|
knot_description = self.knot_description
|
||||||
k_1, k_2, k_3, k_4 = [abs(k) for k in self.k_vector]
|
k_1, k_2, k_3, k_4 = [abs(k) for k in self.k_vector]
|
||||||
|
221
main.sage
Normal file
221
main.sage
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
attach("cable_signature.sage")
|
||||||
|
attach("my_signature.sage")
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
global cable, cab_2, cab_1, joined_formula
|
||||||
|
# self.knot_formula = "[[k[0], k[1], k[3]], " + \
|
||||||
|
# "[-k[1], -k[3]], " + \
|
||||||
|
# "[k[2], k[3]], " + \
|
||||||
|
# "[-k[0], -k[2], -k[3]]]"
|
||||||
|
|
||||||
|
# knot_formula = config.knot_formula
|
||||||
|
# q_vector = (3, 5, 7, 13)
|
||||||
|
# cab_to_update = TorusCable(knot_formula=knot_formula, q_vector=q_vector)
|
||||||
|
# q_vector = (3, 5, 7, 11)
|
||||||
|
# cab_to_add = TorusCable(knot_formula=knot_formula, q_vector=q_vector)
|
||||||
|
# cab_shifted = cab_to_update.add_with_shift(cab_to_add)
|
||||||
|
|
||||||
|
q_vector = (5, 13, 19, 41,\
|
||||||
|
5, 17, 23, 43)
|
||||||
|
|
||||||
|
knot_formula = "[[k[0], k[5], k[3]], " + \
|
||||||
|
"[-k[1], -k[3]], " + \
|
||||||
|
"[k[2], k[3]], " + \
|
||||||
|
"[-k[0], -k[2], -k[3]]]"
|
||||||
|
cab_1 = TorusCable(knot_formula=knot_formula, q_vector=q_vector)
|
||||||
|
knot_formula = "[[k[4], k[1], k[7]], " + \
|
||||||
|
"[-k[5], -k[7]], " + \
|
||||||
|
"[k[6], k[7]], " + \
|
||||||
|
"[-k[4], -k[6], -k[7]]]"
|
||||||
|
cab_2 = TorusCable(knot_formula=knot_formula, q_vector=q_vector)
|
||||||
|
cable = cab_1 + cab_2
|
||||||
|
joined_formula = cable.knot_formula
|
||||||
|
|
||||||
|
def check_all_thetas(cable):
|
||||||
|
upper_bounds = cable.last_k_list[:4]
|
||||||
|
# upper_bounds += [0, 0, 0, 0]
|
||||||
|
ranges_list = [range(1, i + 1) for i in upper_bounds]
|
||||||
|
ranges_list += [range(0, 1) for _ in range(4)]
|
||||||
|
|
||||||
|
|
||||||
|
print(ranges_list)
|
||||||
|
for theta in it.product(*ranges_list):
|
||||||
|
# pass
|
||||||
|
if cable.is_metaboliser(theta):
|
||||||
|
print("\n" * 10)
|
||||||
|
print("!" * 100)
|
||||||
|
for shift in range(1, cable.q_order):
|
||||||
|
shifted_theta = [(shift * th) % cable.last_q_list[i]
|
||||||
|
for i, th in enumerate(theta)]
|
||||||
|
shifted_theta = [min(th, cable.last_q_list[i] - th)
|
||||||
|
for i, th in enumerate(shifted_theta)]
|
||||||
|
print(shifted_theta)
|
||||||
|
sf = cable.signature_as_function_of_theta(*shifted_theta)
|
||||||
|
extremum = abs(sf.extremum())
|
||||||
|
print(extremum)
|
||||||
|
if extremum > 5 + np.count_nonzero(shifted_theta):
|
||||||
|
print("ok")
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print("hliphlip")
|
||||||
|
print("!" * 100)
|
||||||
|
print("\n" * 10)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def get_q_vector(q_vector_size, lowest_number=1):
|
||||||
|
q = [lowest_number] * q_vector_size
|
||||||
|
P = Primes()
|
||||||
|
next_number = P.next(lowest_number)
|
||||||
|
for i in range(q_vector_size):
|
||||||
|
q[i] = next_number
|
||||||
|
next_number = P.next(4 * next_number)
|
||||||
|
|
||||||
|
return q
|
||||||
|
|
||||||
|
|
||||||
|
next_number = P.next(lowest_number)
|
||||||
|
for i, q in enumerate(q_vector):
|
||||||
|
q[i] = next_number
|
||||||
|
next_number = P.next(lowest_number)
|
||||||
|
|
||||||
|
q = [P.unrank(i + config.start_shift) for i in c]
|
||||||
|
ratio = q[3] > 4 * q[2] and q[2] > 4 * q[1] and q[1] > 4 * q[0]
|
||||||
|
if not ratio:
|
||||||
|
# print("Ratio-condition does not hold")
|
||||||
|
continue
|
||||||
|
print("q = ", q)
|
||||||
|
# cable = TorusCable(knot_formula=knot_formula, q_vector=q)
|
||||||
|
# list_of_ranges = config.get_list_of_ranges(cable.q_order)
|
||||||
|
# if cable.eval_cable_for_large_values(list_of_ranges, SIGMA,
|
||||||
|
# verbose=verbose,
|
||||||
|
# print_results=print_results):
|
||||||
|
# good_knots.append(cable.knot_description)
|
||||||
|
# return good_knots
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# cab_to_update.update(cab_to_add)
|
||||||
|
# cab_to_update.update(cab_to_add)
|
||||||
|
# cab_to_update.update(cab_to_add)
|
||||||
|
# cab_to_update.update(cab_to_add)
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# def get_blanchfield_for_pattern(k_n, theta):
|
||||||
|
# if theta == 0:
|
||||||
|
# sf = TorusCable.get_untwisted_signature_function(k_n)
|
||||||
|
# return sf.square_root() + sf.minus_square_root()
|
||||||
|
#
|
||||||
|
# results = []
|
||||||
|
# k = abs(k_n)
|
||||||
|
# ksi = 1/(2 * k + 1)
|
||||||
|
#
|
||||||
|
# # print("lambda_odd, i.e. (theta + e) % 2 != 0")
|
||||||
|
# for e in range(1, k + 1):
|
||||||
|
# if (theta + e) % 2 != 0:
|
||||||
|
# results.append((e * ksi, 1 * sgn(k_n)))
|
||||||
|
# results.append((1 - e * ksi, -1 * sgn(k_n)))
|
||||||
|
# # print("\nlambda_even")
|
||||||
|
# # print("\nnormal")
|
||||||
|
# results_odd = results
|
||||||
|
# results = []
|
||||||
|
# for e in range(1, theta):
|
||||||
|
# if (theta + e) % 2 == 0:
|
||||||
|
# results.append((e * ksi, 1 * sgn(k_n)))
|
||||||
|
# results.append((1 - e * ksi, -1 * sgn(k_n)))
|
||||||
|
# # print(results)
|
||||||
|
# results_even_small = results
|
||||||
|
# results = []
|
||||||
|
# # print("reversed")
|
||||||
|
# for e in range(theta + 1, k + 1):
|
||||||
|
# if (theta + e) % 2 == 0:
|
||||||
|
# results.append((e * ksi, -1 * sgn(k_n)))
|
||||||
|
# results.append((1 - e * ksi, 1 * sgn(k_n)))
|
||||||
|
# # print(results)
|
||||||
|
# results_even_big = results
|
||||||
|
#
|
||||||
|
# return results_odd, results_even_small, results_even_big
|
||||||
|
# # return SignatureFunction(values=results)
|
||||||
|
#
|
||||||
|
# def main():
|
||||||
|
# prim = 3
|
||||||
|
# P = Primes()
|
||||||
|
# for it in range(20):
|
||||||
|
# prim = P.next(prim)
|
||||||
|
# k_j = (prim - 1)/2
|
||||||
|
# print(60 * "*")
|
||||||
|
# print("k is " + str(k_j))
|
||||||
|
# print(60 * "*")
|
||||||
|
#
|
||||||
|
# for i in range(1, k_j + 1):
|
||||||
|
#
|
||||||
|
# a, j, m = get_blanchfield_for_pattern(k_j, i)
|
||||||
|
# sf_j = SignatureFunction(j)
|
||||||
|
# sf_a = SignatureFunction(a)
|
||||||
|
# sf_m = SignatureFunction(m)
|
||||||
|
# sf_jam = sf_j + sf_a + sf_m
|
||||||
|
# assert TorusCable.get_blanchfield_for_pattern(k_j, i) == sf_jam
|
||||||
|
# af, jf, mf = get_blanchfield_for_pattern(-k_j, prim - i)
|
||||||
|
# print(60 * "*")
|
||||||
|
# print("lists")
|
||||||
|
# print(af)
|
||||||
|
# print(jf)
|
||||||
|
# print(mf)
|
||||||
|
# j = SignatureFunction(jf)
|
||||||
|
# a = SignatureFunction(af)
|
||||||
|
# m = SignatureFunction(mf)
|
||||||
|
# minus_jam = j + a + m
|
||||||
|
# values = cmp_blanchfield_for_pattern(-k_j, prim - i)
|
||||||
|
# print("sum of lists - 3 lists added")
|
||||||
|
# print(sorted(jf + af + mf))
|
||||||
|
#
|
||||||
|
# print("sum of lists - all values from Blanchfield")
|
||||||
|
# print(sorted(values))
|
||||||
|
#
|
||||||
|
# assert values == af + jf + mf
|
||||||
|
# print("not equeles - sf from all values")
|
||||||
|
#
|
||||||
|
# print(SignatureFunction(values))
|
||||||
|
# print("not equeles - sum of sf")
|
||||||
|
# print("sf for each list sep")
|
||||||
|
# print("jf")
|
||||||
|
# print(jf)
|
||||||
|
# print("af")
|
||||||
|
# print(af)
|
||||||
|
# print("mf")
|
||||||
|
# print(mf)
|
||||||
|
# print("sum of abouve sfs")
|
||||||
|
# print(minus_jam)
|
||||||
|
# assert TorusCable.get_blanchfield_for_pattern(-k_j, prim - i) == \
|
||||||
|
# SignatureFunction(values)
|
||||||
|
# assert TorusCable.get_blanchfield_for_pattern(-k_j, prim - i) == \
|
||||||
|
# minus_jam
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# # a, j, m = get_blanchfield_for_pattern(k_j, 2 * k_j + 1 - i)
|
||||||
|
# # j = SignatureFunction(j)
|
||||||
|
# # a = SignatureFunction(a)
|
||||||
|
# # m = SignatureFunction(m)
|
||||||
|
#
|
||||||
|
# print("*" * 100)
|
||||||
|
# print("i is " + str(i) + ", q is " + str(2 * k_j + 1), " q - i is " + str(2 * k_j + 1 - i))
|
||||||
|
# print("*" * 100)
|
||||||
|
#
|
||||||
|
# ajm = sf_j + sf_a + sf_m
|
||||||
|
# ajm_minus = a + j + m
|
||||||
|
# print("4 times")
|
||||||
|
# print(ajm + ajm + ajm_minus + ajm_minus)
|
||||||
|
# print("is big")
|
||||||
|
# print((ajm + ajm + ajm_minus + ajm_minus).is_big())
|
||||||
|
# print()
|
@ -141,7 +141,7 @@ def search_for_large_sigma_value(knot_formula=None, limit=None,
|
|||||||
print("Ratio-condition does not hold")
|
print("Ratio-condition does not hold")
|
||||||
continue
|
continue
|
||||||
cable = TorusCable(knot_formula=knot_formula, q_vector=q)
|
cable = TorusCable(knot_formula=knot_formula, q_vector=q)
|
||||||
list_of_ranges = config.get_list_of_ranges(cable.q_vector[-1])
|
list_of_ranges = config.get_list_of_ranges(cable.q_order)
|
||||||
if cable.eval_cable_for_large_values(list_of_ranges, SIGMA,
|
if cable.eval_cable_for_large_values(list_of_ranges, SIGMA,
|
||||||
verbose=verbose,
|
verbose=verbose,
|
||||||
print_results=print_results):
|
print_results=print_results):
|
||||||
|
Loading…
Reference in New Issue
Block a user