diff --git a/my_signature.sage b/my_signature.sage index a2434d8..d7dd24d 100644 --- a/my_signature.sage +++ b/my_signature.sage @@ -1,37 +1,6 @@ #!/usr/bin/python # TBD: read about Factory Method, variable in docstring, sage documentation -def calculate_form(x, y, q4): - x1, x2, x3, x4 = x - y1, y2, y3, y4 = y - form = (x1 * y1 - x2 * y2 + x3 * y3 - x4 * y4) % q_4 - # TBD change for ring modulo q_4 - return form - -def check_condition(v, q4): - if calculate_form(v, v, q4): - return False - return True - -def find_v(q4): - results = [] - for i in range(q4): - for j in range(q4): - for k in range(q4): - for m in range(q4): - if check_condition([i, j, k, m], q_4): - results.add(v) - return results - -def check_inequality(q, v): - a1, a2, a3, a4 = v - q1, q2, q3, q4 = q - pattern = [q1, q2, q4],[-q2, -q4],[q3, q4],[-q1, -q3, -q4] - signature_function_generator = get_function_of_theta_for_sum(pattern) - signature_function_for_sum = signature_function_generator(a1, a2, a3, a4) - - # sigma_v = sigma(q4, a1) - s(a2) + s(a3) - s(a4) - """ This script calculates signature functions for knots (cable sums). @@ -45,9 +14,9 @@ corresponds to a cable knot, e.g. a list 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_thetas as shown below. +the function eval_cable_for_null_signature as shown below. -sage: eval_cable_for_thetas([[1, 3], [2], [-1, -2], [-3]]) +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 @@ -57,12 +26,24 @@ Zero theta combinations: sage: - -The numbers given to the function eval_cable_for_thetas are k-values for each +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_function_of_theta_for_sum (see help/docstring for details). + +About notation: +Cables that we work with follow a schema: + T(2, q_0; 2, q_1; 2, q_3) # -T(2, q_1; 2, q_3) # + # T(2, q_2; 2, q_3) # -T(2, q_0; 2, q_2; 2, q_3) +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 @@ -72,6 +53,7 @@ import collections import inspect import itertools as it import pandas as pd +import numpy as np import re @@ -81,30 +63,23 @@ class MySettings(object): # 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.only_slice_candidates = True + self.only_slice_candidates = False - # knot_sum_formula is a schema for knots which signature function + # knot_formula is a schema for knots which signature function # will be calculated - self.knot_sum_formula = "[[k[0], k[1], k[2]], [k[3], k[4]], \ - [-k[0], -k[3], -k[4]], [-k[1], -k[2]]]" - """ - About notation: - Cables that we work with follow a schema: - T(2, q_0; 2, q_1; 2, q_2) # T(2, q_1; 2, q_2) # - # -T(2, q_3; 2, q_2) # -T(2, q_0; 2, q_3; 2, q_2) - In knot_sum_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_sum_formula - 2) set each q_i all or choose range in which q_i should varry - 3) choose vector v / theata vector. + self.knot_formula = "[[k[0], k[1], k[3]], [-k[1], -k[3]], \ + [k[2], k[3]], [-k[0], -k[2], -k[3]]]" - """ - # self.knot_sum_formula = "[[k[0], k[1], k[2]], [k[3]],\ + + # self.knot_formula = "[[k[0], k[1], k[2]], [k[3], k[4]], \ + # [-k[0], -k[3], -k[4]], [-k[1], -k[2]]]" + # self.knot_formula = "[[k[0], k[1], k[2]], [k[3]],\ # [-k[0], -k[1], -k[3]], [-k[2]]]" self.default_limit = 3 + self.verbose = True + class SignatureFunction(object): """ @@ -190,72 +165,200 @@ class SignatureFunction(object): def __str__(self): return ''.join([str(jump_arg) + ": " + str(jump) + "\n" for jump_arg, jump in sorted(self.data.items())]) + def value(self, arg): + # Compute the value of the signature function at the point arg. + # This requires summing all signature jumps that occur before arg. + assert 0 <= arg and arg < 1 + val = 0 + for jump_arg, jump in self.data.items(): + if jump_arg < arg: + val += 2 * jump + elif jump_arg == arg: + val += jump + return val def main(arg): - """ - This function is run if the script was called from the terminal. - It calls another function, perform_calculations, - to calculate signature functions for a schema - of a cable sum defined in the class MySettings. - Optionaly a parameter (a limit for k_0 value) can be given. - Thought to be run for time consuming calculations. - """ try: new_limit = int(arg[1]) except: new_limit = None - perform_calculations(limit=new_limit) + search_for_large_signature_value(limit=new_limit) + # search_for_null_signature_value(limit=new_limit) -def perform_calculations(knot_sum_formula=None, limit=None): - """ - This function calculates signature functions for knots constracted - accordinga a schema for a cable sum. The schema is given as an argument - or defined in the class MySettings. - Results of calculations will be writen to a file and the stdout. - limit is the upper bound for the first value in k_vector, - i.e k[0] value in a cable sum, where q_0 = 2 * k[0] + 1. - - (the number of knots that will be constracted depends on limit value). - For each knot/cable sum the function eval_cable_for_thetas is called. - eval_cable_for_thetas calculetes the number of all possible thetas - (characters) and the number of combinations for which signature function - equeles zero. In case the first number is larger than squere of the second, - eval_cable_for_thetas returns None (i.e. the knot can not be slice). - Data for knots that are candidates for slice knots are saved to a file. - """ - - settings = MySettings() +def search_for_large_signature_value(knot_formula=None, + limit=None, verbose=None): if limit is None: - limit = settings.default_limit - if knot_sum_formula is None: - knot_sum_formula = settings.knot_sum_formula + limit = config.default_limit + if knot_formula is None: + knot_formula = config.knot_formula + if verbose is None: + vebose = config.verbose - k_vector_size = extract_max(knot_sum_formula) + 1 - combinations = it.combinations_with_replacement(range(1, limit + 1), - k_vector_size) - - with open(settings.f_results, 'w') as f_results: + k_vector_size = extract_max(knot_formula) + 1 + limit = max(limit, k_vector_size) + print limit + combinations = it.combinations(range(1, limit + 1), k_vector_size) + for k in combinations: + print + print k +# P = Primes() +# sage: P.unrank(0) +# 2 +# sage: P.unrank(5) +# 13 +# sage: P.unrank(42) + return None + with open(config.f_results, 'w') as f_results: for k in combinations: - # print - # print k + if verbose: + print + print k # TBD: maybe the following condition or the function # get_shifted_combination should be redefined to a dynamic version - if settings.only_slice_candidates and k_vector_size == 5: + if config.only_slice_candidates and k_vector_size == 5: k = get_shifted_combination(k) # print k - knot_sum = eval(knot_sum_formula) + knot_sum = eval(knot_formula) + print "knot_sum" + print knot_sum if is_trivial_combination(knot_sum): + if verbose: + print "\nTrivial combination" + str(knot_sum) continue - result = eval_cable_for_thetas(knot_sum, print_results=False) + result = eval_cable_for_large_signature(knot_sum, + print_results=False) if result is not None: knot_description, null_comb, all_comb = result line = (str(k) + ", " + str(null_comb) + ", " + str(all_comb) + "\n") f_results.write(line) +def eval_cable_for_large_signature(knot_sum, print_results=True, verbose=None): + if verbose is None: + verbose = config.verbose + if verbose: + print "\neval_cable_for_large_signature" + if len(knot_sum) != 4: + print "Wrong number of cable direct summands!" + return None + q = 2 * abs(knot_sum[-1][-1]) + 1 + print "q is " + str(q) + + f = get_function_of_theta_for_sum(*knot_sum, verbose=False) + knot_description = get_knot_descrption(*knot_sum) + all_combinations = get_number_of_combinations(*knot_sum) + + null_combinations = 0 + zero_theta_combinations = [] + + ranges_list = [range(abs(knot[-1]) + 1) for knot in knot_sum] + if verbose: + print "eval_cable_for_large_signature - knot_description: " + print knot_description + for v_theta in it.product(*ranges_list): + y = f(*v_theta).value(1/2) + print y + if abs(y) > 5 + np.count_nonzero(v_theta): + print "hura hura" + # == 0: + # zero_theta_combinations.append(v_theta) + # m = len([theta for theta in v_theta if theta != 0]) + # null_combinations += 2^m + # else: + # assert sum(v_theta) != 0 + + if print_results: + print + print knot_description + print "Zero cases: " + str(null_combinations) + print "All cases: " + str(all_combinations) + if zero_theta_combinations: + print "Zero theta combinations: " + for el in zero_theta_combinations: + print el + if null_combinations^2 >= all_combinations: + return knot_description, null_combinations, all_combinations + return None + + +def search_for_null_signature_value(knot_formula=None, limit=None): + if limit is None: + limit = config.default_limit + if knot_formula is None: + knot_formula = config.knot_formula + + k_vector_size = extract_max(knot_formula) + 1 + combinations = it.combinations_with_replacement(range(1, limit + 1), + k_vector_size) + + with open(config.f_results, 'w') as f_results: + 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 confi.only_slice_candidates and k_vector_size == 5: + k = get_shifted_combination(k) + # print k + knot_sum = eval(knot_formula) + + if is_trivial_combination(knot_sum): + continue + result = search_for_thetas(knot_sum, print_results=False) + if result is not None: + knot_description, null_comb, all_comb = result + line = (str(k) + ", " + str(null_comb) + ", " + + str(all_comb) + "\n") + f_results.write(line) + +def search_for_thetas(knot_sum, print_results=False, verbose=None): + if verbose is None: + vebose = confi.verbose + if verbose: + print "search_for_thetas" + f = get_function_of_theta_for_sum(*knot_sum) + knot_description = get_knot_descrption(*knot_sum) + all_combinations = get_number_of_combinations(*knot_sum) + + large_value_combinations = 0 + good_theta_list = [] + + ranges_list = [range(abs(knot[-1]) + 1) for knot in knot_sum] + if verbose: + print "knot_description:" + print knot_description + for v_theta in it.product(*ranges_list): + if (v_theta[0]^2 - v_theta[1]^2 + v_theta[2]^2 - v_theta[3]^2) % q: + print "ojojoj" + print (v_theta[0]^2 - v_theta[1]^2 + v_theta[2]^2 - v_theta[3]^2) % q + continue + print f(*v_theta).value(-1) + if f(*v_theta).value(-1): + print "Hip hip hura" + good_theta_list.append(v_theta) + m = len([theta for theta in v_theta if theta != 0]) + large_value_combinations += 2^m + else: + print "smuteczek" + # else: + # assert sum(v_theta) != 0 + + if print_results: + print + print knot_description + print "Zero cases: " + str(null_combinations) + print "All cases: " + str(all_combinations) + if zero_theta_combinations: + print "Zero theta combinations: " + for el in zero_theta_combinations: + print el + if null_combinations^2 >= all_combinations: + return knot_description, null_combinations, all_combinations + return None + def is_trivial_combination(knot_sum): # for now is applicable only for schema that are sums of 4 cables @@ -279,19 +382,6 @@ def get_shifted_combination(combination): def get_blanchfield_for_pattern(k_n, theta): - """ - Arguments: - k_n: a number s.t. q_n = 2 * k_n + 1, where - T(2, q_n) is a pattern knot for a single cable from a cable sum - theta: twist/character for the cable (value form v vector) - Return: - SignatureFunction created for twisted signature function - for a given cable and theta/character - Based on: - Proposition 9.8. in Twisted Blanchfield Pairing - (https://arxiv.org/pdf/1809.08791.pdf) - """ - if theta == 0: a = get_untwisted_signature_function(k_n) return a.square_root() + a.minus_square_root() @@ -322,28 +412,7 @@ def get_blanchfield_for_pattern(k_n, theta): def get_cable_signature_as_theta_function(*arg): - """ - Argument: - n integers that encode a single cable, i.e. - values of q_i for T(2,q_0; 2,q_1; ... 2, q_n) - Return: - a function that returns SignatureFunction for this single cable - and a theta given as an argument - """ - def get_signture_function(theta): - """ - This function returns SignatureFunction for previously defined single - cable T_(2, q) and a theta given as an argument. - The cable was defined by calling function - get_cable_signature_as_theta_function(*arg) - with the cable description as an argument. - It is an implementaion of the formula: - Bl_theta(K'_(2, d)) = - Bl_theta(T_2, d) + Bl(K')(ksi_l^(-theta) * t) - + Bl(K')(ksi_l^theta * t) - """ - # TBD: another formula (for t^2) description k_n = abs(arg[-1]) @@ -368,6 +437,7 @@ def get_cable_signature_as_theta_function(*arg): c = c.double_cover() cable_signature += b + c return cable_signature + get_signture_function.__doc__ = get_signture_function_docsting return get_signture_function @@ -381,7 +451,232 @@ def get_untwisted_signature_function(j): return SignatureFunction(w) -def get_function_of_theta_for_sum(*arg): +def get_function_of_theta_for_sum(*arg, **key_args): + if 'verbose' in key_args: + verbose_default = key_args['verbose'] + else: + verbose_default = confi.verbose + def signature_function_for_sum(*thetas, **kwargs): + verbose = verbose_default + if 'verbose' in kwargs: + verbose = kwargs['verbose'] + la = len(arg) + lt = len(thetas) + + # call with no arguments + if lt == 0: + return signature_function_for_sum(*(la * [0])) + + if lt != la: + msg = "This function takes exactly " + str(la) + \ + " arguments or no argument at all (" + str(lt) + " given)." + raise TypeError(msg) + + sf = SignatureFunction([(0, 0)]) + + # for each cable in cable sum apply theta + for i, knot in enumerate(arg): + try: + sf += (get_cable_signature_as_theta_function(*knot))(thetas[i]) + # 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 + if verbose: + print + print str(thetas) + print sf + return sf + signature_function_for_sum.__doc__ = signature_function_for_sum_docstring + return signature_function_for_sum + + +def eval_cable_for_null_signature(knot_sum, print_results=True, verbose=None): + # search for zero combinations + if verbose is None: + vebose = confi.verbose + f = get_function_of_theta_for_sum(*knot_sum, verbose=False) + knot_description = get_knot_descrption(*knot_sum) + all_combinations = get_number_of_combinations(*knot_sum) + + null_combinations = 0 + zero_theta_combinations = [] + + ranges_list = [range(abs(knot[-1]) + 1) for knot in knot_sum] + if verbose: + print + print knot_description + for v_theta in it.product(*ranges_list): + if f(*v_theta, verbose=False).sum_of_absolute_values() == 0: + zero_theta_combinations.append(v_theta) + m = len([theta for theta in v_theta if theta != 0]) + null_combinations += 2^m + # else: + # assert sum(v_theta) != 0 + + if print_results: + print + print knot_description + print "Zero cases: " + str(null_combinations) + print "All cases: " + str(all_combinations) + if zero_theta_combinations: + print "Zero theta combinations: " + for el in zero_theta_combinations: + print el + if null_combinations^2 >= all_combinations: + return knot_description, null_combinations, all_combinations + return None + + +def check_squares(a, k): + print + p = 2 * k + 1 + k_0 = (p^2 - 1)/2 + knot_sum = [[a, k], [k_0], [-a, -k_0], [-k]] + print get_knot_descrption(*knot_sum) + if a * 4 >= p or is_trivial_combination(knot_sum): + if a * 4 >= p: + print str(knot_sum) + print "a * 4 >= p" + else: + print "Trivial " + str(knot_sum) + return None + eval_cable_for_null_signature(knot_sum) + + +def get_number_of_combinations(*arg): + number_of_combinations = 1 + for knot in arg: + number_of_combinations *= (2 * abs(knot[-1]) + 1) + return number_of_combinations + + +def extract_max(string): + numbers = re.findall('\d+', string) + numbers = map(int, numbers) + return max(numbers) + + +def mod_one(n): + return n - floor(n) + + +def get_knot_descrption(*arg): + description = "" + for knot in arg: + if knot[0] < 0: + description += "-" + description += "T(" + for k in knot: + description += "2, " + str(2 * abs(k) + 1) + "; " + description = description[:-2] + ") # " + return description[:-3] + +get_blanchfield_for_pattern.__doc__ = \ + """ + Arguments: + k_n: a number s.t. q_n = 2 * k_n + 1, where + T(2, q_n) is a pattern knot for a single cable from a cable sum + theta: twist/character for the cable (value form v vector) + Return: + SignatureFunction created for twisted signature function + for a given cable and theta/character + Based on: + Proposition 9.8. in Twisted Blanchfield Pairing + (https://arxiv.org/pdf/1809.08791.pdf) + """ + +get_number_of_combinations.__doc__ = \ + """ + Arguments: + arbitrary number of lists of numbers, each list encodes a single cable + Return: + number of possible theta values combinations that could be applied + for a given cable sum, + i.e. the product of q_j for j = {1,.. n}, + where n is a number of direct components in the cable sum, + and q_j is the last q parameter for the component (a single cable) + """ + +get_knot_descrption.__doc__ = \ + """ + Arguments: + arbitrary number of lists of numbers, each list encodes a single cable. + Examples: + sage: get_knot_descrption([1, 3], [2], [-1, -2], [-3]) + 'T(2, 3; 2, 7) # T(2, 5) # -T(2, 3; 2, 5) # -T(2, 7)' + """ + +mod_one.__doc__ = \ + """ + Argument: + a number + Return: + the fractional part of the argument + Examples: + sage: mod_one(9 + 3/4) + 3/4 + sage: mod_one(-9 + 3/4) + 3/4 + sage: mod_one(-3/4) + 1/4 + """ + +search_for_null_signature_value.__doc__ = \ + """ + This function calculates signature functions for knots constracted + accordinga a schema for a cable sum. The schema is given as an argument + or defined in the class MySettings. + Results of calculations will be writen to a file and the stdout. + limit is the upper bound for the first value in k_vector, + i.e k[0] value in a cable sum, where q_0 = 2 * k[0] + 1. + + (the number of knots that will be constracted depends on limit value). + For each knot/cable sum the function eval_cable_for_null_signature is called. + eval_cable_for_null_signature calculetes the number of all possible thetas + (characters) and the number of combinations for which signature function + equeles zero. In case the first number is larger than squere of the second, + eval_cable_for_null_signature returns None (i.e. the knot can not be slice). + Data for knots that are candidates for slice knots are saved to a file. + """ + +extract_max.__doc__ = \ + """ + Return: + maximum of absolute values of numbers from given string + Examples: + sage: extract_max("([1, 3], [2], [-1, -2], [-10])") + 10 + sage: extract_max("3, 55, ewewe, -42, 3300, 50") + 3300 + """ + +eval_cable_for_null_signature.__doc__ = \ + """ + This function calculates all possible twisted signature functions for + a knot that is given as an argument. The knot should be encoded as a list + of its direct component. Each component schould be presented as a list + of integers. This integers correspond to the k - values in each component/ + cable. If a component is a mirror image of a cable the minus sign should + be written before each number for this component. For example: + eval_cable_for_null_signature([[1, 8], [2], [-2, -8], [-2]]) + eval_cable_for_null_signature([[1, 2], [-1, -2]]) + + 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. + """ + +get_function_of_theta_for_sum.__doc__ = \ """ Function intended to construct signature function for a connected sum of multiple cables with varying theta parameter values. @@ -435,193 +730,84 @@ def get_function_of_theta_for_sum(*arg): 6/7: 0 """ - def signature_function_for_sum(*thetas, **kwargs): - """ - Arguments: - - Returns object of SignatureFunction class for a previously defined - connected sum of len(arg) cables. - Acept len(arg) arguments: for each cable one theta parameter. - If call with no arguments, all theta parameters are set to be 0. - """ - if 'verbose' in kwargs: - verbose = kwargs['verbose'] - else: - verbose = False - - la = len(arg) - lt = len(thetas) - - # call with no arguments - if lt == 0: - return signature_function_for_sum(*(la * [0])) - - if lt != la: - msg = "This function takes exactly " + str(la) + \ - " arguments or no argument at all (" + str(lt) + " given)." - raise TypeError(msg) - - sf = SignatureFunction([(0, 0)]) - - # for each cable in cable sum apply theta - for i, knot in enumerate(arg): - try: - sf += (get_cable_signature_as_theta_function(*knot))(thetas[i]) - # 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 - if verbose: - print - print str(*thetas) - print sf - return sf - return signature_function_for_sum - - -def eval_cable_for_thetas(knot_sum, print_results=True, verbose=False): - """ - This function calculates all possible twisted signature functions for - a knot that is given as an argument. The knot should be encoded as a list - of its direct component. Each component schould be presented as a list - of integers. This integers correspond to the k - values in each component/ - cable. If a component is a mirror image of a cable the minus sign should - be written before each number for this component. For example: - eval_cable_for_thetas([[1, 8], [2], [-2, -8], [-2]]) - eval_cable_for_thetas([[1, 2], [-1, -2]]) - - sage: eval_cable_for_thetas([[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_thetas are k-values for each - component/cable in a direct sum. - - - """ - f = get_function_of_theta_for_sum(*knot_sum) - knot_description = get_knot_descrption(*knot_sum) - all_combinations = get_number_of_combinations(*knot_sum) - - null_combinations = 0 - zero_theta_combinations = [] - - ranges_list = [range(abs(knot[-1]) + 1) for knot in knot_sum] - if verbose: - print - print knot_description - for v_theta in it.product(*ranges_list): - if f(*v_theta, verbose=verbose).sum_of_absolute_values() == 0: - zero_theta_combinations.append(v_theta) - m = len([theta for theta in v_theta if theta != 0]) - null_combinations += 2^m - # else: - # assert sum(v_theta) != 0 - - if print_results: - print - print knot_description - print "Zero cases: " + str(null_combinations) - print "All cases: " + str(all_combinations) - if zero_theta_combinations: - print "Zero theta combinations: " - for el in zero_theta_combinations: - print el - if null_combinations^2 >= all_combinations: - return knot_description, null_combinations, all_combinations - return None - - -def check_squares(a, k): - print - p = 2 * k + 1 - k_0 = (p^2 - 1)/2 - knot_sum = [[a, k], [k_0], [-a, -k_0], [-k]] - print get_knot_descrption(*knot_sum) - if a * 4 >= p or is_trivial_combination(knot_sum): - if a * 4 >= p: - print str(knot_sum) - print "a * 4 >= p" - else: - print "Trivial " + str(knot_sum) - return None - eval_cable_for_thetas(knot_sum) - - -def get_number_of_combinations(*arg): - """ - Arguments: - arbitrary number of lists of numbers, each list encodes a single cable - Return: - number of possible theta values combinations that could be applied - for a given cable sum, - i.e. the product of q_j for j = {1,.. n}, - where n is a number of direct components in the cable sum, - and q_j is the last q parameter for the component (a single cable) - """ - number_of_combinations = 1 - for knot in arg: - number_of_combinations *= (2 * abs(knot[-1]) + 1) - return number_of_combinations - - -def extract_max(string): - """ - Return: - maximum of absolute values of numbers from given string - Examples: - sage: extract_max("([1, 3], [2], [-1, -2], [-10])") - 10 - sage: extract_max("3, 55, ewewe, -42, 3300, 50") - 3300 - """ - numbers = re.findall('\d+', string) - numbers = map(int, numbers) - return max(numbers) - - -def mod_one(n): +get_cable_signature_as_theta_function.__doc__ = \ """ Argument: - a number + n integers that encode a single cable, i.e. + values of q_i for T(2,q_0; 2,q_1; ... 2, q_n) Return: - the fractional part of the argument - Examples: - sage: mod_one(9 + 3/4) - 3/4 - sage: mod_one(-9 + 3/4) - 3/4 - sage: mod_one(-3/4) - 1/4 + a function that returns SignatureFunction for this single cable + and a theta given as an argument """ - return n - floor(n) +get_signture_function_docsting = \ + """ + This function returns SignatureFunction for previously defined single + cable T_(2, q) and a theta given as an argument. + The cable was defined by calling function + get_cable_signature_as_theta_function(*arg) + with the cable description as an argument. + It is an implementaion of the formula: + Bl_theta(K'_(2, d)) = + Bl_theta(T_2, d) + Bl(K')(ksi_l^(-theta) * t) + + Bl(K')(ksi_l^theta * t) + """ -def get_knot_descrption(*arg): +signature_function_for_sum_docstring = \ """ Arguments: - arbitrary number of lists of numbers, each list encodes a single cable. - Examples: - sage: get_knot_descrption([1, 3], [2], [-1, -2], [-3]) - 'T(2, 3; 2, 7) # T(2, 5) # -T(2, 3; 2, 5) # -T(2, 7)' + + Returns object of SignatureFunction class for a previously defined + connected sum of len(arg) cables. + Acept len(arg) arguments: for each cable one theta parameter. + If call with no arguments, all theta parameters are set to be 0. """ - description = "" - for knot in arg: - if knot[0] < 0: - description += "-" - description += "T(" - for k in knot: - description += "2, " + str(2 * abs(k) + 1) + "; " - description = description[:-2] + ") # " - return description[:-3] +main.__doc__ = \ + """ + This function is run if the script was called from the terminal. + It calls another function, search_for_null_signature_value, + to calculate signature functions for a schema + of a cable sum defined in the class MySettings. + Optionaly a parameter (a limit for k_0 value) can be given. + Thought to be run for time consuming calculations. + """ +config = MySettings() if __name__ == '__main__' and '__file__' in globals(): # not called in interactive mode as __file__ is not defined main(sys.argv) + + +# def calculate_form(x, y, q4): + # x1, x2, x3, x4 = x + # y1, y2, y3, y4 = y + # form = (x1 * y1 - x2 * y2 + x3 * y3 - x4 * y4) % q_4 +# # TBD change for ring modulo q_4 +# return form +# +# def check_condition(v, q4): +# if calculate_form(v, v, q4): +# return False +# return True +# +# def find_v(q4): +# results = [] +# for i in range(q4): +# for j in range(q4): +# for k in range(q4): +# for m in range(q4): +# if check_condition([i, j, k, m], q_4): +# results.add(v) +# return results +# +# def check_inequality(q, v): +# a1, a2, a3, a4 = v +# q1, q2, q3, q4 = q +# pattern = [q1, q2, q4],[-q2, -q4],[q3, q4],[-q1, -q3, -q4] +# signature_function_generator = get_function_of_theta_for_sum(pattern) +# signature_function_for_sum = signature_function_generator(a1, a2, a3, a4) +# +# # sigma_v = sigma(q4, a1) - s(a2) + s(a3) - s(a4) +# +#