結び目理論とはぢめてのPython
Dropbox - knot_to_polynomial.py
授業の課題で
ジョーンズ多項式 - Wikipedia
を求めるプログラムを作ってみようというのがあったので、
「あ~~これはそろそろやらなきゃかな~」というので昨晩Pythonに手を出して
課題プログラムを書いてみた。
今回は例として
8の字結び目 - Wikipedia
を用いることとし、
インデントが綺麗に見えてとても良い。
Tupleだとか色々と使いやすそう。
#!/usr/bin/python # -*- coding: utf-8 -*- import os, sys import numpy as np def main(): """ 結び目を表現する初期値 入力を入れるなり、ファイルから読む形でも良い 今回はfigure-eight knotを表現する値を代入 """ table=[(3,6,4,7),(7,2,0,3),(1,5,2,4),(6,0,5,1)] tmp_circle=set() tmp_results=set() ResultTable = [[0 for j in range(8)] for i in range(16)] ResultArray = [0 for j in range(20)] myu = np.poly1d([-1,0,0,0,-1]) print "" print "[s1,s2,s3,s4] : 各結び目s_iの状態({-1,1})" print "(sum,circle) : (各結び目s_iの状態({-1,1})の和 sum, 成分の数 circle)" print "xの多項式 : 各状態の重み" print " 注: pythonにはA^{-2}などを表現出来ないので,x^20=x^0となるように合わせている" print "" for s1 in [-1,1]: for s2 in [-1,1]: for s3 in [-1,1]: for s4 in [-1,1]: state=[s1,s2,s3,s4] current_part = 0 previous_area = -1 i=0 circle_num = 0 remaining_part = set(range(8)) temporary_part = set() while not len(remaining_part) == 0: """ 紐番号が適切かのチェック """ if current_part in remaining_part: if current_part in temporary_part: circle_num += 1 """print "Finished a cycle!""" remaining_part = remaining_part.difference(temporary_part) if len(remaining_part) > 0: current_part = iter(remaining_part).next() temporary_part = set([current_part]) else: temporary_part.add(current_part) else: current_part = iter(remaining_part).next() """ 同じ紐番号をもつ結び目(今居る結び目以外)を検索 """ while (i == previous_area) or not(current_part in table[i]): i += 1 i %= 4 previous_area = i """ 結び目(A,B,C,D)において 状態が"+"ならA<->B,C<->D, 状態が"-"ならA<->D,B<->C, という遷移をする """ if state[i] == 1: ind = table[i].index(current_part) current_part = table[i][(2*(ind % 2) - 1 + ind) % 4] elif state[i] == -1: ind = table[i].index(current_part) current_part = table[i][(-2*(ind % 2) + 1 + ind) % 4] else: print "error" print state print (sum(state),circle_num) ResultTable[sum(state)+4][circle_num] += 1 print np.poly1d([1]+[0]*(20 - 2*(circle_num-1) + sum(state))) * myu**(circle_num-1) print "" ResultArray = ResultArray + np.poly1d([1]+[0]*(20 - 2*(circle_num-1) + sum(state))) * myu**(circle_num-1) print "" print "重みの総和(ジョーンズ方程式:ただし、pythonはx^(負の数)を表現出来ないので、x^20が定数項となるように合わせている)" print ResultArray if __name__ == "__main__": main()
アルゴリズムは時間がないので割愛するが、
実行結果は以下の通り。
[s1,s2,s3,s4] : 各結び目s_iの状態({-1,1}) (sum,circle) : (各結び目s_iの状態({-1,1})の和 sum, 成分の数 circle) xの多項式 : 各状態の重み 注: pythonにはA^{-2}などを表現出来ないので,x^20=x^0となるように合わせている [-1, -1, -1, -1] (-4, 3) 20 16 12 1 x + 2 x + 1 x [-1, -1, -1, 1] (-2, 2) 20 16 -1 x - 1 x [-1, -1, 1, -1] (-2, 2) 20 16 -1 x - 1 x [-1, -1, 1, 1] (0, 1) 20 1 x [-1, 1, -1, -1] (-2, 2) 20 16 -1 x - 1 x [-1, 1, -1, 1] (0, 1) 20 1 x [-1, 1, 1, -1] (0, 1) 20 1 x [-1, 1, 1, 1] (2, 2) 24 20 -1 x - 1 x [1, -1, -1, -1] (-2, 2) 20 16 -1 x - 1 x [1, -1, -1, 1] (0, 1) 20 1 x [1, -1, 1, -1] (0, 1) 20 1 x [1, -1, 1, 1] (2, 2) 24 20 -1 x - 1 x [1, 1, -1, -1] (0, 3) 24 20 16 1 x + 2 x + 1 x [1, 1, -1, 1] (2, 2) 24 20 -1 x - 1 x [1, 1, 1, -1] (2, 2) 24 20 -1 x - 1 x [1, 1, 1, 1] (4, 3) 28 24 20 1 x + 2 x + 1 x 重みの総和(ジョーンズ方程式:ただし、pythonはx^(負の数)を表現出来ないので、x^20が定数項となるように合わせている) 28 24 20 16 12 1 x - 1 x + 1 x - 1 x + 1 x