dimforge / nalgebra

Linear algebra library for Rust.
https://nalgebra.org
Apache License 2.0
4.04k stars 483 forks source link

Calculations on Z/2Z? #723

Open amaury1093 opened 4 years ago

amaury1093 commented 4 years ago

Can I use nalgebra with with elements from Z/2Z (0 and 1)?

More specifically, I'm trying to solve linear equations in Z/2Z, e.g.

  ┌         ┐
  │ 1 1 0 0 │
  │ 1 1 0 1 │
A=│ 0 1 1 1 │  Solve Ax=0
  │ 0 0 1 0 │
  │ 0 0 0 1 │
  └         ┘

There are solutions in Z/2Z (for example: [1 1 0 0 1]t), and apparently no solutions in R (see this playground)

Trying with bool

I read on simba docs that

Simba is a crate defining a set of trait for writing code that can be generic with regard to the number of lanes of the numeric input value. Those traits are implemented by f32, u32, i16, bool as well as SIMD types like f32x4, u32x8, i16x2, etc.

But when I try to create a Matrix<bool>, I get the trait bound not satisfied:

no method named `full_piv_lu` found for struct `nalgebra::base::matrix::Matrix<bool, nalgebra::base::dimension::Dynamic, nalgebra::base::dimension::Dynamic, nalgebra::base::vec_storage::VecStorage<bool, nalgebra::base::dimension::Dynamic, nalgebra::base::dimension::Dynamic>>` in the current scope
the method `lu` exists but the following trait bounds were not satisfied:
`bool : alga::general::complex::ComplexField`

Which makes sense, even Add and Mul are not implemented on bool.

Trying with my own type Bool

So then I tried creating my own wrapper:

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Bool(bool);

impl Bool {
    fn to_bool(&self) -> &bool {
        &self.0
    }
}

impl Add for Bool {
    type Output = Self;

    fn add(self, rhs: Self) -> Self {
        Bool(self.0 ^ rhs.0)
    }
}

impl Mul for Bool {
    type Output = Self;

    fn mul(self, rhs: Self) -> Self {
        Bool(self.0 & rhs.0)
    }
}

Would I need to impl ComplexField for Bool? I'm asking here first, would like to know if that's the way to go, if it's at all possible, or if there are any other shortcuts?

sebcrozet commented 4 years ago

Hi!

Yeah, the documentation of simba may not be completely accurate here. Not all simba traits are implemented by all primitive types. Traits like SimdValue is implemented by all types, but Complex is only implemented for f32, f64, and Complex<N>because such an implementation would make no sense for other types.

So, yeah, to use lu you will need your boolean to implement ComplexField. Perhaps an alternative would be to relax the ComplexField bound required by LU decomposition. Perhaps Field is enough?

exastion commented 4 years ago

Hey, I have a similar issue, where I need to invert matrices over a Galois Field. This is also not a ComplexField but implements everything a Field requires. As far as I see, for a lot of the things that require a ComplexField really only need a Field.

I tried using an extension Trait to get things working, but it seems like a rabbit hole and I don't want to copy all of the nalgebra code over.

This also relates to a quite old issue #303.