Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code Generation Question for Matrices with 0s #424

Open
AlonSpinner opened this issue Jan 29, 2025 · 2 comments
Open

Code Generation Question for Matrices with 0s #424

AlonSpinner opened this issue Jan 29, 2025 · 2 comments

Comments

@AlonSpinner
Copy link

Hi,

I am implementing an efficent factor chain solver.
In the solution I multiply and invert lower triangular matrices.
I want to generate efficent CPP code using symforce, but am unable to do that because the code generation treats 0s in the matrices as symbolic variables.

Of course I could create a full matrix instead of a lower triangular, and then edit the generated code, but I was wondering if you have a built in solution for my issue.

I provide exampel code which produces the following error:
c = codegen.Codegen(
File "/home/alon/.local/lib/python3.10/site-packages/symforce/codegen/codegen.py", line 208, in init
assert len(input_symbols) == len(
AssertionError: Symbols in inputs must be unique. Duplicate symbols = [0, 0, 0, 0, 0, 0]

import symforce
symforce.set_epsilon_to_symbol()
from symforce import codegen
from symforce.values import Values
import symforce.symbolic as sf
import os

current_dir = os.path.dirname(__file__)
parent_dir = os.path.abspath(os.path.join(current_dir, os.pardir))
generated_dir = os.path.join(parent_dir, "generated")

AtAi = sf.Matrix(4, 4)
for i in range(4):
    for j in range(4):
        AtAi[i, j] = sf.Symbol(f'AtAi_{i}_{j}')
Lim1 = sf.Matrix(4, 4)
for i in range(4):
    for j in range(4):
        if j <= i:
            Lim1[i, j] = sf.Symbol(f'Lim1_{i}_{j}')
        else:
            Lim1[i, j] = 0
Li = AtAi.transpose() * Lim1.transpose().inv()

inputs = Values()
inputs["AtAi"] = AtAi
inputs["Lim1"] = Lim1
ouptuts = Values()
ouptuts["Li"] = Li

c = codegen.Codegen(
    inputs=inputs,
    outputs=ouptuts,
    config = codegen.CppConfig(use_eigen_types=True),
    name = "compute_Li"
)


c.generate_function(
    namespace = "generated",
    output_dir = generated_dir,
    skip_directory_nesting=True,
)

Thanks,
Alon.

@aaron-skydio
Copy link
Member

So, the inputs currently need to be full matrices; if you want to represent that you only look at the lower triangle, you can do that like this:

AtAi = sf.Matrix44.symbolic('AtAi')
Lim1_input = sf.Matrix44.symbolic('Lim1')
Lim1 = Lim1_input.lower_triangle()
Li = AtAi.transpose() * Lim1.transpose().inv()

inputs = Values()
inputs["AtAi"] = AtAi
inputs["Lim1"] = Lim1
ouptuts = Values()
ouptuts["Li"] = Li

@aaron-skydio
Copy link
Member

I think it would be reasonable to just ignore zeroes in the inputs in codegen? That seems like something someone could add at some point

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants