Skip to content

Commit

Permalink
Add se3.adjoint() (#407)
Browse files Browse the repository at this point in the history
* add functional.se3.adjoint

* add tests to functional.se3.adjoint

* Add se3.inverse() (#408)

* add inverse to functional.se3

* add tests to functional.se3.inverse

* Add se3.hat() and se3.vee() (#409)

* add functional.se3.hat

* add tests to functional.se3.hat

* fixed minor bugs in se3.vee

* Add se3.compose() (#410)

* add compose() to functional.se3.compose()

* Add se3.lift() and se3.project() (#411)

* refactor the position of se3.rand() and se3.randn()

* add lift() and project() to functional.se3

* fixed minor bugs in se3.lift() and se3.project()

* add tests to se3.lift() and se3.project()

* Add se3.left_act() (#412)

* add se3.left_act()

* minor refactor

* add tests to se3.left_act()

* simplify the code

* fixed a bug in se3.left_act

* Add se3.left_project() (#413)

* add se3.left_project()

* fixed the dimension bug of SE3

* add tests for se3.left_project()

* fixed a bug in se3.left_project()

* Add se3.log() (#414)

* bugs exist

* se3.log() works

* add tests to se3.log()
  • Loading branch information
fantaosha committed Jan 12, 2023
1 parent f0d046c commit d2efac1
Show file tree
Hide file tree
Showing 2 changed files with 877 additions and 52 deletions.
169 changes: 168 additions & 1 deletion tests/geometry/functional/test_se3.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
# LICENSE file in the root directory of this source tree.

import pytest
from .common import check_lie_group_function
from .common import check_lie_group_function, left_project_func
from theseus.geometry.functional.constants import TEST_EPS
import theseus.geometry.functional.se3 as se3

import torch
Expand All @@ -19,3 +20,169 @@ def test_exp(batch_size: int, dtype: torch.dtype):

# check analytic backward for the operator
check_lie_group_function(se3, "exp", 1e-6, (tangent_vector,))


@pytest.mark.parametrize("batch_size", [1, 20, 100])
@pytest.mark.parametrize("dtype", [torch.float32, torch.float64])
def test_log(batch_size: int, dtype: torch.dtype):
rng = torch.Generator()
rng.manual_seed(0)
group = se3.rand(batch_size, generator=rng, dtype=dtype)
left_project = left_project_func(se3, group)

# check analytic backward for the operator
EPS = 5e-6 if dtype == torch.float32 else TEST_EPS
check_lie_group_function(se3, "log", EPS, (group,), (left_project,))


@pytest.mark.parametrize("batch_size", [1, 20, 100])
@pytest.mark.parametrize("dtype", [torch.float32, torch.float64])
def test_adjoint(batch_size: int, dtype: torch.dtype):
rng = torch.Generator()
rng.manual_seed(0)
group = se3.rand(batch_size, generator=rng, dtype=dtype)

# check analytic backward for the operator
check_lie_group_function(se3, "adjoint", TEST_EPS, (group,))


@pytest.mark.parametrize("batch_size", [1, 20, 100])
@pytest.mark.parametrize("dtype", [torch.float32, torch.float64])
def test_inverse(batch_size: int, dtype: torch.dtype):
rng = torch.Generator()
rng.manual_seed(0)
group = se3.rand(batch_size, generator=rng, dtype=dtype)

# check analytic backward for the operator
check_lie_group_function(se3, "inverse", TEST_EPS, (group,))


@pytest.mark.parametrize("batch_size", [1, 20, 100])
@pytest.mark.parametrize("dtype", [torch.float32, torch.float64])
def test_hat(batch_size: int, dtype: torch.dtype):
rng = torch.Generator()
rng.manual_seed(0)
tangent_vector = torch.rand(batch_size, 6, dtype=dtype, generator=rng)

# check analytic backward for the operator
check_lie_group_function(se3, "hat", TEST_EPS, (tangent_vector,))


@pytest.mark.parametrize("batch_size", [1, 20, 100])
@pytest.mark.parametrize("dtype", [torch.float32, torch.float64])
def test_vee(batch_size: int, dtype: torch.dtype):
rng = torch.Generator()
rng.manual_seed(0)
tangent_vector = torch.rand(batch_size, 6, dtype=dtype, generator=rng)
matrix = se3.hat(tangent_vector)

# check analytic backward for the operator
check_lie_group_function(se3, "vee", TEST_EPS, (matrix,))

# check the correctness of hat and vee
actual_tangent_vector = se3.vee(matrix)
assert torch.allclose(actual_tangent_vector, tangent_vector, atol=TEST_EPS)


@pytest.mark.parametrize("batch_size", [1, 20, 100])
@pytest.mark.parametrize("dtype", [torch.float32, torch.float64])
def test_compose(batch_size: int, dtype: torch.dtype):
rng = torch.Generator()
rng.manual_seed(0)
group0 = se3.rand(batch_size, generator=rng, dtype=dtype)
group1 = se3.rand(batch_size, generator=rng, dtype=dtype)

# check analytic backward for the operator
check_lie_group_function(se3, "compose", TEST_EPS, (group0, group1))


@pytest.mark.parametrize("batch_size", [1, 20, 100])
@pytest.mark.parametrize("dtype", [torch.float32, torch.float64])
def test_lift(batch_size: int, dtype: torch.dtype):
rng = torch.Generator()
matrix = torch.rand(
batch_size,
int(torch.randint(1, 20, (1,), generator=rng)),
6,
dtype=dtype,
generator=rng,
)

# check analytic backward for the operator
check_lie_group_function(se3, "lift", TEST_EPS, (matrix,))


@pytest.mark.parametrize("batch_size", [1, 20, 100])
@pytest.mark.parametrize("dtype", [torch.float32, torch.float64])
def test_project(batch_size: int, dtype: torch.dtype):
rng = torch.Generator()
matrix = torch.rand(
batch_size,
int(torch.randint(1, 20, (1,), generator=rng)),
3,
4,
dtype=dtype,
generator=rng,
)

# check analytic backward for the operator
check_lie_group_function(se3, "project", TEST_EPS, (matrix,))


@pytest.mark.parametrize("batch_size", [1, 20, 100])
@pytest.mark.parametrize("dtype", [torch.float32, torch.float64])
def test_left_act(batch_size: int, dtype: torch.dtype):
rng = torch.Generator()
group = se3.rand(batch_size, dtype=dtype, generator=rng)
matrix = torch.rand(
batch_size,
3,
int(torch.randint(1, 5, (1,), generator=rng)),
dtype=dtype,
generator=rng,
)

# check analytic backward for the operator
check_lie_group_function(se3, "left_act", TEST_EPS, (group, matrix))

matrix = torch.rand(
batch_size,
2,
4,
3,
int(torch.randint(1, 5, (1,), generator=rng)),
dtype=dtype,
generator=rng,
)

# check analytic backward for the operator
check_lie_group_function(se3, "left_act", TEST_EPS, (group, matrix))


@pytest.mark.parametrize("batch_size", [1, 20, 100])
@pytest.mark.parametrize("dtype", [torch.float32, torch.float64])
def test_left_project(batch_size: int, dtype: torch.dtype):
rng = torch.Generator()
group = se3.rand(batch_size, dtype=dtype, generator=rng)
matrix = torch.rand(
batch_size,
3,
4,
dtype=dtype,
generator=rng,
)

# check analytic backward for the operator
check_lie_group_function(se3, "left_project", TEST_EPS, (group, matrix))

matrix = torch.rand(
batch_size,
int(torch.randint(1, 5, (1,), generator=rng)),
3,
4,
dtype=dtype,
generator=rng,
)

# check analytic backward for the operator
check_lie_group_function(se3, "left_project", TEST_EPS, (group, matrix))
Loading

0 comments on commit d2efac1

Please sign in to comment.