def testBladeOuterScaleMultplicative(): # multiplicative scaling B1 = Blade(np.array([2, 0])) B2 = Blade(np.array([0, 1])) result1 = bd.outer(B1, B2) print 'B1 outer B2 s: ', result1.s print 'B1 outer B2 blade: ', result1.blade assert la.det(result1.blade) > 0, la.det(result1.blade) assert result1.blade.shape == (2, 2), result1.blade.shape assert np.allclose(np.eye(2), np.dot(result1.blade.T, result1.blade)) assert np.allclose(bd.inner(result1, result1).s, -4), bd.inner(result1, result1).s result2 = bd.outer(B2, B1) print 'B2 outer B1 s: ', result2.s print 'B2 outer B1 blade: ', result2.blade assert la.det(result2.blade) < 0, la.det(result2.blade) assert result2.blade.shape == (2, 2), result2.blade.shape assert np.allclose(np.eye(2), np.dot(result2.blade.T, result2.blade)) assert np.allclose(bd.inner(result2, result2).s, -4), bd.inner(result2, result2).s # result1 == inverse(result2) assert np.allclose(bd.inner(result1, result2).s, 4), bd.inner(result1, result2).s
def testBladeOuterScalar(): # scalar to blade/ scalar to scalar B1 = Blade(np.eye(2)) B2 = Blade(1, s=2) result1 = bd.outer(B1, B2) print 'B1 outer B2 s: ', result1.s assert np.allclose(2, result1.s), 'value' assert result1.blade.shape == (2, 2), 'shape' result2 = bd.outer(B2, B1) print 'B2 outer B1 s: ', result2.s assert np.allclose(2, result2.s), 'value' assert result2.blade.shape == (2, 2), 'shape' result3 = bd.outer(B2, B2) print 'B2 outer B2 s: ', result3.s assert np.allclose(result3.s, 4) B1 = Blade(1, s=2) B2 = Blade(1, s=-.5) result1 = bd.outer(B1, B2) print 'B1 outer B2 s: ', result1.s assert np.allclose(-1, result1.s), 'value' assert result1.blade.shape == (1, 0), 'shape'
def testBladeDualEuclidean(): # s=0 B = Blade(0) try: D = bd.dual(B) except AttributeError as err: assert err[0] == 'Not dualizable, s=0' except: assert False, err # scalar, expect a 2-blade A = Blade(2) D = bd.dual(A, n=2) revPseudo = bd.outer(bd.inverse(A), D) shouldBeOne = bd.inner(revPseudo, bd.pseudoScalar(2)) assert np.allclose(shouldBeOne.s, 1.0), (shouldBeOne.blade, shouldBeOne.s) # 1-blade, expect 1-blade back A = Blade(np.array([1, 0])) D = bd.dual(A) revPseudo = bd.outer(bd.inverse(A), D) shouldBeOne = bd.inner(revPseudo, bd.pseudoScalar(2)) assert np.allclose(shouldBeOne.s, 1.0), (shouldBeOne.blade, shouldBeOne.s) # 2-blade, expect 0-blade back A = Blade(np.eye(2)) D = bd.dual(A) revPseudo = bd.outer(bd.inverse(A), D) shouldBeOne = bd.inner(revPseudo, bd.pseudoScalar(2)) assert np.allclose(shouldBeOne.s, 1.0), (shouldBeOne.blade, shouldBeOne.s)
def testBladeOuterSameSubspace(): B1 = Blade(np.eye(2)) B2 = Blade(np.eye(2)[:, 0]) result = bd.outer(B1, B2) print 'B1 outer B2: ', result.s assert np.allclose(0, result.s) B1 = Blade(np.eye(2)) B2 = Blade(np.eye(2)) result = bd.outer(B1, B2) print 'B1 outer B2: ', result.s assert np.allclose(0, result.s)
def testBladeUnDualEuclidean(): # s=0 B = Blade(0) try: D = bd.undual(B) except AttributeError as err: assert err[0] == 'Not dualizable, s=0' except: assert False, err # scalar, expect a 2-blade A = Blade(2) Aprime = bd.dual(bd.undual(A, n=2), n=2) print 'A: ', A.blade, A.s print 'APrimeInv: ', bd.inverse(Aprime).blade, bd.inverse(Aprime).s shouldBeOne = bd.outer(A, bd.inverse(Aprime)) print 'shouldBeOne: ', shouldBeOne.blade, shouldBeOne.s assert np.allclose(shouldBeOne.s, 1.0), (shouldBeOne.blade, shouldBeOne.s) # 1-blade, expect 1-blade back A = Blade(np.array([1, 0])) Aprime = bd.undual(bd.dual(A, n=2), n=2) shouldBeOne = bd.inner(A, bd.inverse(Aprime)) assert np.allclose(shouldBeOne.s, 1.0), (shouldBeOne.blade, shouldBeOne.s) # 2-blade, expect 0-blade back A = Blade(np.eye(2)) Aprime = bd.undual(bd.dual(A, n=2), n=2) print 'A: ', A.blade, A.s print 'APrimeInv: ', bd.inverse(Aprime).blade, bd.inverse(Aprime).s shouldBeOne = bd.inner(A, bd.inverse(Aprime)) print 'shouldBeOne: ', shouldBeOne.blade, shouldBeOne.s assert np.allclose(shouldBeOne.s, 1.0), (shouldBeOne.blade, shouldBeOne.s)
def testBladeOuterScaleParallelopiped(): # test outer(B1, B2).s == 'area spanned by parallelopiped between B1, B2' B1 = Blade(np.array([1, 0])) B2 = Blade(np.array([1, 1])) # should have same area as [0, 1] when outered with B1 result1 = bd.outer(B1, B2) print 'B1 outer B2 s: ', result1.s print 'B1 outer B2 blade: ', result1.blade assert la.det(result1.blade) > 0, la.det(result1.blade) assert result1.blade.shape == (2, 2), result1.blade.shape assert np.allclose(np.eye(2), np.dot(result1.blade.T, result1.blade)) assert np.allclose(bd.inner(result1, result1).s, -1), bd.inner(result1, result1).s B1 = Blade(np.array([1, 0]), s=2.0) B2 = Blade(np.array([1, 1]), s=3.0) result2 = bd.outer(B1, B2) print 'B1 outer B2 s: ', result2.s print 'B1 outer B2 blade: ', result2.blade assert la.det(result2.blade) > 0, la.det(result2.blade) assert result2.blade.shape == (2, 2), result2.blade.shape assert np.allclose(np.eye(2), np.dot(result2.blade.T, result2.blade)) assert np.allclose(bd.inner(result2, result2).s, -36), bd.inner(result2, result2).s
def testBladeOuterSign(): # sign/antisymmetric B1 = Blade(np.array([1, 0])) B2 = Blade(np.array([0, 1])) result1 = bd.outer(B1, B2) print 'B1 outer B2 s: ', result1.s print 'B1 outer B2 blade: ', result1.blade assert la.det(result1.blade) > 0, la.det(result1.blade) assert result1.blade.shape == (2, 2), result1.blade.shape assert np.allclose(np.eye(2), np.dot(result1.blade.T, result1.blade)) assert np.allclose(bd.inner(result1, result1).s, -1), bd.inner(result1, result1).s result2 = bd.outer(B2, B1) print 'B2 outer B1 s: ', result2.s print 'B2 outer B1 blade: ', result2.blade assert la.det(result2.blade) < 0, la.det(result2.blade) assert result2.blade.shape == (2, 2), result2.blade.shape assert np.allclose(np.eye(2), np.dot(result2.blade.T, result2.blade)) assert np.allclose(bd.inner(result2, result2).s, -1), bd.inner(result2, result2).s # result1 == inverse(result2) assert bd.inner(result1, result2).s > 0, bd.inner(result1, result2).s
def testBladeOuterScaleParallelopiped(): # test outer(B1, B2).s == 'area spanned by parallelopiped between B1, B2' B1 = Blade(np.array([1, 0])) B2 = Blade(np.array( [1, 1])) # should have same area as [0, 1] when outered with B1 result1 = bd.outer(B1, B2) print 'B1 outer B2 s: ', result1.s print 'B1 outer B2 blade: ', result1.blade assert la.det(result1.blade) > 0, la.det(result1.blade) assert result1.blade.shape == (2, 2), result1.blade.shape assert np.allclose(np.eye(2), np.dot(result1.blade.T, result1.blade)) assert np.allclose(bd.inner(result1, result1).s, -1), bd.inner(result1, result1).s B1 = Blade(np.array([1, 0]), s=2.0) B2 = Blade(np.array([1, 1]), s=3.0) result2 = bd.outer(B1, B2) print 'B1 outer B2 s: ', result2.s print 'B1 outer B2 blade: ', result2.blade assert la.det(result2.blade) > 0, la.det(result2.blade) assert result2.blade.shape == (2, 2), result2.blade.shape assert np.allclose(np.eye(2), np.dot(result2.blade.T, result2.blade)) assert np.allclose(bd.inner(result2, result2).s, -36), bd.inner(result2, result2).s
def testBladeDualEuclideanRegression(): # regression test -- tests a bunch of functions and they all have to work # for many input dimensions for this to succeed fully for n in range(1, 10): for k in range(0, n + 1): if k == 0: blade = Blade(1, s=float(rn.rand(1)[0])) else: blade = Blade(rn.randn(n, k)) print 'blade n, k: ', blade.n, blade.k if np.allclose(blade.s, 0): # just skip this one for now... continue # measure 0 event but could happen D = bd.dual(blade, n=n) print 'D n, k: ', D.n, D.k revPseudo = bd.outer(bd.inverse(blade), D) print 'n, k: ', n, k print 'revPseudo blade, s: ', revPseudo.blade, revPseudo.s shouldBeOne = bd.inner(revPseudo, bd.pseudoScalar(n)) assert np.allclose(shouldBeOne.s, 1.0), (shouldBeOne.blade, shouldBeOne.s)
def testBladeMeet(): # two bases A = Blade(np.array([1, 0, 0])) B = Blade(np.array([0, 1, 0])) M = bd.meet(A, B) assert M.blade.shape == (1, 0), M.blade.shape assert M.s == 1 # linearly dependent A = Blade(np.array([1, 0, 0])) B = Blade(np.array([1, 0, 0])) M = bd.meet(A, B) assert M.blade.shape == (3, 1) assert M.s == 1 # share one factor A = bd.outer(Blade(np.array([1, 0, 0])), Blade(np.array([0, 1, 0]))) B = Blade(np.array([1, 0, 0])) M = bd.meet(A, B) assert M.blade.shape == (3, 1), M.blade.shape assert M.s == 1