Skip to content

Commit

Permalink
Merge branch 'master' into use-sparse-solvers
Browse files Browse the repository at this point in the history
  • Loading branch information
duembgen committed Dec 29, 2023
2 parents c43ea3b + 013e7c8 commit 4eb7cbd
Show file tree
Hide file tree
Showing 21 changed files with 154 additions and 432 deletions.
45 changes: 45 additions & 0 deletions .github/workflows/python-package-conda.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# This workflow will install Python dependencies, run tests and lint with a single version of Python
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python

name: Python application

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

permissions:
contents: read

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
with:
token: ${{ secrets.CONSTRAINT_LEARNING_PAT }}
submodules: recursive
- name: Set up Python 3.10
uses: actions/setup-python@v3
with:
python-version: "3.10"
- name: Add conda to system path
run: |
# $CONDA is an environment variable pointing to the root of the miniconda directory
echo $CONDA/bin >> $GITHUB_PATH
- name: Install dependencies
run: |
conda env update --file environment.yml --name base
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
run: |
conda install pytest
pytest
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ venv/
*.code-workspace
solve_mosek.ptf
solve_cvxpy*.ptf
build/
dist/
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
url = [email protected]:utiasASRL/poly_matrix
[submodule "starloc"]
path = starloc
url = [email protected]:duembgen/starloc
url = [email protected]:utiasASRL/starloc
[submodule "certifiable-tools"]
path = certifiable-tools
url = [email protected]:utiasASRL/certifiable-tools
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ conda env create -f environment.yml

## Author

Frederike Dümbgen
- Frederike Dümbgen
- Connor Holmes
146 changes: 11 additions & 135 deletions _test/test_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
from lifters.stereo2d_lifter import Stereo2DLifter
from poly_matrix.poly_matrix import PolyMatrix

INCREMENTAL = True
NORMALIZE = True


def test_canonical_operations():
n_landmarks = 1 # z_0 and z_1
Expand All @@ -17,12 +14,12 @@ def test_canonical_operations():
# fmt: off
Ai_sub = np.array(
[
[1, 0, 0, 0, 0, 0],
[0, 0, .5, 0, 0, 0],
[0, .5, 0, 0, .5, 0],
[0, 0, 0, 1, 0, 0],
[0, 0, .5, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0],
[0, 0,.5, 0, 0, 0],
[0,.5, 0, 0,.5, 0],
[0, 0, 0, 1, 0, 0],
[0, 0,.5, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
]
)
Ai_poly = PolyMatrix(symmetric=True)
Expand All @@ -44,39 +41,6 @@ def test_canonical_operations():


def test_learned_constraints(d=2, param_level="ppT"):
n_landmarks = 2 # z_0 and z_1
if d == 1:
lifter = Stereo1DLifter(n_landmarks=n_landmarks, param_level=param_level)
elif d == 2:
lifter = Stereo2DLifter(
n_landmarks=n_landmarks, param_level=param_level, level="urT"
)
else:
raise ValueError(d)

var_subset = ["l", "z_0", "z_1"]
label_dict = lifter.var_dict_row(var_subset)

basis_row_list = lifter.get_basis_list(var_subset, plot=False)
basis_list = [
basis_row.get_matrix((["l"], label_dict)) for basis_row in basis_row_list
]
A_learned = lifter.generate_matrices(basis_list, var_dict=var_subset)

# first, test that the learned constraints actually work on the original setup.
np.random.seed(0)
lifter.test_constraints(A_learned, errors="print")

# then, with parameters, we can regenerate new learned variables for each new random setup.
for i in range(0, 10):
print(f"---- {i} -----")
np.random.seed(i)
lifter.generate_random_setup()
A_learned = lifter.generate_matrices(basis_list, var_dict=var_subset)
lifter.test_constraints(A_learned, errors="print")


def test_learned_constraints_augment(d=2, param_level="ppT"):
n_landmarks = 2 # z_0 and z_1
if d == 1:
lifter = Stereo1DLifter(n_landmarks=n_landmarks, param_level="p")
Expand All @@ -87,46 +51,18 @@ def test_learned_constraints_augment(d=2, param_level="ppT"):
else:
raise ValueError(d)

if INCREMENTAL:
var_subset = ["l", "z_0", "z_1"]
label_dict = lifter.var_dict_row(var_subset)

basis_list = lifter.get_basis_list(var_subset, plot=False)
basis_list_all = lifter.apply_templates(basis_list)
basis_poly_all = PolyMatrix.init_from_row_list(basis_list_all)

basis_learned = basis_poly_all.get_matrix(
variables=(basis_poly_all.variable_dict_i, label_dict)
)
A_learned = lifter.generate_matrices(basis_list, var_dict=var_subset)
else:
var_subset = list(lifter.var_dict.keys())
label_dict = lifter.var_dict_row(var_subset)
A_learned = lifter.get_A_learned()

A_learned, basis_poly = lifter.get_A_learned(normalize=NORMALIZE)
basis_learned = basis_poly.get_matrix(
variables=(basis_poly.variable_dict_i, label_dict)
)

# first, test that the learned constraints actually work on the original setup.
np.random.seed(0)
lifter.test_constraints(A_learned, errors="raise")

# then, with parameters, we can regenerate new learned variables for each new random setup.
for i in range(10):
np.random.seed(i)
lifter.generate_random_setup()
A_learned = lifter.generate_matrices(basis_learned, var_dict=var_subset)

lifter.test_constraints(A_learned, errors="print")


def test_b_to_a():
n_landmarks = 1 # z_0 only

lifter = Stereo2DLifter(n_landmarks=n_landmarks, param_level="p", level="no")

for var_subset in [("l", "x"), ("l", "x", "z_0")]:
for var_subset in [("h", "x"), ("h", "x", "z_0")]:
Y = lifter.generate_Y(var_subset=var_subset)
basis_new, S = lifter.get_basis(Y)
for i, bi_sub in enumerate(basis_new[:10, :]):
Expand All @@ -151,70 +87,12 @@ def test_b_to_a():
ai_sub = lifter.get_reduced_a(bi_sub, var_subset=var_subset)
assert abs(ai_sub @ x_sub) < 1e-10

# put back in all other variables.

bi_all = lifter.zero_pad_subvector(
bi_sub, var_subset, target_subset=lifter.var_dict
)
# bi_all = lifter.get_vector_dense(bi_poly)

if var_subset == tuple(lifter.var_dict.keys()):
try:
np.testing.assert_allclose(bi_all, bi_sub)
except:
fig, axs = plt.subplots(2, 1)
axs[0].matshow(bi_sub[None, :])
axs[0].set_title("bi sub")
axs[1].matshow(bi_all[None, :])
axs[1].set_title("bi all")
raise

# generate the full matrix, placing the subvar in the correct place.
Ai = lifter.get_mat(ai_sub, var_dict=var_dict)
ai_all_test = lifter.get_vec(Ai)

# generate the full matrix directly from the test vector
ai_all = lifter.get_reduced_a(bi_all)
Ai_test = lifter.get_mat(ai_all)
try:
np.testing.assert_allclose(ai_all_test, ai_all)
except:
fig, axs = plt.subplots(2, 1)
axs[0].matshow(ai_all[None, :])
axs[0].set_title("ai all")
axs[1].matshow(ai_all_test[None, :])
axs[1].set_title("ai all test")
raise

try:
np.testing.assert_allclose(Ai.toarray(), Ai_test)
except:
fig, axs = plt.subplots(1, 2)
axs[0].matshow(Ai.toarray())
axs[0].set_title("Ai")
axs[1].matshow(Ai_test)
axs[1].set_title("Ai test")
raise

assert len(bi_all) == lifter.get_dim_X() * lifter.get_dim_P()

x = lifter.get_x()
x_all = lifter.get_vec(np.outer(x, x))
x_all_aug = lifter.augment_using_parameters(x_all)

# test that x_all_aug @ bi_all holds (x includes parameters)
assert abs(bi_all @ x_all_aug) < 1e-10

ai_all = lifter.get_reduced_a(bi_all)
# test that ai_all @ x_all holds.
assert abs(ai_all @ x_all) < 1e-10


def test_zero_padding():
n_landmarks = 1 # z_0 only
lifter = Stereo2DLifter(n_landmarks=n_landmarks, param_level="p", level="no")

for var_subset in [("l", "x"), ("l", "x", "z_0")]:
for var_subset in [("h", "x"), ("h", "x", "z_0")]:
var_dict = lifter.get_var_dict(var_subset)
# get new patterns for this subset.
Y = lifter.generate_Y(var_subset=var_subset)
Expand All @@ -233,7 +111,7 @@ def test_zero_padding():
# Ai = lifter.get_mat(lifter.get_reduced_a(bi, lifter.var_dict))
try:
lifter.test_constraints([Ai])
except:
except AssertionError:
b_poly_test = lifter.convert_b_to_polyrow(bi_sub, var_subset)
print(b_poly_test)

Expand All @@ -250,8 +128,6 @@ def test_zero_padding():
if __name__ == "__main__":
test_zero_padding()
test_b_to_a()
test_learned_constraints_augment(d=1, param_level="p")
test_learned_constraints_augment(d=2, param_level="ppT")
test_learned_constraints(d=2, param_level="ppT")
test_learned_constraints()
test_canonical_operations()
print("all tests passed")
Loading

0 comments on commit 4eb7cbd

Please sign in to comment.