def subsitutionTest(): sub = {"a":"ab", "b":"a"} curtime = time.time() result = Substitution(sub, "a", 5) posttime = time.time() totaltime = posttime - curtime print(f"out: {result}\nlength:{len(result)}\ntime: {totaltime}") substitution = {"a": "ac", "b" : "bd", "c":"a", "d":"db"} curtime = time.time() result = Substitution(substitution, "a", 5) posttime = time.time() totaltime = posttime - curtime print(f"out: {result}\nlength:{len(result)}\ntime: {totaltime}") substitution = {"a":"ab", "b":"bc", "c":"cd", "d":"da"} curtime = time.time() result = Substitution(substitution, "a", 5) posttime = time.time() totaltime = posttime - curtime print(f"out: {result}\nlength:{len(result)}\ntime: {totaltime}") sub = {"a":"ab", "b":"c", "c":"a"} curtime = time.time() result = Substitution(sub, "a", 10) posttime = time.time() totaltime = posttime - curtime print(f"out: {result}\nlength:{len(result)}\ntime: {totaltime}")
def eigenValuesTest(): print() sub = {"a":"ab", "b":"a"} result = Substitution(sub, "a", 5) eigenval = eigenValues(sub) if (eigenval != None): print(f"Substitution: {sub}\nMatrix:\n{matrix(sub)}\nEigenValues: {eigenval[0]}\nRight Eigenvectors: \n{eigenval[1]}") print() sub = {"a":"ab", "b":"c", "c":"a"} result = Substitution(sub, "a", 5) eigenval = eigenValues(sub) if (eigenval != None): print(f"Substitution: {sub}\nMatrix:\n{matrix(sub)}\nEigenValues: {eigenval[0]}\nRight Eigenvectors: \n{eigenval[1]}") print() sub = {"a":"abc", "b":"bbac", "c":"ccab"} result = Substitution(sub, "a", 5) eigenval = eigenValues(sub) if (eigenval != None): print(f"Substitution: {sub}\nMatrix:\n{matrix(sub)}\nEigenValues: {eigenval[0]}\nRight Eigenvectors: \n{eigenval[1]}") print() sub = {"a":"ab", "b":"bc", "c":"cd", "d":"da"} result = Substitution(sub, "a", 5) eigenval = eigenValues(sub) if (eigenval != None): print(f"Substitution: {sub}\nMatrix:\n{matrix(sub)}\n5th Iteration: {result}\nEigenValues: {eigenval[0]}\nRight Eigenvectors: \n{eigenval[1]}")
import time import numpy as np from Substitution import * '''----------------------------------------------------------- Substitution() Testing -----------------------------------------------------------''' def subsitutionTest(): sub = {"a":"ab", "b":"a"} curtime = time.time() result = Substitution(sub, "a", 5) posttime = time.time() totaltime = posttime - curtime print(f"out: {result}\nlength:{len(result)}\ntime: {totaltime}") substitution = {"a": "ac", "b" : "bd", "c":"a", "d":"db"} curtime = time.time() result = Substitution(substitution, "a", 5) posttime = time.time() totaltime = posttime - curtime print(f"out: {result}\nlength:{len(result)}\ntime: {totaltime}") substitution = {"a":"ab", "b":"bc", "c":"cd", "d":"da"} curtime = time.time() result = Substitution(substitution, "a", 5) posttime = time.time()
def _diff_ast(ast, wrt): """ Return an AST that is the derivative of ast with respect the variable with name 'wrt'. """ # For now, the strategy is to return the most general forms, and let # the simplifier take care of the special cases. if isinstance(ast, Name): if ast.name == wrt: return _ONE else: return _ZERO elif isinstance(ast, Const): return _ZERO elif isinstance(ast, Add) or isinstance(ast, Sub): # Just take the derivative of the arguments. The call to ast.__class__ # lets us use the same code from Add and Sub. return ast.__class__((_diff_ast(ast.left, wrt), _diff_ast(ast.right, wrt))) elif isinstance(ast, Mul) or isinstance(ast, Div): # Collect all the numerators and denominators together nums, denoms = [], [] AST._collect_num_denom(ast, nums, denoms) # Collect the numerator terms into a single AST num = AST._make_product(nums) # Take the derivative of the numerator terms as a product num_d = _product_deriv(nums, wrt) if not denoms: # If there is no denominator return num_d denom = AST._make_product(denoms) denom_d = _product_deriv(denoms, wrt) # Derivative of x/y is x'/y + -x*y'/y**2 term1 = Div((num_d, denom)) term2 = Div((Mul((UnarySub(num), denom_d)), Power((denom, Const(2))))) return Add((term1, term2)) elif isinstance(ast, Power): # Use the derivative of the 'pow' function ast = CallFunc(Name('pow'), [ast.left, ast.right]) return _diff_ast(ast, wrt) elif isinstance(ast, CallFunc): func_name = AST.ast2str(ast.node) args = ast.args args_d = [_diff_ast(arg, wrt) for arg in args] if _KNOWN_FUNCS.has_key((func_name, len(args))): form = copy.deepcopy(_KNOWN_FUNCS[(func_name, len(args))]) else: # If this isn't a known function, our form is # (f_0(args), f_1(args), ...) args_expr = [Name('arg%i' % ii) for ii in range(len(args))] form = [ CallFunc(Name('%s_%i' % (func_name, ii)), args_expr) for ii in range(len(args)) ] # We build up the terms in our derivative # f_0(x,y)*x' + f_1(x,y)*y', etc. outs = [] for arg_d, arg_form_d in zip(args_d, form): # We skip arguments with 0 derivative if arg_d == _ZERO: continue for ii, arg in enumerate(args): Substitution._sub_subtrees_for_vars(arg_form_d, {'arg%i' % ii: arg}) outs.append(Mul((arg_form_d, arg_d))) # If all arguments had zero deriviative if not outs: return _ZERO else: # We add up all our terms ret = outs[0] for term in outs[1:]: ret = Add((ret, term)) return ret elif isinstance(ast, UnarySub): return UnarySub(_diff_ast(ast.expr, wrt)) elif isinstance(ast, UnaryAdd): return UnaryAdd(_diff_ast(ast.expr, wrt))
def analyzeSubstitution(sub, iterations=5, initialState='a', debug=False): '''----------------------------------------------------------- Substitution -----------------------------------------------------------''' if (debug == True): curtime = time.time() pfEigenVector = pfEigenVal(sub) result = Substitution(sub, initialState, iterations) if (debug == True): print("Analysis time breakdown:") posttime = time.time() totaltime = posttime - curtime print(f"substitution time: {totaltime}") '''----------------------------------------------------------- SegmentList Construction -----------------------------------------------------------''' if (debug == True): curtime = time.time() segments = [] xvalue = 0 borderPercent = 0.03 keys = list(sub.keys()) for segment in result: segmentLength = pfEigenVector[keys.index(segment), 0] segmentBoundary = segmentLength * borderPercent newSegment = [(xvalue + segmentBoundary, 0)] xvalue += segmentLength newSegment.append((xvalue - segmentBoundary, 0)) segments.append(newSegment) if (debug == True): posttime = time.time() totaltime = posttime - curtime print(f"segmentlist time: {totaltime}") '''----------------------------------------------------------- ColorList Construction -----------------------------------------------------------''' if (debug == True): curtime = time.time() #setting up a list of colors to match the substitution result colorlist = ["#e89f73", "#4c91d1", "#c28897", "#c4e0ef", "#a0a5b1"] c = [] while (len(keys) > len(colorlist)): colorlist.append((np.random.rand(3, ))) for segment in result: c.append(colorlist[keys.index(segment)]) if (debug == True): posttime = time.time() totaltime = posttime - curtime print(f"color time: {totaltime}") '''----------------------------------------------------------- Legend Construction -----------------------------------------------------------''' legendList = [] legendCol = [] xvalue = 0 borderPercent = 0.01 for segment in keys: segmentLength = pfEigenVector[keys.index(segment), 0] segmentBoundary = segmentLength * borderPercent newSegment = [(xvalue + segmentBoundary, 0)] xvalue += segmentLength newSegment.append((xvalue - segmentBoundary, 0)) legendList.append(newSegment) legendCol.append(colorlist[keys.index(segment)]) '''----------------------------------------------------------- Drawing the Segments / Legend -----------------------------------------------------------''' if (debug == True): curtime = time.time() fig, ax = plt.subplots(2, 1) legendCol = mc.LineCollection(legendList, linewidths=10, colors=legendCol) ax[0].add_collection(legendCol) ax[0].margins(0.01) ax[0].set_ylim(-1, 1) ax[0].autoscale ax[0].grid() ax[0].yaxis.set_visible(False) xvalue = 0 for segment in keys: pfval = pfEigenVector[keys.index(segment), 0] xvalue += pfval ax[0].text(xvalue - (pfval / 2), 0.25, segment, fontsize=15) linecol = mc.LineCollection(segments, linewidths=10, colors=c) ax[1].add_collection(linecol) ax[1].margins(0.01) ax[1].autoscale ax[1].grid() ax[1].yaxis.set_visible(False) fig.suptitle("Substitution Segment Diagram for: " + str(sub).replace("'", ""), fontsize=16) if (debug == True): posttime = time.time() totaltime = posttime - curtime print(f"draw time: {totaltime}") print("--------------------------------------------------------------") plt.show()
def GUI(): header = '''----------------------------------------------------------------------------- One Dimenstional Subsitution Viewer - Orion Sehn 2021 -----------------------------------------------------------------------------''' standardSubs = [["Fibonacci", { "a": "ab", "b": "a" }], ["2-component Rauzy Fractal", { "a": "acb", "b": "c", "c": "a" }], ["A->AB, B->C, C->A", { "a": "ab", "b": "c", "c": "a" }], ["Central Fibonacci", { "a": "ac", "b": "db", "c": "b", "d": "a" }], [ "Infinite component Rauzy Fractal", { "a": "baca", "b": "aac", "c": "a" } ], ["Kidney and its dual", { "a": "ab", "b": "cb", "c": "a" }], [ "Kolakoski-(3,1) symmmetric variant, dual", { "a": "aca", "b": "a", "c": "b" } ], [ "Kolakoski-(3,1) variant A, with dual", { "a": "bcc", "b": "ba", "c": "bc" } ], [ "Kolakoski-(3,1) variant B, with dual", { "a": "abcc", "b": "a", "c": "bc" } ], [ "Kolakoski-(3,1), with dual", { "a": "abc", "b": "ab", "c": "b" } ], [ "Non-invertible connected Rauzy Fractal", { "a": "bacb", "b": "abc", "c": "ba" } ], [ "Non-reducible 4-letter", { "a": "aad", "b": "cd", "c": "cb", "d": "ab" } ], ["Period Doubling", { "a": "ab", "b": "aa" }], ["Smallest PV", { "a": "bc", "b": "c", "c": "a" }], ["Thue Morse", { "a": "ab", "b": "ba" }], ["Tribonacci", { "a": "ab", "b": "ac", "c": "a" }]] # print(standardSubs) options = ''' 1 - Define a Substitution 2 - View info about the Substitution 3 - View a symbolic text representaion of the Substitution 4 - View a segment diagram of the substitution 5 - View the diffraction intensity function for the Substitution 6 - View a projection of the diffraction pattern for the Substitution 7 - Select from saved common substitutions 8 - Quit ''' sub = {"a": "ab", "b": "a"} exitflag = False userinput = "" while (exitflag == False): print(header) print(options, "") userinput = input() if (userinput.strip() == "1"): print("Defining Substitution - (enter nothing to cancel)") numVar = input("Number of Variables: ") if (numVar != ""): asciicode = 97 newsub = dict() for i in range(int(numVar)): variable = chr(asciicode) newsub[variable] = input( f"Substitute {variable} with: ").strip() asciicode += 1 if isValid(newsub): print("New substitution defined: ") print(newsub) sub = newsub else: print(f"Substitution {newsub} is not a valid substitution") if (userinput.strip() == "2"): print("Printing info about the Substitution") substitutioninfo(sub) if (userinput.strip() == "3"): errorFlag = False print("Printing a symbolic text representaion of the Substitution") print("Default settings = (iterations = 5, initialstate 'a')") custom = input( "Enter c to enter custom parameters or press enter to use default: " ) if (custom.strip() == "c"): iterations = input("Enter a number of iterations: ") initialState = input("Define an initial state ie. (abba): ") #Error checking input for validity try: iterations = int(iterations) except: print("Iterations must be a natural number") errorFlag = True if (errorFlag == False): if (iterations < 0): print("Iterations must be greater than or equal to 0") errorFlag = True if (errorFlag == False): for char in initialState: if (char not in sub.keys()): print(f"Initialstate: {initialState} is not valid") errorFlag = True #Printing subsitution with custom parameters if (errorFlag == False): print() print(Substitution(sub, initialState, int(iterations))) else: print(Substitution(sub, "a", 5)) if (userinput.strip() == "4"): errorFlag = False print("Displaying a segment diagram of the substitution") print("Default settings = (iterations = 5, initialstate 'a')") custom = input( "Enter c to enter custom parameters or press enter to use default: " ) if (custom.strip() == "c"): iterations = input("Enter a number of iterations: ") initialState = input("Define an initial state ie. (abba): ") #Error checking input for validity try: iterations = int(iterations) except: print("Iterations must be a natural number") errorFlag = True if (errorFlag == False): if (iterations < 0): print("Iterations must be greater than or equal to 0") errorFlag = True if (errorFlag == False): for char in initialState: if (char not in sub.keys()): print(f"Initialstate: {initialState} is not valid") errorFlag = True if (errorFlag == False): analyzeSubstitution(sub, iterations, initialState) else: analyzeSubstitution(sub) if (userinput.strip() == "5"): errorFlag = False print( "Displaying diffraction intensity function for the Substitution" ) print("Default settings = (0 < x < 10, x interval = 0.01, k = 20)") custom = input( "Enter c to enter custom parameters or press enter to use default: " ) if (custom.strip() == "c"): xlower = input("Enter lower bound for x: ") xupper = input("Enter upper bound for x: ") xint = input("Enter value for x interval: ") k = input("Enter value for k: ") try: int(xlower) int(xupper) float(xint) int(k) except: print( "xlower, xupper and k must be natural numebrs, xint must be a decimal" ) errorFlag = True if (errorFlag == False): x, y = diffraction(sub, int(xlower), int(xupper), float(xint), int(k)) plt.plot(x, y) plt.title("Substitution Intensity Function for: " + str(sub).replace("'", ""), fontsize=16) plt.show() else: x, y = diffraction(sub) plt.plot(x, y) plt.title("Substitution Intensity Function for: " + str(sub).replace("'", ""), fontsize=16) plt.show() if (userinput.strip() == "6"): print( "Displaying projection of the diffraction pattern for the Substitution" ) fig, ax = plt.subplots(1, 1) X = projection(sub) lowerbound = 0 upperbound = 10 img = ax.imshow( X, extent=[lowerbound, upperbound, lowerbound, upperbound]) ax.yaxis.set_visible(False) fig.suptitle("Substitution Projection for: " + str(sub).replace("'", ""), fontsize=16) fig.colorbar(img) plt.show() if (userinput.strip() == "7"): print("Select from saved substitutions") index = 1 for standard in standardSubs: print(f"{index} - {standard[0]}") index += 1 userinput = input() try: userinput = int(userinput) except: print("Input Error - Try Again") if (1 <= userinput <= len(standardSubs)): sub = standardSubs[userinput - 1][1] print( f"Substitution {standardSubs[userinput - 1][0]} {standardSubs[userinput - 1][1]} Selected" ) else: print("Input Error - Try Again") userinput = "" if (userinput.strip() == "8"): print("Quit") exitflag = True