nalgebra icon indicating copy to clipboard operation
nalgebra copied to clipboard

Public interface for submatrices and minors

Open sed-i opened this issue 3 years ago • 3 comments

Would it be possible to expose public interfaces for submatrices and minors?

Could it also simplify some internal logic? For example:

https://github.com/dimforge/nalgebra/blob/1576a1517ad652db5bfa1bb9071eeadc699b4328/src/linalg/inverse.rs#L71-L74

https://github.com/dimforge/nalgebra/blob/1576a1517ad652db5bfa1bb9071eeadc699b4328/src/linalg/determinant.rs#L38-L41

https://github.com/dimforge/nalgebra/blob/1576a1517ad652db5bfa1bb9071eeadc699b4328/src/base/matrix.rs#L2111-L2113

sed-i avatar Dec 22 '21 18:12 sed-i

Hello @sed-i

I can't speak for the maintainers, but it seems the snippets you posted are specific cases for e.g. 3x3 matrices and thus wouldn't be appropriate for general use.

I would like to point some public functions that may be of use to get the functionality you need without much manual manipulation of individual matrix values.

Slicing

These function extract contiguous submatrices (which is different from the sort of submatrix than you linked too)

remove_columns/remove_rows

These functions will drop a row or column from your matrix and can probably used to generate first minors fairly easily. There are variants for dropping more than one row/column.

select_row/select_columns

With these methods you provide an iterator which indicates which columns to keep-- sort of the converse of remove_columns

CattleProdigy avatar Dec 28 '21 19:12 CattleProdigy

Thanks for the pointers, @CattleProdigy !

I tried

let m = matrix.clone(); // 4x4 matrix
let mm = m.remove_row(1);
let mmm = mm.remove_column(1);
assert_eq!(mmm.lu().determinant(), 42.);

and got a compilation error for calling .lu() this way:

method cannot be called on `Matrix<{integer}, Const<3_usize>, Const<3_usize>, ArrayStorage<{integer}, 3_usize, 3_usize>>` due to unsatisfied trait bounds

Anyway, would be handy to have a .minor(i, j) method instead of manually rmrow+rmcol+det.

sed-i avatar Jan 03 '22 07:01 sed-i

Hey @sed-i

You're welcome! The snippet you posted actually builds for me (nalgebra 0.29). I suspect that you're relying on type deduction to build matrix and since you probably typed some integer values, you got a matrix of integers. LU has a trait bound which requires the field type to satisfy (ComplexField). This is likely because computing an LU decomp requires division or square roots or something that isn't well-formed for integers. Floating point types fit the bill here. So you can either specify your matrix's type explicitly somewhere, or use floating point literals (1.0 or 1.0f32 instead of 1) or cast your matrix before passing to the decomp.

R/e the minor function. The fastest way to get this feature, would be to implement it yourself. In which case I'd suggest amending this issue with a proposed API and tag the maintainer(s). You could also try talking about it in the Discord. I'm sure a change like this would be accepted if the semantics are clear and the implementation is good.

CattleProdigy avatar Jan 04 '22 17:01 CattleProdigy