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

Limited, experimental, sparse matrix support #535

Merged
merged 26 commits into from Feb 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0d24cf4
Run rustmt.
sebcrozet Oct 20, 2018
9fa3e7a
Implement CsMatrix: axpy_cs, transpose, Add and Mul.
sebcrozet Oct 20, 2018
dc8edec
Use an iterator to iterate through a column entries.
sebcrozet Oct 21, 2018
e4e5659
Add lower triangular solve with dense right-hand-side.
sebcrozet Oct 22, 2018
34b20dc
Add lower triangular solve with sparse right-hand-side.
sebcrozet Oct 23, 2018
7ecbaca
Add elimination tree computation.
sebcrozet Oct 30, 2018
9bf1d02
Fix cholesky computation.
sebcrozet Oct 30, 2018
50d0b64
Avoid bound-checking on cholesky decomposition.
sebcrozet Oct 30, 2018
c3e8112
Add implementation of the left-looking cholesky decomposition.
sebcrozet Nov 4, 2018
748cfee
Ensure the output of multiplication and triangular solve are sorted.
sebcrozet Nov 5, 2018
538e18b
Ensure the output of addition is sorted.
sebcrozet Nov 5, 2018
383a18f
Improve CsMatrix multiplaction performances.
sebcrozet Nov 6, 2018
ed07b78
Add matrixmarket parser.
sebcrozet Nov 6, 2018
8341ec2
Run rustfmt.
sebcrozet Nov 6, 2018
1866d59
Add rustfmt.toml.
sebcrozet Nov 6, 2018
f43ab96
Fix matrix market grammar.
sebcrozet Nov 6, 2018
b4b66bd
Add comment about cs matrix multiplication implementation.
sebcrozet Nov 6, 2018
cae2be5
Add .min and .max.
sebcrozet Dec 22, 2018
a14d8a4
Add coordinates access to translations.
sebcrozet Dec 26, 2018
9fbdedb
Implement ContiguousStorage for some matrix slices.
sebcrozet Jan 28, 2019
a7ab61f
Add horizontal and vertical resizing for dynamic matrices and vectors.
sebcrozet Jan 29, 2019
13f76ef
Add simple constructors for pure-translation and pure-rotation isomet…
sebcrozet Jan 29, 2019
fc24db8
Merge branch 'master-public' into sparse
sebcrozet Feb 3, 2019
ce8879c
Add all the missing docs.
sebcrozet Feb 3, 2019
7be7fc8
Fix compilation with no-std.
sebcrozet Feb 3, 2019
08f3183
Update to alga 0.8.
sebcrozet Feb 3, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 7 additions & 3 deletions Cargo.toml
Expand Up @@ -23,8 +23,10 @@ stdweb = [ "rand/stdweb" ]
arbitrary = [ "quickcheck" ]
serde-serialize = [ "serde", "serde_derive", "num-complex/serde" ]
abomonation-serialize = [ "abomonation" ]
sparse = [ ]
debug = [ ]
alloc = [ ]
io = [ "pest", "pest_derive" ]

[dependencies]
typenum = "1.10"
Expand All @@ -33,17 +35,19 @@ rand = { version = "0.6", default-features = false }
num-traits = { version = "0.2", default-features = false }
num-complex = { version = "0.2", default-features = false }
approx = { version = "0.3", default-features = false }
alga = { version = "0.7", default-features = false }
alga = { version = "0.8", default-features = false }
matrixmultiply = { version = "0.2", optional = true }
serde = { version = "1.0", optional = true }
serde_derive = { version = "1.0", optional = true }
abomonation = { version = "0.7", optional = true }
mint = { version = "0.5", optional = true }
quickcheck = { version = "0.7", optional = true }
quickcheck = { version = "0.8", optional = true }
pest = { version = "2.0", optional = true }
pest_derive = { version = "2.0", optional = true }

[dev-dependencies]
serde_json = "1.0"
rand_xorshift = "0.1"

[workspace]
members = [ "nalgebra-lapack", "nalgebra-glm" ]
members = [ "nalgebra-lapack", "nalgebra-glm" ]
2 changes: 1 addition & 1 deletion ci/build.sh
Expand Up @@ -11,7 +11,7 @@ if [ -z "$NO_STD" ]; then
cargo build --verbose -p nalgebra --features "serde-serialize";
cargo build --verbose -p nalgebra --features "abomonation-serialize";
cargo build --verbose -p nalgebra --features "debug";
cargo build --verbose -p nalgebra --features "debug arbitrary mint serde-serialize abomonation-serialize";
cargo build --verbose -p nalgebra --all-features
else
cargo build -p nalgebra-lapack;
fi
Expand Down
4 changes: 2 additions & 2 deletions examples/matrix_construction.rs
Expand Up @@ -51,8 +51,8 @@ fn main() {
// Components listed column-by-column.
1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
]
.iter()
.cloned(),
.iter()
.cloned(),
);

assert_eq!(dm, dm1);
Expand Down
2 changes: 1 addition & 1 deletion nalgebra-glm/Cargo.toml
Expand Up @@ -23,5 +23,5 @@ abomonation-serialize = [ "nalgebra/abomonation-serialize" ]
[dependencies]
num-traits = { version = "0.2", default-features = false }
approx = { version = "0.3", default-features = false }
alga = { version = "0.7", default-features = false }
alga = { version = "0.8", default-features = false }
nalgebra = { path = "..", version = "^0.16.13", default-features = false }
2 changes: 1 addition & 1 deletion nalgebra-glm/src/ext/matrix_transform.rs
Expand Up @@ -9,7 +9,7 @@ where DefaultAllocator: Alloc<N, D, D> {
TMat::<N, D, D>::identity()
}

/// Build a right hand look at view matrix
/// Build a look at view matrix based on the right handedness.
///
/// # Parameters:
///
Expand Down
1 change: 1 addition & 0 deletions nalgebra-glm/src/lib.rs
Expand Up @@ -110,6 +110,7 @@
and keep in mind it is possible to convert, e.g., an `Isometry3` to a `Mat4` and vice-versa (see the [conversions section](#conversions)).
*/

#![doc(html_favicon_url = "http://nalgebra.org/img/favicon.ico")]
#![cfg_attr(not(feature = "std"), no_std)]

extern crate num_traits as num;
Expand Down
4 changes: 2 additions & 2 deletions nalgebra-lapack/Cargo.toml
Expand Up @@ -25,7 +25,7 @@ intel-mkl = ["lapack-src/intel-mkl"]
nalgebra = { version = "0.16", path = ".." }
num-traits = "0.2"
num-complex = { version = "0.2", default-features = false }
alga = { version = "0.7", default-features = false }
alga = { version = "0.8", default-features = false }
serde = { version = "1.0", optional = true }
serde_derive = { version = "1.0", optional = true }
lapack = { version = "0.16", default-features = false }
Expand All @@ -34,6 +34,6 @@ lapack-src = { version = "0.2", default-features = false }

[dev-dependencies]
nalgebra = { version = "0.16", path = "..", features = [ "arbitrary" ] }
quickcheck = "0.7"
quickcheck = "0.8"
approx = "0.3"
rand = "0.6"
6 changes: 4 additions & 2 deletions nalgebra-lapack/src/lib.rs
Expand Up @@ -68,8 +68,10 @@
#![deny(unused_qualifications)]
#![deny(unused_results)]
#![deny(missing_docs)]
#![doc(html_favicon_url = "http://nalgebra.org/img/favicon.ico",
html_root_url = "http://nalgebra.org/rustdoc")]
#![doc(
html_favicon_url = "http://nalgebra.org/img/favicon.ico",
html_root_url = "http://nalgebra.org/rustdoc"
)]

extern crate alga;
extern crate lapack;
Expand Down
2 changes: 1 addition & 1 deletion rustfmt.toml
@@ -1,3 +1,3 @@
unstable_features = true
indent_style = "Block"
where_single_line = true
where_single_line = true
2 changes: 1 addition & 1 deletion src/base/componentwise.rs
@@ -1,4 +1,4 @@
// Non-conventional componentwise operators.
// Non-conventional component-wise operators.

use num::{Signed, Zero};
use std::ops::{Add, Mul};
Expand Down
4 changes: 3 additions & 1 deletion src/base/conversion.rs
Expand Up @@ -12,8 +12,10 @@ use typenum::Prod;
use base::allocator::{Allocator, SameShapeAllocator};
use base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
use base::dimension::{
Dim, DimName, Dynamic, U1, U10, U11, U12, U13, U14, U15, U16, U2, U3, U4, U5, U6, U7, U8, U9,
Dim, DimName, U1, U10, U11, U12, U13, U14, U15, U16, U2, U3, U4, U5, U6, U7, U8, U9,
};
#[cfg(any(feature = "std", feature = "alloc"))]
use base::dimension::Dynamic;
use base::iter::{MatrixIter, MatrixIterMut};
use base::storage::{ContiguousStorage, ContiguousStorageMut, Storage, StorageMut};
#[cfg(any(feature = "std", feature = "alloc"))]
Expand Down
6 changes: 4 additions & 2 deletions src/base/dimension.rs
Expand Up @@ -364,7 +364,8 @@ impl<
G: Bit + Any + Debug + Copy + PartialEq + Send + Sync,
> IsNotStaticOne
for UInt<UInt<UInt<UInt<UInt<UInt<UInt<UInt<UTerm, B1>, A>, B>, C>, D>, E>, F>, G>
{}
{
}

impl<U: Unsigned + DimName, B: Bit + Any + Debug + Copy + PartialEq + Send + Sync> NamedDim
for UInt<U, B>
Expand Down Expand Up @@ -405,4 +406,5 @@ impl<U: Unsigned + DimName, B: Bit + Any + Debug + Copy + PartialEq + Send + Syn

impl<U: Unsigned + DimName, B: Bit + Any + Debug + Copy + PartialEq + Send + Sync> IsNotStaticOne
for UInt<U, B>
{}
{
}
94 changes: 93 additions & 1 deletion src/base/edition.rs
@@ -1,13 +1,18 @@
use num::{One, Zero};
use std::cmp;
use std::ptr;
#[cfg(any(feature = "std", feature = "alloc"))]
use std::iter::ExactSizeIterator;
#[cfg(any(feature = "std", feature = "alloc"))]
use std::mem;

use base::allocator::{Allocator, Reallocator};
use base::constraint::{DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
use base::dimension::{
Dim, DimAdd, DimDiff, DimMin, DimMinimum, DimName, DimSub, DimSum, Dynamic, U1,
Dim, DimAdd, DimDiff, DimMin, DimMinimum, DimName, DimSub, DimSum, U1,
};
#[cfg(any(feature = "std", feature = "alloc"))]
use base::dimension::Dynamic;
use base::storage::{Storage, StorageMut};
#[cfg(any(feature = "std", feature = "alloc"))]
use base::DMatrix;
Expand Down Expand Up @@ -35,6 +40,7 @@ impl<N: Scalar + Zero, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
}

/// Creates a new matrix by extracting the given set of rows from `self`.
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn select_rows<'a, I>(&self, irows: I) -> MatrixMN<N, Dynamic, C>
where I: IntoIterator<Item = &'a usize>,
I::IntoIter: ExactSizeIterator + Clone,
Expand Down Expand Up @@ -65,6 +71,7 @@ impl<N: Scalar + Zero, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
}

/// Creates a new matrix by extracting the given set of columns from `self`.
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn select_columns<'a, I>(&self, icols: I) -> MatrixMN<N, R, Dynamic>
where I: IntoIterator<Item = &'a usize>,
I::IntoIter: ExactSizeIterator,
Expand Down Expand Up @@ -295,6 +302,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {

/// Removes `n` consecutive columns from this matrix, starting with the `i`-th (included).
#[inline]
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn remove_columns(self, i: usize, n: usize) -> MatrixMN<N, R, Dynamic>
where
C: DimSub<Dynamic, Output = Dynamic>,
Expand Down Expand Up @@ -377,6 +385,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {

/// Removes `n` consecutive rows from this matrix, starting with the `i`-th (included).
#[inline]
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn remove_rows(self, i: usize, n: usize) -> MatrixMN<N, Dynamic, C>
where
R: DimSub<Dynamic, Output = Dynamic>,
Expand Down Expand Up @@ -454,6 +463,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {

/// Inserts `n` columns filled with `val` starting at the `i-th` position.
#[inline]
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn insert_columns(self, i: usize, n: usize, val: N) -> MatrixMN<N, R, Dynamic>
where
C: DimAdd<Dynamic, Output = Dynamic>,
Expand Down Expand Up @@ -531,6 +541,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {

/// Inserts `n` rows filled with `val` starting at the `i-th` position.
#[inline]
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn insert_rows(self, i: usize, n: usize, val: N) -> MatrixMN<N, Dynamic, C>
where
R: DimAdd<Dynamic, Output = Dynamic>,
Expand Down Expand Up @@ -596,6 +607,29 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
self.resize_generic(Dynamic::new(new_nrows), Dynamic::new(new_ncols), val)
}

/// Resizes this matrix vertically, i.e., so that it contains `new_nrows` rows while keeping the same number of columns.
///
/// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more
/// rows than `self`, then the extra rows are filled with `val`.
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn resize_vertically(self, new_nrows: usize, val: N) -> MatrixMN<N, Dynamic, C>
where DefaultAllocator: Reallocator<N, R, C, Dynamic, C> {
let ncols = self.data.shape().1;
self.resize_generic(Dynamic::new(new_nrows), ncols, val)
}

/// Resizes this matrix horizontally, i.e., so that it contains `new_ncolumns` columns while keeping the same number of columns.
///
/// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more
/// columns than `self`, then the extra columns are filled with `val`.
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn resize_horizontally(self, new_ncols: usize, val: N) -> MatrixMN<N, R, Dynamic>
where DefaultAllocator: Reallocator<N, R, C, R, Dynamic> {
let nrows = self.data.shape().0;
self.resize_generic(nrows, Dynamic::new(new_ncols), val)
}


/// Resizes this matrix so that it contains `R2::value()` rows and `C2::value()` columns.
///
/// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more
Expand Down Expand Up @@ -673,6 +707,61 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
}
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl<N: Scalar> DMatrix<N> {
/// Resizes this matrix in-place.
///
/// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more
/// rows and/or columns than `self`, then the extra rows or columns are filled with `val`.
///
/// Defined only for owned fully-dynamic matrices, i.e., `DMatrix`.
pub fn resize_mut(&mut self, new_nrows: usize, new_ncols: usize, val: N)
where DefaultAllocator: Reallocator<N, Dynamic, Dynamic, Dynamic, Dynamic> {
let placeholder = unsafe { Self::new_uninitialized(0, 0) };
let old = mem::replace(self, placeholder);
let new = old.resize(new_nrows, new_ncols, val);
let _ = mem::replace(self, new);
}
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl<N: Scalar, C: Dim> MatrixMN<N, Dynamic, C>
where DefaultAllocator: Allocator<N, Dynamic, C> {
/// Changes the number of rows of this matrix in-place.
///
/// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more
/// rows than `self`, then the extra rows are filled with `val`.
///
/// Defined only for owned matrices with a dynamic number of rows (for example, `DVector`).
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn resize_vertically_mut(&mut self, new_nrows: usize, val: N)
where DefaultAllocator: Reallocator<N, Dynamic, C, Dynamic, C> {
let placeholder = unsafe { Self::new_uninitialized_generic(Dynamic::new(0), self.data.shape().1) };
let old = mem::replace(self, placeholder);
let new = old.resize_vertically(new_nrows, val);
let _ = mem::replace(self, new);
}
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl<N: Scalar, R: Dim> MatrixMN<N, R, Dynamic>
where DefaultAllocator: Allocator<N, R, Dynamic> {
/// Changes the number of column of this matrix in-place.
///
/// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more
/// columns than `self`, then the extra columns are filled with `val`.
///
/// Defined only for owned matrices with a dynamic number of columns (for example, `DVector`).
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn resize_horizontally_mut(&mut self, new_ncols: usize, val: N)
where DefaultAllocator: Reallocator<N, R, Dynamic, R, Dynamic> {
let placeholder = unsafe { Self::new_uninitialized_generic(self.data.shape().0, Dynamic::new(0)) };
let old = mem::replace(self, placeholder);
let new = old.resize_horizontally(new_ncols, val);
let _ = mem::replace(self, new);
}
}

unsafe fn compress_rows<N: Scalar>(
data: &mut [N],
nrows: usize,
Expand Down Expand Up @@ -753,6 +842,7 @@ unsafe fn extend_rows<N: Scalar>(

/// Extend the number of columns of the `Matrix` with elements from
/// a given iterator.
#[cfg(any(feature = "std", feature = "alloc"))]
impl<N, R, S> Extend<N> for Matrix<N, R, Dynamic, S>
where
N: Scalar,
Expand Down Expand Up @@ -800,6 +890,7 @@ where

/// Extend the number of rows of the `Vector` with elements from
/// a given iterator.
#[cfg(any(feature = "std", feature = "alloc"))]
impl<N, S> Extend<N> for Matrix<N, Dynamic, U1, S>
where
N: Scalar,
Expand All @@ -820,6 +911,7 @@ where
}
}

#[cfg(any(feature = "std", feature = "alloc"))]
impl<N, R, S, RV, SV> Extend<Vector<N, RV, SV>> for Matrix<N, R, Dynamic, S>
where
N: Scalar,
Expand Down
8 changes: 4 additions & 4 deletions src/base/matrix_alga.rs
Expand Up @@ -6,7 +6,7 @@ use num::{One, Zero};
use alga::general::{
AbstractGroup, AbstractGroupAbelian, AbstractLoop, AbstractMagma, AbstractModule,
AbstractMonoid, AbstractQuasigroup, AbstractSemigroup, Additive, ClosedAdd, ClosedMul,
ClosedNeg, Field, Identity, Inverse, JoinSemilattice, Lattice, MeetSemilattice, Module,
ClosedNeg, Field, Identity, TwoSidedInverse, JoinSemilattice, Lattice, MeetSemilattice, Module,
Multiplicative, Real, RingCommutative,
};
use alga::linear::{
Expand Down Expand Up @@ -45,18 +45,18 @@ where
}
}

impl<N, R: DimName, C: DimName> Inverse<Additive> for MatrixMN<N, R, C>
impl<N, R: DimName, C: DimName> TwoSidedInverse<Additive> for MatrixMN<N, R, C>
where
N: Scalar + ClosedNeg,
DefaultAllocator: Allocator<N, R, C>,
{
#[inline]
fn inverse(&self) -> MatrixMN<N, R, C> {
fn two_sided_inverse(&self) -> MatrixMN<N, R, C> {
-self
}

#[inline]
fn inverse_mut(&mut self) {
fn two_sided_inverse_mut(&mut self) {
*self = -self.clone()
}
}
Expand Down