def test_derivatives_in_rectangular_coordinates(): with GA_Printer(): X = (x, y, z) = symbols('x y z') (ex, ey, ez, grad) = MV.setup('e_x e_y e_z', metric='[1,1,1]', coords=X) f = MV('f', 'scalar', fct=True) A = MV('A', 'vector', fct=True) B = MV('B', 'grade2', fct=True) C = MV('C', 'mv', fct=True) assert str(f) == 'f' assert str(A) == 'A__x*e_x + A__y*e_y + A__z*e_z' assert str(B) == 'B__xy*e_x^e_y + B__xz*e_x^e_z + B__yz*e_y^e_z' assert str(C) == 'C + C__x*e_x + C__y*e_y + C__z*e_z + C__xy*e_x^e_y + C__xz*e_x^e_z + C__yz*e_y^e_z + C__xyz*e_x^e_y^e_z' assert str(grad*f) == 'D{x}f*e_x + D{y}f*e_y + D{z}f*e_z' assert str(grad | A) == 'D{x}A__x + D{y}A__y + D{z}A__z' assert str(grad*A) == 'D{x}A__x + D{y}A__y + D{z}A__z + (-D{y}A__x + D{x}A__y)*e_x^e_y + (-D{z}A__x + D{x}A__z)*e_x^e_z + (-D{z}A__y + D{y}A__z)*e_y^e_z' assert str(-MV.I*(grad ^ A)) == '(-D{z}A__y + D{y}A__z)*e_x + (D{z}A__x - D{x}A__z)*e_y + (-D{y}A__x + D{x}A__y)*e_z' assert str(grad*B) == '(-(D{y}B__xy + D{z}B__xz))*e_x + (D{x}B__xy - D{z}B__yz)*e_y + (D{x}B__xz + D{y}B__yz)*e_z + (D{z}B__xy - D{y}B__xz + D{x}B__yz)*e_x^e_y^e_z' assert str(grad ^ B) == '(D{z}B__xy - D{y}B__xz + D{x}B__yz)*e_x^e_y^e_z' assert str(grad | B) == '(-(D{y}B__xy + D{z}B__xz))*e_x + (D{x}B__xy - D{z}B__yz)*e_y + (D{x}B__xz + D{y}B__yz)*e_z' assert str(grad < A) == 'D{x}A__x + D{y}A__y + D{z}A__z' assert str(grad > A) == 'D{x}A__x + D{y}A__y + D{z}A__z' assert str(grad < B) == '(-(D{y}B__xy + D{z}B__xz))*e_x + (D{x}B__xy - D{z}B__yz)*e_y + (D{x}B__xz + D{y}B__yz)*e_z' assert str(grad > B) == '0' assert str(grad < C) == 'D{x}C__x + D{y}C__y + D{z}C__z + (-(D{y}C__xy + D{z}C__xz))*e_x + (D{x}C__xy - D{z}C__yz)*e_y + (D{x}C__xz + D{y}C__yz)*e_z + D{z}C__xyz*e_x^e_y - D{y}C__xyz*e_x^e_z + D{x}C__xyz*e_y^e_z' assert str(grad > C) == 'D{x}C__x + D{y}C__y + D{z}C__z + D{x}C*e_x + D{y}C*e_y + D{z}C*e_z' return
def test_derivatives_in_spherical_coordinates(): GA_Printer.on() X = (r, th, phi) = symbols('r theta phi') curv = [[r * cos(phi) * sin(th), r * sin(phi) * sin(th), r * cos(th)], [1, r, r * sin(th)]] (er, eth, ephi, grad) = MV.setup('e_r e_theta e_phi', metric='[1,1,1]', coords=X, curv=curv) f = MV('f', 'scalar', fct=True) A = MV('A', 'vector', fct=True) B = MV('B', 'grade2', fct=True) assert str(f) == 'f' assert str(A) == 'A__r*e_r + A__theta*e_theta + A__phi*e_phi' assert str( B ) == 'B__rtheta*e_r^e_theta + B__rphi*e_r^e_phi + B__thetaphi*e_theta^e_phi' assert str( grad * f) == 'D{r}f*e_r + D{theta}f/r*e_theta + D{phi}f/(r*sin(theta))*e_phi' assert str( grad | A ) == 'D{r}A__r + 2*A__r/r + A__theta*cos(theta)/(r*sin(theta)) + D{theta}A__theta/r + D{phi}A__phi/(r*sin(theta))' assert str( -MV.I * (grad ^ A) ) == '((A__phi*cos(theta)/sin(theta) + D{theta}A__phi - D{phi}A__theta/sin(theta))/r)*e_r + (-D{r}A__phi - A__phi/r + D{phi}A__r/(r*sin(theta)))*e_theta + (D{r}A__theta + A__theta/r - D{theta}A__r/r)*e_phi' assert str( grad ^ B ) == '(D{r}B__thetaphi - B__rphi*cos(theta)/(r*sin(theta)) + 2*B__thetaphi/r - D{theta}B__rphi/r + D{phi}B__rtheta/(r*sin(theta)))*e_r^e_theta^e_phi' GA_Printer.off() return
def test_str(): e_1, e_2, e_3 = MV.setup('e_1 e_2 e_3', '1 0 0, 0 1 0, 0 0 1') X = MV('x') assert str(X) == 'x + x__1*e_1 + x__2*e_2 + x__3*e_3 + x__12*e_1^e_2 + x__13*e_1^e_3 + x__23*e_2^e_3 + x__123**e_1^e_2^e_3' Y = MV('y', 'spinor') assert str(Y) == 'y + y__12*e_1^e_2 + y__13*e_1^e_3 + y__23*e_2^e_3' Z = X + Y assert str(Z) == 'x + y + x__1*e_1 + x__2*e_2 + x__3*e_3 + (x__12 + y__12)*e_1^e_2 + (x__13 + y__13)*e_1^e_3 + (x__23 + y__23)*e_2^e_3 + x__123*e_1^e_2^e_3' assert str(e_1 | e_1) == '1'
def test_derivative(): coords = x, y, z = symbols('x y z') e_x, e_y, e_z, _ = MV.setup('e', '1 0 0, 0 1 0, 0 0 1', coords=coords) X = x * e_x + y * e_y + z * e_z a = MV('a', 'vector') assert ((X | a).grad()) == a assert ((X * X).grad()) == 2 * X assert (X * X * X).grad() == 5 * X * X assert X.grad_int() == 3
def test_metrics_xfail(): from sympy.galgebra.ga import arbitrary_metric_conformal metric = arbitrary_metric_conformal(3) p1, p2, p3 = MV.setup('p1 p2 p3', metric, debug=0) v1 = x1 * p1 + y1 * p2 + z1 * p3 v2 = x2 * p1 + y2 * p2 + z2 * p3 prod1 = v1 * v2 prod2 = (v1 | v2) + (v1 ^ v2) diff = prod1 - prod2 assert diff == MV(S.Zero)
def make_vector(a, m=3): global n, nbar if isinstance(a, str): sym_str = '' for i in range(m): sym_str += a + str(i + 1) + ' ' sym_lst = list(symbols(sym_str)) sym_lst.append(S.Zero) sym_lst.append(S.Zero) a = MV(sym_lst, 'vector') return F(a, n, nbar)
def main(): enhance_print() (ex, ey, ez) = MV.setup('e*x|y|z', metric='[1,1,1]') u = MV('u', 'vector') v = MV('v', 'vector') w = MV('w', 'vector') print(u) print(v) print(w) uv = u ^ v print(uv) print(uv.is_blade()) uvw = u ^ v ^ w print(uvw) print(uvw.is_blade()) print(simplify((uv * uv).scalar())) return
def test_geometry(): """ Test conformal geometric description of circles, lines, spheres, and planes. """ metric = '1 0 0 0 0,' + \ '0 1 0 0 0,' + \ '0 0 1 0 0,' + \ '0 0 0 0 2,' + \ '0 0 0 2 0' e0, e1, e2, n, nbar = MV.setup('e0 e1 e2 n nbar', metric, debug=0) e = n + nbar #conformal representation of points A = F(e0, n, nbar) # point a = (1,0,0) A = F(a) B = F(e1, n, nbar) # point b = (0,1,0) B = F(b) C = F(-1 * e0, n, nbar) # point c = (-1,0,0) C = F(c) D = F(e2, n, nbar) # point d = (0,0,1) D = F(d) x0, x1, x2 = symbols('x0 x1 x2') X = F(MV([x0, x1, x2], 'vector'), n, nbar) Circle = A ^ B ^ C ^ X Line = A ^ B ^ n ^ X Sphere = A ^ B ^ C ^ D ^ X Plane = A ^ B ^ n ^ D ^ X #Circle through a, b, and c Circle_test = -x2 * (e0 ^ e1 ^ e2 ^ n) + x2 * ( e0 ^ e1 ^ e2 ^ nbar) + Rational( 1, 2) * (-1 + x0**2 + x1**2 + x2**2) * (e0 ^ e1 ^ n ^ nbar) diff = Circle - Circle_test assert diff == S.Zero #Line through a and b Line_test = -x2*(e0 ^ e1 ^ e2 ^ n) + \ Rational(1, 2)*(-1 + x0 + x1)*(e0 ^ e1 ^ n ^ nbar) + \ (Rational(1, 2)*x2)*(e0 ^ e2 ^ n ^ nbar) + \ (-Rational(1, 2)*x2)*(e1 ^ e2 ^ n ^ nbar) diff = Line - Line_test assert diff == S.Zero #Sphere through a, b, c, and d Sphere_test = Rational( 1, 2) * (1 - x0**2 - x1**2 - x2**2) * (e0 ^ e1 ^ e2 ^ n ^ nbar) diff = Sphere - Sphere_test assert diff == S.Zero #Plane through a, b, and d Plane_test = Rational(1, 2) * (1 - x0 - x1 - x2) * (e0 ^ e1 ^ e2 ^ n ^ nbar) diff = Plane - Plane_test assert diff == S.Zero
def DD(self, v, f, opstr=False): mf_comp = [] for e in self.rbasis: mf_comp.append((v | e).scalar() / self.E_sq) result = MV() op = '' for (coord, comp) in zip(self.coords, mf_comp): result += comp * (f.diff(coord)) if opstr: op += '(' + str(comp) + ')D{' + str(coord) + '}+' if opstr: return str(result), op[:-1] return result
def test_constructor(): """ Test various multivector constructors """ e_1, e_2, e_3 = MV.setup('e_1 e_2 e_3', '[1,1,1]') assert str(MV('a', 'scalar')) == 'a' assert str(MV('a', 'vector')) == 'a__1*e_1 + a__2*e_2 + a__3*e_3' assert str(MV('a', 'pseudo')) == 'a__123*e_1^e_2^e_3' assert str(MV('a', 'spinor')) == 'a + a__12*e_1^e_2 + a__13*e_1^e_3 + a__23*e_2^e_3' assert str(MV('a')) == 'a + a__1*e_1 + a__2*e_2 + a__3*e_3 + a__12*e_1^e_2 + a__13*e_1^e_3 + a__23*e_2^e_3 + a__123*e_1^e_2^e_3' assert str(MV([2, 'a'], 'grade')) == 'a__12*e_1^e_2 + a__13*e_1^e_3 + a__23*e_2^e_3' assert str(MV('a', 'grade2')) == 'a__12*e_1^e_2 + a__13*e_1^e_3 + a__23*e_2^e_3'
def test_metrics(): """ Test specific metrics (diagpq, arbitrary_metric, arbitrary_metric_conformal) """ from sympy.galgebra.ga import diagpq, arbitrary_metric, arbitrary_metric_conformal metric = diagpq(3) p1, p2, p3 = MV.setup('p1 p2 p3', metric, debug=0) x1, y1, z1 = symbols('x1 y1 z1') x2, y2, z2 = symbols('x2 y2 z2') v1 = x1 * p1 + y1 * p2 + z1 * p3 v2 = x2 * p1 + y2 * p2 + z2 * p3 prod1 = v1 * v2 prod2 = (v1 | v2) + (v1 ^ v2) diff = prod1 - prod2 assert diff == MV(S.Zero) metric = arbitrary_metric(3) p1, p2, p3 = MV.setup('p1 p2 p3', metric, debug=0) v1 = x1 * p1 + y1 * p2 + z1 * p3 v2 = x2 * p1 + y2 * p2 + z2 * p3 prod1 = v1 * v2 prod2 = (v1 | v2) + (v1 ^ v2) diff = prod1 - prod2 assert diff == MV(S.Zero)
def test_basic_multivector_operations(): with GA_Printer(): (ex, ey, ez) = MV.setup('e*x|y|z') A = MV('A', 'mv') assert str(A) == 'A + A__x*e_x + A__y*e_y + A__z*e_z + A__xy*e_x^e_y + A__xz*e_x^e_z + A__yz*e_y^e_z + A__xyz*e_x^e_y^e_z' assert str(A) == 'A + A__x*e_x + A__y*e_y + A__z*e_z + A__xy*e_x^e_y + A__xz*e_x^e_z + A__yz*e_y^e_z + A__xyz*e_x^e_y^e_z' assert str(A) == 'A + A__x*e_x + A__y*e_y + A__z*e_z + A__xy*e_x^e_y + A__xz*e_x^e_z + A__yz*e_y^e_z + A__xyz*e_x^e_y^e_z' X = MV('X', 'vector') Y = MV('Y', 'vector') assert str(X) == 'X__x*e_x + X__y*e_y + X__z*e_z' assert str(Y) == 'Y__x*e_x + Y__y*e_y + Y__z*e_z' assert str((X*Y)) == '(e_x.e_x)*X__x*Y__x + (e_x.e_y)*X__x*Y__y + (e_x.e_y)*X__y*Y__x + (e_x.e_z)*X__x*Y__z + (e_x.e_z)*X__z*Y__x + (e_y.e_y)*X__y*Y__y + (e_y.e_z)*X__y*Y__z + (e_y.e_z)*X__z*Y__y + (e_z.e_z)*X__z*Y__z + (X__x*Y__y - X__y*Y__x)*e_x^e_y + (X__x*Y__z - X__z*Y__x)*e_x^e_z + (X__y*Y__z - X__z*Y__y)*e_y^e_z' assert str((X ^ Y)) == '(X__x*Y__y - X__y*Y__x)*e_x^e_y + (X__x*Y__z - X__z*Y__x)*e_x^e_z + (X__y*Y__z - X__z*Y__y)*e_y^e_z' assert str((X | Y)) == '(e_x.e_x)*X__x*Y__x + (e_x.e_y)*X__x*Y__y + (e_x.e_y)*X__y*Y__x + (e_x.e_z)*X__x*Y__z + (e_x.e_z)*X__z*Y__x + (e_y.e_y)*X__y*Y__y + (e_y.e_z)*X__y*Y__z + (e_y.e_z)*X__z*Y__y + (e_z.e_z)*X__z*Y__z' (ex, ey) = MV.setup('e*x|y') X = MV('X', 'vector') A = MV('A', 'spinor') assert str(X) == 'X__x*e_x + X__y*e_y' assert str(A) == 'A + A__xy*e_x^e_y' assert str((X | A)) == '(-A__xy*((e_x.e_y)*X__x + (e_y.e_y)*X__y))*e_x + (A__xy*((e_x.e_x)*X__x + (e_x.e_y)*X__y))*e_y' assert str((X < A)) == '(-A__xy*((e_x.e_y)*X__x + (e_y.e_y)*X__y))*e_x + (A__xy*((e_x.e_x)*X__x + (e_x.e_y)*X__y))*e_y' assert str((A > X)) == '(A__xy*((e_x.e_y)*X__x + (e_y.e_y)*X__y))*e_x + (-A__xy*((e_x.e_x)*X__x + (e_x.e_y)*X__y))*e_y' (ex, ey) = MV.setup('e*x|y', metric='[1,1]') X = MV('X', 'vector') A = MV('A', 'spinor') assert str(X) == 'X__x*e_x + X__y*e_y' assert str(A) == 'A + A__xy*e_x^e_y' assert str((X*A)) == '(A*X__x - A__xy*X__y)*e_x + (A*X__y + A__xy*X__x)*e_y' assert str((X | A)) == '-A__xy*X__y*e_x + A__xy*X__x*e_y' assert str((X < A)) == '-A__xy*X__y*e_x + A__xy*X__x*e_y' assert str((X > A)) == 'A*X__x*e_x + A*X__y*e_y' assert str((A*X)) == '(A*X__x + A__xy*X__y)*e_x + (A*X__y - A__xy*X__x)*e_y' assert str((A | X)) == 'A__xy*X__y*e_x - A__xy*X__x*e_y' assert str((A < X)) == 'A*X__x*e_x + A*X__y*e_y' assert str((A > X)) == 'A__xy*X__y*e_x - A__xy*X__x*e_y' return
def __init__(self, x, coords, debug=False, I=None): """ coords: list of coordinate variables x: vector fuction of coordinate variables (parametric surface) """ self.I = I self.x = x self.coords = coords self.basis = [] self.basis_str = [] self.embedded_basis = [] for u in coords: tv = x.diff(u) self.basis.append(tv) (coefs, bases) = linear_expand(tv.obj) tc = {} for (coef, base) in zip(coefs, bases): str_base = str(base) tc[str_base] = coef if str_base not in self.embedded_basis: self.embedded_basis.append(str_base) self.basis_str.append(tc) self.gij = [] for base1 in self.basis: tmp = [] for base2 in self.basis: tmp.append(simplify(trigsimp((base1 | base2).scalar()))) self.gij.append(tmp) for tv in self.basis_str: for base in self.embedded_basis: if base not in tv: tv[base] = 0 self.dim = len(self.basis) indexes = tuple(range(self.dim)) self.index = [()] for i in indexes: self.index.append(tuple(combinations(indexes, i + 1))) self.index = tuple(self.index) self.MFbasis = [[MV.ONE], self.basis] for igrade in self.index[2:]: grade = [] for iblade in igrade: blade = MV(1, 'scalar') for ibasis in iblade: blade ^= self.basis[ibasis] blade = blade.trigsimp(deep=True, recursive=True) grade.append(blade) self.MFbasis.append(grade) self.E = self.MFbasis[-1][0] self.E_sq = trigsimp((self.E * self.E).scalar(), deep=True, recursive=True) duals = copy.copy(self.MFbasis[-2]) duals.reverse() sgn = 1 self.rbasis = [] for dual in duals: recpv = (sgn * dual * self.E).trigsimp(deep=True, recursive=True) self.rbasis.append(recpv) sgn = -sgn self.dbasis = [] for base in self.basis: dbase = [] for coord in self.coords: d = base.diff(coord).trigsimp(deep=True, recursive=True) dbase.append(d) self.dbasis.append(dbase) self.surface = {} (coefs, bases) = linear_expand(self.x.obj) for (coef, base) in zip(coefs, bases): self.surface[str(base)] = coef self.grad = MV() self.grad.is_grad = True self.grad.blade_rep = True self.grad.igrade = 1 self.grad.rcpr_bases_MV = [] for rbase in self.rbasis: self.grad.rcpr_bases_MV.append(rbase / self.E_sq) self.grad.rcpr_bases_MV = tuple(self.grad.rcpr_bases_MV) self.grad.coords = self.coords self.grad.norm = self.E_sq self.grad.connection = {} if debug: oprint('x', self.x, 'coords', self.coords, 'basis vectors', self.basis, 'index', self.index, 'basis blades', self.MFbasis, 'E', self.E, 'E**2', self.E_sq, '*basis', duals, 'rbasis', self.rbasis, 'basis derivatives', self.dbasis, 'surface', self.surface, 'basis strings', self.basis_str, 'embedding basis', self.embedded_basis, 'metric tensor', self.gij)