def create_mesh_mapping_nodes(a): x0 = -1 y0 = 1 count = 0 mapping = {} elements = [] nodes = [] while (not math.isclose(x0, 1, rel_tol=1e-5) and not math.isclose(y0, -1, rel_tol=1e-5)) or ( math.isclose(x0, 1, rel_tol=1e-5) and not math.isclose(y0, -1, rel_tol=1e-5)) or ( not math.isclose(x0, 1, rel_tol=1e-5) and math.isclose(y0, -1, rel_tol=1e-5)): if 0 < y0 <= 1: if x0 <= 1: if is_in_area(x0, y0 - a): elements.append(Elem(Fract(x0), y0 - a, a)) mapping[(x0, y0)] = count nodes.append((x0, y0)) count += 1 x0 += a else: x0 = -1 y0 -= a else: if x0 <= 1: if is_in_area(x0, y0 - a): elements.append(Elem(Fract(x0), y0 - a, a)) mapping[(x0, y0)] = count nodes.append((x0, y0)) count += 1 x0 += a else: x0 = 0 y0 -= a mapping[1, -1] = count return mapping, elements, nodes
tests = [[[150,[100,200,300]],[50,50,50]]] tests += [[[200,[100,200,300]],[50,75,75]]] tests += [[[300,[100,200,300]],[50,100,150]]] tests += [[[400,[100,200,300]],[50,125,225]]] tests += [[[600,[100,200,300]],[100,200,300]]] for i in tests: actual = divide_estate(*i[0]) expected = i[1] assert actual == expected, print("expected",expected,"\nactual",actual) if __name__ == '__main__': import sys, re def print_help(): s = ['no arguments: prints help string', '\n-f: total estate funds to allocate', '\n-c: sorted comma-separated list of debts', '\nusage example:', '\n talmud_estate_division.py -f 200 -c 100,200,300'] print(*s) creditors = estate = None prev_arg = '' for i in sys.argv[1:]: if prev_arg == '-f': if re.fullmatch('\d+(\.\d*)?',i): estate = Fract(i) elif prev_arg == '-c': if re.fullmatch('(\d+(\.\d*)?,)*\d+(\.\d*)?',i): creditors = [Fract(j) for j in i.split(',')] prev_arg = i if creditors and estate: print(str([float(i) for i in divide_estate(estate,creditors)])[1:-1]) else: print_help()
def wblueq(a1, b1, a2, b2): return (a2 - a1) * (a2 - a1) + (b2 - b1) * (b2 - b1) for m in range(-depth, depth): for n in range(-depth, depth): for m1 in range(-depth, depth): for n1 in range(-depth, depth): if m + n == 0: continue if m1 + n1 == 0: continue bq, rq, gq = blueq(m, n), redq(m, n), greenq(m, n) bq1, rq1, gq1 = blueq(m1, n1), redq(m1, n1), greenq(m1, n1) wbq1 = wblueq(-n1, 0, m1, n1) z = small_radius * Fract(rq1, wbq1) l = small_radius * Fract(gq1, bq1) x = (big_radius - l) * Fract(rq, bq) y = (big_radius - l) * Fract(gq, bq) print x, y, z, ' sq sum: ', x * x + y * y + z * z xs += [x] ys += [z] zs += [y] max = max(xs + ys + zs) for i in range(0, len(xs)): xs[i] = Fract(xs[i], max) ys[i] = Fract(ys[i], max) zs[i] = Fract(zs[i], max) print len(xs)
# y = (greenq/redq) / blueq( blueq/redq, greenq/redq ) # where q = quadrance between 0,0 and integer point m,n # please see pythbernlem.py for full explanation def sqr(x): return x*x def greenq(x,y,x2,y2): return 2*(x2-x)*(y2-y) def redq(x,y,x2,y2): return sqr(x2-x)-sqr(y2-y) def blueq(x,y,x2,y2): return sqr(x2-x)+sqr(y2-y) xs,ys=[],[] depth = 20 for m in range(-depth,depth): for n in range(-depth,depth): if redq(0,0,m,n)==0: continue if greenq(0,0,m,n)==0: continue bq,rq,gq = blueq(0,0,m,n),redq(0,0,m,n),greenq(0,0,m,n) x = Fract( Fract(bq,gq), blueq(0,0,Fract(bq,gq),Fract(bq,rq)) ) y = Fract( Fract(rq,rq), blueq(0,0,Fract(rq,gq),Fract(rq,rq)) ) xs += [x] ys += [y] max=max(xs+ys) for i in range(0,2): print xs[i],',',ys[i], print '....' for i in range(0,len(xs)): xs[i] = Fract( xs[i], max ) ys[i] = Fract( ys[i], max ) print len(xs), 'points' import numpy as np import matplotlib.pylab as plt
def redq(x, y, x2, y2): return sqr(x2 - x) - sqr(y2 - y) def blueq(x, y, x2, y2): return sqr(x2 - x) + sqr(y2 - y) xs, ys = [], [] depth = 20 for m in range(-depth, depth): for n in range(-depth, depth): if redq(0, 0, m, n) == 0: continue if greenq(0, 0, m, n) == 0: continue bq, rq, gq = blueq(0, 0, m, n), redq(0, 0, m, n), greenq(0, 0, m, n) x = Fract(Fract(gq, bq), blueq(0, 0, Fract(rq, bq), Fract(rq, bq))) y = Fract(Fract(rq, bq), blueq(0, 0, Fract(gq, bq), Fract(gq, bq))) xs += [x] ys += [y] max = max(xs + ys) for i in range(0, 2): print xs[i], ',', ys[i], print '....' for i in range(0, len(xs)): xs[i] = Fract(xs[i], max) ys[i] = Fract(ys[i], max) print len(xs), 'points' import numpy as np import matplotlib.pylab as plt
def solver(): a1 = int(input('enter size(1/a)> ')) a = Fract(1, a1) mapping, elements, nodes = create_mesh_mapping_nodes(a) nodes_number = int(3 * a1 * a1 + 2 * (a1 + a1) + 1) B = np.zeros((nodes_number, nodes_number)) L = np.zeros((nodes_number, 1)) for elem in elements: position = elem.get_cords() (x, y) = elem.get_pos() for index in range(4): pos_1 = position[index] pos_2 = position[(index + 1) % 4] (x0, y0) = pos_1 (xn, yn) = pos_2 if check_if_neumann([pos_1, pos_2]): xh = float(xn / 2 + x0 / 2) yh = float(yn / 2 + y0 / 2) L[mapping[position[0]]] += l_fun(xh, yh, fis[0], x, y, a) L[mapping[position[1]]] += l_fun(xh, yh, fis[1], x, y, a) L[mapping[position[2]]] += l_fun(xh, yh, fis[2], x, y, a) L[mapping[position[3]]] += l_fun(xh, yh, fis[3], x, y, a) for index2 in range(4): B[mapping.get(position[index])][mapping.get( position[index2])] += b(index, index2, a) for node in mapping: if check_if_dirichlet(node): B[mapping[node]] = 0 L[mapping[node]] = 0 B[mapping[node]][mapping[node]] = 1 A = np.linalg.solve(B, L) n = 30 xs = np.linspace(-1, 1, n) ys = np.linspace(-1, 1, n) Z = np.zeros((len(xs), len(ys))) for (i, x) in enumerate(xs): for (j, y) in enumerate(ys): match_elem = None for elem in elements: (x0, y0) = elem.get_pos() (x1, y1) = elem.get_top_pos() if (x0 <= x <= x1) and (y0 <= y <= y1): match_elem = elem break if match_elem is None: continue (bx, by) = match_elem.get_pos() position = match_elem.get_cords() Z[i, j] += A[mapping.get(position[0])] * fis[0](x, y, bx, by, a) # phi0 Z[i, j] += A[mapping.get(position[1])] * fis[1](x, y, bx, by, a) # phi1 Z[i, j] += A[mapping.get(position[2])] * fis[2](x, y, bx, by, a) # phi2 Z[i, j] += A[mapping.get(position[3])] * fis[3](x, y, bx, by, a) # phi3 fig = plt.figure(figsize=(15, 10)) ax = fig.gca(projection='3d') X, Y = np.meshgrid(xs, ys) ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=plt.get_cmap('jet')) ax.view_init(45, 240) plt.show()
def greenq(a, b): return 2 * a * b for m1 in range(-depth, depth): for n1 in range(-depth, depth): for m2 in range(-depth / 2, depth / 2): for n2 in range(-depth / 2, depth / 2): blue1, red1, green1 = blueq(m1, n1), redq(m1, n1), greenq(m1, n1) blue2, red2, green2 = blueq(m2, n2), redq(m2, n2), greenq(m2, n2) if red1 == 0: continue if blue2 == 0: continue xh = Fract(blue1, red1) yh = Fract(green1, red1) OH = blueq(xh, yh) x = Fract(k, OH) * xh l = Fract(k, OH) * yh y = l * Fract(green2, blue2) z = l * Fract(red2, blue2) #print x,y,z,' sq sum: ',x*x+y*y+z*z xs += [x] ys += [y] zs += [z] max = max(xs + ys + zs) for i in range(0, len(xs)): xs[i] = Fract(xs[i], max) ys[i] = Fract(ys[i], max)
def invert(matrix): """Inverts the matrix. Requires python's Fract library. If matrix is singular, prints 'Inversion impossible' and returns nothing. """ matrix = as_Fractions(matrix) accum = deepcopy(matrix) size = len(matrix) inverse_accum = identity_matrix(size) row = 0 # row being processed singular = False loopcount = 0 # this while loop makes the matrix triangular while row < size: loopcount += 1 # make matrix[row][row] = 1 if it doesn't already # eliminate all entries below matrix[row][row] # then accum will be triangular upper try: row_op = create_row_operation(size,row,row,Fract(1,accum[row][row])) except(ZeroDivisionError): # currently singular, attempt fixing # if it can't be fixed, throw an exception # and the original matrix will be modified # print("Singular matrix found:") # print(accum) # print("Attempting fix by swapping for a later row") fix = -1 for i in range(row+1, size): # print("Testing row "+str(i)+" out of "+str(size)) if accum[i][row] != 0: # print("Row "+str(i)+" will fix") fix = i break if fix == -1: print('Inversion impossible'); return row_op = rowSwap(size,fix,row) ("Matrix operation: "+ str(row_op)) # print("Accumulated: " + str(accum)) accum = matrix_multiply(row_op,accum) # print("After operation: " + str(accum)) inverse_accum = matrix_multiply(row_op,inverse_accum) if accum[row][row] == 1: # print("Checking "+str(column(accum,row)[(row+1):])+" against "+str([0]*(size-row-1))) if column(accum,row)[(row+1):] == [0]*(size-row-1): # print("Row "+str(row)+" finished, progressing") row += 1 else: # need to make the zeroes below the cursor for i in range(row+1, size): # Need to nullify below accum[i][row], to maintain invariant row_op = create_row_operation(size,row,i,-accum[i][row]) # print("Matrix operation: "+ str(row_op)) # print("Accumulated: " + str(accum)) accum = matrix_multiply(row_op,accum) # print("After operation: " + str(accum)) inverse_accum = matrix_multiply(row_op,inverse_accum) # print("Column below "+str(row)+","+str(row)+" should be zeroes:") # print(accum) # this while loop performs backsubstitution row = size-1 while row >= 0: # cursor starts at bottom-right, zeros out everything above # then moves up 1, left 1, repeats # print("Checking "+str(column(accum,row)[:row])+" against "+str([0]*(row))) if column(accum,row)[0:row] == [0]*(row): # print("Row "+str(row)+" finished, progressing") row -= 1 else: for i in range(0,row): row_op = create_row_operation(size,row,i,-accum[i][row]) # print("Matrix operation: "+ str(row_op)) # print("Accumulated: " + str(accum)) accum = matrix_multiply(row_op,accum) # print("After operation: " + str(accum)) inverse_accum = matrix_multiply(row_op,inverse_accum) # print("Accumulated: should be identity matrix") # print(accum) # print("Accumulated matrix operations (aka inverse):") # print(inverse_accum) return inverse_accum
def as_Fractions(matrix): return [[Fract(j) for j in i] for i in matrix]