Skip to content

Commit

Permalink
Merge pull request #319 from eric-wieser/fix-flake8
Browse files Browse the repository at this point in the history
Delay imports for the large algebra tests.

General speedups for test setup and execution times, see merged commits for details.
  • Loading branch information
eric-wieser committed May 28, 2020
2 parents 9c26f72 + 692bce6 commit 2c0374d
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 37 deletions.
77 changes: 53 additions & 24 deletions clifford/test/test_dg3c.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
import unittest
import pytest
import numpy as np
import numba

from ..dg3c import *

"""
All basic test identities come from:
Expand All @@ -13,17 +6,29 @@
https://doi.org/10.1007/s00006-017-0784-0
"""

import pytest
import numpy as np
import numba

too_slow_without_jit = pytest.mark.skipif(
numba.config.DISABLE_JIT, reason="test is too slow without JIT"
)


class BasicTests(unittest.TestCase):
def setup_module():
# do this separately so that we get distinct timing information for it
import clifford.dg3c # noqa: F401


@too_slow_without_jit
class TestBasic:
def test_metric(self):
"""
Ensure that the metric comes out with a double copy of
the CGA metric
"""
from clifford.dg3c import layout

assert np.all(layout.metric == np.array([
[1., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
Expand All @@ -40,6 +45,8 @@ def test_up_down(self):
"""
Test that we can map points up and down into the dpga
"""
from clifford.dg3c import up, down

rng = np.random.RandomState()
for i in range(1 if numba.config.DISABLE_JIT else 100):
pnt_vector = rng.randn(3)
Expand All @@ -55,6 +62,8 @@ def test_up_down_cga1(self):
"""
Test that we can map points up and down from cga1
"""
from clifford.dg3c import up_cga1, down_cga1

rng = np.random.RandomState()
pnt_vector = rng.randn(3)
for i in range(10 if numba.config.DISABLE_JIT else 100):
Expand All @@ -67,22 +76,27 @@ def test_up_down_cga1(self):
up_cga1([1, 2, 3, 4])


class GeometricPrimitiveTests(unittest.TestCase):
@too_slow_without_jit
class TestGeometricPrimitives:
@too_slow_without_jit
def test_reciprocality(self):
"""
Ensure that the cyclide ops and the reciprocal frame are
actually reciprocal...
"""
from clifford.dg3c import cyclide_ops, cyclide_ops_reciprocal

for key, cyc_op in cyclide_ops.items():
for key2, cyc_op_recip in cyclide_ops_reciprocal.items():
assert cyc_op|cyc_op_recip == layout.scalar*(key == key2)
assert cyc_op|cyc_op_recip == int(key == key2)

def test_general_elipsoid(self):
"""
Test the construction of a general elipsoid as per
Appendix A.1
"""
from clifford.dg3c import cyclide_ops, eo

px = 0
py = 1
pz = 0
Expand All @@ -99,9 +113,12 @@ def test_general_elipsoid(self):
(px**2 / rx ** 2 + py**2 / ry ** 2 + pz**2 / rz ** 2 - 1) * cyclide_ops['T1']
])
# The cyclides are an IPNS
assert E|eo == 0*e1
assert E|eo == 0

def test_line(self):
from clifford.dg3c import up, up_cga1, up_cga2
from clifford.dg3c import einf1, einf2, IC1, IC2

rng = np.random.RandomState()
# Make a dcga line
pnt_vec_a = rng.randn(3)
Expand All @@ -111,12 +128,17 @@ def test_line(self):
Ldcga = Lcga1 ^ Lcga2

# Assert that it is an IPNS
assert Ldcga | up(pnt_vec_a) == 0*eo
assert Ldcga | up(pnt_vec_b) == 0 * eo
assert Ldcga | up(0.5*pnt_vec_a + 0.5*pnt_vec_b) == 0 * eo
assert Ldcga | up(pnt_vec_a) == 0
assert Ldcga | up(pnt_vec_b) == 0
assert Ldcga | up(0.5*pnt_vec_a + 0.5*pnt_vec_b) == 0

@too_slow_without_jit
def test_translation(self):
from clifford.dg3c import up, up_cga1, up_cga2
from clifford.dg3c import cyclide_ops
from clifford.dg3c import eo, e1, e2, e3, einf1, e6, e7, e8, einf2
from clifford.dg3c import IC1, IC2

rng = np.random.RandomState()
# Make a dcga line
pnt_vec = rng.randn(3)
Expand All @@ -131,7 +153,7 @@ def test_translation(self):
Tdcga = (Tc1*Tc2).normal()

# Assert the rotor is normalised
assert Tdcga*~Tdcga == layout.scalar
assert Tdcga*~Tdcga == 1

# Apply the rotor to the line
np.testing.assert_allclose((Tdcga*Ldcga*~Tdcga).value, Ldcga.value, rtol=1E-4, atol=1E-6)
Expand All @@ -156,7 +178,7 @@ def test_translation(self):
(px ** 2 / rx ** 2 + py ** 2 / ry ** 2 + pz ** 2 / rz ** 2 - 1) * cyclide_ops['T1']
])
# Before moving the elipsoid surface is not touching the origin
assert E|eo != 0*e1
assert E|eo != 0

# Make a dcga translation rotor to move the ellipsoid
Tc1 = 1 - 0.5 * rx * e1 * einf1
Expand All @@ -178,11 +200,16 @@ def test_translation(self):

@too_slow_without_jit
def test_line_rotation(self):
from clifford.dg3c import up, up_cga1, up_cga2
from clifford.dg3c import einf1, einf2
from clifford.dg3c import e12, e67
from clifford.dg3c import IC1, IC2

theta = np.pi/2
RC1 = np.e ** (-0.5*theta*e12)
RC2 = np.e ** (-0.5*theta*e67)
Rdcga = (RC1 * RC2).normal()
assert Rdcga * ~Rdcga == 1.0 + 0 * eo
assert Rdcga * ~Rdcga == 1

# Construct a line
pnt_vec = np.array([1, 0, 0])
Expand All @@ -198,12 +225,16 @@ def test_line_rotation(self):
Ldcga_rotated = Lcga1_rotated ^ Lcga2_rotated

# Assert the rotor rotates it
assert (Rdcga * Ldcga * ~Rdcga)|up(pnt_vec_rotated) == 0*e1
assert (Rdcga * Ldcga * ~Rdcga)|up(pnt_vec_rotated) == 0
np.testing.assert_allclose((Rdcga * Ldcga * ~Rdcga).value, Ldcga_rotated.value, rtol=1E-4, atol=1E-6)

@too_slow_without_jit
def test_quadric_rotation(self):
# Construct and ellipsoid
from clifford.dg3c import cyclide_ops
from clifford.dg3c import eo, e2, e7, einf1, einf2
from clifford.dg3c import e23, e78

px = 0
py = 2.5
pz = 0
Expand All @@ -219,7 +250,7 @@ def test_quadric_rotation(self):
(1 / rz ** 2) * cyclide_ops['Tz2'],
(px ** 2 / rx ** 2 + py ** 2 / ry ** 2 + pz ** 2 / rz ** 2 - 1) * cyclide_ops['T1']
])
assert E | eo != 0 * eo
assert E | eo != 0

# Make a dcga translation rotor to move the ellipsoid
Tc1 = 1 - 0.5 * py * e2 * einf1
Expand All @@ -236,13 +267,15 @@ def test_quadric_rotation(self):

Erot = Comborotor*E*~Comborotor

assert Erot|eo == 0*eo
assert Erot|eo == 0

@too_slow_without_jit
def test_bivector_orthogonality(self):
"""
Rotors in each algebra should be orthogonal
"""
from clifford.dg3c import e2, e7, einf1, einf2
from clifford.dg3c import e12, e67
theta = np.pi / 2
RC1 = np.e ** (-0.5 * theta * e12)
RC2 = np.e ** (-0.5 * theta * e67)
Expand All @@ -258,7 +291,3 @@ def test_bivector_orthogonality(self):
Texp = np.e ** (-0.5 * mag * (e2 * einf1 + e7 * einf2))
np.testing.assert_allclose(Texp.value, Tdcga.value,
rtol=1E-4, atol=1E-6)


if __name__ == '__main__':
unittest.main()
48 changes: 37 additions & 11 deletions clifford/test/test_dpga.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@

from clifford.dpga import *
# do not import dpga here, as that slows down test collection considerably,
# even if we do not run these tests.
import numba
import numpy as np


def setup_module():
# do this separately so that we get distinct timing information for it
import clifford.dpga # noqa: F401


class TestBasicDPGA:
def test_non_orthogonal_metric(self):
from clifford.dpga import wbasis

w_metric = np.array([
[
(a | b)[0]
Expand All @@ -29,6 +37,8 @@ def test_bivector_identities(self):
R(4, 4) As a Computational Framework for 3-Dimensional Computer Graphics
by Ron Goldman and Stephen Mann
"""
from clifford.dpga import wlist, wslist, wbasis

for wi in wlist:
for wj in wlist:
assert wi^wj == -wj*wi
Expand All @@ -38,12 +48,14 @@ def test_bivector_identities(self):
assert wis^wjs == -wjs*wis

for w in wbasis:
assert w**2 == 0*w1
assert w**2 == 0

for wi, wis in zip(wlist, wslist):
assert wi*wis == 1 - wis*wi

def test_up_down(self):
from clifford.dpga import up, down

rng = np.random.RandomState() # can pass a seed here later
for i in range(10 if numba.config.DISABLE_JIT else 1000):
p = rng.standard_normal(3)
Expand All @@ -52,6 +64,9 @@ def test_up_down(self):
np.testing.assert_allclose(pnt_down, p)

def test_translate(self):
from clifford.dpga import w0, w1, w2, w3, w0s
from clifford.dpga import up

rng = np.random.RandomState() # can pass a seed here later
for i in range(10 if numba.config.DISABLE_JIT else 100):
tvec = rng.standard_normal(3)
Expand All @@ -76,6 +91,9 @@ def test_translate(self):
assert res == desired_result

def test_rotate(self):
from clifford.dpga import w0, w1, w2, w3, w1s, w2s, w3s
from clifford.dpga import up, down

rng = np.random.RandomState() # can pass a seed here later
for i in range(10 if numba.config.DISABLE_JIT else 100):
mvec = rng.standard_normal(3)
Expand Down Expand Up @@ -106,6 +124,10 @@ def test_rotate(self):
np.testing.assert_allclose(l, lres, atol=1E-6)

def test_line(self):
from clifford.dpga import w0, w1, w2, w3, w0s
from clifford.dpga import e12, e13, e23, e1b2b, e1b3b, e2b3b
from clifford.dpga import up, down

rng = np.random.RandomState() # can pass a seed here later
for i in range(5 if numba.config.DISABLE_JIT else 100):
p1vec = rng.standard_normal(3)
Expand Down Expand Up @@ -155,19 +177,23 @@ def test_line(self):
np.testing.assert_allclose((Rline*~Rline).value, (1 + 0*w1).value, rtol=1E-4, atol=1E-4)

def test_quadric(self):
from clifford.dpga import w0, w1, w2, w3, w0s, w1s, w2s, w3s
from clifford.dpga import e12, e13, e23, e1b2b, e1b3b, e2b3b
from clifford.dpga import up, dual_point

rng = np.random.RandomState() # can pass a seed here later
# Make a cone which passes through the origin
# This is the construction from Transverse Approach paper
quadric_coefs = [0.0, 1.0, 1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
a, b, c, d, e, f, g, h, i, j = quadric_coefs
quadric = 4 * a * (w0s ^ w0) + 4 * b * (w1s ^ w1) + \
4 * c * (w2s ^ w2) + 4 * j * (w3s ^ w3) + \
2 * d * ((w0s ^ w1) + (w1s ^ w0)) + \
2 * e * ((w0s ^ w2) + (w2s ^ w0)) + \
2 * f * ((w1s ^ w2) + (w2s ^ w1)) + \
2 * g * ((w0s ^ w3) + (w3s ^ w0)) + \
2 * h * ((w1s ^ w3) + (w3s ^ w1)) + \
2 * i * ((w2s ^ w3) + (w3s ^ w2))
quadric = (4 * a * (w0s ^ w0) + 4 * b * (w1s ^ w1) +
4 * c * (w2s ^ w2) + 4 * j * (w3s ^ w3) +
2 * d * ((w0s ^ w1) + (w1s ^ w0)) +
2 * e * ((w0s ^ w2) + (w2s ^ w0)) +
2 * f * ((w1s ^ w2) + (w2s ^ w1)) +
2 * g * ((w0s ^ w3) + (w3s ^ w0)) +
2 * h * ((w1s ^ w3) + (w3s ^ w1)) +
2 * i * ((w2s ^ w3) + (w3s ^ w2)))

# The quadrics do not form an OPNS
assert quadric ^ w0s != 0*w1
Expand Down
2 changes: 0 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ per-file-ignores =
clifford/test/test_tools.py:F841,F401
clifford/test/test_g3c_tools.py:F401,F403,F405,F841,E722
clifford/test/test_g3c_CUDA.py:F401,F403,F405,F841,E722
clifford/test/test_dpga.py:F403,F405,E127
clifford/test/test_dg3c.py:F403,F405,E127
clifford/_layout.py:E306
clifford/__init__.py:E402

Expand Down

0 comments on commit 2c0374d

Please sign in to comment.