end of implementation for large gignature
This commit is contained in:
parent
1ec26c1b55
commit
ac1a1d3475
@ -27,6 +27,17 @@ class TorusCable(object):
|
|||||||
self.__sigma_function = None
|
self.__sigma_function = None
|
||||||
self.__signature_as_function_of_theta = None
|
self.__signature_as_function_of_theta = None
|
||||||
|
|
||||||
|
|
||||||
|
def get_untwisted_signature_function(self, j, q=None):
|
||||||
|
# return the signature function of the T_{2,2k+1} torus knot
|
||||||
|
k = abs(j)
|
||||||
|
q = 2 * k + 1
|
||||||
|
w = ([((2 * a + 1)/(2 * q), -1 * sgn(j)) for a in range(k)] +
|
||||||
|
[((2 * a + 1)/(2 * q), 1 * sgn(j))
|
||||||
|
for a in range(k + 1, 2 * k + 1)])
|
||||||
|
return SignatureFunction(values=w)
|
||||||
|
|
||||||
|
|
||||||
def get_knot_descrption(self):
|
def get_knot_descrption(self):
|
||||||
description = ""
|
description = ""
|
||||||
for knot in self.knot_sum:
|
for knot in self.knot_sum:
|
||||||
@ -63,17 +74,20 @@ class TorusCable(object):
|
|||||||
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:
|
||||||
msg = "This function takes exactly " + str(len_a) + \
|
if len(thetas[0]) == len_a:
|
||||||
" arguments or no argument at all (" + str(len_t) + \
|
thetas = thetas[0]
|
||||||
" given)."
|
else:
|
||||||
raise TypeError(msg)
|
msg = "This function takes exactly " + str(len_a) + \
|
||||||
|
" arguments or no argument at all (" + str(len_t) + \
|
||||||
|
" given)."
|
||||||
|
raise TypeError(msg)
|
||||||
|
|
||||||
sf = SignatureFunction()
|
sf = SignatureFunction()
|
||||||
|
|
||||||
# for each cable knot in cable sum apply theta
|
# for each cable knot in cable sum apply theta
|
||||||
for i, knot in enumerate(self.knot_sum):
|
for i, knot in enumerate(self.knot_sum):
|
||||||
try:
|
try:
|
||||||
ssf = get_signature_summand_as_theta_function(*knot)
|
ssf = get_summand_signature_as_theta_function(*knot)
|
||||||
sf += ssf(thetas[i])
|
sf += ssf(thetas[i])
|
||||||
# in case wrong theata value was given
|
# in case wrong theata value was given
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
@ -102,6 +116,94 @@ class TorusCable(object):
|
|||||||
number_of_null_comb += 2^m
|
number_of_null_comb += 2^m
|
||||||
return number_of_null_comb, list_of_good_vectors
|
return number_of_null_comb, list_of_good_vectors
|
||||||
|
|
||||||
|
|
||||||
|
def eval_cable_for_large_signature(self, list_of_ranges,
|
||||||
|
print_results=False,
|
||||||
|
verbose=False):
|
||||||
|
if self.__signature_as_function_of_theta is None:
|
||||||
|
self.__signature_as_function_of_theta= \
|
||||||
|
self.__get_signature_as_function_of_theta()
|
||||||
|
if print_results:
|
||||||
|
print()
|
||||||
|
print(self.knot_description, end="\t\t\t")
|
||||||
|
print()
|
||||||
|
f = self.__signature_as_function_of_theta
|
||||||
|
if self.s__check_all_combinations_in_ranges(list_of_ranges,
|
||||||
|
print_results=print_results):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def s__check_all_combinations_in_ranges(self, list_of_ranges,
|
||||||
|
print_results=False):
|
||||||
|
all_combinations_pass = True
|
||||||
|
all_bad_vectors = []
|
||||||
|
number_of_all_good_v = 0
|
||||||
|
for i, range_product in enumerate(list_of_ranges):
|
||||||
|
good_v, bad_v = self.s__check_combinations_in_range(range_product)
|
||||||
|
number_of_all_good_v += len(good_v)
|
||||||
|
all_bad_vectors = list(it.chain(all_bad_vectors, bad_v))
|
||||||
|
if bad_v:
|
||||||
|
all_combinations_pass = False
|
||||||
|
# if print_results:
|
||||||
|
# print("good : bad:\t " + str(len(good_v)) +\
|
||||||
|
# " : " + str(len(bad_v)))
|
||||||
|
# if i in [0, 4,]:
|
||||||
|
# print()
|
||||||
|
# if bad_v:
|
||||||
|
# print(bad_v)
|
||||||
|
|
||||||
|
if print_results:
|
||||||
|
print("good : bad:\t " + str(number_of_all_good_v) +\
|
||||||
|
" : " + str(len(all_bad_vectors)))
|
||||||
|
return all_combinations_pass
|
||||||
|
|
||||||
|
def s__check_combinations_in_range(self, range_product):
|
||||||
|
large_sigma_for_all_combinations = True
|
||||||
|
bad_vectors = []
|
||||||
|
good_vectors = []
|
||||||
|
q_4 = self.q_vector[-1]
|
||||||
|
for vector in range_product:
|
||||||
|
a_1, a_2, a_3, a_4 = vector
|
||||||
|
if (a_1^2 - a_2^2 + a_3^2 - a_4^2) % q_4:
|
||||||
|
continue
|
||||||
|
if all(a in [1, q_4 - 1] for a in vector):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
if self.s__is_sigma_for_vector_class_big(vector):
|
||||||
|
good_vectors.append(vector)
|
||||||
|
else:
|
||||||
|
# print(vector)
|
||||||
|
bad_vectors.append(vector)
|
||||||
|
return good_vectors, bad_vectors
|
||||||
|
|
||||||
|
def s__is_sigma_for_vector_class_big(self, theta_vector):
|
||||||
|
[a_1, a_2, a_3, a_4] = theta_vector
|
||||||
|
q_4 = self.q_vector[-1]
|
||||||
|
k_4 = self.k_vector[-1]
|
||||||
|
max_sigma = 0
|
||||||
|
|
||||||
|
print(theta_vector, end="\t")
|
||||||
|
|
||||||
|
for shift in range(1, k_4 + 1):
|
||||||
|
shifted_theta = [(shift * a) % q_4 for a in
|
||||||
|
[a_1, a_2, a_3, a_4]]
|
||||||
|
sf = self.__signature_as_function_of_theta(shifted_theta)
|
||||||
|
sigma_v = sf.is_big()
|
||||||
|
print(sigma_v, end=" ")
|
||||||
|
if abs(sigma_v) > abs(max_sigma):
|
||||||
|
max_sigma = sigma_v
|
||||||
|
if abs(sigma_v) > 5 + np.count_nonzero(shifted_theta):
|
||||||
|
print("\tok " + str(sigma_v))
|
||||||
|
return True
|
||||||
|
print("\tbad class " + str(max_sigma))
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 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
|
||||||
@ -114,9 +216,10 @@ class TorusCable(object):
|
|||||||
print(self.knot_description)
|
print(self.knot_description)
|
||||||
print("Zero cases: " + str(number_of_null_comb))
|
print("Zero cases: " + str(number_of_null_comb))
|
||||||
print("All cases: " + str(number_of_all_comb))
|
print("All cases: " + str(number_of_all_comb))
|
||||||
print("Zero theta combinations: ")
|
if list_of_good_vectors:
|
||||||
for el in list_of_good_vectors:
|
print("Zero theta combinations: ")
|
||||||
print(el)
|
for el in list_of_good_vectors:
|
||||||
|
print(el)
|
||||||
if number_of_null_comb^2 >= number_of_all_comb:
|
if number_of_null_comb^2 >= number_of_all_comb:
|
||||||
return number_of_null_comb, number_of_all_comb
|
return number_of_null_comb, number_of_all_comb
|
||||||
return None
|
return None
|
||||||
@ -124,8 +227,9 @@ class TorusCable(object):
|
|||||||
# check sigma for all v = s * [a_1, a_2, a_3, a_4] for s in [1, q_4 - 1]
|
# check sigma for all v = s * [a_1, a_2, a_3, a_4] for s in [1, q_4 - 1]
|
||||||
def __is_sigma_for_vector_class_big(self, theta_vector):
|
def __is_sigma_for_vector_class_big(self, theta_vector):
|
||||||
[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[3]
|
q_4 = self.q_vector[-1]
|
||||||
for shift in range(1, q_4):
|
k_4 = self.k_vector[-1]
|
||||||
|
for shift in range(1, k_4 + 1):
|
||||||
shifted_theta = [(shift * a) % q_4 for a in
|
shifted_theta = [(shift * a) % q_4 for a in
|
||||||
[a_1, a_2, a_3, a_4]]
|
[a_1, a_2, a_3, a_4]]
|
||||||
sigma_v = self.__sigma_function(shifted_theta)
|
sigma_v = self.__sigma_function(shifted_theta)
|
||||||
@ -147,9 +251,6 @@ class TorusCable(object):
|
|||||||
print("\n")
|
print("\n")
|
||||||
|
|
||||||
def __tmp_get_max_sigma_for_vector_class(self, theta_vector):
|
def __tmp_get_max_sigma_for_vector_class(self, theta_vector):
|
||||||
# print("\n")
|
|
||||||
# print(self.knot_description)
|
|
||||||
# print("vector = " + str(theta_vector))
|
|
||||||
max_sigma = (theta_vector, 0)
|
max_sigma = (theta_vector, 0)
|
||||||
[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[3]
|
q_4 = self.q_vector[3]
|
||||||
@ -159,13 +260,8 @@ class TorusCable(object):
|
|||||||
sigma = self.__sigma_function(shifted_theta)
|
sigma = self.__sigma_function(shifted_theta)
|
||||||
if abs(sigma) > abs(max_sigma[1]):
|
if abs(sigma) > abs(max_sigma[1]):
|
||||||
max_sigma = (shifted_theta, sigma)
|
max_sigma = (shifted_theta, sigma)
|
||||||
assert max_sigma[1] == 0, knot_description
|
|
||||||
# print("\n" + self.knot_description + "\t" + str(max_sigma[0]) +\
|
|
||||||
# "\t" + str(max_sigma[1]))
|
|
||||||
return max_sigma[1]
|
return max_sigma[1]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def is_sigma_for_vector_class_big(self, theta_vector):
|
def is_sigma_for_vector_class_big(self, theta_vector):
|
||||||
if self.__sigma_function is None:
|
if self.__sigma_function is None:
|
||||||
self.__sigma_function = self.__get_sigma_function()
|
self.__sigma_function = self.__get_sigma_function()
|
||||||
@ -175,9 +271,9 @@ class TorusCable(object):
|
|||||||
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]
|
||||||
q_4 = 2 * k_4 + 1
|
q_4 = 2 * k_4 + 1
|
||||||
ksi = 1/q_4
|
ksi = 1/q_4
|
||||||
sigma_q_1 = get_untwisted_signature_function(k_1)
|
sigma_q_1 = self.get_untwisted_signature_function(k_1)
|
||||||
sigma_q_2 = get_untwisted_signature_function(k_2)
|
sigma_q_2 = self.get_untwisted_signature_function(k_2)
|
||||||
sigma_q_3 = get_untwisted_signature_function(k_3)
|
sigma_q_3 = self.get_untwisted_signature_function(k_3)
|
||||||
|
|
||||||
def sigma_function(theta_vector, print_results=False):
|
def sigma_function(theta_vector, print_results=False):
|
||||||
# "untwisted" part (Levine-Tristram signatures)
|
# "untwisted" part (Levine-Tristram signatures)
|
||||||
@ -208,9 +304,9 @@ class TorusCable(object):
|
|||||||
a_1, a_2, a_3, a_4 = theta_vector
|
a_1, a_2, a_3, a_4 = theta_vector
|
||||||
q_4 = 2 * k_4 + 1
|
q_4 = 2 * k_4 + 1
|
||||||
ksi = 1/q_4
|
ksi = 1/q_4
|
||||||
sigma_q_1 = get_untwisted_signature_function(k_1)
|
sigma_q_1 = self.get_untwisted_signature_function(k_1)
|
||||||
sigma_q_2 = get_untwisted_signature_function(k_2)
|
sigma_q_2 = self.get_untwisted_signature_function(k_2)
|
||||||
sigma_q_3 = get_untwisted_signature_function(k_3)
|
sigma_q_3 = self.get_untwisted_signature_function(k_3)
|
||||||
print("\n\nLevine-Tristram signatures for the cable sum: ")
|
print("\n\nLevine-Tristram signatures for the cable sum: ")
|
||||||
print(knot_description)
|
print(knot_description)
|
||||||
print("and characters:\n" + str(theta_vector) + ",")
|
print("and characters:\n" + str(theta_vector) + ",")
|
||||||
@ -335,10 +431,8 @@ class TorusCable(object):
|
|||||||
self.__sigma_function = self.__get_sigma_function()
|
self.__sigma_function = self.__get_sigma_function()
|
||||||
return self.__sigma_function(theta_vector)
|
return self.__sigma_function(theta_vector)
|
||||||
|
|
||||||
|
|
||||||
# searching for sigma > 5 + #(v_i != 0)
|
# searching for sigma > 5 + #(v_i != 0)
|
||||||
def __check_combinations_in_range(self, range_product):
|
def __check_combinations_in_range(self, range_product):
|
||||||
large_sigma_for_all_combinations = True
|
|
||||||
bad_vectors = []
|
bad_vectors = []
|
||||||
good_vectors = []
|
good_vectors = []
|
||||||
q_4 = self.q_vector[-1]
|
q_4 = self.q_vector[-1]
|
||||||
@ -346,19 +440,12 @@ class TorusCable(object):
|
|||||||
a_1, a_2, a_3, a_4 = vector
|
a_1, a_2, a_3, a_4 = vector
|
||||||
if (a_1^2 - a_2^2 + a_3^2 - a_4^2) % q_4:
|
if (a_1^2 - a_2^2 + a_3^2 - a_4^2) % q_4:
|
||||||
continue
|
continue
|
||||||
if all(a in [1, q_4 - 1] for a in vector):
|
# if all(a in [1, q_4 - 1] for a in vector):
|
||||||
continue
|
# continue
|
||||||
if self.__is_sigma_for_vector_class_big(vector):
|
if self.__is_sigma_for_vector_class_big(vector):
|
||||||
good_vectors.append(vector)
|
good_vectors.append(vector)
|
||||||
# pass
|
|
||||||
else:
|
else:
|
||||||
bad_vectors.append(vector)
|
bad_vectors.append(vector)
|
||||||
# large_sigma_for_all_combinations = False
|
|
||||||
# if len(bad_vectors) > 8:
|
|
||||||
# break
|
|
||||||
print(len(bad_vectors))
|
|
||||||
if a_1 and a_2 and a_3 and a_4:
|
|
||||||
assert len(bad_vectors) % 8 == 0
|
|
||||||
return good_vectors, bad_vectors
|
return good_vectors, bad_vectors
|
||||||
|
|
||||||
# searching for sigma > 5 + #(v_i != 0)
|
# searching for sigma > 5 + #(v_i != 0)
|
||||||
@ -369,7 +456,7 @@ class TorusCable(object):
|
|||||||
|
|
||||||
# searching for sigma > 5 + #(v_i != 0)
|
# searching for sigma > 5 + #(v_i != 0)
|
||||||
def __check_all_combinations_in_ranges(self, list_of_ranges,
|
def __check_all_combinations_in_ranges(self, list_of_ranges,
|
||||||
print_results=True):
|
print_results=False):
|
||||||
all_combinations_pass = True
|
all_combinations_pass = True
|
||||||
all_bad_vectors = []
|
all_bad_vectors = []
|
||||||
number_of_all_good_v = 0
|
number_of_all_good_v = 0
|
||||||
@ -379,8 +466,6 @@ class TorusCable(object):
|
|||||||
all_bad_vectors = list(it.chain(all_bad_vectors, bad_v))
|
all_bad_vectors = list(it.chain(all_bad_vectors, bad_v))
|
||||||
if bad_v:
|
if bad_v:
|
||||||
all_combinations_pass = False
|
all_combinations_pass = False
|
||||||
if len(all_bad_vectors) > 8:
|
|
||||||
break
|
|
||||||
# if print_results:
|
# if print_results:
|
||||||
# print("good : bad:\t " + str(len(good_v)) +\
|
# print("good : bad:\t " + str(len(good_v)) +\
|
||||||
# " : " + str(len(bad_v)))
|
# " : " + str(len(bad_v)))
|
||||||
@ -392,11 +477,6 @@ class TorusCable(object):
|
|||||||
if print_results:
|
if print_results:
|
||||||
print("good : bad:\t " + str(number_of_all_good_v) +\
|
print("good : bad:\t " + str(number_of_all_good_v) +\
|
||||||
" : " + str(len(all_bad_vectors)))
|
" : " + str(len(all_bad_vectors)))
|
||||||
# if len(all_bad_vectors) < 8:
|
|
||||||
# print()
|
|
||||||
# print(all_bad_vectors)
|
|
||||||
|
|
||||||
|
|
||||||
return all_combinations_pass
|
return all_combinations_pass
|
||||||
|
|
||||||
# searching for sigma > 5 + #(v_i != 0)
|
# searching for sigma > 5 + #(v_i != 0)
|
||||||
@ -405,11 +485,7 @@ class TorusCable(object):
|
|||||||
if self.__sigma_function is None:
|
if self.__sigma_function is None:
|
||||||
self.__sigma_function = self.__get_sigma_function()
|
self.__sigma_function = self.__get_sigma_function()
|
||||||
if print_results:
|
if print_results:
|
||||||
# print("\n\n")
|
|
||||||
# print(100 * "*")
|
|
||||||
# print("Searching for a large signature values for the cable sum: ")
|
|
||||||
print(self.knot_description, end="\t\t\t")
|
print(self.knot_description, end="\t\t\t")
|
||||||
# print()
|
|
||||||
if self.__check_all_combinations_in_ranges(list_of_ranges,
|
if self.__check_all_combinations_in_ranges(list_of_ranges,
|
||||||
print_results=print_results):
|
print_results=print_results):
|
||||||
return True
|
return True
|
||||||
@ -459,16 +535,16 @@ class SignatureFunction(object):
|
|||||||
counter[mod_one(2 * jump_arg)] = jump
|
counter[mod_one(2 * jump_arg)] = jump
|
||||||
return SignatureFunction(counter=counter)
|
return SignatureFunction(counter=counter)
|
||||||
|
|
||||||
def __lshift__(self, shift):
|
|
||||||
# A shift of the signature functions corresponds to the rotation.
|
|
||||||
return self.__rshift__(-shift)
|
|
||||||
|
|
||||||
def __rshift__(self, shift):
|
def __rshift__(self, shift):
|
||||||
|
# A shift of the signature functions corresponds to the rotation.
|
||||||
new_data = []
|
new_data = []
|
||||||
for jump_arg, jump in self.cnt_signature_jumps.items():
|
for jump_arg, jump in self.cnt_signature_jumps.items():
|
||||||
new_data.append((mod_one(jump_arg + shift), jump))
|
new_data.append((mod_one(jump_arg + shift), jump))
|
||||||
return SignatureFunction(values=new_data)
|
return SignatureFunction(values=new_data)
|
||||||
|
|
||||||
|
def __lshift__(self, shift):
|
||||||
|
return self.__rshift__(-shift)
|
||||||
|
|
||||||
def __neg__(self):
|
def __neg__(self):
|
||||||
counter = collections.Counter()
|
counter = collections.Counter()
|
||||||
counter.subtract(self.cnt_signature_jumps)
|
counter.subtract(self.cnt_signature_jumps)
|
||||||
@ -498,16 +574,33 @@ class SignatureFunction(object):
|
|||||||
return result[:-2] + "."
|
return result[:-2] + "."
|
||||||
|
|
||||||
def __call__(self, arg):
|
def __call__(self, arg):
|
||||||
# Compute the value of the signature function at the point arg.
|
# return the value of the signature function at the point arg, i.e.
|
||||||
# This requires summing all signature jumps that occur before arg.
|
# sum of all signature jumps that occur before arg
|
||||||
arg = mod_one(arg)
|
arg = mod_one(arg)
|
||||||
cnt = self.cnt_signature_jumps
|
cnt = self.cnt_signature_jumps
|
||||||
before_arg = [jump for jump_arg, jump in cnt.items() if jump_arg < arg]
|
before_arg = [jump for jump_arg, jump in cnt.items() if jump_arg < arg]
|
||||||
return 2 * sum(before_arg) + cnt[arg]
|
return 2 * sum(before_arg) + cnt[arg]
|
||||||
|
|
||||||
|
|
||||||
|
def is_big(self):
|
||||||
|
max = 0
|
||||||
|
items = self.cnt_signature_jumps.items()
|
||||||
|
for arg, _ in items:
|
||||||
|
current = sum([jump for jump_arg, jump in items if jump_arg <= arg])
|
||||||
|
if abs(current) > abs(max):
|
||||||
|
max = current
|
||||||
|
if abs(max) > 9:
|
||||||
|
return max
|
||||||
|
return max
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def mod_one(n):
|
def mod_one(n):
|
||||||
return n - floor(n)
|
return n - floor(n)
|
||||||
|
|
||||||
|
|
||||||
def get_untwisted_signature_function(j):
|
def get_untwisted_signature_function(j):
|
||||||
# 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)
|
||||||
@ -517,15 +610,16 @@ def get_untwisted_signature_function(j):
|
|||||||
return SignatureFunction(values=w)
|
return SignatureFunction(values=w)
|
||||||
|
|
||||||
|
|
||||||
def get_signature_summand_as_theta_function(*arg):
|
def get_summand_signature_as_theta_function(*arg):
|
||||||
def get_signture_function(theta):
|
def get_summand_signture_function(theta):
|
||||||
# TBD: another formula (for t^2) description
|
# TBD: another formula (for t^2) description
|
||||||
|
|
||||||
k_n = abs(arg[-1])
|
k_n = abs(arg[-1])
|
||||||
if theta > k_n:
|
if theta > k_n:
|
||||||
msg = "k for the pattern in the cable is " + str(arg[-1]) + \
|
msg = "k for the pattern in the cable is " + str(arg[-1]) + \
|
||||||
". Parameter theta should not be larger than abs(k)."
|
". Parameter theta should not be larger than abs(k)."
|
||||||
raise ValueError(msg)
|
pass
|
||||||
|
# print(msg)
|
||||||
|
# raise ValueError(msg)
|
||||||
|
|
||||||
# twisted part
|
# twisted part
|
||||||
cable_signature = get_blanchfield_for_pattern(arg[-1], theta)
|
cable_signature = get_blanchfield_for_pattern(arg[-1], theta)
|
||||||
@ -546,8 +640,8 @@ def get_signature_summand_as_theta_function(*arg):
|
|||||||
test2 = -c + b
|
test2 = -c + b
|
||||||
assert test == test
|
assert test == test
|
||||||
return cable_signature
|
return cable_signature
|
||||||
get_signture_function.__doc__ = get_signture_function_docsting
|
get_summand_signture_function.__doc__ = get_summand_signture_function_docsting
|
||||||
return get_signture_function
|
return get_summand_signture_function
|
||||||
|
|
||||||
|
|
||||||
def get_blanchfield_for_pattern(k_n, theta):
|
def get_blanchfield_for_pattern(k_n, theta):
|
||||||
@ -580,15 +674,17 @@ def get_blanchfield_for_pattern(k_n, theta):
|
|||||||
return SignatureFunction(values=results)
|
return SignatureFunction(values=results)
|
||||||
|
|
||||||
|
|
||||||
def get_signature_summand_as_theta_function(*arg):
|
def get_summand_signature_as_theta_function(*arg):
|
||||||
def get_signture_function(theta):
|
def get_summand_signture_function(theta):
|
||||||
# TBD: another formula (for t^2) description
|
# TBD: another formula (for t^2) description
|
||||||
|
|
||||||
k_n = abs(arg[-1])
|
k_n = abs(arg[-1])
|
||||||
if theta > k_n:
|
if theta > k_n:
|
||||||
msg = "k for the pattern in the cable is " + str(arg[-1]) + \
|
msg = "k for the pattern in the cable is " + str(arg[-1]) + \
|
||||||
". Parameter theta should not be larger than abs(k)."
|
". Parameter theta should not be larger than abs(k)."
|
||||||
raise ValueError(msg)
|
pass
|
||||||
|
# print(msg)
|
||||||
|
# raise ValueError(msg)
|
||||||
|
|
||||||
# twisted part
|
# twisted part
|
||||||
cable_signature = get_blanchfield_for_pattern(arg[-1], theta)
|
cable_signature = get_blanchfield_for_pattern(arg[-1], theta)
|
||||||
@ -609,8 +705,8 @@ def get_signature_summand_as_theta_function(*arg):
|
|||||||
test2 = -c + b
|
test2 = -c + b
|
||||||
assert test == test
|
assert test == test
|
||||||
return cable_signature
|
return cable_signature
|
||||||
get_signture_function.__doc__ = get_signture_function_docsting
|
get_summand_signture_function.__doc__ = get_summand_signture_function_docsting
|
||||||
return get_signture_function
|
return get_summand_signture_function
|
||||||
|
|
||||||
|
|
||||||
def get_untwisted_signature_function(j):
|
def get_untwisted_signature_function(j):
|
||||||
@ -733,12 +829,12 @@ SignatureFunction.__doc__ = \
|
|||||||
signature functions as defined on the interval [0,1).
|
signature functions as defined on the interval [0,1).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
get_signture_function_docsting = \
|
get_summand_signture_function_docsting = \
|
||||||
"""
|
"""
|
||||||
This function returns SignatureFunction for previously defined single
|
This function returns SignatureFunction for previously defined single
|
||||||
cable T_(2, q) and a theta given as an argument.
|
cable T_(2, q) and a theta given as an argument.
|
||||||
The cable was defined by calling function
|
The cable was defined by calling function
|
||||||
get_signature_summand_as_theta_function(*arg)
|
get_summand_signature_as_theta_function(*arg)
|
||||||
with the cable description as an argument.
|
with the cable description as an argument.
|
||||||
It is an implementaion of the formula:
|
It is an implementaion of the formula:
|
||||||
Bl_theta(K'_(2, d)) =
|
Bl_theta(K'_(2, d)) =
|
||||||
@ -785,7 +881,7 @@ get_blanchfield_for_pattern.__doc__ = \
|
|||||||
(https://arxiv.org/pdf/1809.08791.pdf)
|
(https://arxiv.org/pdf/1809.08791.pdf)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
get_signature_summand_as_theta_function.__doc__ = \
|
get_summand_signature_as_theta_function.__doc__ = \
|
||||||
"""
|
"""
|
||||||
Argument:
|
Argument:
|
||||||
n integers that encode a single cable, i.e.
|
n integers that encode a single cable, i.e.
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
# TBD: read about Factory Method, variable in docstring, sage documentation
|
# TBD: read about Factory Method, variable in docstring, sage documentation
|
||||||
# move settings to sep file
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@ -13,7 +12,7 @@ import re
|
|||||||
# os.system('sage --preparse cable_signature.sage')
|
# os.system('sage --preparse cable_signature.sage')
|
||||||
# os.system('mv cable_signature.sage.py cable_signature.py')
|
# os.system('mv cable_signature.sage.py cable_signature.py')
|
||||||
# from cable_signature import SignatureFunction, TorusCable
|
# from cable_signature import SignatureFunction, TorusCable
|
||||||
#
|
|
||||||
|
|
||||||
class Config(object):
|
class Config(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -42,115 +41,58 @@ class Config(object):
|
|||||||
self.verbose = False
|
self.verbose = False
|
||||||
|
|
||||||
self.print_results = True
|
self.print_results = True
|
||||||
self.print_results = False
|
# self.print_results = False
|
||||||
|
|
||||||
self.print_calculations_for_large_sigma = True
|
self.print_calculations_for_large_sigma = True
|
||||||
self.print_calculations_for_large_sigma = False
|
self.print_calculations_for_large_sigma = False
|
||||||
|
|
||||||
# is the ratio restriction for values in k_vector taken into account
|
# is the ratio restriction for values in q_vector taken into account
|
||||||
# False flag is usefull to make quick script tests
|
|
||||||
self.only_slice_candidates = True
|
self.only_slice_candidates = True
|
||||||
self.only_slice_candidates = False
|
self.only_slice_candidates = False
|
||||||
|
|
||||||
|
|
||||||
# range for a_i, v = [a_1, a_2, a_3, a_4], for sigma calculations
|
# range for a_i, v = [a_1, a_2, a_3, a_4], for sigma calculations
|
||||||
def get_list_of_ranges(self, q):
|
# upper bound supposed to be ub = k + 1
|
||||||
|
def get_list_of_ranges(self, ub):
|
||||||
list_of_ranges = [
|
list_of_ranges = [
|
||||||
# all characters a_1, a_2, a_3, a_4 != 0
|
# all characters a_1, a_2, a_3, a_4 != 0
|
||||||
it.product(range(1, q), range(1, q), range(1, q), range(1, 2)),
|
it.product(range(1, ub), range(1, ub), range(1, ub), range(1, 2)),
|
||||||
|
|
||||||
# a_1 == 0, a_2, a_3, a_4 != 0
|
# a_1 == 0, a_2, a_3, a_4 != 0
|
||||||
it.product(range(1), range(1, q), range(1, q), range(1, 2)),
|
it.product(range(1), range(1, ub), range(1, ub), range(1, 2)),
|
||||||
# a_2 == 0, a_1, a_3, a_4 != 0
|
# a_2 == 0, a_1, a_3, a_4 != 0
|
||||||
it.product(range(1, q), range(1), range(1, q), range(1, 2)),
|
it.product(range(1, ub), range(1), range(1, ub), range(1, 2)),
|
||||||
# a_3 == 0, a_1, a_2, a_4 != 0
|
# a_3 == 0, a_1, a_2, a_4 != 0
|
||||||
it.product(range(1, q), range(1, q), range(1), range(1, 2)),
|
it.product(range(1, ub), range(1, ub), range(1), range(1, 2)),
|
||||||
# a_4 == 0, a_1, a_2, a_3 != 0
|
# a_4 == 0, a_1, a_2, a_3 != 0
|
||||||
it.product(range(1, q), range(1, q), range(1, 2), range(1)),
|
it.product(range(1, ub), range(1, ub), range(1, 2), range(1)),
|
||||||
|
|
||||||
# a_1 == 0, a_2 == 0, a_3, a_4 != 0
|
# a_1 == 0, a_2 == 0, a_3, a_4 != 0
|
||||||
it.product(range(1), range(1), range(1, q), range(1, 2)),
|
it.product(range(1), range(1), range(1, ub), range(1, 2)),
|
||||||
# a_1 == 0, a_3 == 0, a_2, a_4 != 0
|
# a_1 == 0, a_3 == 0, a_2, a_4 != 0
|
||||||
it.product(range(1), range(1, q), range(1), range(1, 2)),
|
it.product(range(1), range(1, ub), range(1), range(1, 2)),
|
||||||
# a_1 == 0, a_4 == 0, a_3, a_2 != 0
|
# a_1 == 0, a_4 == 0, a_3, a_2 != 0
|
||||||
it.product(range(1), range(1, q), range(1, 2), range(1)),
|
it.product(range(1), range(1, ub), range(1, 2), range(1)),
|
||||||
# a_2 == 0, a_3 == 0, a_1, a_4 != 0
|
# a_2 == 0, a_3 == 0, a_1, a_4 != 0
|
||||||
it.product(range(1, q), range(1), range(1), range(1, 2)),
|
it.product(range(1, ub), range(1), range(1), range(1, 2)),
|
||||||
# a_2 == 0, a_4 == 0, a_1, a_3 != 0
|
# a_2 == 0, a_4 == 0, a_1, a_3 != 0
|
||||||
it.product(range(1, q), range(1), range(1, 2), range(1)),
|
it.product(range(1, ub), range(1), range(1, 2), range(1)),
|
||||||
# a_3 == 0, a_4 == 0, a_1, a_2 != 0
|
# a_3 == 0, a_4 == 0, a_1, a_2 != 0
|
||||||
it.product(range(1, q), range(1, 2), range(1), range(1)),
|
it.product(range(1, ub), range(1, 2), range(1), range(1)),
|
||||||
]
|
]
|
||||||
|
|
||||||
list_of_ranges =
|
|
||||||
[
|
|
||||||
# all characters a_1, a_2, a_3, a_4 != 0
|
|
||||||
# 1, 1, 1, 1
|
|
||||||
it.product(range(1, 2), range(1, 2), range(1, 2), range(1, 2)),
|
|
||||||
|
|
||||||
# -1, -1, -1, 1
|
|
||||||
it.product(range(q - 1, q), range(q - 1, q), range(q - 1, q), \
|
|
||||||
range(1, 2)),
|
|
||||||
|
|
||||||
# 1, -1, -1, 1
|
|
||||||
it.product(range(1, 2), range(q - 1, q), range(q - 1, q), \
|
|
||||||
range(1, 2)),
|
|
||||||
# -1 , -1, 1, 1
|
|
||||||
it.product(range(q - 1, q), range(q - 1, q), range(1, 2), \
|
|
||||||
range(1, 2)),
|
|
||||||
# -1, 1, -1, 1
|
|
||||||
it.product(range(q - 1, q), range(1, 2), range(q - 1, q), \
|
|
||||||
range(1, 2)),
|
|
||||||
# 1, 1, -1, 1
|
|
||||||
it.product(range(1, 2), range(1, 2), range(q - 1, q), \
|
|
||||||
range(1, 2)),
|
|
||||||
# 1, -1, 1, 1
|
|
||||||
it.product(range(1, 2), range(q - 1, q), range(1, 2), \
|
|
||||||
range(1, 2)),
|
|
||||||
# -1, 1, 1, 1
|
|
||||||
it.product(range(q - 1, q), range(1, 2), range(1, 2), \
|
|
||||||
range(1, 2)),
|
|
||||||
]
|
|
||||||
|
|
||||||
return list_of_ranges
|
return list_of_ranges
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def main(arg):
|
def main(arg):
|
||||||
if arg[1]:
|
try:
|
||||||
limit = int(arg[1])
|
limit = int(arg[1])
|
||||||
else:
|
except IndexError:
|
||||||
limit = None
|
limit = None
|
||||||
knots_with_large_sigma = search_for_large_signature_value(limit=limit)
|
search_for_large_signature_value(limit=limit)
|
||||||
|
knots_with_large_sigma = search_for_large_sigma_value(limit=limit)
|
||||||
# search_for_null_signature_value(limit=limit)
|
# search_for_null_signature_value(limit=limit)
|
||||||
|
|
||||||
# searching for sigma > 5 + #(v_i != 0) over given knot schema
|
def set_parameters(knot_formula, limit, verbose, print_results):
|
||||||
def __search_for_large_signature_value(knot_formula, limit,
|
|
||||||
verbose, print_results):
|
|
||||||
# number of k_i (q_i) variables to substitute
|
|
||||||
k_size = extract_max(knot_formula) + 1
|
|
||||||
combinations = it.combinations_with_replacement(range(0, limit + 1), k_size)
|
|
||||||
P = Primes()
|
|
||||||
good_knots = []
|
|
||||||
# iterate over q-vector
|
|
||||||
for c in combinations:
|
|
||||||
q = list(c)
|
|
||||||
q[0] = P.unrank(q[0] + 1 + config.start_shift)
|
|
||||||
q[1] = P.next(q[0] * 4 + q[1])
|
|
||||||
q[2] = P.next(q[1] * 4 + q[2])
|
|
||||||
q[3] = P.next(q[2] * 4 + q[3])
|
|
||||||
cable = TorusCable(knot_formula=knot_formula, q_vector=q)
|
|
||||||
list_of_ranges = config.get_list_of_ranges(cable.q_vector[-1])
|
|
||||||
print(cable.knot_description)
|
|
||||||
if cable.eval_cable_for_large_sigma(list_of_ranges, verbose=verbose,
|
|
||||||
print_results=print_results):
|
|
||||||
good_knots.append(cable)
|
|
||||||
return good_knots
|
|
||||||
|
|
||||||
# searching for sigma > 5 + #(v_i != 0) over given knot schema
|
|
||||||
def search_for_large_signature_value(knot_formula=None, limit=None,
|
|
||||||
verbose=None, print_results=None):
|
|
||||||
if limit is None:
|
if limit is None:
|
||||||
limit = config.limit
|
limit = config.limit
|
||||||
if knot_formula is None:
|
if knot_formula is None:
|
||||||
@ -159,12 +101,19 @@ def search_for_large_signature_value(knot_formula=None, limit=None,
|
|||||||
vebose = config.verbose
|
vebose = config.verbose
|
||||||
if print_results is None:
|
if print_results is None:
|
||||||
print_results = config.print_results
|
print_results = config.print_results
|
||||||
|
return knot_formula, limit, verbose, print_results
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# searching for sigma > 5 + #(v_i != 0) over given knot schema
|
||||||
|
def search_for_large_sigma_value(knot_formula=None, limit=None,
|
||||||
|
verbose=None, print_results=None):
|
||||||
|
|
||||||
|
knot_formula, limit, verbose, print_results = \
|
||||||
|
set_parameters(knot_formula, limit, verbose, print_results)
|
||||||
|
|
||||||
k_vector_size = extract_max(knot_formula) + 1
|
k_vector_size = extract_max(knot_formula) + 1
|
||||||
limit = max(limit, k_vector_size)
|
limit = max(limit, k_vector_size)
|
||||||
if config.only_slice_candidates:
|
|
||||||
return __search_for_large_signature_value(knot_formula, limit, verbose,
|
|
||||||
print_results)
|
|
||||||
|
|
||||||
# number of k_i (q_i) variables to substitute
|
# number of k_i (q_i) variables to substitute
|
||||||
combinations = it.combinations(range(1, limit + 1), k_vector_size)
|
combinations = it.combinations(range(1, limit + 1), k_vector_size)
|
||||||
@ -173,23 +122,27 @@ def search_for_large_signature_value(knot_formula=None, limit=None,
|
|||||||
|
|
||||||
# iterate over q-vector
|
# iterate over q-vector
|
||||||
for c in combinations:
|
for c in combinations:
|
||||||
k = [(P.unrank(i + config.start_shift) - 1)/2 for i in c]
|
q = [P.unrank(i + config.start_shift) for i in c]
|
||||||
cable = TorusCable(knot_formula=knot_formula, k_vector=k)
|
if config.only_slice_candidates:
|
||||||
list_of_ranges = config.get_list_of_ranges(cable.q_vector[-1])
|
if not (q[3] > 4 * q[2] and
|
||||||
print(cable.knot_description)
|
q[2] > 4 * q[1] and
|
||||||
|
q[1] > 4 * q[0]):
|
||||||
|
if verbose:
|
||||||
|
print("Ratio-condition does not hold")
|
||||||
|
continue
|
||||||
|
cable = TorusCable(knot_formula=knot_formula, q_vector=q)
|
||||||
|
list_of_ranges = config.get_list_of_ranges(cable.k_vector[-1] + 1)
|
||||||
if cable.eval_cable_for_large_sigma(list_of_ranges, verbose=verbose,
|
if cable.eval_cable_for_large_sigma(list_of_ranges, verbose=verbose,
|
||||||
print_results=print_results):
|
print_results=print_results):
|
||||||
good_knots.append(cable)
|
good_knots.append(cable.knot_description)
|
||||||
return good_knots
|
return good_knots
|
||||||
|
|
||||||
# searching for signature == 0
|
# searching for signature == 0
|
||||||
def search_for_null_signature_value(knot_formula=None, limit=None):
|
def search_for_null_signature_value(knot_formula=None, limit=None,
|
||||||
if limit is None:
|
verbose=None, print_results=None):
|
||||||
limit = config.limit
|
|
||||||
if knot_formula is None:
|
knot_formula, limit, verbose, print_results = \
|
||||||
knot_formula = config.knot_formula
|
set_parameters(knot_formula, limit, verbose, print_results)
|
||||||
print_results = config.print_results
|
|
||||||
verbose = config.verbose
|
|
||||||
|
|
||||||
k_vector_size = extract_max(knot_formula) + 1
|
k_vector_size = extract_max(knot_formula) + 1
|
||||||
combinations = it.combinations_with_replacement(range(1, limit + 1),
|
combinations = it.combinations_with_replacement(range(1, limit + 1),
|
||||||
@ -210,11 +163,57 @@ def search_for_null_signature_value(knot_formula=None, limit=None):
|
|||||||
str(all_comb) + "\n")
|
str(all_comb) + "\n")
|
||||||
f_results.write(line)
|
f_results.write(line)
|
||||||
|
|
||||||
|
# searching for signature > 5 + #(v_i != 0) over given knot schema
|
||||||
|
def search_for_large_signature_value(knot_formula=None, limit=None,
|
||||||
|
verbose=None, print_results=None):
|
||||||
|
|
||||||
|
knot_formula, limit, verbose, print_results = \
|
||||||
|
set_parameters(knot_formula, limit, verbose, print_results)
|
||||||
|
|
||||||
|
k_vector_size = extract_max(knot_formula) + 1
|
||||||
|
combinations = it.combinations(range(1, limit + 1), k_vector_size)
|
||||||
|
P = Primes()
|
||||||
|
good_knots = []
|
||||||
|
|
||||||
|
# iterate over q-vector
|
||||||
|
for c in combinations:
|
||||||
|
q = [P.unrank(i + config.start_shift) for i in c]
|
||||||
|
if config.only_slice_candidates:
|
||||||
|
if not (q[3] > 4 * q[2] and
|
||||||
|
q[2] > 4 * q[1] and
|
||||||
|
q[1] > 4 * q[0]):
|
||||||
|
if verbose:
|
||||||
|
print("Ratio-condition does not hold")
|
||||||
|
continue
|
||||||
|
cable = TorusCable(knot_formula=knot_formula, q_vector=q)
|
||||||
|
list_of_ranges = config.get_list_of_ranges(cable.q_vector[-1])
|
||||||
|
if cable.eval_cable_for_large_signature(list_of_ranges, verbose=verbose,
|
||||||
|
print_results=print_results):
|
||||||
|
good_knots.append(cable.knot_description)
|
||||||
|
|
||||||
|
return good_knots
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def get_shifted_combination(combination):
|
||||||
|
# for now applicable only for schama
|
||||||
|
# "[[k[0], k[1], k[2]], [k[3], k[4]],
|
||||||
|
# [-k[0], -k[3], -k[4]], [-k[1], -k[2]]]"
|
||||||
|
# shift the combination so that the knot can be a candidate for slice
|
||||||
|
combination = [combination[0], 4 * combination[0] + combination[1],
|
||||||
|
4 * (4 * combination[0] + combination[1]) + combination[2],
|
||||||
|
4 * combination[0] + combination[3],
|
||||||
|
4 * (4 * combination[0] + combination[3]) + combination[4]]
|
||||||
|
return combination
|
||||||
|
|
||||||
|
|
||||||
def extract_max(string):
|
def extract_max(string):
|
||||||
numbers = re.findall('\d+', string)
|
numbers = re.findall('\d+', string)
|
||||||
numbers = map(int, numbers)
|
numbers = map(int, numbers)
|
||||||
return max(numbers)
|
return max(numbers)
|
||||||
|
|
||||||
|
|
||||||
def is_trivial_combination(knot_sum):
|
def is_trivial_combination(knot_sum):
|
||||||
# for now is applicable only for schema that are sums of 4 cables
|
# for now is applicable only for schema that are sums of 4 cables
|
||||||
if len(knot_sum) == 4:
|
if len(knot_sum) == 4:
|
||||||
|
Loading…
Reference in New Issue
Block a user