Skip to content

Commit

Permalink
Merge pull request #535 from rustsim/sparse
Browse files Browse the repository at this point in the history
Limited, experimental, sparse matrix support
  • Loading branch information
sebcrozet committed Feb 3, 2019
2 parents d702bf0 + 08f3183 commit 8117f61
Show file tree
Hide file tree
Showing 54 changed files with 2,874 additions and 344 deletions.
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

0 comments on commit 8117f61

Please sign in to comment.