def cubic_0(): a2,a1,a0 = symbols("a2 a1 a0") x,y,z,l = symbols("x y z l") ez = z**3 + a2*z**2 + a1*z + a0 print "ez: %r (cubic with top coeff 1)" % ez ex = ez.subs(z, x-l ).subs(l, a2/3) print "ex: %r (shift to kill **2 term)" % ex print "ex: %r (shift to kill **2 term)" % expand(ex) cx = get_coeff(ex, x, 4 ) assert cx[2] == 0 # **2 term is killed p,q = symbols("p q", real=True) eq = (9*a2*a1 - 2*a2**3 - 27*a0)/27 ep = ( 3*a1 - a2**2)/3 simp = [ (eq*27, q*27), (ep*3, p*3) ] print_coeff(cx, "cx") subs_coeff(cx, simp) print_coeff(cx, "c-simp") ex2 = expr_coeff(cx, x) w= symbols("w") ew = expand(ex2.subs(x, w-p/(3*w) )) # Vieta's substitution ew2 = expand(ew*w**3) # becomes quadratic in w**3 w3= symbols("w3") ew3 = ew2.subs(w**3, w3) cw3 = get_coeff(ew3,w3,3) c,b,a = cw3 isc = b**2 - 4*a*c # quadratic, b^2 - 4ac , -b -sqrt() , -b+sqrt() r1 = (-b + sqrt(isc))/(2*a) r2 = (-b - sqrt(isc))/(2*a) print "r1:%s " % r1 print "r2:%s " % r2 print "isc: %r " % isc rr = solve(ew3, w3)
def torus_0(): x, y, z, r, R = symbols("x y z r R") expr = (x * x + y * y + z * z + R * R - r * r)**2 - 4 * R * R * (x * x + y * y) ox, oy, oz, t, sx, sy, sz, SS, OO, OS = symbols( "ox oy oz t sx sy sz SS OO OS") ray = [(x, ox + t * sx), (y, oy + t * sy), (z, oz + t * sz)] simp = [(sx**2 + sy**2 + sz**2, SS), (ox**2 + oy**2 + oz**2, OO), (ox * sx + oy * sy + oz * sz, OS)] expr2 = expr.subs(ray + simp) x_expr2 = expand(expr2) t_expr2 = collect(x_expr2, t) c = get_coeff(expr2, t, 5) subs_coeff(c, simp) print_coeff(c) return expr2, c
def cubic_1(): a,b,c = symbols("a b c") x,y = symbols("x y") ex = x**3 + a*x**2 + b*x + c print "ex:%s " % ex ey = expand(ex.subs([(x, y-a/3)])) print "ey:%s " % ey cy = get_coeff(ey, y, 4) eq = cy[0] ep = cy[1] print "eq:%s " % eq print "ep:%s " % ep z,p,q = symbols("z p q") simp = [ (eq*27, q*27), (ep*3, p*3) ] print_coeff(cy, "cy") subs_coeff(cy, simp) print_coeff(cy, "cy-simp") ez = expr_coeff(cy, z) print "ez:%s " % ez
def quartic_0(): a0, a1, a2, a3, a4 = symbols("a0 a1 a2 a3 a4") q0, q1, q2, q3, q4 = symbols("q0 q1 q2 q3 q4") x, z, l = symbols("x z l") ex_ = Pow(x, 4) + a3 * Pow(x, 3) + a2 * Pow(x, 2) + a1 * Pow( x, 1) + a0 # setting a4 to 1 ex = ex_.subs(x, x - l).subs(l, a3 / 4) # picking this l kills the x**3 term c = get_coeff(ex, x, 5) assert c[3] == 0 # x**3 term is killed p, q, r = symbols("p q r") simp = [(a2 - 3 * a3**2 / 8, p), (a1 - a2 * a3 / 2 + a3**3 / 8, q), (-a1 * a3 / 4 + a2 * a3**2 / 16 - 3 * a3**4 / 256, r)] cs = get_coeff_(ex, x, 5) print_coeff(cs, "cs")
def torus_1(): """ http://www.cosinekitty.com/raytrace/chapter13_torus.html Symbolic manipulations matching cosinekitty example * simplifying coeffs separately then putting back together seems an effective approach """ x, y, z, A, B = symbols("x y z A B") _sq_lhs = (x * x + y * y + z * z + A * A - B * B) _rhs = 4 * A * A * (x * x + y * y) ox, oy, oz, t, sx, sy, sz, SS, OO, OS = symbols( "ox oy oz t sx sy sz SS OO OS") ray = [(x, ox + t * sx), (y, oy + t * sy), (z, oz + t * sz)] simp0 = [(sx**2 + sy**2 + sz**2, SS), (ox**2 + oy**2 + oz**2, OO), (ox * sx + oy * sy + oz * sz, OS)] G, H, I, J, K, L = symbols("G H I J K L") exG = 4 * A * A * (sx * sx + sy * sy) exH = 8 * A * A * (ox * sx + oy * sy) exI = 4 * A * A * (ox * ox + oy * oy) exJ = sx * sx + sy * sy + sz * sz exK = 2 * (ox * sx + oy * sy + oz * sz) exL = ox * ox + oy * oy + oz * oz + A * A - B * B simp1 = [ (exG, G), (exH, H), (exI, I), (exJ, J), (exK / 2, K / 2), # fails to sub with 2 on other side (exL, L) ] sq_lhs = _sq_lhs.subs(ray + simp0) rhs = _rhs.subs(ray + simp0) cl = get_coeff(sq_lhs, t, 3) cr = get_coeff(rhs, t, 3) subs_coeff(cl, simp1) subs_coeff(cr, simp1) print_coeff(cl, "cl") print_coeff(cr, "cr") SQ_LHS = expr_coeff(cl, t) RHS = expr_coeff(cr, t) ex = Pow(SQ_LHS, 2) - RHS c = get_coeff(ex, t, 5) print_coeff(c, "c") exc = range(5) exc[4] = exJ**2 exc[3] = 2 * exJ * exK exc[2] = -exG + 2 * exJ * exL + exK**2 exc[1] = -exH + 2 * exK * exL exc[0] = -exI + exL**2 subs = {} subs["O->X+"] = [(ox, 0), (oy, 0), (oz, 0), (sx, 1), (sy, 0), (sz, 0)] subs["zenith->-Z"] = [(ox, 0), (oy, 0), (oz, A), (sx, 0), (sy, 0), (sz, -1)] subs["corner"] = [(ox, A), (oy, A), (oz, A), (sx, -isq3), (sy, -isq3), (sz, -isq3)] radii = [(A, 500), (B, 50)] for key in subs: print("\n\n", key) for j, exc_ in enumerate(exc): print("\n", j, exc_) print(exc_.subs(subs[key])) print(exc_.subs(subs[key]).subs(radii)) return ex, cl