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

[Use Case]: Recursively calculating determinant of Matrix<M, M> #49

Open
jamesthurley opened this issue Nov 29, 2022 · 0 comments
Open
Labels
A-generic-exprs Generic const expressions C-use-case Category: This is a use case for a feature

Comments

@jamesthurley
Copy link

Code description

I've been enjoying using const generics to implement a simple struct Matrix<const M: usize, const N: usize>.

I successfully implemented a fn submatrix(&self, row: usize, column: usize) -> Matrix<{ M - 1 }, { N - 1 }> using feature(generic_const_exprs).

Next, I wanted to calculate the determinant using recursion. For the determinant of a generic square Matrix<M, M> it needs to calculate the cofactors of the matrix, and they require calculating the determinants of submatrices Matrix<M - 1, M - 1>. This happens recursively until you have a 2x2 matrix, at which point you can calculate the determinant of that directly and the recursion can unwind.

What worked well

I was able to successfully implement most of the supporting functions for calculating the determinant.

What worked less well

Once the recursive aspect was in place, I received a compiler error:

error: unconstrained generic constant
  --> src/lib.rs:64:19
   |
64 |         submatrix.determinant()
   |                   ^^^^^^^^^^^
   |
   = help: try adding a `where` bound using this expression: `where [(); M - 1]:`
note: required by a bound in `Matrix::<M, M>::determinant`
  --> src/lib.rs:45:14
   |
43 |     pub fn determinant(&self) -> f32
   |            ----------- required by a bound in this
44 |     where
45 |         [(); M - 1]:,
   |              ^^^^^ required by this bound in `Matrix::<M, M>::determinant`

However the suggested where bound already exists on the function.

I have one code sample showing the specific matrix case:

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=143d8b7005a53b59d8a91953e41e1121

I have another simplified example showing the same error with less code:

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=2151c05d5e451fd14929fb16792520ff

Here the problematic function is get_one(). The idea is that when you call get_one() on an A<S> it will use recursion to return you an A<1>. This is dumb, but it shows the issue.

There has been some discussion on Zulip:

https://rust-lang.zulipchat.com/#narrow/stream/260443-project-const-generics/topic/Recursive.20method.20calls.20with.20generic_const_exprs

@jamesthurley jamesthurley added A-generic-exprs Generic const expressions C-use-case Category: This is a use case for a feature labels Nov 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-generic-exprs Generic const expressions C-use-case Category: This is a use case for a feature
Projects
None yet
Development

No branches or pull requests

1 participant