Version v0 for Maciej and Wojtek. Functions to print calculations for sigma_v. Printing results in 3 columns.

This commit is contained in:
Maria Marchwicka 2020-08-04 00:36:57 +02:00
parent f9c9f5dd1d
commit c7c16ab4c0

View File

@ -3,48 +3,6 @@
# 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 # move settings to sep file
"""
This script calculates signature functions for knots (cable sums).
The script can be run as a sage script from the terminal
or used in interactive mode.
A knot (cable sum) is encoded as a list where each element (also a list)
corresponds to a cable knot, e.g. a list
[[1, 3], [2], [-1, -2], [-3]] encodes
T(2, 3; 2, 7) # T(2, 5) # -T(2, 3; 2, 5) # -T(2, 7).
To calculate the number of characters for which signature function vanish use
the function eval_cable_for_null_signature as shown below.
sage: eval_cable_for_null_signature([[1, 3], [2], [-1, -2], [-3]])
T(2, 3; 2, 7) # T(2, 5) # -T(2, 3; 2, 5) # -T(2, 7)
Zero cases: 1
All cases: 1225
Zero theta combinations:
(0, 0, 0, 0)
sage:
The numbers given to the function eval_cable_for_null_signature are k-values for each
component/cable in a direct sum.
To calculate signature function for a knot and a theta value, use function
get_signature_as_theta_function (see help/docstring for details).
About notation:
Cables that we work with follow a schema:
T(2, q_1; 2, q_2; 2, q_4) # -T(2, q_2; 2, q_4) #
# T(2, q_3; 2, q_4) # -T(2, q_1; 2, q_3; 2, q_4)
In knot_formula each k[i] is related with some q_i value, where
q_i = 2*k[i] + 1.
So we can work in the following steps:
1) choose a schema/formula by changing the value of knot_formula
2) set each q_i all or choose range in which q_i should varry
3) choose vector v / theata vector.
"""
import os import os
import sys import sys
@ -54,24 +12,18 @@ import itertools as it
import pandas as pd import pandas as pd
import numpy as np import numpy as np
import re import re
import doc_signature
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")
# is the ratio restriction for values in k_vector taken into account
# False flag is usefull to make quick script tests
self.only_slice_candidates = True
self.only_slice_candidates = 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]], [-k[1], -k[3]], \ self.knot_formula = "[[k[0], k[1], k[3]], [-k[1], -k[3]], \
[k[2], k[3]], [-k[0], -k[2], -k[3]]]" [k[2], k[3]], [-k[0], -k[2], -k[3]]]"
# self.knot_formula = "[[k[0], k[1], k[2]], [k[3], k[4]], \ # self.knot_formula = "[[k[0], k[1], k[2]], [k[3], k[4]], \
# [-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]],\
@ -79,7 +31,23 @@ class Config(object):
self.limit = 3 self.limit = 3
self.verbose = True self.verbose = True
# self.verbose = False self.verbose = False
self.print_calculations_for_small_signature = True
# self.print_calculations_for_small_signature = False
self.print_calculations_for_large_signature = True
# self.print_calculations_for_large_signature = False
# is the ratio restriction for values in k_vector taken into account
# False flag is usefull to make quick script tests
self.only_slice_candidates = True
self.only_slice_candidates = False
self.stop_after_firts_large_signature = True
self.stop_after_firts_large_signature = False
class SignatureFunction(object): class SignatureFunction(object):
@ -93,21 +61,24 @@ class SignatureFunction(object):
and value encodes the value of the jump. Remember that we treat and value encodes the value of the jump. Remember that we treat
signature functions as defined on the interval [0,1). signature functions as defined on the interval [0,1).
""" """
def __init__(self, values=[]): def __init__(self, values=[], counter=collections.Counter()):
# set values of signature jumps # set values of signature jumps
self.signature_jumps = collections.defaultdict(int) self.signature_jumps = collections.defaultdict(int, counter)
self.ttsignature_jumps = collections.Counter() self.counter_signature_jumps = counter
if not counter:
for jump_arg, jump in values: for jump_arg, jump in values:
assert 0 <= jump_arg < 1, \ assert 0 <= jump_arg < 1, \
"Signature function is defined on the interval [0, 1)." "Signature function is defined on the interval [0, 1)."
self.signature_jumps[jump_arg] = jump self.signature_jumps[jump_arg] = jump
self.counter_signature_jumps = collections.Counter(self.signature_jumps)
def sum_of_absolute_values(self): def sum_of_absolute_values(self):
return sum([abs(i) for i in self.signature_jumps.values()]) return sum([abs(i) for i in self.signature_jumps.values()])
def is_zero_everywhere(self): def is_zero_everywhere(self):
return not any(self.signature_jumps.values()) result = not any(self.signature_jumps.values())
assert result == (not any(self.counter_signature_jumps.values()))
return result
def double_cover(self): def double_cover(self):
# to read values for t^2 # to read values for t^2
@ -125,8 +96,6 @@ class SignatureFunction(object):
new_data.append((2 * jump_arg, jump)) new_data.append((2 * jump_arg, jump))
return SignatureFunction(new_data) return SignatureFunction(new_data)
def get_signture_jump(self, t):
return self.signature_jumps.get(t, 0)
def minus_square_root(self): def minus_square_root(self):
# to read values for t^(1/2) # to read values for t^(1/2)
@ -151,16 +120,11 @@ class SignatureFunction(object):
new_data = [] new_data = []
for jump_arg, jump in self.signature_jumps.items(): for jump_arg, jump in self.signature_jumps.items():
new_data.append((jump_arg, -jump)) new_data.append((jump_arg, -jump))
sf = SignatureFunction(new_data)
return SignatureFunction(new_data) return SignatureFunction(new_data)
# TBD short # TBD short
def __add__(self, other): def __add__(self, other):
print "\n" * 3
print "other"
print other.signature_jumps
print "self"
print self.signature_jumps
new_signature_function = SignatureFunction()
new_data = collections.defaultdict(int) new_data = collections.defaultdict(int)
for jump_arg, jump in other.signature_jumps.items(): for jump_arg, jump in other.signature_jumps.items():
new_data[jump_arg] = jump + self.signature_jumps.get(jump_arg, 0) new_data[jump_arg] = jump + self.signature_jumps.get(jump_arg, 0)
@ -168,28 +132,12 @@ class SignatureFunction(object):
if jump_arg not in new_data.keys(): if jump_arg not in new_data.keys():
new_data[jump_arg] = self.signature_jumps[jump_arg] new_data[jump_arg] = self.signature_jumps[jump_arg]
tnew_signature_function = SignatureFunction() counter = collections.Counter()
tnew_data = collections.defaultdict(int) counter.update(self.counter_signature_jumps)
self.ttsignature_jumps = collections.Counter(self.signature_jumps) counter.update(other.counter_signature_jumps)
other.ttsignature_jumps = collections.Counter(other.signature_jumps) assert collections.defaultdict(int, counter) == new_data
for jump_arg, jump in other.ttsignature_jumps.items(): return SignatureFunction(counter=counter)
tnew_data[jump_arg] = jump + self.ttsignature_jumps.get(jump_arg, 0)
for jump_arg, jump in self.ttsignature_jumps.items():
if jump_arg not in tnew_data.keys():
tnew_data[jump_arg] = self.ttsignature_jumps[jump_arg]
tt = other.ttsignature_jumps + self.ttsignature_jumps
# tt = dict(tt)
tt = collections.defaultdict(int, tt)
print "\n" * 3
print "tt"
print tt
print "new_data"
print new_data
assert new_data == tnew_data
new_signature_function.signature_jumps = new_data
return new_signature_function
def __sub__(self, other): def __sub__(self, other):
return self + other.__neg__() return self + other.__neg__()
@ -198,6 +146,11 @@ class SignatureFunction(object):
return ''.join([str(jump_arg) + ": " + str(jump) + "\n" return ''.join([str(jump_arg) + ": " + str(jump) + "\n"
for jump_arg, jump in sorted(self.signature_jumps.items())]) for jump_arg, jump in sorted(self.signature_jumps.items())])
def __repr__(self):
result = ''.join([str(jump_arg) + ": " + str(jump) + ", "
for jump_arg, jump in sorted(self.signature_jumps.items())])
return result[:-2] + "."
def __call__(self, arg): def __call__(self, arg):
# Compute the value of the signature function at the point arg. # Compute the value of the signature function at the point arg.
# This requires summing all signature jumps that occur before arg. # This requires summing all signature jumps that occur before arg.
@ -208,22 +161,19 @@ class SignatureFunction(object):
val += 2 * jump val += 2 * jump
elif jump_arg == arg: elif jump_arg == arg:
val += jump val += jump
a = self.sum_of_absolute_values()
b = self.is_zero_everywhere()
assert (a and not b) or (not a and b)
return val return val
def main(arg): def main(arg):
try: try:
new_limit = int(arg[1]) new_limit = int(arg[1])
except: except IndexError:
new_limit = None new_limit = None
search_for_large_signature_value(limit=new_limit) search_for_large_signature_value(limit=new_limit)
# search_for_null_signature_value(limit=new_limit) # search_for_null_signature_value(limit=new_limit)
# searching for signture > 5 + #(v_i != 0) # searching for signture > 5 + #(v_i != 0) over given knot schema
def search_for_large_signature_value(knot_formula=None, def search_for_large_signature_value(knot_formula=None,
limit=None, limit=None,
verbose=None): verbose=None):
@ -234,39 +184,51 @@ def search_for_large_signature_value(knot_formula=None,
if verbose is None: if verbose is None:
vebose = config.verbose vebose = config.verbose
# number of k_i (q_i) variables to substitute
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)
combinations = it.combinations(range(1, limit + 1), k_vector_size) combinations = it.combinations(range(1, limit + 1), k_vector_size)
P = Primes() P = Primes()
with open(config.f_results, 'w') as f_results: # with open(config.f_results, 'w') as f_results:
for c in combinations: for c in combinations:
k = [(P.unrank(i) - 1)/2 for i in c] k = [(P.unrank(i) - 1)/2 for i in c]
knot_sum = eval(knot_formula)
if config.only_slice_candidates: if config.only_slice_candidates:
if not (k[3] > 4 * k[2] and if not (k[3] > 4 * k[2] and
k[2] > 4 * k[1] and k[2] > 4 * k[1] and
k[1] > 4 * k[0]): k[1] > 4 * k[0]):
print "niu niu" if verbose:
print "Ratio-condition does not hold"
continue continue
result = eval_cable_for_large_signature(knot_sum, result = eval_cable_for_large_signature(k_vector=k,
knot_formula=knot_formula,
print_results=False) print_results=False)
# if result is not None:
# knot_description, large_comb, all_comb = result
# line = (str(k) + ", " + str(all_comb) + ", " +
# str(all_comb) + "\n")
# f_results.write(line)
# searching for signture > 5 + #(v_i != 0) # searching for signture > 5 + #(v_i != 0)
def eval_cable_for_large_signature(knot_sum, def eval_cable_for_large_signature(k_vector=None,
knot_formula=None,
print_results=True, print_results=True,
verbose=None): verbose=None,
q_vector=None):
knot_description = get_knot_descrption(*knot_sum) if knot_formula is None:
knot_formula = config.knot_formula
if verbose is None: if verbose is None:
verbose = config.verbose verbose = config.verbose
if k_vector is None:
if q_vector is None:
# TBD docstring
print "Please give a list of k (k_vector) or q values (q_vector)."
k = k_vector
knot_sum = eval(knot_formula)
knot_description = get_knot_descrption(*knot_sum)
k_1, k_2, k_3, k_4 = [abs(i) for i in k]
q_4 = 2 * k_4 + 1
ksi = 1/q_4
if verbose: if verbose:
print "\n\n" print "\n\n"
@ -274,52 +236,32 @@ def eval_cable_for_large_signature(knot_sum,
print "Searching for a large signature values for the cable sum: " print "Searching for a large signature values for the cable sum: "
print knot_description print knot_description
if len(knot_sum) != 4: if len(knot_sum) != 4:
print "Wrong number of cable direct summands!" print "Wrong number of cable direct summands!"
return None return None
f = get_signature_as_theta_function(*knot_sum, verbose=False) # iteration over all possible character combinations
# g = get_signature_as_theta_function_test(*knot_sum, verbose=False)
# large_value_combinations = 0
# good_thetas_list = []
ranges_list = [range(abs(knot[-1]) + 1) for knot in knot_sum] ranges_list = [range(abs(knot[-1]) + 1) for knot in knot_sum]
q = 2 * abs(knot_sum[-1][-1]) + 1
q_4 = q
for v_theta in it.product(*ranges_list): for v_theta in it.product(*ranges_list):
theta_squers = [i^2 for i in v_theta] theta_squers = [i^2 for i in v_theta]
condition = "(" + str(theta_squers[0]) + " - " + str(theta_squers[1]) \ condition = "(" + str(theta_squers[0]) \
+ " + " + str(theta_squers[1]) + " - " + \ + " - " + str(theta_squers[1]) \
str(theta_squers[3]) + ") % " + str(q_4) + " + " + str(theta_squers[2]) \
if verbose: + " - " + str(theta_squers[3]) \
print "\nChecking for characters: " + str(v_theta) + ") % " + str(q_4)
# if verbose:
# print "\nChecking for characters: " + str(v_theta)
if (theta_squers[0] - theta_squers[1] + if (theta_squers[0] - theta_squers[1] +
theta_squers[2] - theta_squers[3]) % q: theta_squers[2] - theta_squers[3]) % q_4:
if verbose: if verbose:
print "Condition not satisfied: " + str(condition) + " != 0." print "The condition is not satisfied: " + \
str(condition) + " != 0."
continue continue
y = f(*v_theta)(1/2) # T(2, q_1; 2, q_2; 2, q_4) # -T(2, q_2; 2, q_4) #
# # T(2, q_3; 2, q_4) # -T(2, q_1; 2, q_3; 2, q_4)
# "untwisted" part (Levine-Tristram signatures)
#
#
# twisted_part = 0
# old_twisted_part = 0
# # T(2, q_1; 2, q_2; 2, q_4) # -T(2, q_2; 2, q_4) #
# # # T(2, q_3; 2, q_4) # -T(2, q_1; 2, q_3; 2, q_4)
k_1, k_2, k_4 = [abs(i) for i in knot_sum[0]]
k_3 = abs(knot_sum[2][1])
q_4 = 2 * k_4 + 1
ksi = 1/q_4
print "k values: "
print str(k_1) + " " + str(k_2) + " " + str(k_3) + " " + str(k_4)
sigma_q_1 = get_untwisted_signature_function(k_1) sigma_q_1 = get_untwisted_signature_function(k_1)
sigma_q_2 = get_untwisted_signature_function(k_2) sigma_q_2 = get_untwisted_signature_function(k_2)
sigma_q_3 = get_untwisted_signature_function(k_3) sigma_q_3 = get_untwisted_signature_function(k_3)
@ -331,53 +273,183 @@ def eval_cable_for_large_signature(knot_sum,
sigma_q_3(mod_one(ksi * a_4)) - sigma_q_3(mod_one(ksi * a_4)) -
sigma_q_1(mod_one(ksi * a_4 * 2))) sigma_q_1(mod_one(ksi * a_4 * 2)))
# tp = [0, 0, 0, 0] # "twisted" part
# for i, a in enumerate(thetas): tp = [0, 0, 0, 0]
# if a: for i, a in enumerate(v_theta):
# tp[i] = -q_4 + 2 * a - (2 * a^2)/q_4 if a:
# print "petla" tp[i] = -q_4 + 2 * a - 2 * (a^2/q_4)
# print i twisted_part = tp[0] - tp[1] + tp[2] - tp[3]
# print tp[i] assert twisted_part == int(twisted_part)
# print 5 * "\n"
# print tp
# new_twisted_part = tp[0] - tp[1] + tp[2] - tp[3]
# print new_twisted_part
#
# for i, knot in enumerate(arg):
# try:
# dssf = get_signature_summand_as_theta_function_test(*knot)(thetas[i])
# sf += dssf
# # in case wrong theata value was given
# except ValueError as e:
# print "ValueError: " + str(e.args[0]) +\
# " Please change " + str(i + 1) + ". parameter."
# return None
# print "\nold_twisted_part"
# print old_twisted_part
# print "twisted_part: "
# print new_twisted_part
# print "untwisted_part: "
# print untwisted_part
# print "\n\n\n\n" + 50 * "*" + "\nsum " + str(untwisted_part + new_twisted_part)
#
#
#
# j = g(*v_theta)(1/2) # y = f(*v_theta)(1/2)
# assert y == j sigma_v = untwisted_part + twisted_part
if abs(sigma_v) > 5 + np.count_nonzero(v_theta):
if abs(y) > 5 + np.count_nonzero(v_theta): if config.print_calculations_for_large_signature:
print "\n\tLarge signature value" print "*" * 100
else: print "\n\nLarge signature value\n"
print "\n\tSmall signature value"
print knot_description print knot_description
print "v_theta: " + str(v_theta) print "\nv_theta: ",
print v_theta
print "k values: ",
print str(k_1) + " " + str(k_2) + " " + \
str(k_3) + " " + str(k_4)
print condition print condition
print "non zero value in v_theta: " + str(np.count_nonzero(v_theta)) print "non zero value in v_theta: " + \
print "signature at 1/2: " + str(y) str(np.count_nonzero(v_theta))
print "sigma_v: " + str(sigma_v)
print "\ntwisted_part: ",
print twisted_part
print "untwisted_part: ",
print untwisted_part
print "\n\nCALCULATIONS"
print "*" * 100
print_results_LT(v_theta, knot_description,
ksi, untwisted_part,
k, sigma_q_1, sigma_q_2, sigma_q_3)
print_results_sigma(v_theta, knot_description, tp, q_4)
print "*" * 100 + "\n" * 5
else:
print knot_description + "\t" + str(v_theta) +\
"\t" + str(sigma_v)
if config.stop_after_firts_large_signature:
break
else:
if config.print_calculations_for_small_signature:
print "\n" * 5 + "*" * 100
print "\nSmall signature value\n"
print knot_description
print_results_LT(v_theta, knot_description, ksi, untwisted_part,
k, sigma_q_1, sigma_q_2, sigma_q_3)
print_results_sigma(v_theta, knot_description, tp, q_4)
print "*" * 100 + "\n" * 5
# else:
# print "\n\tSmall signature value"
# print knot_description
# print "v_theta: " + str(v_theta)
# print condition
# print "non zero value in v_theta: " + str(np.count_nonzero(v_theta))
# print "signature at 1/2: " + str(y)
return None return None
def print_results_LT(v_theta, knot_description, ksi, untwisted_part,
k, sigma_q_1, sigma_q_2, sigma_q_3):
a_1, a_2, a_3, a_4 = v_theta
k_1, k_2, k_3, k_4 = [abs(i) for i in k]
print "\n\nLevine-Tristram signatures for the cable sum: "
print knot_description
print "and characters:\n" + str(v_theta) + ","
print "ksi = " + str(ksi)
print "\n\n2 * (sigma_q_2(ksi * a_1) + " + \
"sigma_q_1(ksi * a_1 * 2) - " +\
"sigma_q_2(ksi * a_2) + " +\
"sigma_q_3(ksi * a_3) - " +\
"sigma_q_3(ksi * a_4) - " +\
"sigma_q_1(ksi * a_4 * 2))" +\
\
" = \n\n2 * (sigma_q_2(" + \
str(ksi) + " * " + str(a_1) + \
") + sigma_q_1(" + \
str(ksi) + " * " + str(a_1) + " * 2" + \
") - sigma_q_2(" + \
str(ksi) + " * " + str(a_2) + \
") + sigma_q_3(" + \
str(ksi) + " * " + str(a_3) + \
") - sigma_q_3(" + \
str(ksi) + " * " + str(a_4) + \
") - sigma_q_1(" + \
str(ksi) + " * " + str(a_4) + " * 2)) " + \
\
" = \n\n2 * (sigma_q_2(" + \
str(mod_one(ksi * a_1)) + \
") + sigma_q_1(" + \
str(mod_one(ksi * a_1 * 2)) + \
") - sigma_q_2(" + \
str(mod_one(ksi * a_2)) + \
") + sigma_q_3(" + \
str(mod_one(ksi * a_3)) + \
") - sigma_q_3(" + \
str(mod_one(ksi * a_4)) + \
") - sigma_q_1(" + \
str(mod_one(ksi * a_4 * 2)) + \
\
") = \n\n2 * ((" + \
str(sigma_q_2(mod_one(ksi * a_1))) + \
") + (" + \
str(sigma_q_1(mod_one(ksi * a_1 * 2))) + \
") - (" + \
str(sigma_q_2(mod_one(ksi * a_2))) + \
") + (" + \
str(sigma_q_3(mod_one(ksi * a_3))) + \
") - (" + \
str(sigma_q_3(mod_one(ksi * a_4))) + \
") - (" + \
str(sigma_q_1(mod_one(ksi * a_4 * 2))) + ")) = " + \
"\n\n2 * (" + \
str(sigma_q_2(mod_one(ksi * a_1)) +
sigma_q_1(mod_one(ksi * a_1 * 2)) -
sigma_q_2(mod_one(ksi * a_2)) +
sigma_q_3(mod_one(ksi * a_3)) -
sigma_q_3(mod_one(ksi * a_4)) -
sigma_q_1(mod_one(ksi * a_4 * 2))) + \
") = " + str(untwisted_part)
print "\nSignatures:"
print "\nq_1 = " + str(2 * k_1 + 1) + ": " + repr(sigma_q_1)
print "\nq_2 = " + str(2 * k_2 + 1) + ": " + repr(sigma_q_2)
print "\nq_3 = " + str(2 * k_3 + 1) + ": " + repr(sigma_q_3)
def print_results_sigma(v_theta, knot_description, tp, q_4):
a_1, a_2, a_3, a_4 = v_theta
print "\n\nSigma values for the cable sum: "
print knot_description
print "and characters: " + str(v_theta)
print "\nsigma(T_{2, q_4}, ksi_a) = " + \
"-q + (2 * a * (q_4 - a)/q_4) " +\
"= -q + 2 * a - 2 * a^2/q_4 if a != 0,\n\t\t\t" +\
" = 0 if a == 0."
print "\nsigma(T_{2, q_4}, chi_a_1) = ",
if a_1:
print "- (" + str(q_4) + ") + 2 * " + str(a_1) + " + " +\
"- 2 * " + str(a_1^2) + "/" + str(q_4) + \
" = " + str(tp[0])
else:
print "0"
print "\nsigma(T_{2, q_4}, chi_a_2) = ",
if a_2:
print "- (" + str(q_4) + ") + 2 * " + str(a_2) + " + " +\
"- 2 * " + str(a_2^2) + "/" + str(q_4) + \
" = " + str(tp[1])
else:
print "0",
print "\nsigma(T_{2, q_4}, chi_a_3) = ",
if a_3:
print "- (" + str(q_4) + ") + 2 * " + str(a_3) + " + " +\
"- 2 * " + str(a_3^2) + "/" + str(q_4) + \
" = " + str(tp[2])
else:
print "0",
print "\nsigma(T_{2, q_4}, chi_a_4) = ",
if a_4:
print "- (" + str(q_4) + ") + 2 * " + str(a_4) + " + " +\
"- 2 * " + str(a_4^2) + "/" + str(q_4) + \
" = " + str(tp[3])
else:
print "0"
print "\n\nsigma(T_{2, q_4}, chi_a_1) " + \
"- sigma(T_{2, q_4}, chi_a_2) " + \
"+ sigma(T_{2, q_4}, chi_a_3) " + \
"- sigma(T_{2, q_4}, chi_a_4) =\n" + \
"sigma(T_{2, q_4}, " + str(a_1) + \
") - sigma(T_{2, q_4}, " + str(a_2) + \
") + sigma(T_{2, q_4}, " + str(a_3) + \
") - sigma(T_{2, q_4}, " + str(a_4) + ") = " + \
str(tp[0] - tp[1] + tp[2] - tp[3])
# 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: if limit is None:
@ -390,18 +462,15 @@ def search_for_null_signature_value(knot_formula=None, limit=None):
k_vector_size) k_vector_size)
with open(config.f_results, 'w') as f_results: with open(config.f_results, 'w') as f_results:
for k in combinations: for k in combinations:
# print
# print k
# TBD: maybe the following condition or the function
# get_shifted_combination should be redefined to a dynamic version
if config.only_slice_candidates and k_vector_size == 5: if config.only_slice_candidates and k_vector_size == 5:
k = get_shifted_combination(k) k = get_shifted_combination(k)
# print k
knot_sum = eval(knot_formula) knot_sum = eval(knot_formula)
if is_trivial_combination(knot_sum): if is_trivial_combination(knot_sum):
print knot_sum
continue continue
result = eval_cable_for_null_signature(knot_sum) result = eval_cable_for_null_signature(knot_sum)
if result is not None: if result is not None:
knot_description, null_comb, all_comb = result knot_description, null_comb, all_comb = result
@ -426,7 +495,7 @@ def eval_cable_for_null_signature(knot_sum, print_results=False, verbose=None):
print print
print knot_description print knot_description
for v_theta in it.product(*ranges_list): for v_theta in it.product(*ranges_list):
if f(*v_theta, verbose=False).sum_of_absolute_values() == 0: if f(*v_theta, verbose=False).is_zero_everywhere():
zero_theta_combinations.append(v_theta) zero_theta_combinations.append(v_theta)
m = len([theta for theta in v_theta if theta != 0]) m = len([theta for theta in v_theta if theta != 0])
null_combinations += 2^m null_combinations += 2^m
@ -497,52 +566,6 @@ def get_blanchfield_for_pattern(k_n, theta):
results.append((1 - e * ksi, 1 * sgn(k_n))) results.append((1 - e * ksi, 1 * sgn(k_n)))
return SignatureFunction(results) return SignatureFunction(results)
def get_signature_summand_as_theta_function_test(*arg):
sf = SignatureFunction([(0, 0)])
def get_signture_function_test(theta):
# untwisted part
k_n = abs(arg[-1])
cable_signature = sf
# print k_0, k_1, k_2, k_3
for i, k in enumerate(arg[:-1][::-1]):
ksi = 1/(2 * k_n + 1)
power = 2^i
a = get_untwisted_signature_function(k)
shift = theta * ksi * power
b = a >> shift
c = a << shift
for _ in range(i):
b = b.double_cover()
c = c.double_cover()
cable_signature += b + c
if theta > k_n:
msg = "k for the pattern in the cable is " + str(arg[-1]) + \
". Parameter theta should not be larger than abs(k)."
raise ValueError(msg)
# twisted part
tp = get_blanchfield_for_pattern(arg[-1], theta)
cable_signature += tp
print "\ncs: "
print cable_signature(1/2)
tp_at = tp(1/2)
print "tp: "
print tp_at
return cable_signature
get_signture_function_test.__doc__ = get_signture_function_docsting
return get_signture_function_test
def get_signature_summand_as_theta_function(*arg): def get_signature_summand_as_theta_function(*arg):
def get_signture_function(theta): def get_signture_function(theta):
# TBD: another formula (for t^2) description # TBD: another formula (for t^2) description
@ -568,14 +591,16 @@ def get_signature_summand_as_theta_function(*arg):
b = b.double_cover() b = b.double_cover()
c = c.double_cover() c = c.double_cover()
cable_signature += b + c cable_signature += b + c
test = b - c
test2 = -c + b
assert test == test
return cable_signature return cable_signature
get_signture_function.__doc__ = get_signture_function_docsting get_signture_function.__doc__ = get_signture_function_docsting
return get_signture_function return get_signture_function
def get_untwisted_signature_function(j): def get_untwisted_signature_function(j):
"""This function returns the signature function of the T_{2,2k+1} # return the signature function of the T_{2,2k+1} torus knot
torus knot."""
k = abs(j) k = abs(j)
w = ([((2 * a + 1)/(4 * k + 2), -1 * sgn(j)) for a in range(k)] + w = ([((2 * a + 1)/(4 * k + 2), -1 * sgn(j)) for a in range(k)] +
[((2 * a + 1)/(4 * k + 2), 1 * sgn(j)) [((2 * a + 1)/(4 * k + 2), 1 * sgn(j))
@ -583,95 +608,6 @@ def get_untwisted_signature_function(j):
return SignatureFunction(w) return SignatureFunction(w)
def get_signature_as_theta_function_test(*arg, **key_args):
if 'verbose' in key_args:
verbose_default = key_args['verbose']
else:
verbose_default = config.verbose
sf0 = SignatureFunction([(0, 0)])
sf0_test = SignatureFunction([(0, 0)])
def signature_as_theta_function_test(*thetas, **kwargs):
verbose = verbose_default
if 'verbose' in kwargs:
verbose = kwargs['verbose']
la = len(arg)
lt = len(thetas)
sf = sf0
sf_test = sf0_test
# call with no arguments
if lt == 0:
return signature_as_theta_function_test(*(la * [0]))
if lt != la:
msg = "This function takes exactly " + str(la) + \
" arguments or no argument at all (" + str(lt) + " given)."
raise TypeError(msg)
# for each cable in cable sum apply theta
twisted_part = 0
old_twisted_part = 0
# T(2, q_1; 2, q_2; 2, q_4) # -T(2, q_2; 2, q_4) #
# # T(2, q_3; 2, q_4) # -T(2, q_1; 2, q_3; 2, q_4)
k_1, k_2, k_4 = [abs(i) for i in arg[0]]
k_3 = abs(arg[2][0])
ksi = 1/(2 * k_4 + 1)
print arg[0]
print str(k_1) + " " + str(k_2) + " " + str(k_3) + " " + str(k_4)
sigma_q_1 = get_untwisted_signature_function(k_1)
sigma_q_2 = get_untwisted_signature_function(k_2)
sigma_q_3 = get_untwisted_signature_function(k_3)
a_1, a_2, a_3, a_4 = thetas
untwisted_part = 2 * (sigma_q_2(ksi * a_1) +
sigma_q_1(ksi * a_1 * 2) -
sigma_q_2(ksi * a_2) +
sigma_q_3(ksi * a_3) -
sigma_q_3(ksi * a_4) -
sigma_q_1(ksi * a_4 * 2))
q_4 = 2 * k_4 + 1
tp = [0, 0, 0, 0]
for i, a in enumerate(thetas):
if a:
tp[i] = -q_4 + 2 * a - (2 * a^2)/q_4
print "petla"
print i
print tp[i]
print 5 * "\n"
print tp
new_twisted_part = tp[0] - tp[1] + tp[2] - tp[3]
print new_twisted_part
for i, knot in enumerate(arg):
try:
dssf = get_signature_summand_as_theta_function_test(*knot)(thetas[i])
sf += dssf
# in case wrong theata value was given
except ValueError as e:
print "ValueError: " + str(e.args[0]) +\
" Please change " + str(i + 1) + ". parameter."
return None
print "\nold_twisted_part"
print old_twisted_part
print "twisted_part: "
print new_twisted_part
print "untwisted_part: "
print untwisted_part
print "\n\n\n\n" + 50 * "*" + "\nsum " + str(untwisted_part + new_twisted_part)
print "old sum at 1/2: "
print sf(1/2)
if verbose:
print
print str(thetas)
print sf
return sf
signature_as_theta_function_test.__doc__ = signature_as_theta_function_docstring
return signature_as_theta_function_test
def get_signature_as_theta_function(*arg, **key_args): def get_signature_as_theta_function(*arg, **key_args):
if 'verbose' in key_args: if 'verbose' in key_args:
verbose_default = key_args['verbose'] verbose_default = key_args['verbose']
@ -741,6 +677,7 @@ def get_knot_descrption(*arg):
description = description[:-2] + ") # " description = description[:-2] + ") # "
return description[:-3] return description[:-3]
get_blanchfield_for_pattern.__doc__ = \ get_blanchfield_for_pattern.__doc__ = \
""" """
Arguments: Arguments:
@ -947,3 +884,45 @@ if __name__ == '__main__':
if '__file__' in globals(): if '__file__' in globals():
# skiped in interactive mode as __file__ is not defined # skiped in interactive mode as __file__ is not defined
main(sys.argv) main(sys.argv)
"""
This script calculates signature functions for knots (cable sums).
The script can be run as a sage script from the terminal
or used in interactive mode.
A knot (cable sum) is encoded as a list where each element (also a list)
corresponds to a cable knot, e.g. a list
[[1, 3], [2], [-1, -2], [-3]] encodes
T(2, 3; 2, 7) # T(2, 5) # -T(2, 3; 2, 5) # -T(2, 7).
To calculate the number of characters for which signature function vanish use
the function eval_cable_for_null_signature as shown below.
sage: eval_cable_for_null_signature([[1, 3], [2], [-1, -2], [-3]])
T(2, 3; 2, 7) # T(2, 5) # -T(2, 3; 2, 5) # -T(2, 7)
Zero cases: 1
All cases: 1225
Zero theta combinations:
(0, 0, 0, 0)
sage:
The numbers given to the function eval_cable_for_null_signature are k-values for each
component/cable in a direct sum.
To calculate signature function for a knot and a theta value, use function
get_signature_as_theta_function (see help/docstring for details).
About notation:
Cables that we work with follow a schema:
T(2, q_1; 2, q_2; 2, q_4) # -T(2, q_2; 2, q_4) #
# T(2, q_3; 2, q_4) # -T(2, q_1; 2, q_3; 2, q_4)
In knot_formula each k[i] is related with some q_i value, where
q_i = 2*k[i] + 1.
So we can work in the following steps:
1) choose a schema/formula by changing the value of knot_formula
2) set each q_i all or choose range in which q_i should varry
3) choose vector v / theata vector.
"""