I tried to implement LWE with Rust. Here is the memo about linear algebra libraries.
As of Nov.2021, there was no “defacto standard” linear algebra library in Rust.
I investigated, and decided to use ndarray
or nlagebra
.
https://github.com/rust-ndarray/ndarray
lapack
crate, which is a wrapper crate for LAPACK.I tried to use Static vector nalgebra::base::SVector
(optimized).
check test and know the traits.
SVector
s into a matrix (no trait like that?, dynamic?)::from_vec!
.from_vec!
doesn’t combine vectores:let dm = DMatrix::from_vec(2, 3, vec![0, 1, 2, 3, 4, 5]);
Matrix
definition, so I guess they don’t provide such API so far.https://docs.rs/nalgebra/latest/nalgebra/base/struct.Matrix.html
Matrix data is stored in 1D vector (data.data
attribute), and the size are stored in data.nrows
and data.ncols
, respectively.
The matrix data is called VecStorage
.
https://docs.rs/nalgebra/latest/src/nalgebra/base/vec_storage.rs.html#33-37
pub struct VecStorage<T, R: Dim, C: Dim> {
data: Vec<T>,
nrows: R,
ncols: C,
}
When I followed allocator.rs
-> default_allocator.rs
, I could see use std::ptr;
and use alloc::vec::Vec;
OK, the core Vec is normal standard library.
Review: When you create a matrix, from memory point of view, all data is stored in Vec
(1D) and the size is defined col
times row
, which means, the library is specialized for matrix (2D).
Finally I decided to implement only standard Vec
lib.
https://www.joshmcguigan.com/blog/array-initialization-rust/
let mut A = Vec::<Vec::<Z>>::new();
A.push(vec!(4, 9, 6));
A.push(vec!(4, 9, 9));
This 2D array is fragmented, because memory allocation of each vectors occured every time.
// Check
assert_eq!(A[4], vec!(5, 10, 4));
assert_eq!(A[6][2], 4);
assert_eq!(e[5], 9);
Vec
The type of A
is Vec<Vec<Z>>
, and the type of s
is Vec<T>
:
for a_i in A.iter() {
b.push(
a_i.iter().zip(s.iter())
.map(|(x, y)| x * y)
.sum::<Z>()
);
}
+
(failed)I tried to implement std::ops::Add
tarit for Vec
.
https://doc.rust-lang.org/std/ops/index.html
Failed:
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> src/main.rs:69:1
|
69 | impl<T> Add for Vec<T>
| ^^^^^^^^---^^^^^------
| | | |
| | | `Vec` is not defined in the current crate
| | `Vec` is not defined in the current crate
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
usize
https://doc.rust-lang.org/book/appendix-02-operators.html
path::<...>
,method::<...>
: Specifies parameters to generic type, function, or method in an expression; often referred to as turbofish (e.g.,"42".parse::<i32>()
).