Merge remote-tracking branch 'upstream/dev' into rot-interp

This commit is contained in:
Joshua Smith 2024-03-28 20:33:00 -04:00
commit 5a1f9a5236
192 changed files with 9270 additions and 4435 deletions

View File

@ -49,8 +49,6 @@ jobs:
build-nalgebra-all-features: build-nalgebra-all-features:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
# Needed because the --all-features build which enables cuda support.
- uses: Jimver/cuda-toolkit@v0.2.4
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- run: cargo build --all-features; - run: cargo build --all-features;
- run: cargo build -p nalgebra-glm --all-features; - run: cargo build -p nalgebra-glm --all-features;
@ -61,7 +59,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: test - name: test
run: cargo test --features arbitrary,rand,serde-serialize,sparse,debug,io,compare,libm,proptest-support,slow-tests; run: cargo test --features arbitrary,rand,serde-serialize,sparse,debug,io,compare,libm,proptest-support,slow-tests,rkyv-safe-deser,rayon;
test-nalgebra-glm: test-nalgebra-glm:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@ -120,20 +118,9 @@ jobs:
run: xargo build --verbose --no-default-features -p nalgebra-glm --target=x86_64-unknown-linux-gnu; run: xargo build --verbose --no-default-features -p nalgebra-glm --target=x86_64-unknown-linux-gnu;
- name: build thumbv7em-none-eabihf nalgebra-glm - name: build thumbv7em-none-eabihf nalgebra-glm
run: xargo build --verbose --no-default-features -p nalgebra-glm --target=thumbv7em-none-eabihf; run: xargo build --verbose --no-default-features -p nalgebra-glm --target=thumbv7em-none-eabihf;
build-cuda: docs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: Jimver/cuda-toolkit@v0.2.4
with:
cuda: '11.2.2'
- name: Install nightly-2021-12-04
uses: actions-rs/toolchain@v1
with:
toolchain: nightly-2021-12-04
override: true
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- run: rustup target add nvptx64-nvidia-cuda - name: Generate documentation
- run: cargo build --no-default-features --features cuda run: cargo doc
- run: cargo build --no-default-features --features cuda --target=nvptx64-nvidia-cuda
env:
CUDA_ARCH: "350"

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[package] [package]
name = "nalgebra" name = "nalgebra"
version = "0.30.1" version = "0.32.3"
authors = [ "Sébastien Crozet <developer@crozet.re>" ] authors = [ "Sébastien Crozet <developer@crozet.re>" ]
description = "General-purpose linear algebra library with transformations and statically-sized or dynamically-sized matrices." description = "General-purpose linear algebra library with transformations and statically-sized or dynamically-sized matrices."
@ -10,7 +10,7 @@ repository = "https://github.com/dimforge/nalgebra"
readme = "README.md" readme = "README.md"
categories = [ "science", "mathematics", "wasm", "no-std" ] categories = [ "science", "mathematics", "wasm", "no-std" ]
keywords = [ "linear", "algebra", "matrix", "vector", "math" ] keywords = [ "linear", "algebra", "matrix", "vector", "math" ]
license = "BSD-3-Clause" license = "Apache-2.0"
edition = "2018" edition = "2018"
exclude = ["/ci/*", "/.travis.yml", "/Makefile"] exclude = ["/ci/*", "/.travis.yml", "/Makefile"]
@ -23,7 +23,7 @@ path = "src/lib.rs"
[features] [features]
default = [ "std", "macros" ] default = [ "std", "macros" ]
std = [ "matrixmultiply", "simba/std" ] std = [ "matrixmultiply", "num-traits/std", "num-complex/std", "num-rational/std", "approx/std", "simba/std" ]
sparse = [ ] sparse = [ ]
debug = [ "approx/num-complex", "rand" ] debug = [ "approx/num-complex", "rand" ]
alloc = [ ] alloc = [ ]
@ -32,12 +32,11 @@ compare = [ "matrixcompare-core" ]
libm = [ "simba/libm" ] libm = [ "simba/libm" ]
libm-force = [ "simba/libm_force" ] libm-force = [ "simba/libm_force" ]
macros = [ "nalgebra-macros" ] macros = [ "nalgebra-macros" ]
cuda = [ "cust_core", "simba/cuda" ]
# Conversion # Conversion
convert-mint = [ "mint" ] convert-mint = [ "mint" ]
convert-bytemuck = [ "bytemuck" ] convert-bytemuck = [ "bytemuck" ]
convert-glam013 = [ "glam013" ]
convert-glam014 = [ "glam014" ] convert-glam014 = [ "glam014" ]
convert-glam015 = [ "glam015" ] convert-glam015 = [ "glam015" ]
convert-glam016 = [ "glam016" ] convert-glam016 = [ "glam016" ]
@ -45,6 +44,11 @@ convert-glam017 = [ "glam017" ]
convert-glam018 = [ "glam018" ] convert-glam018 = [ "glam018" ]
convert-glam019 = [ "glam019" ] convert-glam019 = [ "glam019" ]
convert-glam020 = [ "glam020" ] convert-glam020 = [ "glam020" ]
convert-glam021 = [ "glam021" ]
convert-glam022 = [ "glam022" ]
convert-glam023 = [ "glam023" ]
convert-glam024 = [ "glam024" ]
convert-glam025 = [ "glam025" ]
# Serialization # Serialization
## To use serde in a #[no-std] environment, enable the ## To use serde in a #[no-std] environment, enable the
@ -53,8 +57,8 @@ convert-glam020 = [ "glam020" ]
## `serde-serialize`. ## `serde-serialize`.
serde-serialize-no-std = [ "serde", "num-complex/serde" ] serde-serialize-no-std = [ "serde", "num-complex/serde" ]
serde-serialize = [ "serde-serialize-no-std", "serde/std" ] serde-serialize = [ "serde-serialize-no-std", "serde/std" ]
rkyv-serialize-no-std = [ "rkyv" ] rkyv-serialize-no-std = [ "rkyv/size_32" ]
rkyv-serialize = [ "rkyv-serialize-no-std", "rkyv/std" ] rkyv-serialize = [ "rkyv-serialize-no-std", "rkyv/std", "rkyv/validation" ]
# Randomness # Randomness
## To use rand in a #[no-std] environment, enable the ## To use rand in a #[no-std] environment, enable the
@ -66,21 +70,22 @@ rand = [ "rand-no-std", "rand-package/std", "rand-package/std_rng", "rand
arbitrary = [ "quickcheck" ] arbitrary = [ "quickcheck" ]
proptest-support = [ "proptest" ] proptest-support = [ "proptest" ]
slow-tests = [] slow-tests = []
rkyv-safe-deser = [ "rkyv-serialize", "rkyv/validation" ]
[dependencies] [dependencies]
nalgebra-macros = { version = "0.1", path = "nalgebra-macros", optional = true } nalgebra-macros = { version = "0.2.1", path = "nalgebra-macros", optional = true }
typenum = "1.12" typenum = "1.12"
rand-package = { package = "rand", version = "0.8", optional = true, default-features = false } rand-package = { package = "rand", version = "0.8", optional = true, default-features = false }
num-traits = { version = "0.2", default-features = false } num-traits = { version = "0.2", default-features = false }
num-complex = { version = "0.4", default-features = false } num-complex = { version = "0.4", default-features = false }
num-rational = { version = "0.4", default-features = false } num-rational = { version = "0.4", default-features = false }
approx = { version = "0.5", default-features = false } approx = { version = "0.5", default-features = false }
simba = { version = "0.7", default-features = false } simba = { version = "0.8", default-features = false }
alga = { version = "0.9", default-features = false, optional = true } alga = { version = "0.9", default-features = false, optional = true }
rand_distr = { version = "0.4", default-features = false, optional = true } rand_distr = { version = "0.4", default-features = false, optional = true }
matrixmultiply = { version = "0.3", optional = true } matrixmultiply = { version = "0.3", optional = true }
serde = { version = "1.0", default-features = false, features = [ "derive" ], optional = true } serde = { version = "1.0", default-features = false, features = [ "derive" ], optional = true }
rkyv = { version = "~0.6.4", default-features = false, features = ["const_generics"], optional = true } rkyv = { version = "0.7.41", default-features = false, optional = true }
mint = { version = "0.5", optional = true } mint = { version = "0.5", optional = true }
quickcheck = { version = "1", optional = true } quickcheck = { version = "1", optional = true }
pest = { version = "2", optional = true } pest = { version = "2", optional = true }
@ -88,7 +93,6 @@ pest_derive = { version = "2", optional = true }
bytemuck = { version = "1.5", optional = true } bytemuck = { version = "1.5", optional = true }
matrixcompare-core = { version = "0.1", optional = true } matrixcompare-core = { version = "0.1", optional = true }
proptest = { version = "1", optional = true, default-features = false, features = ["std"] } proptest = { version = "1", optional = true, default-features = false, features = ["std"] }
glam013 = { package = "glam", version = "0.13", optional = true }
glam014 = { package = "glam", version = "0.14", optional = true } glam014 = { package = "glam", version = "0.14", optional = true }
glam015 = { package = "glam", version = "0.15", optional = true } glam015 = { package = "glam", version = "0.15", optional = true }
glam016 = { package = "glam", version = "0.16", optional = true } glam016 = { package = "glam", version = "0.16", optional = true }
@ -96,14 +100,19 @@ glam017 = { package = "glam", version = "0.17", optional = true }
glam018 = { package = "glam", version = "0.18", optional = true } glam018 = { package = "glam", version = "0.18", optional = true }
glam019 = { package = "glam", version = "0.19", optional = true } glam019 = { package = "glam", version = "0.19", optional = true }
glam020 = { package = "glam", version = "0.20", optional = true } glam020 = { package = "glam", version = "0.20", optional = true }
cust_core = { version = "0.1", optional = true } glam021 = { package = "glam", version = "0.21", optional = true }
glam022 = { package = "glam", version = "0.22", optional = true }
glam023 = { package = "glam", version = "0.23", optional = true }
glam024 = { package = "glam", version = "0.24", optional = true }
glam025 = { package = "glam", version = "0.25", optional = true }
rayon = { version = "1.6", optional = true }
[dev-dependencies] [dev-dependencies]
serde_json = "1.0" serde_json = "1.0"
rand_xorshift = "0.3" rand_xorshift = "0.3"
rand_isaac = "0.3" rand_isaac = "0.3"
criterion = { version = "0.3", features = ["html_reports"] } criterion = { version = "0.4", features = ["html_reports"] }
nalgebra = { path = ".", features = ["debug", "compare", "rand", "macros"]}
# For matrix comparison macro # For matrix comparison macro
matrixcompare = "0.3.0" matrixcompare = "0.3.0"
@ -131,6 +140,7 @@ required-features = ["rand"]
lto = true lto = true
[package.metadata.docs.rs] [package.metadata.docs.rs]
# Enable certain features when building docs for docs.rs # Enable all the features when building the docs on docs.rs
features = [ "proptest-support", "compare", "macros", "rand" ] all-features = true
# define the configuration attribute `docsrs`
rustdoc-args = ["--cfg", "docsrs"]

View File

@ -29,19 +29,3 @@
</p> </p>
----- -----
## Acknowledgements
nalgebra is supported by our **platinum** sponsors:
<p>
<a href="https://embark-studios.com">
<img src="https://www.embark.dev/img/logo_black.png" width="301px">
</a>
</p>
And our gold sponsors:
<p>
<a href="https://fragcolor.com">
<img src="https://dimforge.com/img/fragcolor_logo1_color_black.svg" width="151px">
</a>
</p>

View File

@ -53,7 +53,7 @@ fn mat_div_scalar(b: &mut criterion::Criterion) {
b.bench_function("mat_div_scalar", move |bh| { b.bench_function("mat_div_scalar", move |bh| {
bh.iter(|| { bh.iter(|| {
let mut aa = a.clone(); let mut aa = a.clone();
let mut b = aa.slice_mut((0, 0), (1000, 1000)); let mut b = aa.view_mut((0, 0), (1000, 1000));
b /= n b /= n
}) })
}); });
@ -142,7 +142,7 @@ fn iter(bench: &mut criterion::Criterion) {
bench.bench_function("iter", move |bh| { bench.bench_function("iter", move |bh| {
bh.iter(|| { bh.iter(|| {
for value in a.iter() { for value in a.iter() {
criterion::black_box(value); std::hint::black_box(value);
} }
}) })
}); });
@ -154,7 +154,7 @@ fn iter_rev(bench: &mut criterion::Criterion) {
bench.bench_function("iter_rev", move |bh| { bench.bench_function("iter_rev", move |bh| {
bh.iter(|| { bh.iter(|| {
for value in a.iter().rev() { for value in a.iter().rev() {
criterion::black_box(value); std::hint::black_box(value);
} }
}) })
}); });

View File

@ -1,4 +1,3 @@
#![feature(bench_black_box)]
#![allow(unused_macros)] #![allow(unused_macros)]
extern crate nalgebra as na; extern crate nalgebra as na;

View File

@ -4,7 +4,7 @@ version = "0.0.0"
authors = [ "You" ] authors = [ "You" ]
[dependencies] [dependencies]
nalgebra = "0.30.0" nalgebra = "0.32.0"
[[bin]] [[bin]]
name = "example" name = "example"

View File

@ -28,7 +28,7 @@ where
} }
/// Reflects a 3D vector wrt. the 3D plane with normal `plane_normal`. /// Reflects a 3D vector wrt. the 3D plane with normal `plane_normal`.
/// /!\ This is an exact replicate of `reflect_wrt_hyperplane2, but for 3D. /// /!\ This is an exact replicate of `reflect_wrt_hyperplane2`, but for 3D.
fn reflect_wrt_hyperplane3<T>(plane_normal: &Unit<Vector3<T>>, vector: &Vector3<T>) -> Vector3<T> fn reflect_wrt_hyperplane3<T>(plane_normal: &Unit<Vector3<T>>, vector: &Vector3<T>) -> Vector3<T>
where where
T: RealField, T: RealField,

View File

@ -2,7 +2,7 @@
extern crate nalgebra as na; extern crate nalgebra as na;
use na::{DMatrix, Dynamic, Matrix2x3, Matrix3x2, Const}; use na::{DMatrix, Dyn, Matrix2x3, Matrix3x2, Const};
fn main() { fn main() {
// Matrices can be reshaped in-place without moving or copying values. // Matrices can be reshaped in-place without moving or copying values.
@ -46,9 +46,9 @@ fn main() {
], ],
); );
let dm3 = dm1.reshape_generic(Dynamic::new(6), Dynamic::new(2)); let dm3 = dm1.reshape_generic(Dyn(6), Dyn(2));
assert_eq!(dm3, dm2); assert_eq!(dm3, dm2);
// Invalid reshapings of dynamic matrices will panic at run-time. // Invalid reshapings of dynamic matrices will panic at run-time.
//let dm4 = dm3.reshape_generic(Dynamic::new(6), Dynamic::new(6)); //let dm4 = dm3.reshape_generic(Dyn(6), Dyn(6));
} }

View File

@ -1,6 +1,6 @@
[package] [package]
name = "nalgebra-glm" name = "nalgebra-glm"
version = "0.16.0" version = "0.18.0"
authors = ["sebcrozet <developer@crozet.re>"] authors = ["sebcrozet <developer@crozet.re>"]
description = "A computer-graphics oriented API for nalgebra, inspired by the C++ GLM library." description = "A computer-graphics oriented API for nalgebra, inspired by the C++ GLM library."
@ -10,7 +10,7 @@ repository = "https://github.com/dimforge/nalgebra"
readme = "../README.md" readme = "../README.md"
categories = [ "science", "mathematics", "wasm", "no standard library" ] categories = [ "science", "mathematics", "wasm", "no standard library" ]
keywords = [ "linear", "algebra", "matrix", "vector", "math" ] keywords = [ "linear", "algebra", "matrix", "vector", "math" ]
license = "BSD-3-Clause" license = "Apache-2.0"
edition = "2018" edition = "2018"
[badges] [badges]
@ -21,12 +21,10 @@ default = [ "std" ]
std = [ "nalgebra/std", "simba/std" ] std = [ "nalgebra/std", "simba/std" ]
arbitrary = [ "nalgebra/arbitrary" ] arbitrary = [ "nalgebra/arbitrary" ]
serde-serialize = [ "nalgebra/serde-serialize-no-std" ] serde-serialize = [ "nalgebra/serde-serialize-no-std" ]
cuda = [ "nalgebra/cuda" ]
# Conversion # Conversion
convert-mint = [ "nalgebra/mint" ] convert-mint = [ "nalgebra/mint" ]
convert-bytemuck = [ "nalgebra/bytemuck" ] convert-bytemuck = [ "nalgebra/bytemuck" ]
convert-glam013 = [ "nalgebra/glam013" ]
convert-glam014 = [ "nalgebra/glam014" ] convert-glam014 = [ "nalgebra/glam014" ]
convert-glam015 = [ "nalgebra/glam015" ] convert-glam015 = [ "nalgebra/glam015" ]
convert-glam016 = [ "nalgebra/glam016" ] convert-glam016 = [ "nalgebra/glam016" ]
@ -36,5 +34,5 @@ convert-glam018 = [ "nalgebra/glam018" ]
[dependencies] [dependencies]
num-traits = { version = "0.2", default-features = false } num-traits = { version = "0.2", default-features = false }
approx = { version = "0.5", default-features = false } approx = { version = "0.5", default-features = false }
simba = { version = "0.7", default-features = false } simba = { version = "0.8", default-features = false }
nalgebra = { path = "..", version = "0.30", default-features = false } nalgebra = { path = "..", version = "0.32", default-features = false }

1
nalgebra-glm/LICENSE Symbolic link
View File

@ -0,0 +1 @@
../LICENSE

View File

@ -5,38 +5,38 @@ use na::{
/// A matrix with components of type `T`. It has `R` rows, and `C` columns. /// A matrix with components of type `T`. It has `R` rows, and `C` columns.
/// ///
/// In this library, vectors, represented as [`TVec`](type.TVec.html) and /// In this library, vectors, represented as [`TVec`] and
/// friends, are also matrices. Operations that operate on a matrix will /// friends, are also matrices. Operations that operate on a matrix will
/// also work on a vector. /// also work on a vector.
/// ///
/// # See also: /// # See also:
/// ///
/// * [`TMat2`](type.TMat2.html) /// * [`TMat2`]
/// * [`TMat2x2`](type.TMat2x2.html) /// * [`TMat2x2`]
/// * [`TMat2x3`](type.TMat2x3.html) /// * [`TMat2x3`]
/// * [`TMat2x4`](type.TMat2x4.html) /// * [`TMat2x4`]
/// * [`TMat3`](type.TMat3.html) /// * [`TMat3`]
/// * [`TMat3x2`](type.TMat3x2.html) /// * [`TMat3x2`]
/// * [`TMat3x3`](type.TMat3x3.html) /// * [`TMat3x3`]
/// * [`TMat3x4`](type.TMat3x4.html) /// * [`TMat3x4`]
/// * [`TMat4`](type.TMat4.html) /// * [`TMat4`]
/// * [`TMat4x2`](type.TMat4x2.html) /// * [`TMat4x2`]
/// * [`TMat4x3`](type.TMat4x3.html) /// * [`TMat4x3`]
/// * [`TMat4x4`](type.TMat4x4.html) /// * [`TMat4x4`]
/// * [`TVec`](type.TVec.html) /// * [`TVec`]
pub type TMat<T, const R: usize, const C: usize> = SMatrix<T, R, C>; pub type TMat<T, const R: usize, const C: usize> = SMatrix<T, R, C>;
/// A column vector with components of type `T`. It has `D` rows (and one column). /// A column vector with components of type `T`. It has `D` rows (and one column).
/// ///
/// In this library, vectors are represented as a single column matrix, so /// In this library, vectors are represented as a single column matrix, so
/// operations on [`TMat`](type.TMat.html) are also valid on vectors. /// operations on [`TMat`] are also valid on vectors.
/// ///
/// # See also: /// # See also:
/// ///
/// * [`TMat`](type.TMat.html) /// * [`TMat`]
/// * [`TVec1`](type.TVec1.html) /// * [`TVec1`]
/// * [`TVec2`](type.TVec2.html) /// * [`TVec2`]
/// * [`TVec3`](type.TVec3.html) /// * [`TVec3`]
/// * [`TVec4`](type.TVec4.html) /// * [`TVec4`]
pub type TVec<T, const R: usize> = SVector<T, R>; pub type TVec<T, const R: usize> = SVector<T, R>;
/// A quaternion with components of type `T`. /// A quaternion with components of type `T`.
pub type Qua<T> = Quaternion<T>; pub type Qua<T> = Quaternion<T>;
@ -47,28 +47,28 @@ pub type Qua<T> = Quaternion<T>;
/// ///
/// ## Constructors: /// ## Constructors:
/// ///
/// * [`make_vec1`](fn.make_vec1.html) /// * [`make_vec1()`](crate::make_vec1)
/// * [`vec1`](fn.vec1.html) /// * [`vec1()`](crate::vec1)
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html) /// * [`vec2_to_vec1()`](crate::vec2_to_vec1)
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html) /// * [`vec3_to_vec1()`](crate::vec3_to_vec1)
/// * [`vec4_to_vec1`](fn.vec4_to_vec1.html) /// * [`vec4_to_vec1()`](crate::vec4_to_vec1)
/// ///
/// ## Related types: /// ## Related types:
/// ///
/// * [`BVec1`](type.BVec1.html) /// * [`BVec1`]
/// * [`DVec1`](type.DVec1.html) /// * [`DVec1`]
/// * [`IVec1`](type.IVec1.html) /// * [`IVec1`]
/// * [`I16Vec1`](type.I16Vec1.html) /// * [`I16Vec1`]
/// * [`I32Vec1`](type.I32Vec1.html) /// * [`I32Vec1`]
/// * [`I64Vec1`](type.I64Vec1.html) /// * [`I64Vec1`]
/// * [`I8Vec1`](type.I8Vec1.html) /// * [`I8Vec1`]
/// * [`TVec`](type.TVec.html) /// * [`TVec`]
/// * [`UVec1`](type.UVec1.html) /// * [`UVec1`]
/// * [`U16Vec1`](type.U16Vec1.html) /// * [`U16Vec1`]
/// * [`U32Vec1`](type.U32Vec1.html) /// * [`U32Vec1`]
/// * [`U64Vec1`](type.U64Vec1.html) /// * [`U64Vec1`]
/// * [`U8Vec1`](type.U8Vec1.html) /// * [`U8Vec1`]
/// * [`Vec1`](type.Vec1.html) /// * [`Vec1`]
pub type TVec1<T> = TVec<T, 1>; pub type TVec1<T> = TVec<T, 1>;
/// A 2D vector with components of type `T`. /// A 2D vector with components of type `T`.
/// ///
@ -76,29 +76,28 @@ pub type TVec1<T> = TVec<T, 1>;
/// ///
/// ## Constructors: /// ## Constructors:
/// ///
/// * [`make_vec2`](fn.make_vec2.html) /// * [`make_vec2()`](crate::make_vec2)
/// * [`vec2`](fn.vec2.html) /// * [`vec2()`](crate::vec2)
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html) /// * [`vec1_to_vec2()`](crate::vec1_to_vec2)
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html) /// * [`vec3_to_vec2()`](crate::vec3_to_vec2)
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html) /// * [`vec4_to_vec2()`](crate::vec4_to_vec2)
/// ///
/// ## Related types: /// ## Related types:
/// ///
/// * [`vec2`](fn.vec2.html) /// * [`BVec2`]
/// * [`BVec2`](type.BVec2.html) /// * [`DVec2`]
/// * [`DVec2`](type.DVec2.html) /// * [`IVec2`]
/// * [`IVec2`](type.IVec2.html) /// * [`I16Vec2`]
/// * [`I16Vec2`](type.I16Vec2.html) /// * [`I32Vec2`]
/// * [`I32Vec2`](type.I32Vec2.html) /// * [`I64Vec2`]
/// * [`I64Vec2`](type.I64Vec2.html) /// * [`I8Vec2`]
/// * [`I8Vec2`](type.I8Vec2.html) /// * [`TVec`]
/// * [`TVec`](type.TVec.html) /// * [`UVec2`]
/// * [`UVec2`](type.UVec2.html) /// * [`U16Vec2`]
/// * [`U16Vec2`](type.U16Vec2.html) /// * [`U32Vec2`]
/// * [`U32Vec2`](type.U32Vec2.html) /// * [`U64Vec2`]
/// * [`U64Vec2`](type.U64Vec2.html) /// * [`U8Vec2`]
/// * [`U8Vec2`](type.U8Vec2.html) /// * [`Vec2`]
/// * [`Vec2`](type.Vec2.html)
pub type TVec2<T> = TVec<T, 2>; pub type TVec2<T> = TVec<T, 2>;
/// A 3D vector with components of type `T`. /// A 3D vector with components of type `T`.
/// ///
@ -106,29 +105,28 @@ pub type TVec2<T> = TVec<T, 2>;
/// ///
/// ## Constructors: /// ## Constructors:
/// ///
/// * [`make_vec3`](fn.make_vec3.html) /// * [`make_vec3()`](crate::make_vec3)
/// * [`vec3`](fn.vec3.html) /// * [`vec3()`](crate::vec3)
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html) /// * [`vec1_to_vec3()`](crate::vec1_to_vec3)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html) /// * [`vec2_to_vec3()`](crate::vec2_to_vec3)
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html) /// * [`vec4_to_vec3()`](crate::vec4_to_vec3)
/// ///
/// ## Related types: /// ## Related types:
/// ///
/// * [`vec3`](fn.vec3.html) /// * [`BVec3`]
/// * [`BVec3`](type.BVec3.html) /// * [`DVec3`]
/// * [`DVec3`](type.DVec3.html) /// * [`IVec3`]
/// * [`IVec3`](type.IVec3.html) /// * [`I16Vec3`]
/// * [`I16Vec3`](type.I16Vec3.html) /// * [`I32Vec3`]
/// * [`I32Vec3`](type.I32Vec3.html) /// * [`I64Vec3`]
/// * [`I64Vec3`](type.I64Vec3.html) /// * [`I8Vec3`]
/// * [`I8Vec3`](type.I8Vec3.html) /// * [`TVec`]
/// * [`TVec`](type.TVec.html) /// * [`UVec3`]
/// * [`UVec3`](type.UVec3.html) /// * [`U16Vec3`]
/// * [`U16Vec3`](type.U16Vec3.html) /// * [`U32Vec3`]
/// * [`U32Vec3`](type.U32Vec3.html) /// * [`U64Vec3`]
/// * [`U64Vec3`](type.U64Vec3.html) /// * [`U8Vec3`]
/// * [`U8Vec3`](type.U8Vec3.html) /// * [`Vec3`]
/// * [`Vec3`](type.Vec3.html)
pub type TVec3<T> = TVec<T, 3>; pub type TVec3<T> = TVec<T, 3>;
/// A 4D vector with components of type `T`. /// A 4D vector with components of type `T`.
/// ///
@ -136,28 +134,27 @@ pub type TVec3<T> = TVec<T, 3>;
/// ///
/// ## Constructors: /// ## Constructors:
/// ///
/// * [`make_vec4`](fn.make_vec4.html) /// * [`make_vec4()`](crate::make_vec4)
/// * [`vec4`](fn.vec4.html) /// * [`vec4()`](crate::vec4)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html) /// * [`vec1_to_vec4()`](crate::vec1_to_vec4)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html) /// * [`vec2_to_vec4()`](crate::vec2_to_vec4)
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html) /// * [`vec3_to_vec4()`](crate::vec3_to_vec4)
/// ///
/// ## Related types: /// ## Related types:
/// ///
/// * [`vec4`](fn.vec4.html) /// * [`BVec4`]
/// * [`BVec4`](type.BVec4.html) /// * [`DVec4`]
/// * [`DVec4`](type.DVec4.html) /// * [`IVec4`]
/// * [`IVec4`](type.IVec4.html) /// * [`I16Vec4`]
/// * [`I16Vec4`](type.I16Vec4.html) /// * [`I32Vec4`]
/// * [`I32Vec4`](type.I32Vec4.html) /// * [`I64Vec4`]
/// * [`I64Vec4`](type.I64Vec4.html) /// * [`I8Vec4`]
/// * [`I8Vec4`](type.I8Vec4.html) /// * [`UVec4`]
/// * [`UVec4`](type.UVec4.html) /// * [`U16Vec4`]
/// * [`U16Vec4`](type.U16Vec4.html) /// * [`U32Vec4`]
/// * [`U32Vec4`](type.U32Vec4.html) /// * [`U64Vec4`]
/// * [`U64Vec4`](type.U64Vec4.html) /// * [`U8Vec4`]
/// * [`U8Vec4`](type.U8Vec4.html) /// * [`Vec4`]
/// * [`Vec4`](type.Vec4.html)
pub type TVec4<T> = TVec<T, 4>; pub type TVec4<T> = TVec<T, 4>;
/// A 1D vector with boolean components. /// A 1D vector with boolean components.
pub type BVec1 = TVec1<bool>; pub type BVec1 = TVec1<bool>;

View File

@ -1,5 +1,4 @@
use core::mem; use core::mem;
use na;
use crate::aliases::{TMat, TVec}; use crate::aliases::{TMat, TVec};
use crate::traits::Number; use crate::traits::Number;
@ -20,7 +19,7 @@ use crate::RealNumber;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`sign`](fn.sign.html) /// * [`sign()`]
pub fn abs<T: Number, const R: usize, const C: usize>(x: &TMat<T, R, C>) -> TMat<T, R, C> { pub fn abs<T: Number, const R: usize, const C: usize>(x: &TMat<T, R, C>) -> TMat<T, R, C> {
x.abs() x.abs()
} }
@ -37,11 +36,11 @@ pub fn abs<T: Number, const R: usize, const C: usize>(x: &TMat<T, R, C>) -> TMat
/// ///
/// # See also: /// # See also:
/// ///
/// * [`ceil`](fn.ceil.html) /// * [`ceil()`]
/// * [`floor`](fn.floor.html) /// * [`floor()`]
/// * [`fract`](fn.fract.html) /// * [`fract()`]
/// * [`round`](fn.round.html) /// * [`round()`]
/// * [`trunc`](fn.trunc.html) /// * [`trunc()`]
pub fn ceil<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> { pub fn ceil<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
x.map(|x| x.ceil()) x.map(|x| x.ceil())
} }
@ -65,8 +64,8 @@ pub fn ceil<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`clamp`](fn.clamp.html) /// * [`clamp()`]
/// * [`clamp_vec`](fn.clamp_vec.html) /// * [`clamp_vec()`]
pub fn clamp_scalar<T: Number>(x: T, min_val: T, max_val: T) -> T { pub fn clamp_scalar<T: Number>(x: T, min_val: T, max_val: T) -> T {
na::clamp(x, min_val, max_val) na::clamp(x, min_val, max_val)
} }
@ -89,8 +88,8 @@ pub fn clamp_scalar<T: Number>(x: T, min_val: T, max_val: T) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`clamp_scalar`](fn.clamp_scalar.html) /// * [`clamp_scalar()`]
/// * [`clamp_vec`](fn.clamp_vec.html) /// * [`clamp_vec()`]
pub fn clamp<T: Number, const D: usize>(x: &TVec<T, D>, min_val: T, max_val: T) -> TVec<T, D> { pub fn clamp<T: Number, const D: usize>(x: &TVec<T, D>, min_val: T, max_val: T) -> TVec<T, D> {
x.map(|x| na::clamp(x, min_val, max_val)) x.map(|x| na::clamp(x, min_val, max_val))
} }
@ -120,8 +119,8 @@ pub fn clamp<T: Number, const D: usize>(x: &TVec<T, D>, min_val: T, max_val: T)
/// ///
/// # See also: /// # See also:
/// ///
/// * [`clamp_scalar`](fn.clamp_scalar.html) /// * [`clamp_scalar()`]
/// * [`clamp`](fn.clamp.html) /// * [`clamp()`]
pub fn clamp_vec<T: Number, const D: usize>( pub fn clamp_vec<T: Number, const D: usize>(
x: &TVec<T, D>, x: &TVec<T, D>,
min_val: &TVec<T, D>, min_val: &TVec<T, D>,
@ -136,13 +135,13 @@ pub fn clamp_vec<T: Number, const D: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html) /// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html) /// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html) /// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float`](fn.int_bits_to_float.html) /// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html) /// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html) /// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html) /// * [`uint_bits_to_float_scalar()`]
pub fn float_bits_to_int(v: f32) -> i32 { pub fn float_bits_to_int(v: f32) -> i32 {
unsafe { mem::transmute(v) } unsafe { mem::transmute(v) }
} }
@ -153,13 +152,13 @@ pub fn float_bits_to_int(v: f32) -> i32 {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`float_bits_to_int`](fn.float_bits_to_int.html) /// * [`float_bits_to_int()`]
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html) /// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html) /// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float`](fn.int_bits_to_float.html) /// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html) /// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html) /// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html) /// * [`uint_bits_to_float_scalar()`]
pub fn float_bits_to_int_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<i32, D> { pub fn float_bits_to_int_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<i32, D> {
v.map(float_bits_to_int) v.map(float_bits_to_int)
} }
@ -170,13 +169,13 @@ pub fn float_bits_to_int_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<i32, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`float_bits_to_int`](fn.float_bits_to_int.html) /// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html) /// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html) /// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float`](fn.int_bits_to_float.html) /// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html) /// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html) /// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html) /// * [`uint_bits_to_float_scalar()`]
pub fn float_bits_to_uint(v: f32) -> u32 { pub fn float_bits_to_uint(v: f32) -> u32 {
unsafe { mem::transmute(v) } unsafe { mem::transmute(v) }
} }
@ -187,13 +186,13 @@ pub fn float_bits_to_uint(v: f32) -> u32 {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`float_bits_to_int`](fn.float_bits_to_int.html) /// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html) /// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html) /// * [`float_bits_to_uint()`]
/// * [`int_bits_to_float`](fn.int_bits_to_float.html) /// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html) /// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html) /// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html) /// * [`uint_bits_to_float_scalar()`]
pub fn float_bits_to_uint_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<u32, D> { pub fn float_bits_to_uint_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<u32, D> {
v.map(float_bits_to_uint) v.map(float_bits_to_uint)
} }
@ -210,10 +209,10 @@ pub fn float_bits_to_uint_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<u32, D>
/// ///
/// # See also: /// # See also:
/// ///
/// * [`ceil`](fn.ceil.html) /// * [`ceil()`]
/// * [`fract`](fn.fract.html) /// * [`fract()`]
/// * [`round`](fn.round.html) /// * [`round()`]
/// * [`trunc`](fn.trunc.html) /// * [`trunc()`]
pub fn floor<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> { pub fn floor<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
x.map(|x| x.floor()) x.map(|x| x.floor())
} }
@ -236,10 +235,10 @@ pub fn floor<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`ceil`](fn.ceil.html) /// * [`ceil()`]
/// * [`floor`](fn.floor.html) /// * [`floor()`]
/// * [`round`](fn.round.html) /// * [`round()`]
/// * [`trunc`](fn.trunc.html) /// * [`trunc()`]
pub fn fract<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> { pub fn fract<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
x.map(|x| x.fract()) x.map(|x| x.fract())
} }
@ -258,13 +257,13 @@ pub fn fract<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`float_bits_to_int`](fn.float_bits_to_int.html) /// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html) /// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html) /// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html) /// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html) /// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html) /// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html) /// * [`uint_bits_to_float_scalar()`]
pub fn int_bits_to_float(v: i32) -> f32 { pub fn int_bits_to_float(v: i32) -> f32 {
f32::from_bits(v as u32) f32::from_bits(v as u32)
} }
@ -275,13 +274,13 @@ pub fn int_bits_to_float(v: i32) -> f32 {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`float_bits_to_int`](fn.float_bits_to_int.html) /// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html) /// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html) /// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html) /// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float`](fn.int_bits_to_float.html) /// * [`int_bits_to_float()`]
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html) /// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html) /// * [`uint_bits_to_float_scalar()`]
pub fn int_bits_to_float_vec<const D: usize>(v: &TVec<i32, D>) -> TVec<f32, D> { pub fn int_bits_to_float_vec<const D: usize>(v: &TVec<i32, D>) -> TVec<f32, D> {
v.map(int_bits_to_float) v.map(int_bits_to_float)
} }
@ -315,8 +314,8 @@ pub fn int_bits_to_float_vec<const D: usize>(v: &TVec<i32, D>) -> TVec<f32, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`mix`](fn.mix.html) /// * [`mix()`]
/// * [`mix_vec`](fn.mix_vec.html) /// * [`mix_vec()`]
pub fn mix_scalar<T: Number>(x: T, y: T, a: T) -> T { pub fn mix_scalar<T: Number>(x: T, y: T, a: T) -> T {
x * (T::one() - a) + y * a x * (T::one() - a) + y * a
} }
@ -336,8 +335,8 @@ pub fn mix_scalar<T: Number>(x: T, y: T, a: T) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`mix_scalar`](fn.mix_scalar.html) /// * [`mix_scalar()`]
/// * [`mix_vec`](fn.mix_vec.html) /// * [`mix_vec()`]
pub fn mix<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) -> TVec<T, D> { pub fn mix<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) -> TVec<T, D> {
x * (T::one() - a) + y * a x * (T::one() - a) + y * a
} }
@ -359,14 +358,14 @@ pub fn mix<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) -> T
/// ///
/// # See also: /// # See also:
/// ///
/// * [`mix_scalar`](fn.mix_scalar.html) /// * [`mix_scalar()`]
/// * [`mix`](fn.mix.html) /// * [`mix()`]
pub fn mix_vec<T: Number, const D: usize>( pub fn mix_vec<T: Number, const D: usize>(
x: &TVec<T, D>, x: &TVec<T, D>,
y: &TVec<T, D>, y: &TVec<T, D>,
a: &TVec<T, D>, a: &TVec<T, D>,
) -> TVec<T, D> { ) -> TVec<T, D> {
x.component_mul(&(TVec::<T, D>::repeat(T::one()) - a)) + y.component_mul(&a) x.component_mul(&(TVec::<T, D>::repeat(T::one()) - a)) + y.component_mul(a)
} }
/// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the scalars x and y using the scalar value a. /// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the scalars x and y using the scalar value a.
@ -383,8 +382,8 @@ pub fn mix_vec<T: Number, const D: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`lerp`](fn.lerp.html) /// * [`lerp()`]
/// * [`lerp_vec`](fn.lerp_vec.html) /// * [`lerp_vec()`]
pub fn lerp_scalar<T: Number>(x: T, y: T, a: T) -> T { pub fn lerp_scalar<T: Number>(x: T, y: T, a: T) -> T {
mix_scalar(x, y, a) mix_scalar(x, y, a)
} }
@ -405,8 +404,8 @@ pub fn lerp_scalar<T: Number>(x: T, y: T, a: T) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`lerp_scalar`](fn.lerp_scalar.html) /// * [`lerp_scalar()`]
/// * [`lerp_vec`](fn.lerp_vec.html) /// * [`lerp_vec()`]
pub fn lerp<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) -> TVec<T, D> { pub fn lerp<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) -> TVec<T, D> {
mix(x, y, a) mix(x, y, a)
} }
@ -429,8 +428,8 @@ pub fn lerp<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) ->
/// ///
/// # See also: /// # See also:
/// ///
/// * [`lerp_scalar`](fn.lerp_scalar.html) /// * [`lerp_scalar()`]
/// * [`lerp`](fn.lerp.html) /// * [`lerp()`]
pub fn lerp_vec<T: Number, const D: usize>( pub fn lerp_vec<T: Number, const D: usize>(
x: &TVec<T, D>, x: &TVec<T, D>,
y: &TVec<T, D>, y: &TVec<T, D>,
@ -445,7 +444,7 @@ pub fn lerp_vec<T: Number, const D: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`modf`](fn.modf.html) /// * [`modf()`]
pub fn modf_vec<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<T, D> { pub fn modf_vec<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<T, D> {
x.zip_map(y, |x, y| x % y) x.zip_map(y, |x, y| x % y)
} }
@ -454,7 +453,7 @@ pub fn modf_vec<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TV
/// ///
/// # See also: /// # See also:
/// ///
/// * [`modf_vec`](fn.modf_vec.html) /// * [`modf_vec()`]
pub fn modf<T: Number>(x: T, i: T) -> T { pub fn modf<T: Number>(x: T, i: T) -> T {
x % i x % i
} }
@ -473,10 +472,10 @@ pub fn modf<T: Number>(x: T, i: T) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`ceil`](fn.ceil.html) /// * [`ceil()`]
/// * [`floor`](fn.floor.html) /// * [`floor()`]
/// * [`fract`](fn.fract.html) /// * [`fract()`]
/// * [`trunc`](fn.trunc.html) /// * [`trunc()`]
pub fn round<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> { pub fn round<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
x.map(|x| x.round()) x.map(|x| x.round())
} }
@ -497,7 +496,7 @@ pub fn round<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`abs`](fn.abs.html) /// * [`abs()`]
/// ///
pub fn sign<T: Number, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> { pub fn sign<T: Number, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
x.map(|x| if x.is_zero() { T::zero() } else { x.signum() }) x.map(|x| if x.is_zero() { T::zero() } else { x.signum() })
@ -545,10 +544,10 @@ pub fn step_vec<T: Number, const D: usize>(edge: &TVec<T, D>, x: &TVec<T, D>) ->
/// ///
/// # See also: /// # See also:
/// ///
/// * [`ceil`](fn.ceil.html) /// * [`ceil()`]
/// * [`floor`](fn.floor.html) /// * [`floor()`]
/// * [`fract`](fn.fract.html) /// * [`fract()`]
/// * [`round`](fn.round.html) /// * [`round()`]
pub fn trunc<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> { pub fn trunc<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
x.map(|x| x.trunc()) x.map(|x| x.trunc())
} }
@ -559,13 +558,13 @@ pub fn trunc<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`float_bits_to_int`](fn.float_bits_to_int.html) /// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html) /// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html) /// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html) /// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float`](fn.int_bits_to_float.html) /// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html) /// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html) /// * [`uint_bits_to_float()`]
pub fn uint_bits_to_float_scalar(v: u32) -> f32 { pub fn uint_bits_to_float_scalar(v: u32) -> f32 {
f32::from_bits(v) f32::from_bits(v)
} }
@ -576,13 +575,13 @@ pub fn uint_bits_to_float_scalar(v: u32) -> f32 {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`float_bits_to_int`](fn.float_bits_to_int.html) /// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html) /// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html) /// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html) /// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float`](fn.int_bits_to_float.html) /// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html) /// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html) /// * [`uint_bits_to_float_scalar()`]
pub fn uint_bits_to_float<const D: usize>(v: &TVec<u32, D>) -> TVec<f32, D> { pub fn uint_bits_to_float<const D: usize>(v: &TVec<u32, D>) -> TVec<f32, D> {
v.map(uint_bits_to_float_scalar) v.map(uint_bits_to_float_scalar)
} }

View File

@ -91,6 +91,7 @@ pub fn mat2x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
/// ); /// );
/// ``` /// ```
#[rustfmt::skip] #[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat3<T: Scalar>(m11: T, m12: T, m13: T, pub fn mat3<T: Scalar>(m11: T, m12: T, m13: T,
m21: T, m22: T, m23: T, m21: T, m22: T, m23: T,
m31: T, m32: T, m33: T) -> TMat3<T> { m31: T, m32: T, m33: T) -> TMat3<T> {
@ -115,6 +116,7 @@ pub fn mat3x2<T: Scalar>(m11: T, m12: T,
/// Create a new 3x3 matrix. /// Create a new 3x3 matrix.
#[rustfmt::skip] #[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat3x3<T: Scalar>(m11: T, m12: T, m13: T, pub fn mat3x3<T: Scalar>(m11: T, m12: T, m13: T,
m21: T, m22: T, m23: T, m21: T, m22: T, m23: T,
m31: T, m32: T, m33: T) -> TMat3<T> { m31: T, m32: T, m33: T) -> TMat3<T> {
@ -127,6 +129,7 @@ pub fn mat3x3<T: Scalar>(m11: T, m12: T, m13: T,
/// Create a new 3x4 matrix. /// Create a new 3x4 matrix.
#[rustfmt::skip] #[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat3x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T, pub fn mat3x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
m21: T, m22: T, m23: T, m24: T, m21: T, m22: T, m23: T, m24: T,
m31: T, m32: T, m33: T, m34: T) -> TMat3x4<T> { m31: T, m32: T, m33: T, m34: T) -> TMat3x4<T> {
@ -153,6 +156,7 @@ pub fn mat4x2<T: Scalar>(m11: T, m12: T,
/// Create a new 4x3 matrix. /// Create a new 4x3 matrix.
#[rustfmt::skip] #[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat4x3<T: Scalar>(m11: T, m12: T, m13: T, pub fn mat4x3<T: Scalar>(m11: T, m12: T, m13: T,
m21: T, m22: T, m23: T, m21: T, m22: T, m23: T,
m31: T, m32: T, m33: T, m31: T, m32: T, m33: T,
@ -167,6 +171,7 @@ pub fn mat4x3<T: Scalar>(m11: T, m12: T, m13: T,
/// Create a new 4x4 matrix. /// Create a new 4x4 matrix.
#[rustfmt::skip] #[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat4x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T, pub fn mat4x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
m21: T, m22: T, m23: T, m24: T, m21: T, m22: T, m23: T, m24: T,
m31: T, m32: T, m33: T, m34: T, m31: T, m32: T, m33: T, m34: T,
@ -181,6 +186,7 @@ pub fn mat4x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
/// Create a new 4x4 matrix. /// Create a new 4x4 matrix.
#[rustfmt::skip] #[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat4<T: Scalar>(m11: T, m12: T, m13: T, m14: T, pub fn mat4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
m21: T, m22: T, m23: T, m24: T, m21: T, m22: T, m23: T, m24: T,
m31: T, m32: T, m33: T, m34: T, m31: T, m32: T, m33: T, m34: T,

View File

@ -5,7 +5,7 @@ use crate::RealNumber;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`exp2`](fn.exp2.html) /// * [`exp2()`]
pub fn exp<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> { pub fn exp<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
v.map(|x| x.exp()) v.map(|x| x.exp())
} }
@ -14,7 +14,7 @@ pub fn exp<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`exp`](fn.exp.html) /// * [`exp()`]
pub fn exp2<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> { pub fn exp2<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
v.map(|x| x.exp2()) v.map(|x| x.exp2())
} }
@ -23,7 +23,7 @@ pub fn exp2<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`sqrt`](fn.sqrt.html) /// * [`sqrt()`]
pub fn inversesqrt<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> { pub fn inversesqrt<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
v.map(|x| T::one() / x.sqrt()) v.map(|x| T::one() / x.sqrt())
} }
@ -32,7 +32,7 @@ pub fn inversesqrt<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D>
/// ///
/// # See also: /// # See also:
/// ///
/// * [`log2`](fn.log2.html) /// * [`log2()`]
pub fn log<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> { pub fn log<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
v.map(|x| x.ln()) v.map(|x| x.ln())
} }
@ -41,7 +41,7 @@ pub fn log<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`log`](fn.log.html) /// * [`log()`]
pub fn log2<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> { pub fn log2<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
v.map(|x| x.log2()) v.map(|x| x.log2())
} }
@ -55,10 +55,10 @@ pub fn pow<T: RealNumber, const D: usize>(base: &TVec<T, D>, exponent: &TVec<T,
/// ///
/// # See also: /// # See also:
/// ///
/// * [`exp`](fn.exp.html) /// * [`exp()`]
/// * [`exp2`](fn.exp2.html) /// * [`exp2()`]
/// * [`inversesqrt`](fn.inversesqrt.html) /// * [`inversesqrt()`]
/// * [`pow`](fn.pow.html) /// * [`pow`]
pub fn sqrt<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> { pub fn sqrt<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
v.map(|x| x.sqrt()) v.map(|x| x.sqrt())
} }

View File

@ -1,5 +1,3 @@
use na;
use crate::aliases::{TMat4, TVec2, TVec3, TVec4}; use crate::aliases::{TMat4, TVec2, TVec3, TVec4};
use crate::RealNumber; use crate::RealNumber;
@ -41,11 +39,11 @@ pub fn pick_matrix<T: RealNumber>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`project_no`](fn.project_no.html) /// * [`project_no()`]
/// * [`project_zo`](fn.project_zo.html) /// * [`project_zo()`]
/// * [`unproject`](fn.unproject.html) /// * [`unproject()`]
/// * [`unproject_no`](fn.unproject_no.html) /// * [`unproject_no()`]
/// * [`unproject_zo`](fn.unproject_zo.html) /// * [`unproject_zo()`]
pub fn project<T: RealNumber>( pub fn project<T: RealNumber>(
obj: &TVec3<T>, obj: &TVec3<T>,
model: &TMat4<T>, model: &TMat4<T>,
@ -68,11 +66,11 @@ pub fn project<T: RealNumber>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`project`](fn.project.html) /// * [`project()`]
/// * [`project_zo`](fn.project_zo.html) /// * [`project_zo()`]
/// * [`unproject`](fn.unproject.html) /// * [`unproject()`]
/// * [`unproject_no`](fn.unproject_no.html) /// * [`unproject_no()`]
/// * [`unproject_zo`](fn.unproject_zo.html) /// * [`unproject_zo()`]
pub fn project_no<T: RealNumber>( pub fn project_no<T: RealNumber>(
obj: &TVec3<T>, obj: &TVec3<T>,
model: &TMat4<T>, model: &TMat4<T>,
@ -96,11 +94,11 @@ pub fn project_no<T: RealNumber>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`project`](fn.project.html) /// * [`project()`]
/// * [`project_no`](fn.project_no.html) /// * [`project_no()`]
/// * [`unproject`](fn.unproject.html) /// * [`unproject()`]
/// * [`unproject_no`](fn.unproject_no.html) /// * [`unproject_no()`]
/// * [`unproject_zo`](fn.unproject_zo.html) /// * [`unproject_zo()`]
pub fn project_zo<T: RealNumber>( pub fn project_zo<T: RealNumber>(
obj: &TVec3<T>, obj: &TVec3<T>,
model: &TMat4<T>, model: &TMat4<T>,
@ -129,11 +127,11 @@ pub fn project_zo<T: RealNumber>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`project`](fn.project.html) /// * [`project()`]
/// * [`project_no`](fn.project_no.html) /// * [`project_no()`]
/// * [`project_zo`](fn.project_zo.html) /// * [`project_zo()`]
/// * [`unproject_no`](fn.unproject_no.html) /// * [`unproject_no()`]
/// * [`unproject_zo`](fn.unproject_zo.html) /// * [`unproject_zo()`]
pub fn unproject<T: RealNumber>( pub fn unproject<T: RealNumber>(
win: &TVec3<T>, win: &TVec3<T>,
model: &TMat4<T>, model: &TMat4<T>,
@ -156,11 +154,11 @@ pub fn unproject<T: RealNumber>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`project`](fn.project.html) /// * [`project()`]
/// * [`project_no`](fn.project_no.html) /// * [`project_no()`]
/// * [`project_zo`](fn.project_zo.html) /// * [`project_zo()`]
/// * [`unproject`](fn.unproject.html) /// * [`unproject()`]
/// * [`unproject_zo`](fn.unproject_zo.html) /// * [`unproject_zo()`]
pub fn unproject_no<T: RealNumber>( pub fn unproject_no<T: RealNumber>(
win: &TVec3<T>, win: &TVec3<T>,
model: &TMat4<T>, model: &TMat4<T>,
@ -193,11 +191,11 @@ pub fn unproject_no<T: RealNumber>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`project`](fn.project.html) /// * [`project()`]
/// * [`project_no`](fn.project_no.html) /// * [`project_no()`]
/// * [`project_zo`](fn.project_zo.html) /// * [`project_zo()`]
/// * [`unproject`](fn.unproject.html) /// * [`unproject()`]
/// * [`unproject_no`](fn.unproject_no.html) /// * [`unproject_no()`]
pub fn unproject_zo<T: RealNumber>( pub fn unproject_zo<T: RealNumber>(
win: &TVec3<T>, win: &TVec3<T>,
model: &TMat4<T>, model: &TMat4<T>,

View File

@ -18,8 +18,8 @@ pub fn identity<T: Number, const D: usize>() -> TMat<T, D, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`look_at_lh`](fn.look_at_lh.html) /// * [`look_at_lh()`]
/// * [`look_at_rh`](fn.look_at_rh.html) /// * [`look_at_rh()`]
pub fn look_at<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> { pub fn look_at<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
look_at_rh(eye, center, up) look_at_rh(eye, center, up)
} }
@ -34,8 +34,8 @@ pub fn look_at<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>)
/// ///
/// # See also: /// # See also:
/// ///
/// * [`look_at`](fn.look_at.html) /// * [`look_at()`]
/// * [`look_at_rh`](fn.look_at_rh.html) /// * [`look_at_rh()`]
pub fn look_at_lh<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> { pub fn look_at_lh<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
TMat::look_at_lh(&Point3::from(*eye), &Point3::from(*center), up) TMat::look_at_lh(&Point3::from(*eye), &Point3::from(*center), up)
} }
@ -50,8 +50,8 @@ pub fn look_at_lh<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T
/// ///
/// # See also: /// # See also:
/// ///
/// * [`look_at`](fn.look_at.html) /// * [`look_at()`]
/// * [`look_at_lh`](fn.look_at_lh.html) /// * [`look_at_lh()`]
pub fn look_at_rh<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> { pub fn look_at_rh<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
TMat::look_at_rh(&Point3::from(*eye), &Point3::from(*center), up) TMat::look_at_rh(&Point3::from(*eye), &Point3::from(*center), up)
} }
@ -66,11 +66,11 @@ pub fn look_at_rh<T: RealNumber>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotate_x`](fn.rotate_x.html) /// * [`rotate_x()`]
/// * [`rotate_y`](fn.rotate_y.html) /// * [`rotate_y()`]
/// * [`rotate_z`](fn.rotate_z.html) /// * [`rotate_z()`]
/// * [`scale`](fn.scale.html) /// * [`scale()`]
/// * [`translate`](fn.translate.html) /// * [`translate()`]
pub fn rotate<T: RealNumber>(m: &TMat4<T>, angle: T, axis: &TVec3<T>) -> TMat4<T> { pub fn rotate<T: RealNumber>(m: &TMat4<T>, angle: T, axis: &TVec3<T>) -> TMat4<T> {
m * Rotation3::from_axis_angle(&Unit::new_normalize(*axis), angle).to_homogeneous() m * Rotation3::from_axis_angle(&Unit::new_normalize(*axis), angle).to_homogeneous()
} }
@ -84,11 +84,11 @@ pub fn rotate<T: RealNumber>(m: &TMat4<T>, angle: T, axis: &TVec3<T>) -> TMat4<T
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotate`](fn.rotate.html) /// * [`rotate()`]
/// * [`rotate_y`](fn.rotate_y.html) /// * [`rotate_y()`]
/// * [`rotate_z`](fn.rotate_z.html) /// * [`rotate_z()`]
/// * [`scale`](fn.scale.html) /// * [`scale()`]
/// * [`translate`](fn.translate.html) /// * [`translate()`]
pub fn rotate_x<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> { pub fn rotate_x<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
rotate(m, angle, &TVec::x()) rotate(m, angle, &TVec::x())
} }
@ -102,11 +102,11 @@ pub fn rotate_x<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotate`](fn.rotate.html) /// * [`rotate()`]
/// * [`rotate_x`](fn.rotate_x.html) /// * [`rotate_x()`]
/// * [`rotate_z`](fn.rotate_z.html) /// * [`rotate_z()`]
/// * [`scale`](fn.scale.html) /// * [`scale()`]
/// * [`translate`](fn.translate.html) /// * [`translate()`]
pub fn rotate_y<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> { pub fn rotate_y<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
rotate(m, angle, &TVec::y()) rotate(m, angle, &TVec::y())
} }
@ -120,11 +120,11 @@ pub fn rotate_y<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotate`](fn.rotate.html) /// * [`rotate()`]
/// * [`rotate_x`](fn.rotate_x.html) /// * [`rotate_x()`]
/// * [`rotate_y`](fn.rotate_y.html) /// * [`rotate_y()`]
/// * [`scale`](fn.scale.html) /// * [`scale()`]
/// * [`translate`](fn.translate.html) /// * [`translate()`]
pub fn rotate_z<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> { pub fn rotate_z<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
rotate(m, angle, &TVec::z()) rotate(m, angle, &TVec::z())
} }
@ -138,11 +138,11 @@ pub fn rotate_z<T: RealNumber>(m: &TMat4<T>, angle: T) -> TMat4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotate`](fn.rotate.html) /// * [`rotate()`]
/// * [`rotate_x`](fn.rotate_x.html) /// * [`rotate_x()`]
/// * [`rotate_y`](fn.rotate_y.html) /// * [`rotate_y()`]
/// * [`rotate_z`](fn.rotate_z.html) /// * [`rotate_z()`]
/// * [`translate`](fn.translate.html) /// * [`translate()`]
pub fn scale<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> { pub fn scale<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> {
m.prepend_nonuniform_scaling(v) m.prepend_nonuniform_scaling(v)
} }
@ -156,11 +156,11 @@ pub fn scale<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotate`](fn.rotate.html) /// * [`rotate()`]
/// * [`rotate_x`](fn.rotate_x.html) /// * [`rotate_x()`]
/// * [`rotate_y`](fn.rotate_y.html) /// * [`rotate_y()`]
/// * [`rotate_z`](fn.rotate_z.html) /// * [`rotate_z()`]
/// * [`scale`](fn.scale.html) /// * [`scale()`]
pub fn translate<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> { pub fn translate<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> {
m.prepend_translation(v) m.prepend_translation(v)
} }

View File

@ -1,4 +1,4 @@
use na::{self, Unit}; use na::Unit;
use crate::aliases::Qua; use crate::aliases::Qua;
use crate::RealNumber; use crate::RealNumber;

View File

@ -12,9 +12,9 @@ use crate::traits::Number;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`max4_scalar`](fn.max4_scalar.html) /// * [`max4_scalar()`]
/// * [`min3_scalar`](fn.min3_scalar.html) /// * [`min3_scalar()`]
/// * [`min4_scalar`](fn.min4_scalar.html) /// * [`min4_scalar()`]
pub fn max2_scalar<T: Number>(a: T, b: T) -> T { pub fn max2_scalar<T: Number>(a: T, b: T) -> T {
if a >= b { if a >= b {
a a
@ -35,9 +35,9 @@ pub fn max2_scalar<T: Number>(a: T, b: T) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`max4_scalar`](fn.max4_scalar.html) /// * [`max4_scalar()`]
/// * [`min3_scalar`](fn.min3_scalar.html) /// * [`min3_scalar()`]
/// * [`min4_scalar`](fn.min4_scalar.html) /// * [`min4_scalar()`]
pub fn min2_scalar<T: Number>(a: T, b: T) -> T { pub fn min2_scalar<T: Number>(a: T, b: T) -> T {
if a <= b { if a <= b {
a a
@ -58,9 +58,9 @@ pub fn min2_scalar<T: Number>(a: T, b: T) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`max4_scalar`](fn.max4_scalar.html) /// * [`max4_scalar()`]
/// * [`min3_scalar`](fn.min3_scalar.html) /// * [`min3_scalar()`]
/// * [`min4_scalar`](fn.min4_scalar.html) /// * [`min4_scalar()`]
pub fn max3_scalar<T: Number>(a: T, b: T, c: T) -> T { pub fn max3_scalar<T: Number>(a: T, b: T, c: T) -> T {
max2_scalar(max2_scalar(a, b), c) max2_scalar(max2_scalar(a, b), c)
} }
@ -77,9 +77,9 @@ pub fn max3_scalar<T: Number>(a: T, b: T, c: T) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`max3_scalar`](fn.max3_scalar.html) /// * [`max3_scalar()`]
/// * [`min3_scalar`](fn.min3_scalar.html) /// * [`min3_scalar()`]
/// * [`min4_scalar`](fn.min4_scalar.html) /// * [`min4_scalar()`]
pub fn max4_scalar<T: Number>(a: T, b: T, c: T, d: T) -> T { pub fn max4_scalar<T: Number>(a: T, b: T, c: T, d: T) -> T {
max2_scalar(max2_scalar(a, b), max2_scalar(c, d)) max2_scalar(max2_scalar(a, b), max2_scalar(c, d))
} }
@ -96,9 +96,9 @@ pub fn max4_scalar<T: Number>(a: T, b: T, c: T, d: T) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`max3_scalar`](fn.max3_scalar.html) /// * [`max3_scalar()`]
/// * [`max4_scalar`](fn.max4_scalar.html) /// * [`max4_scalar()`]
/// * [`min4_scalar`](fn.min4_scalar.html) /// * [`min4_scalar()`]
pub fn min3_scalar<T: Number>(a: T, b: T, c: T) -> T { pub fn min3_scalar<T: Number>(a: T, b: T, c: T) -> T {
min2_scalar(min2_scalar(a, b), c) min2_scalar(min2_scalar(a, b), c)
} }
@ -115,9 +115,9 @@ pub fn min3_scalar<T: Number>(a: T, b: T, c: T) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`max3_scalar`](fn.max3_scalar.html) /// * [`max3_scalar()`]
/// * [`max4_scalar`](fn.max4_scalar.html) /// * [`max4_scalar()`]
/// * [`min3_scalar`](fn.min3_scalar.html) /// * [`min3_scalar()`]
pub fn min4_scalar<T: Number>(a: T, b: T, c: T, d: T) -> T { pub fn min4_scalar<T: Number>(a: T, b: T, c: T, d: T) -> T {
min2_scalar(min2_scalar(a, b), min2_scalar(c, d)) min2_scalar(min2_scalar(a, b), min2_scalar(c, d))
} }

View File

@ -10,18 +10,18 @@ pub fn epsilon<T: AbsDiffEq<Epsilon = T>>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi`](fn.four_over_pi.html) /// * [`four_over_pi()`](crate::four_over_pi)
/// * [`half_pi`](fn.half_pi.html) /// * [`half_pi()`](crate::half_pi)
/// * [`one_over_pi`](fn.one_over_pi.html) /// * [`one_over_pi()`](crate::one_over_pi)
/// * [`one_over_two_pi`](fn.one_over_two_pi.html) /// * [`one_over_two_pi()`](crate::one_over_two_pi)
/// * [`quarter_pi`](fn.quarter_pi.html) /// * [`quarter_pi()`](crate::quarter_pi)
/// * [`root_half_pi`](fn.root_half_pi.html) /// * [`root_half_pi()`](crate::root_half_pi)
/// * [`root_pi`](fn.root_pi.html) /// * [`root_pi()`](crate::root_pi)
/// * [`root_two_pi`](fn.root_two_pi.html) /// * [`root_two_pi()`](crate::root_two_pi)
/// * [`three_over_two_pi`](fn.three_over_two_pi.html) /// * [`three_over_two_pi()`](crate::three_over_two_pi)
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi()`](crate::two_over_pi)
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi()`](crate::two_over_root_pi)
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi()`](crate::two_pi)
pub fn pi<T: RealNumber>() -> T { pub fn pi<T: RealNumber>() -> T {
T::pi() T::pi()
} }

View File

@ -5,15 +5,15 @@ use crate::traits::Number;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_max`](fn.comp_max.html) /// * [`comp_max()`](crate::comp_max)
/// * [`comp_min`](fn.comp_min.html) /// * [`comp_min()`](crate::comp_min)
/// * [`max2`](fn.max2.html) /// * [`max2()`]
/// * [`max3`](fn.max3.html) /// * [`max3()`]
/// * [`max4`](fn.max4.html) /// * [`max4()`]
/// * [`min`](fn.min.html) /// * [`min()`]
/// * [`min2`](fn.min2.html) /// * [`min2()`]
/// * [`min3`](fn.min3.html) /// * [`min3()`]
/// * [`min4`](fn.min4.html) /// * [`min4()`]
pub fn max<T: Number, const D: usize>(a: &TVec<T, D>, b: T) -> TVec<T, D> { pub fn max<T: Number, const D: usize>(a: &TVec<T, D>, b: T) -> TVec<T, D> {
a.map(|a| crate::max2_scalar(a, b)) a.map(|a| crate::max2_scalar(a, b))
} }
@ -22,15 +22,15 @@ pub fn max<T: Number, const D: usize>(a: &TVec<T, D>, b: T) -> TVec<T, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_max`](fn.comp_max.html) /// * [`comp_max()`](crate::comp_max)
/// * [`comp_min`](fn.comp_min.html) /// * [`comp_min()`](crate::comp_min)
/// * [`max`](fn.max.html) /// * [`max()`]
/// * [`max3`](fn.max3.html) /// * [`max3()`]
/// * [`max4`](fn.max4.html) /// * [`max4()`]
/// * [`min`](fn.min.html) /// * [`min()`]
/// * [`min2`](fn.min2.html) /// * [`min2()`]
/// * [`min3`](fn.min3.html) /// * [`min3()`]
/// * [`min4`](fn.min4.html) /// * [`min4()`]
pub fn max2<T: Number, const D: usize>(a: &TVec<T, D>, b: &TVec<T, D>) -> TVec<T, D> { pub fn max2<T: Number, const D: usize>(a: &TVec<T, D>, b: &TVec<T, D>) -> TVec<T, D> {
a.zip_map(b, |a, b| crate::max2_scalar(a, b)) a.zip_map(b, |a, b| crate::max2_scalar(a, b))
} }
@ -39,15 +39,15 @@ pub fn max2<T: Number, const D: usize>(a: &TVec<T, D>, b: &TVec<T, D>) -> TVec<T
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_max`](fn.comp_max.html) /// * [`comp_max()`](crate::comp_max)
/// * [`comp_min`](fn.comp_min.html) /// * [`comp_min()`](crate::comp_min)
/// * [`max`](fn.max.html) /// * [`max()`]
/// * [`max2`](fn.max2.html) /// * [`max2()`]
/// * [`max4`](fn.max4.html) /// * [`max4()`]
/// * [`min`](fn.min.html) /// * [`min()`]
/// * [`min2`](fn.min2.html) /// * [`min2()`]
/// * [`min3`](fn.min3.html) /// * [`min3()`]
/// * [`min4`](fn.min4.html) /// * [`min4()`]
pub fn max3<T: Number, const D: usize>( pub fn max3<T: Number, const D: usize>(
a: &TVec<T, D>, a: &TVec<T, D>,
b: &TVec<T, D>, b: &TVec<T, D>,
@ -60,15 +60,15 @@ pub fn max3<T: Number, const D: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_max`](fn.comp_max.html) /// * [`comp_max()`](crate::comp_max)
/// * [`comp_min`](fn.comp_min.html) /// * [`comp_min()`](crate::comp_min)
/// * [`max`](fn.max.html) /// * [`max()`]
/// * [`max2`](fn.max2.html) /// * [`max2()`]
/// * [`max3`](fn.max3.html) /// * [`max3()`]
/// * [`min`](fn.min.html) /// * [`min()`]
/// * [`min2`](fn.min2.html) /// * [`min2()`]
/// * [`min3`](fn.min3.html) /// * [`min3()`]
/// * [`min4`](fn.min4.html) /// * [`min4()`]
pub fn max4<T: Number, const D: usize>( pub fn max4<T: Number, const D: usize>(
a: &TVec<T, D>, a: &TVec<T, D>,
b: &TVec<T, D>, b: &TVec<T, D>,
@ -82,15 +82,15 @@ pub fn max4<T: Number, const D: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_max`](fn.comp_max.html) /// * [`comp_max()`](crate::comp_max)
/// * [`comp_min`](fn.comp_min.html) /// * [`comp_min()`](crate::comp_min)
/// * [`max`](fn.max.html) /// * [`max()`]
/// * [`max2`](fn.max2.html) /// * [`max2()`]
/// * [`max3`](fn.max3.html) /// * [`max3()`]
/// * [`max4`](fn.max4.html) /// * [`max4()`]
/// * [`min2`](fn.min2.html) /// * [`min2()`]
/// * [`min3`](fn.min3.html) /// * [`min3()`]
/// * [`min4`](fn.min4.html) /// * [`min4()`]
pub fn min<T: Number, const D: usize>(x: &TVec<T, D>, y: T) -> TVec<T, D> { pub fn min<T: Number, const D: usize>(x: &TVec<T, D>, y: T) -> TVec<T, D> {
x.map(|x| crate::min2_scalar(x, y)) x.map(|x| crate::min2_scalar(x, y))
} }
@ -99,15 +99,15 @@ pub fn min<T: Number, const D: usize>(x: &TVec<T, D>, y: T) -> TVec<T, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_max`](fn.comp_max.html) /// * [`comp_max()`](crate::comp_max)
/// * [`comp_min`](fn.comp_min.html) /// * [`comp_min()`](crate::comp_min)
/// * [`max`](fn.max.html) /// * [`max()`]
/// * [`max2`](fn.max2.html) /// * [`max2()`]
/// * [`max3`](fn.max3.html) /// * [`max3()`]
/// * [`max4`](fn.max4.html) /// * [`max4()`]
/// * [`min`](fn.min.html) /// * [`min()`]
/// * [`min3`](fn.min3.html) /// * [`min3()`]
/// * [`min4`](fn.min4.html) /// * [`min4()`]
pub fn min2<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<T, D> { pub fn min2<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<T, D> {
x.zip_map(y, |a, b| crate::min2_scalar(a, b)) x.zip_map(y, |a, b| crate::min2_scalar(a, b))
} }
@ -116,15 +116,15 @@ pub fn min2<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<T
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_max`](fn.comp_max.html) /// * [`comp_max()`](crate::comp_max)
/// * [`comp_min`](fn.comp_min.html) /// * [`comp_min()`](crate::comp_min)
/// * [`max`](fn.max.html) /// * [`max()`]
/// * [`max2`](fn.max2.html) /// * [`max2()`]
/// * [`max3`](fn.max3.html) /// * [`max3()`]
/// * [`max4`](fn.max4.html) /// * [`max4()`]
/// * [`min`](fn.min.html) /// * [`min()`]
/// * [`min2`](fn.min2.html) /// * [`min2()`]
/// * [`min4`](fn.min4.html) /// * [`min4()`]
pub fn min3<T: Number, const D: usize>( pub fn min3<T: Number, const D: usize>(
a: &TVec<T, D>, a: &TVec<T, D>,
b: &TVec<T, D>, b: &TVec<T, D>,
@ -137,15 +137,15 @@ pub fn min3<T: Number, const D: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_max`](fn.comp_max.html) /// * [`comp_max()`](crate::comp_max)
/// * [`comp_min`](fn.comp_min.html) /// * [`comp_min()`](crate::comp_min)
/// * [`max`](fn.max.html) /// * [`max()`]
/// * [`max2`](fn.max2.html) /// * [`max2()`]
/// * [`max3`](fn.max3.html) /// * [`max3()`]
/// * [`max4`](fn.max4.html) /// * [`max4()`]
/// * [`min`](fn.min.html) /// * [`min()`]
/// * [`min2`](fn.min2.html) /// * [`min2()`]
/// * [`min3`](fn.min3.html) /// * [`min3()`]
pub fn min4<T: Number, const D: usize>( pub fn min4<T: Number, const D: usize>(
a: &TVec<T, D>, a: &TVec<T, D>,
b: &TVec<T, D>, b: &TVec<T, D>,

View File

@ -5,9 +5,9 @@ use crate::traits::Number;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`equal_eps_vec`](fn.equal_eps_vec.html) /// * [`equal_eps_vec()`]
/// * [`not_equal_eps`](fn.not_equal_eps.html) /// * [`not_equal_eps()`]
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html) /// * [`not_equal_eps_vec()`]
pub fn equal_eps<T: Number, const D: usize>( pub fn equal_eps<T: Number, const D: usize>(
x: &TVec<T, D>, x: &TVec<T, D>,
y: &TVec<T, D>, y: &TVec<T, D>,
@ -20,9 +20,9 @@ pub fn equal_eps<T: Number, const D: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`equal_eps`](fn.equal_eps.html) /// * [`equal_eps()`]
/// * [`not_equal_eps`](fn.not_equal_eps.html) /// * [`not_equal_eps()`]
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html) /// * [`not_equal_eps_vec()`]
pub fn equal_eps_vec<T: Number, const D: usize>( pub fn equal_eps_vec<T: Number, const D: usize>(
x: &TVec<T, D>, x: &TVec<T, D>,
y: &TVec<T, D>, y: &TVec<T, D>,
@ -35,9 +35,9 @@ pub fn equal_eps_vec<T: Number, const D: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`equal_eps`](fn.equal_eps.html) /// * [`equal_eps()`]
/// * [`equal_eps_vec`](fn.equal_eps_vec.html) /// * [`equal_eps_vec()`]
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html) /// * [`not_equal_eps_vec()`]
pub fn not_equal_eps<T: Number, const D: usize>( pub fn not_equal_eps<T: Number, const D: usize>(
x: &TVec<T, D>, x: &TVec<T, D>,
y: &TVec<T, D>, y: &TVec<T, D>,
@ -50,9 +50,9 @@ pub fn not_equal_eps<T: Number, const D: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`equal_eps`](fn.equal_eps.html) /// * [`equal_eps()`]
/// * [`equal_eps_vec`](fn.equal_eps_vec.html) /// * [`equal_eps_vec()`]
/// * [`not_equal_eps`](fn.not_equal_eps.html) /// * [`not_equal_eps()`]
pub fn not_equal_eps_vec<T: Number, const D: usize>( pub fn not_equal_eps_vec<T: Number, const D: usize>(
x: &TVec<T, D>, x: &TVec<T, D>,
y: &TVec<T, D>, y: &TVec<T, D>,

View File

@ -12,7 +12,7 @@ pub fn cross<T: Number>(x: &TVec3<T>, y: &TVec3<T>) -> TVec3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`distance2`](fn.distance2.html) /// * [`distance2()`](crate::distance2)
pub fn distance<T: RealNumber, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T { pub fn distance<T: RealNumber, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T {
(p1 - p0).norm() (p1 - p0).norm()
} }
@ -37,13 +37,13 @@ pub fn faceforward<T: Number, const D: usize>(
/// The magnitude of a vector. /// The magnitude of a vector.
/// ///
/// A synonym for [`magnitude`](fn.magnitude.html). /// A synonym for [`magnitude()`].
/// ///
/// # See also: /// # See also:
/// ///
/// * [`length2`](fn.length2.html) /// * [`length2()`](crate::length2)
/// * [`magnitude`](fn.magnitude.html) /// * [`magnitude()`]
/// * [`magnitude2`](fn.magnitude2.html) /// * [`magnitude2()`](crate::magnitude2)
pub fn length<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T { pub fn length<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
x.norm() x.norm()
} }
@ -54,8 +54,8 @@ pub fn length<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`length`](fn.length.html) /// * [`length()`]
/// * [`magnitude2`](fn.magnitude2.html) /// * [`magnitude2()`](crate::magnitude2)
/// * [`nalgebra::norm`](../nalgebra/fn.norm.html) /// * [`nalgebra::norm`](../nalgebra/fn.norm.html)
pub fn magnitude<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T { pub fn magnitude<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
x.norm() x.norm()

View File

@ -1,9 +1,8 @@
use crate::RealNumber; use crate::RealNumber;
use na;
/// The Euler constant. /// The Euler constant.
/// ///
/// This is a shorthand alias for [`euler`](fn.euler.html). /// This is a shorthand alias for [`euler()`].
pub fn e<T: RealNumber>() -> T { pub fn e<T: RealNumber>() -> T {
T::e() T::e()
} }
@ -17,18 +16,18 @@ pub fn euler<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`half_pi`](fn.half_pi.html) /// * [`half_pi()`]
/// * [`one_over_pi`](fn.one_over_pi.html) /// * [`one_over_pi()`]
/// * [`one_over_two_pi`](fn.one_over_two_pi.html) /// * [`one_over_two_pi()`]
/// * [`pi`](fn.pi.html) /// * [`pi()`](crate::pi)
/// * [`quarter_pi`](fn.quarter_pi.html) /// * [`quarter_pi()`]
/// * [`root_half_pi`](fn.root_half_pi.html) /// * [`root_half_pi()`]
/// * [`root_pi`](fn.root_pi.html) /// * [`root_pi()`]
/// * [`root_two_pi`](fn.root_two_pi.html) /// * [`root_two_pi()`]
/// * [`three_over_two_pi`](fn.three_over_two_pi.html) /// * [`three_over_two_pi()`]
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi()`]
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi()`]
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi()`]
pub fn four_over_pi<T: RealNumber>() -> T { pub fn four_over_pi<T: RealNumber>() -> T {
na::convert::<_, T>(4.0) / T::pi() na::convert::<_, T>(4.0) / T::pi()
} }
@ -42,18 +41,18 @@ pub fn golden_ratio<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi`](fn.four_over_pi.html) /// * [`four_over_pi()`]
/// * [`one_over_pi`](fn.one_over_pi.html) /// * [`one_over_pi()`]
/// * [`one_over_two_pi`](fn.one_over_two_pi.html) /// * [`one_over_two_pi()`]
/// * [`pi`](fn.pi.html) /// * [`pi()`](crate::pi)
/// * [`quarter_pi`](fn.quarter_pi.html) /// * [`quarter_pi()`]
/// * [`root_half_pi`](fn.root_half_pi.html) /// * [`root_half_pi()`]
/// * [`root_pi`](fn.root_pi.html) /// * [`root_pi()`]
/// * [`root_two_pi`](fn.root_two_pi.html) /// * [`root_two_pi()`]
/// * [`three_over_two_pi`](fn.three_over_two_pi.html) /// * [`three_over_two_pi()`]
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi()`]
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi()`]
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi()`]
pub fn half_pi<T: RealNumber>() -> T { pub fn half_pi<T: RealNumber>() -> T {
T::frac_pi_2() T::frac_pi_2()
} }
@ -62,8 +61,8 @@ pub fn half_pi<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`ln_ten`](fn.ln_ten.html) /// * [`ln_ten()`]
/// * [`ln_two`](fn.ln_two.html) /// * [`ln_two()`]
pub fn ln_ln_two<T: RealNumber>() -> T { pub fn ln_ln_two<T: RealNumber>() -> T {
T::ln_2().ln() T::ln_2().ln()
} }
@ -72,8 +71,8 @@ pub fn ln_ln_two<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`ln_ln_two`](fn.ln_ln_two.html) /// * [`ln_ln_two()`]
/// * [`ln_two`](fn.ln_two.html) /// * [`ln_two()`]
pub fn ln_ten<T: RealNumber>() -> T { pub fn ln_ten<T: RealNumber>() -> T {
T::ln_10() T::ln_10()
} }
@ -82,8 +81,8 @@ pub fn ln_ten<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`ln_ln_two`](fn.ln_ln_two.html) /// * [`ln_ln_two()`]
/// * [`ln_ten`](fn.ln_ten.html) /// * [`ln_ten()`]
pub fn ln_two<T: RealNumber>() -> T { pub fn ln_two<T: RealNumber>() -> T {
T::ln_2() T::ln_2()
} }
@ -95,18 +94,18 @@ pub use na::one;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi`](fn.four_over_pi.html) /// * [`four_over_pi()`]
/// * [`half_pi`](fn.half_pi.html) /// * [`half_pi()`]
/// * [`one_over_two_pi`](fn.one_over_two_pi.html) /// * [`one_over_two_pi()`]
/// * [`pi`](fn.pi.html) /// * [`pi()`](crate::pi)
/// * [`quarter_pi`](fn.quarter_pi.html) /// * [`quarter_pi()`]
/// * [`root_half_pi`](fn.root_half_pi.html) /// * [`root_half_pi()`]
/// * [`root_pi`](fn.root_pi.html) /// * [`root_pi()`]
/// * [`root_two_pi`](fn.root_two_pi.html) /// * [`root_two_pi()`]
/// * [`three_over_two_pi`](fn.three_over_two_pi.html) /// * [`three_over_two_pi()`]
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi()`]
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi()`]
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi()`]
pub fn one_over_pi<T: RealNumber>() -> T { pub fn one_over_pi<T: RealNumber>() -> T {
T::frac_1_pi() T::frac_1_pi()
} }
@ -120,18 +119,18 @@ pub fn one_over_root_two<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi`](fn.four_over_pi.html) /// * [`four_over_pi()`]
/// * [`half_pi`](fn.half_pi.html) /// * [`half_pi()`]
/// * [`one_over_pi`](fn.one_over_pi.html) /// * [`one_over_pi()`]
/// * [`pi`](fn.pi.html) /// * [`pi()`](crate::pi)
/// * [`quarter_pi`](fn.quarter_pi.html) /// * [`quarter_pi()`]
/// * [`root_half_pi`](fn.root_half_pi.html) /// * [`root_half_pi()`]
/// * [`root_pi`](fn.root_pi.html) /// * [`root_pi()`]
/// * [`root_two_pi`](fn.root_two_pi.html) /// * [`root_two_pi()`]
/// * [`three_over_two_pi`](fn.three_over_two_pi.html) /// * [`three_over_two_pi()`]
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi()`]
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi()`]
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi()`]
pub fn one_over_two_pi<T: RealNumber>() -> T { pub fn one_over_two_pi<T: RealNumber>() -> T {
T::frac_1_pi() * na::convert(0.5) T::frac_1_pi() * na::convert(0.5)
} }
@ -140,18 +139,18 @@ pub fn one_over_two_pi<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi`](fn.four_over_pi.html) /// * [`four_over_pi()`]
/// * [`half_pi`](fn.half_pi.html) /// * [`half_pi()`]
/// * [`one_over_pi`](fn.one_over_pi.html) /// * [`one_over_pi()`]
/// * [`one_over_two_pi`](fn.one_over_two_pi.html) /// * [`one_over_two_pi()`]
/// * [`pi`](fn.pi.html) /// * [`pi()`](crate::pi)
/// * [`root_half_pi`](fn.root_half_pi.html) /// * [`root_half_pi()`]
/// * [`root_pi`](fn.root_pi.html) /// * [`root_pi()`]
/// * [`root_two_pi`](fn.root_two_pi.html) /// * [`root_two_pi()`]
/// * [`three_over_two_pi`](fn.three_over_two_pi.html) /// * [`three_over_two_pi()`]
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi()`]
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi()`]
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi()`]
pub fn quarter_pi<T: RealNumber>() -> T { pub fn quarter_pi<T: RealNumber>() -> T {
T::frac_pi_4() T::frac_pi_4()
} }
@ -160,8 +159,8 @@ pub fn quarter_pi<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`root_three`](fn.root_three.html) /// * [`root_three()`]
/// * [`root_two`](fn.root_two.html) /// * [`root_two()`]
pub fn root_five<T: RealNumber>() -> T { pub fn root_five<T: RealNumber>() -> T {
na::convert::<_, T>(5.0).sqrt() na::convert::<_, T>(5.0).sqrt()
} }
@ -170,18 +169,18 @@ pub fn root_five<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi`](fn.four_over_pi.html) /// * [`four_over_pi()`]
/// * [`half_pi`](fn.half_pi.html) /// * [`half_pi()`]
/// * [`one_over_pi`](fn.one_over_pi.html) /// * [`one_over_pi()`]
/// * [`one_over_two_pi`](fn.one_over_two_pi.html) /// * [`one_over_two_pi()`]
/// * [`pi`](fn.pi.html) /// * [`pi()`](crate::pi)
/// * [`quarter_pi`](fn.quarter_pi.html) /// * [`quarter_pi()`]
/// * [`root_pi`](fn.root_pi.html) /// * [`root_pi()`]
/// * [`root_two_pi`](fn.root_two_pi.html) /// * [`root_two_pi()`]
/// * [`three_over_two_pi`](fn.three_over_two_pi.html) /// * [`three_over_two_pi()`]
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi()`]
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi()`]
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi()`]
pub fn root_half_pi<T: RealNumber>() -> T { pub fn root_half_pi<T: RealNumber>() -> T {
(T::pi() / na::convert(2.0)).sqrt() (T::pi() / na::convert(2.0)).sqrt()
} }
@ -195,18 +194,18 @@ pub fn root_ln_four<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi`](fn.four_over_pi.html) /// * [`four_over_pi()`]
/// * [`half_pi`](fn.half_pi.html) /// * [`half_pi()`]
/// * [`one_over_pi`](fn.one_over_pi.html) /// * [`one_over_pi()`]
/// * [`one_over_two_pi`](fn.one_over_two_pi.html) /// * [`one_over_two_pi()`]
/// * [`pi`](fn.pi.html) /// * [`pi()`](crate::pi)
/// * [`quarter_pi`](fn.quarter_pi.html) /// * [`quarter_pi()`]
/// * [`root_half_pi`](fn.root_half_pi.html) /// * [`root_half_pi()`]
/// * [`root_two_pi`](fn.root_two_pi.html) /// * [`root_two_pi()`]
/// * [`three_over_two_pi`](fn.three_over_two_pi.html) /// * [`three_over_two_pi()`]
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi()`]
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi()`]
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi()`]
pub fn root_pi<T: RealNumber>() -> T { pub fn root_pi<T: RealNumber>() -> T {
T::pi().sqrt() T::pi().sqrt()
} }
@ -215,8 +214,8 @@ pub fn root_pi<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`root_five`](fn.root_five.html) /// * [`root_five()`]
/// * [`root_two`](fn.root_two.html) /// * [`root_two()`]
pub fn root_three<T: RealNumber>() -> T { pub fn root_three<T: RealNumber>() -> T {
na::convert::<_, T>(3.0).sqrt() na::convert::<_, T>(3.0).sqrt()
} }
@ -225,8 +224,8 @@ pub fn root_three<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`root_five`](fn.root_five.html) /// * [`root_five()`]
/// * [`root_three`](fn.root_three.html) /// * [`root_three()`]
pub fn root_two<T: RealNumber>() -> T { pub fn root_two<T: RealNumber>() -> T {
// TODO: there should be a crate::sqrt_2() on the RealNumber trait. // TODO: there should be a crate::sqrt_2() on the RealNumber trait.
na::convert::<_, T>(2.0).sqrt() na::convert::<_, T>(2.0).sqrt()
@ -236,18 +235,18 @@ pub fn root_two<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi`](fn.four_over_pi.html) /// * [`four_over_pi()`]
/// * [`half_pi`](fn.half_pi.html) /// * [`half_pi()`]
/// * [`one_over_pi`](fn.one_over_pi.html) /// * [`one_over_pi()`]
/// * [`one_over_two_pi`](fn.one_over_two_pi.html) /// * [`one_over_two_pi()`]
/// * [`pi`](fn.pi.html) /// * [`pi()`](crate::pi)
/// * [`quarter_pi`](fn.quarter_pi.html) /// * [`quarter_pi()`]
/// * [`root_half_pi`](fn.root_half_pi.html) /// * [`root_half_pi()`]
/// * [`root_pi`](fn.root_pi.html) /// * [`root_pi()`]
/// * [`three_over_two_pi`](fn.three_over_two_pi.html) /// * [`three_over_two_pi()`]
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi()`]
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi()`]
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi()`]
pub fn root_two_pi<T: RealNumber>() -> T { pub fn root_two_pi<T: RealNumber>() -> T {
T::two_pi().sqrt() T::two_pi().sqrt()
} }
@ -256,7 +255,7 @@ pub fn root_two_pi<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`two_thirds`](fn.two_thirds.html) /// * [`two_thirds()`]
pub fn third<T: RealNumber>() -> T { pub fn third<T: RealNumber>() -> T {
na::convert(1.0 / 3.0) na::convert(1.0 / 3.0)
} }
@ -265,18 +264,18 @@ pub fn third<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi`](fn.four_over_pi.html) /// * [`four_over_pi()`]
/// * [`half_pi`](fn.half_pi.html) /// * [`half_pi()`]
/// * [`one_over_pi`](fn.one_over_pi.html) /// * [`one_over_pi()`]
/// * [`one_over_two_pi`](fn.one_over_two_pi.html) /// * [`one_over_two_pi()`]
/// * [`pi`](fn.pi.html) /// * [`pi()`](crate::pi)
/// * [`quarter_pi`](fn.quarter_pi.html) /// * [`quarter_pi()`]
/// * [`root_half_pi`](fn.root_half_pi.html) /// * [`root_half_pi()`]
/// * [`root_pi`](fn.root_pi.html) /// * [`root_pi()`]
/// * [`root_two_pi`](fn.root_two_pi.html) /// * [`root_two_pi()`]
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi()`]
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi()`]
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi()`]
pub fn three_over_two_pi<T: RealNumber>() -> T { pub fn three_over_two_pi<T: RealNumber>() -> T {
na::convert::<_, T>(3.0) / T::two_pi() na::convert::<_, T>(3.0) / T::two_pi()
} }
@ -285,17 +284,18 @@ pub fn three_over_two_pi<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi`](fn.four_over_pi.html) /// * [`four_over_pi()`]
/// * [`half_pi`](fn.half_pi.html) /// * [`half_pi()`]
/// * [`one_over_pi`](fn.one_over_pi.html) /// * [`one_over_pi()`]
/// * [`one_over_two_pi`](fn.one_over_two_pi.html) /// * [`one_over_two_pi()`]
/// * [`quarter_pi`](fn.quarter_pi.html) /// * [`pi()`](crate::pi)
/// * [`root_half_pi`](fn.root_half_pi.html) /// * [`quarter_pi()`]
/// * [`root_pi`](fn.root_pi.html) /// * [`root_half_pi()`]
/// * [`root_two_pi`](fn.root_two_pi.html) /// * [`root_pi()`]
/// * [`three_over_two_pi`](fn.three_over_two_pi.html) /// * [`root_two_pi()`]
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`three_over_two_pi()`]
/// * [`two_pi`](fn.two_pi.html) /// * [`two_over_root_pi()`]
/// * [`two_pi()`]
pub fn two_over_pi<T: RealNumber>() -> T { pub fn two_over_pi<T: RealNumber>() -> T {
T::frac_2_pi() T::frac_2_pi()
} }
@ -304,18 +304,18 @@ pub fn two_over_pi<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi`](fn.four_over_pi.html) /// * [`four_over_pi()`]
/// * [`half_pi`](fn.half_pi.html) /// * [`half_pi()`]
/// * [`one_over_pi`](fn.one_over_pi.html) /// * [`one_over_pi()`]
/// * [`one_over_two_pi`](fn.one_over_two_pi.html) /// * [`one_over_two_pi()`]
/// * [`pi`](fn.pi.html) /// * [`pi()`](crate::pi)
/// * [`quarter_pi`](fn.quarter_pi.html) /// * [`quarter_pi()`]
/// * [`root_half_pi`](fn.root_half_pi.html) /// * [`root_half_pi()`]
/// * [`root_pi`](fn.root_pi.html) /// * [`root_pi()`]
/// * [`root_two_pi`](fn.root_two_pi.html) /// * [`root_two_pi()`]
/// * [`three_over_two_pi`](fn.three_over_two_pi.html) /// * [`three_over_two_pi()`]
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi()`]
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi()`]
pub fn two_over_root_pi<T: RealNumber>() -> T { pub fn two_over_root_pi<T: RealNumber>() -> T {
T::frac_2_sqrt_pi() T::frac_2_sqrt_pi()
} }
@ -324,18 +324,18 @@ pub fn two_over_root_pi<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`four_over_pi`](fn.four_over_pi.html) /// * [`four_over_pi()`]
/// * [`half_pi`](fn.half_pi.html) /// * [`half_pi()`]
/// * [`one_over_pi`](fn.one_over_pi.html) /// * [`one_over_pi()`]
/// * [`one_over_two_pi`](fn.one_over_two_pi.html) /// * [`one_over_two_pi()`]
/// * [`pi`](fn.pi.html) /// * [`pi()`](crate::pi)
/// * [`quarter_pi`](fn.quarter_pi.html) /// * [`quarter_pi()`]
/// * [`root_half_pi`](fn.root_half_pi.html) /// * [`root_half_pi()`]
/// * [`root_pi`](fn.root_pi.html) /// * [`root_pi()`]
/// * [`root_two_pi`](fn.root_two_pi.html) /// * [`root_two_pi()`]
/// * [`three_over_two_pi`](fn.three_over_two_pi.html) /// * [`three_over_two_pi()`]
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi()`]
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi()`]
pub fn two_pi<T: RealNumber>() -> T { pub fn two_pi<T: RealNumber>() -> T {
T::two_pi() T::two_pi()
} }
@ -344,7 +344,7 @@ pub fn two_pi<T: RealNumber>() -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`third`](fn.third.html) /// * [`third()`]
pub fn two_thirds<T: RealNumber>() -> T { pub fn two_thirds<T: RealNumber>() -> T {
na::convert(2.0 / 3.0) na::convert(2.0 / 3.0)
} }

View File

@ -7,24 +7,24 @@ use na::DefaultAllocator;
use crate::traits::{Alloc, Number, Dimension}; use crate::traits::{Alloc, Number, Dimension};
use crate::aliases::TVec; use crate::aliases::TVec;
/// Component-wise approximate equality beween two vectors. /// Component-wise approximate equality between two vectors.
pub fn epsilon_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, epsilon: T) -> TVec<bool, D> pub fn epsilon_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, epsilon: T) -> TVec<bool, D>
where DefaultAllocator: Alloc<T, D> { where DefaultAllocator: Alloc<T, D> {
x.zip_map(y, |x, y| abs_diff_eq!(x, y, epsilon = epsilon)) x.zip_map(y, |x, y| abs_diff_eq!(x, y, epsilon = epsilon))
} }
/// Component-wise approximate equality beween two scalars. /// Component-wise approximate equality between two scalars.
pub fn epsilon_equal2<T: AbsDiffEq<Epsilon = T>>(x: T, y: T, epsilon: T) -> bool { pub fn epsilon_equal2<T: AbsDiffEq<Epsilon = T>>(x: T, y: T, epsilon: T) -> bool {
abs_diff_eq!(x, y, epsilon = epsilon) abs_diff_eq!(x, y, epsilon = epsilon)
} }
/// Component-wise approximate non-equality beween two vectors. /// Component-wise approximate non-equality between two vectors.
pub fn epsilon_not_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, epsilon: T) -> TVec<bool, D> pub fn epsilon_not_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, epsilon: T) -> TVec<bool, D>
where DefaultAllocator: Alloc<T, D> { where DefaultAllocator: Alloc<T, D> {
x.zip_map(y, |x, y| abs_diff_ne!(x, y, epsilon = epsilon)) x.zip_map(y, |x, y| abs_diff_ne!(x, y, epsilon = epsilon))
} }
/// Component-wise approximate non-equality beween two scalars. /// Component-wise approximate non-equality between two scalars.
pub fn epsilon_not_equal2<T: AbsDiffEq<Epsilon = T>>(x: T, y: T, epsilon: T) -> bool { pub fn epsilon_not_equal2<T: AbsDiffEq<Epsilon = T>>(x: T, y: T, epsilon: T) -> bool {
abs_diff_ne!(x, y, epsilon = epsilon) abs_diff_ne!(x, y, epsilon = epsilon)
} }

View File

@ -6,9 +6,9 @@ use crate::aliases::{TMat, TVec};
/// ///
/// # See also: /// # See also:
/// ///
/// * [`row`](fn.row.html) /// * [`row()`]
/// * [`set_column`](fn.set_column.html) /// * [`set_column()`]
/// * [`set_row`](fn.set_row.html) /// * [`set_row()`]
pub fn column<T: Scalar, const R: usize, const C: usize>( pub fn column<T: Scalar, const R: usize, const C: usize>(
m: &TMat<T, R, C>, m: &TMat<T, R, C>,
index: usize, index: usize,
@ -20,9 +20,9 @@ pub fn column<T: Scalar, const R: usize, const C: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`column`](fn.column.html) /// * [`column()`]
/// * [`row`](fn.row.html) /// * [`row()`]
/// * [`set_row`](fn.set_row.html) /// * [`set_row()`]
pub fn set_column<T: Scalar, const R: usize, const C: usize>( pub fn set_column<T: Scalar, const R: usize, const C: usize>(
m: &TMat<T, R, C>, m: &TMat<T, R, C>,
index: usize, index: usize,
@ -37,9 +37,9 @@ pub fn set_column<T: Scalar, const R: usize, const C: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`column`](fn.column.html) /// * [`column()`]
/// * [`set_column`](fn.set_column.html) /// * [`set_column()`]
/// * [`set_row`](fn.set_row.html) /// * [`set_row()`]
pub fn row<T: Scalar, const R: usize, const C: usize>( pub fn row<T: Scalar, const R: usize, const C: usize>(
m: &TMat<T, R, C>, m: &TMat<T, R, C>,
index: usize, index: usize,
@ -51,9 +51,9 @@ pub fn row<T: Scalar, const R: usize, const C: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`column`](fn.column.html) /// * [`column()`]
/// * [`row`](fn.row.html) /// * [`row()`]
/// * [`set_column`](fn.set_column.html) /// * [`set_column()`]
pub fn set_row<T: Scalar, const R: usize, const C: usize>( pub fn set_row<T: Scalar, const R: usize, const C: usize>(
m: &TMat<T, R, C>, m: &TMat<T, R, C>,
index: usize, index: usize,

View File

@ -128,9 +128,9 @@ pub fn make_quat<T: RealNumber>(ptr: &[T]) -> Qua<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`make_vec2`](fn.make_vec2.html) /// * [`make_vec2()`]
/// * [`make_vec3`](fn.make_vec3.html) /// * [`make_vec3()`]
/// * [`make_vec4`](fn.make_vec4.html) /// * [`make_vec4()`]
pub fn make_vec1<T: Scalar>(v: &TVec1<T>) -> TVec1<T> { pub fn make_vec1<T: Scalar>(v: &TVec1<T>) -> TVec1<T> {
v.clone() v.clone()
} }
@ -139,12 +139,11 @@ pub fn make_vec1<T: Scalar>(v: &TVec1<T>) -> TVec1<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec1_to_vec1`](fn.vec1_to_vec1.html) /// * [`vec3_to_vec1()`]
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html) /// * [`vec4_to_vec1()`]
/// * [`vec4_to_vec1`](fn.vec4_to_vec1.html) /// * [`vec1_to_vec2()`]
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html) /// * [`vec1_to_vec3()`]
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html) /// * [`vec1_to_vec4()`]
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
pub fn vec2_to_vec1<T: Scalar>(v: &TVec2<T>) -> TVec1<T> { pub fn vec2_to_vec1<T: Scalar>(v: &TVec2<T>) -> TVec1<T> {
TVec1::new(v.x.clone()) TVec1::new(v.x.clone())
} }
@ -153,12 +152,11 @@ pub fn vec2_to_vec1<T: Scalar>(v: &TVec2<T>) -> TVec1<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec1_to_vec1`](fn.vec1_to_vec1.html) /// * [`vec2_to_vec1()`]
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html) /// * [`vec4_to_vec1()`]
/// * [`vec4_to_vec1`](fn.vec4_to_vec1.html) /// * [`vec1_to_vec2()`]
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html) /// * [`vec1_to_vec3()`]
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html) /// * [`vec1_to_vec4()`]
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
pub fn vec3_to_vec1<T: Scalar>(v: &TVec3<T>) -> TVec1<T> { pub fn vec3_to_vec1<T: Scalar>(v: &TVec3<T>) -> TVec1<T> {
TVec1::new(v.x.clone()) TVec1::new(v.x.clone())
} }
@ -167,12 +165,11 @@ pub fn vec3_to_vec1<T: Scalar>(v: &TVec3<T>) -> TVec1<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec1_to_vec1`](fn.vec1_to_vec1.html) /// * [`vec2_to_vec1()`]
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html) /// * [`vec3_to_vec1()`]
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html) /// * [`vec1_to_vec2()`]
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html) /// * [`vec1_to_vec3()`]
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html) /// * [`vec1_to_vec4()`]
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
pub fn vec4_to_vec1<T: Scalar>(v: &TVec4<T>) -> TVec1<T> { pub fn vec4_to_vec1<T: Scalar>(v: &TVec4<T>) -> TVec1<T> {
TVec1::new(v.x.clone()) TVec1::new(v.x.clone())
} }
@ -183,12 +180,12 @@ pub fn vec4_to_vec1<T: Scalar>(v: &TVec4<T>) -> TVec1<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html) /// * [`vec3_to_vec2()`]
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html) /// * [`vec4_to_vec2()`]
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html) /// * [`vec2_to_vec1()`]
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html) /// * [`vec2_to_vec2()`]
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html) /// * [`vec2_to_vec3()`]
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html) /// * [`vec2_to_vec4()`]
pub fn vec1_to_vec2<T: Number>(v: &TVec1<T>) -> TVec2<T> { pub fn vec1_to_vec2<T: Number>(v: &TVec1<T>) -> TVec2<T> {
TVec2::new(v.x.clone(), T::zero()) TVec2::new(v.x.clone(), T::zero())
} }
@ -197,13 +194,13 @@ pub fn vec1_to_vec2<T: Number>(v: &TVec1<T>) -> TVec2<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html) /// * [`vec1_to_vec2()`]
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html) /// * [`vec3_to_vec2()`]
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html) /// * [`vec4_to_vec2()`]
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html) /// * [`vec2_to_vec1()`]
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html) /// * [`vec2_to_vec2()`]
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html) /// * [`vec2_to_vec3()`]
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html) /// * [`vec2_to_vec4()`]
pub fn vec2_to_vec2<T: Scalar>(v: &TVec2<T>) -> TVec2<T> { pub fn vec2_to_vec2<T: Scalar>(v: &TVec2<T>) -> TVec2<T> {
v.clone() v.clone()
} }
@ -212,12 +209,12 @@ pub fn vec2_to_vec2<T: Scalar>(v: &TVec2<T>) -> TVec2<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html) /// * [`vec1_to_vec2()`]
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html) /// * [`vec4_to_vec2()`]
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html) /// * [`vec2_to_vec1()`]
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html) /// * [`vec2_to_vec2()`]
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html) /// * [`vec2_to_vec3()`]
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html) /// * [`vec2_to_vec4()`]
pub fn vec3_to_vec2<T: Scalar>(v: &TVec3<T>) -> TVec2<T> { pub fn vec3_to_vec2<T: Scalar>(v: &TVec3<T>) -> TVec2<T> {
TVec2::new(v.x.clone(), v.y.clone()) TVec2::new(v.x.clone(), v.y.clone())
} }
@ -226,12 +223,12 @@ pub fn vec3_to_vec2<T: Scalar>(v: &TVec3<T>) -> TVec2<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html) /// * [`vec1_to_vec2()`]
/// * [`vec3_to_vec2`](fn.vec4_to_vec2.html) /// * [`vec3_to_vec2()`]
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html) /// * [`vec2_to_vec1()`]
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html) /// * [`vec2_to_vec2()`]
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html) /// * [`vec2_to_vec3()`]
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html) /// * [`vec2_to_vec4()`]
pub fn vec4_to_vec2<T: Scalar>(v: &TVec4<T>) -> TVec2<T> { pub fn vec4_to_vec2<T: Scalar>(v: &TVec4<T>) -> TVec2<T> {
TVec2::new(v.x.clone(), v.y.clone()) TVec2::new(v.x.clone(), v.y.clone())
} }
@ -240,9 +237,9 @@ pub fn vec4_to_vec2<T: Scalar>(v: &TVec4<T>) -> TVec2<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`make_vec1`](fn.make_vec1.html) /// * [`make_vec1()`]
/// * [`make_vec3`](fn.make_vec3.html) /// * [`make_vec3()`]
/// * [`make_vec4`](fn.make_vec4.html) /// * [`make_vec4()`]
pub fn make_vec2<T: Scalar>(ptr: &[T]) -> TVec2<T> { pub fn make_vec2<T: Scalar>(ptr: &[T]) -> TVec2<T> {
TVec2::from_column_slice(ptr) TVec2::from_column_slice(ptr)
} }
@ -253,11 +250,11 @@ pub fn make_vec2<T: Scalar>(ptr: &[T]) -> TVec2<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html) /// * [`vec2_to_vec3()`]
/// * [`vec3_to_vec3`](fn.vec3_to_vec3.html) /// * [`vec3_to_vec3()`]
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html) /// * [`vec4_to_vec3()`]
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html) /// * [`vec1_to_vec2()`]
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html) /// * [`vec1_to_vec4()`]
pub fn vec1_to_vec3<T: Number>(v: &TVec1<T>) -> TVec3<T> { pub fn vec1_to_vec3<T: Number>(v: &TVec1<T>) -> TVec3<T> {
TVec3::new(v.x.clone(), T::zero(), T::zero()) TVec3::new(v.x.clone(), T::zero(), T::zero())
} }
@ -268,12 +265,12 @@ pub fn vec1_to_vec3<T: Number>(v: &TVec1<T>) -> TVec3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html) /// * [`vec1_to_vec3()`]
/// * [`vec3_to_vec3`](fn.vec3_to_vec3.html) /// * [`vec3_to_vec3()`]
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html) /// * [`vec4_to_vec3()`]
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html) /// * [`vec3_to_vec1()`]
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html) /// * [`vec3_to_vec2()`]
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html) /// * [`vec3_to_vec4()`]
pub fn vec2_to_vec3<T: Number>(v: &TVec2<T>) -> TVec3<T> { pub fn vec2_to_vec3<T: Number>(v: &TVec2<T>) -> TVec3<T> {
TVec3::new(v.x.clone(), v.y.clone(), T::zero()) TVec3::new(v.x.clone(), v.y.clone(), T::zero())
} }
@ -282,12 +279,12 @@ pub fn vec2_to_vec3<T: Number>(v: &TVec2<T>) -> TVec3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html) /// * [`vec1_to_vec3()`]
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html) /// * [`vec2_to_vec3()`]
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html) /// * [`vec4_to_vec3()`]
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html) /// * [`vec3_to_vec1()`]
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html) /// * [`vec3_to_vec2()`]
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html) /// * [`vec3_to_vec4()`]
pub fn vec3_to_vec3<T: Scalar>(v: &TVec3<T>) -> TVec3<T> { pub fn vec3_to_vec3<T: Scalar>(v: &TVec3<T>) -> TVec3<T> {
v.clone() v.clone()
} }
@ -296,12 +293,12 @@ pub fn vec3_to_vec3<T: Scalar>(v: &TVec3<T>) -> TVec3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html) /// * [`vec1_to_vec3()`]
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html) /// * [`vec2_to_vec3()`]
/// * [`vec3_to_vec3`](fn.vec3_to_vec3.html) /// * [`vec3_to_vec3()`]
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html) /// * [`vec3_to_vec1()`]
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html) /// * [`vec3_to_vec2()`]
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html) /// * [`vec3_to_vec4()`]
pub fn vec4_to_vec3<T: Scalar>(v: &TVec4<T>) -> TVec3<T> { pub fn vec4_to_vec3<T: Scalar>(v: &TVec4<T>) -> TVec3<T> {
TVec3::new(v.x.clone(), v.y.clone(), v.z.clone()) TVec3::new(v.x.clone(), v.y.clone(), v.z.clone())
} }
@ -310,9 +307,9 @@ pub fn vec4_to_vec3<T: Scalar>(v: &TVec4<T>) -> TVec3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`make_vec1`](fn.make_vec1.html) /// * [`make_vec1()`]
/// * [`make_vec2`](fn.make_vec2.html) /// * [`make_vec2()`]
/// * [`make_vec4`](fn.make_vec4.html) /// * [`make_vec4()`]
pub fn make_vec3<T: Scalar>(ptr: &[T]) -> TVec3<T> { pub fn make_vec3<T: Scalar>(ptr: &[T]) -> TVec3<T> {
TVec3::from_column_slice(ptr) TVec3::from_column_slice(ptr)
} }
@ -323,12 +320,12 @@ pub fn make_vec3<T: Scalar>(ptr: &[T]) -> TVec3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html) /// * [`vec2_to_vec4()`]
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html) /// * [`vec3_to_vec4()`]
/// * [`vec4_to_vec4`](fn.vec4_to_vec4.html) /// * [`vec4_to_vec4()`]
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html) /// * [`vec1_to_vec2()`]
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html) /// * [`vec1_to_vec3()`]
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html) /// * [`vec1_to_vec4()`]
pub fn vec1_to_vec4<T: Number>(v: &TVec1<T>) -> TVec4<T> { pub fn vec1_to_vec4<T: Number>(v: &TVec1<T>) -> TVec4<T> {
TVec4::new(v.x, T::zero(), T::zero(), T::zero()) TVec4::new(v.x, T::zero(), T::zero(), T::zero())
} }
@ -339,12 +336,12 @@ pub fn vec1_to_vec4<T: Number>(v: &TVec1<T>) -> TVec4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html) /// * [`vec1_to_vec4()`]
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html) /// * [`vec3_to_vec4()`]
/// * [`vec4_to_vec4`](fn.vec4_to_vec4.html) /// * [`vec4_to_vec4()`]
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html) /// * [`vec2_to_vec1()`]
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html) /// * [`vec2_to_vec2()`]
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html) /// * [`vec2_to_vec3()`]
pub fn vec2_to_vec4<T: Number>(v: &TVec2<T>) -> TVec4<T> { pub fn vec2_to_vec4<T: Number>(v: &TVec2<T>) -> TVec4<T> {
TVec4::new(v.x, v.y, T::zero(), T::zero()) TVec4::new(v.x, v.y, T::zero(), T::zero())
} }
@ -355,12 +352,12 @@ pub fn vec2_to_vec4<T: Number>(v: &TVec2<T>) -> TVec4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html) /// * [`vec1_to_vec4()`]
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html) /// * [`vec2_to_vec4()`]
/// * [`vec4_to_vec4`](fn.vec4_to_vec4.html) /// * [`vec4_to_vec4()`]
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html) /// * [`vec3_to_vec1()`]
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html) /// * [`vec3_to_vec2()`]
/// * [`vec3_to_vec3`](fn.vec3_to_vec3.html) /// * [`vec3_to_vec3()`]
pub fn vec3_to_vec4<T: Number>(v: &TVec3<T>) -> TVec4<T> { pub fn vec3_to_vec4<T: Number>(v: &TVec3<T>) -> TVec4<T> {
TVec4::new(v.x, v.y, v.z, T::zero()) TVec4::new(v.x, v.y, v.z, T::zero())
} }
@ -369,12 +366,12 @@ pub fn vec3_to_vec4<T: Number>(v: &TVec3<T>) -> TVec4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html) /// * [`vec1_to_vec4()`]
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html) /// * [`vec2_to_vec4()`]
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html) /// * [`vec3_to_vec4()`]
/// * [`vec4_to_vec1`](fn.vec4_to_vec1.html) /// * [`vec4_to_vec1()`]
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html) /// * [`vec4_to_vec2()`]
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html) /// * [`vec4_to_vec3()`]
pub fn vec4_to_vec4<T: Scalar>(v: &TVec4<T>) -> TVec4<T> { pub fn vec4_to_vec4<T: Scalar>(v: &TVec4<T>) -> TVec4<T> {
v.clone() v.clone()
} }
@ -383,9 +380,9 @@ pub fn vec4_to_vec4<T: Scalar>(v: &TVec4<T>) -> TVec4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`make_vec1`](fn.make_vec1.html) /// * [`make_vec1()`]
/// * [`make_vec2`](fn.make_vec2.html) /// * [`make_vec2()`]
/// * [`make_vec3`](fn.make_vec3.html) /// * [`make_vec3()`]
pub fn make_vec4<T: Scalar>(ptr: &[T]) -> TVec4<T> { pub fn make_vec4<T: Scalar>(ptr: &[T]) -> TVec4<T> {
TVec4::from_column_slice(ptr) TVec4::from_column_slice(ptr)
} }

View File

@ -16,9 +16,9 @@ use crate::traits::Number;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_max`](fn.comp_max.html) /// * [`comp_max()`]
/// * [`comp_min`](fn.comp_min.html) /// * [`comp_min()`]
/// * [`comp_mul`](fn.comp_mul.html) /// * [`comp_mul()`]
pub fn comp_add<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T { pub fn comp_add<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
m.iter().fold(T::zero(), |x, y| x + *y) m.iter().fold(T::zero(), |x, y| x + *y)
} }
@ -38,13 +38,13 @@ pub fn comp_add<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) ->
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_add`](fn.comp_add.html) /// * [`comp_add()`]
/// * [`comp_max`](fn.comp_max.html) /// * [`comp_max()`]
/// * [`comp_min`](fn.comp_min.html) /// * [`comp_min()`]
/// * [`max`](fn.max.html) /// * [`max()`](crate::max)
/// * [`max2`](fn.max2.html) /// * [`max2()`](crate::max2)
/// * [`max3`](fn.max3.html) /// * [`max3()`](crate::max3)
/// * [`max4`](fn.max4.html) /// * [`max4()`](crate::max4)
pub fn comp_max<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T { pub fn comp_max<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
m.iter() m.iter()
.fold(T::min_value(), |x, y| crate::max2_scalar(x, *y)) .fold(T::min_value(), |x, y| crate::max2_scalar(x, *y))
@ -65,13 +65,13 @@ pub fn comp_max<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) ->
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_add`](fn.comp_add.html) /// * [`comp_add()`]
/// * [`comp_max`](fn.comp_max.html) /// * [`comp_max()`]
/// * [`comp_mul`](fn.comp_mul.html) /// * [`comp_mul()`]
/// * [`min`](fn.min.html) /// * [`min()`](crate::min)
/// * [`min2`](fn.min2.html) /// * [`min2()`](crate::min2)
/// * [`min3`](fn.min3.html) /// * [`min3()`](crate::min3)
/// * [`min4`](fn.min4.html) /// * [`min4()`](crate::min4)
pub fn comp_min<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T { pub fn comp_min<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
m.iter() m.iter()
.fold(T::max_value(), |x, y| crate::min2_scalar(x, *y)) .fold(T::max_value(), |x, y| crate::min2_scalar(x, *y))
@ -92,9 +92,9 @@ pub fn comp_min<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) ->
/// ///
/// # See also: /// # See also:
/// ///
/// * [`comp_add`](fn.comp_add.html) /// * [`comp_add()`]
/// * [`comp_max`](fn.comp_max.html) /// * [`comp_max()`]
/// * [`comp_min`](fn.comp_min.html) /// * [`comp_min()`]
pub fn comp_mul<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T { pub fn comp_mul<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
m.iter().fold(T::one(), |x, y| x * *y) m.iter().fold(T::one(), |x, y| x * *y)
} }

View File

@ -5,7 +5,7 @@ use crate::traits::Number;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`right_handed`](fn.right_handed.html) /// * [`right_handed()`]
pub fn left_handed<T: Number>(a: &TVec3<T>, b: &TVec3<T>, c: &TVec3<T>) -> bool { pub fn left_handed<T: Number>(a: &TVec3<T>, b: &TVec3<T>, c: &TVec3<T>) -> bool {
a.cross(b).dot(c) < T::zero() a.cross(b).dot(c) < T::zero()
} }
@ -14,7 +14,7 @@ pub fn left_handed<T: Number>(a: &TVec3<T>, b: &TVec3<T>, c: &TVec3<T>) -> bool
/// ///
/// # See also: /// # See also:
/// ///
/// * [`left_handed`](fn.left_handed.html) /// * [`left_handed()`]
pub fn right_handed<T: Number>(a: &TVec3<T>, b: &TVec3<T>, c: &TVec3<T>) -> bool { pub fn right_handed<T: Number>(a: &TVec3<T>, b: &TVec3<T>, c: &TVec3<T>) -> bool {
a.cross(b).dot(c) > T::zero() a.cross(b).dot(c) > T::zero()
} }

View File

@ -5,7 +5,7 @@ use crate::RealNumber;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`matrix_cross`](fn.matrix_cross.html) /// * [`matrix_cross()`]
pub fn matrix_cross3<T: RealNumber>(x: &TVec3<T>) -> TMat3<T> { pub fn matrix_cross3<T: RealNumber>(x: &TVec3<T>) -> TMat3<T> {
x.cross_matrix() x.cross_matrix()
} }
@ -14,7 +14,7 @@ pub fn matrix_cross3<T: RealNumber>(x: &TVec3<T>) -> TMat3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`matrix_cross3`](fn.matrix_cross3.html) /// * [`matrix_cross3()`]
pub fn matrix_cross<T: RealNumber>(x: &TVec3<T>) -> TMat4<T> { pub fn matrix_cross<T: RealNumber>(x: &TVec3<T>) -> TMat4<T> {
crate::mat3_to_mat4(&x.cross_matrix()) crate::mat3_to_mat4(&x.cross_matrix())
} }

View File

@ -7,14 +7,14 @@ use crate::traits::Number;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`diagonal2x3`](fn.diagonal2x3.html) /// * [`diagonal2x3()`]
/// * [`diagonal2x4`](fn.diagonal2x4.html) /// * [`diagonal2x4()`]
/// * [`diagonal3x2`](fn.diagonal3x2.html) /// * [`diagonal3x2()`]
/// * [`diagonal3x3`](fn.diagonal3x3.html) /// * [`diagonal3x3()`]
/// * [`diagonal3x4`](fn.diagonal3x4.html) /// * [`diagonal3x4()`]
/// * [`diagonal4x2`](fn.diagonal4x2.html) /// * [`diagonal4x2()`]
/// * [`diagonal4x3`](fn.diagonal4x3.html) /// * [`diagonal4x3()`]
/// * [`diagonal4x4`](fn.diagonal4x4.html) /// * [`diagonal4x4()`]
pub fn diagonal2x2<T: Number>(v: &TVec2<T>) -> TMat2<T> { pub fn diagonal2x2<T: Number>(v: &TVec2<T>) -> TMat2<T> {
TMat2::from_diagonal(v) TMat2::from_diagonal(v)
} }
@ -23,14 +23,14 @@ pub fn diagonal2x2<T: Number>(v: &TVec2<T>) -> TMat2<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`diagonal2x2`](fn.diagonal2x2.html) /// * [`diagonal2x2()`]
/// * [`diagonal2x4`](fn.diagonal2x4.html) /// * [`diagonal2x4()`]
/// * [`diagonal3x2`](fn.diagonal3x2.html) /// * [`diagonal3x2()`]
/// * [`diagonal3x3`](fn.diagonal3x3.html) /// * [`diagonal3x3()`]
/// * [`diagonal3x4`](fn.diagonal3x4.html) /// * [`diagonal3x4()`]
/// * [`diagonal4x2`](fn.diagonal4x2.html) /// * [`diagonal4x2()`]
/// * [`diagonal4x3`](fn.diagonal4x3.html) /// * [`diagonal4x3()`]
/// * [`diagonal4x4`](fn.diagonal4x4.html) /// * [`diagonal4x4()`]
pub fn diagonal2x3<T: Number>(v: &TVec2<T>) -> TMat2x3<T> { pub fn diagonal2x3<T: Number>(v: &TVec2<T>) -> TMat2x3<T> {
TMat2x3::from_partial_diagonal(v.as_slice()) TMat2x3::from_partial_diagonal(v.as_slice())
} }
@ -39,14 +39,14 @@ pub fn diagonal2x3<T: Number>(v: &TVec2<T>) -> TMat2x3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`diagonal2x2`](fn.diagonal2x2.html) /// * [`diagonal2x2()`]
/// * [`diagonal2x3`](fn.diagonal2x3.html) /// * [`diagonal2x3()`]
/// * [`diagonal3x2`](fn.diagonal3x2.html) /// * [`diagonal3x2()`]
/// * [`diagonal3x3`](fn.diagonal3x3.html) /// * [`diagonal3x3()`]
/// * [`diagonal3x4`](fn.diagonal3x4.html) /// * [`diagonal3x4()`]
/// * [`diagonal4x2`](fn.diagonal4x2.html) /// * [`diagonal4x2()`]
/// * [`diagonal4x3`](fn.diagonal4x3.html) /// * [`diagonal4x3()`]
/// * [`diagonal4x4`](fn.diagonal4x4.html) /// * [`diagonal4x4()`]
pub fn diagonal2x4<T: Number>(v: &TVec2<T>) -> TMat2x4<T> { pub fn diagonal2x4<T: Number>(v: &TVec2<T>) -> TMat2x4<T> {
TMat2x4::from_partial_diagonal(v.as_slice()) TMat2x4::from_partial_diagonal(v.as_slice())
} }
@ -55,14 +55,14 @@ pub fn diagonal2x4<T: Number>(v: &TVec2<T>) -> TMat2x4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`diagonal2x2`](fn.diagonal2x2.html) /// * [`diagonal2x2()`]
/// * [`diagonal2x3`](fn.diagonal2x3.html) /// * [`diagonal2x3()`]
/// * [`diagonal2x4`](fn.diagonal2x4.html) /// * [`diagonal2x4()`]
/// * [`diagonal3x3`](fn.diagonal3x3.html) /// * [`diagonal3x3()`]
/// * [`diagonal3x4`](fn.diagonal3x4.html) /// * [`diagonal3x4()`]
/// * [`diagonal4x2`](fn.diagonal4x2.html) /// * [`diagonal4x2()`]
/// * [`diagonal4x3`](fn.diagonal4x3.html) /// * [`diagonal4x3()`]
/// * [`diagonal4x4`](fn.diagonal4x4.html) /// * [`diagonal4x4()`]
pub fn diagonal3x2<T: Number>(v: &TVec2<T>) -> TMat3x2<T> { pub fn diagonal3x2<T: Number>(v: &TVec2<T>) -> TMat3x2<T> {
TMat3x2::from_partial_diagonal(v.as_slice()) TMat3x2::from_partial_diagonal(v.as_slice())
} }
@ -71,14 +71,14 @@ pub fn diagonal3x2<T: Number>(v: &TVec2<T>) -> TMat3x2<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`diagonal2x2`](fn.diagonal2x2.html) /// * [`diagonal2x2()`]
/// * [`diagonal2x3`](fn.diagonal2x3.html) /// * [`diagonal2x3()`]
/// * [`diagonal2x4`](fn.diagonal2x4.html) /// * [`diagonal2x4()`]
/// * [`diagonal3x2`](fn.diagonal3x2.html) /// * [`diagonal3x2()`]
/// * [`diagonal3x4`](fn.diagonal3x4.html) /// * [`diagonal3x4()`]
/// * [`diagonal4x2`](fn.diagonal4x2.html) /// * [`diagonal4x2()`]
/// * [`diagonal4x3`](fn.diagonal4x3.html) /// * [`diagonal4x3()`]
/// * [`diagonal4x4`](fn.diagonal4x4.html) /// * [`diagonal4x4()`]
pub fn diagonal3x3<T: Number>(v: &TVec3<T>) -> TMat3<T> { pub fn diagonal3x3<T: Number>(v: &TVec3<T>) -> TMat3<T> {
TMat3::from_diagonal(v) TMat3::from_diagonal(v)
} }
@ -87,14 +87,14 @@ pub fn diagonal3x3<T: Number>(v: &TVec3<T>) -> TMat3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`diagonal2x2`](fn.diagonal2x2.html) /// * [`diagonal2x2()`]
/// * [`diagonal2x3`](fn.diagonal2x3.html) /// * [`diagonal2x3()`]
/// * [`diagonal2x4`](fn.diagonal2x4.html) /// * [`diagonal2x4()`]
/// * [`diagonal3x2`](fn.diagonal3x2.html) /// * [`diagonal3x2()`]
/// * [`diagonal3x3`](fn.diagonal3x3.html) /// * [`diagonal3x3()`]
/// * [`diagonal4x2`](fn.diagonal4x2.html) /// * [`diagonal4x2()`]
/// * [`diagonal4x3`](fn.diagonal4x3.html) /// * [`diagonal4x3()`]
/// * [`diagonal4x4`](fn.diagonal4x4.html) /// * [`diagonal4x4()`]
pub fn diagonal3x4<T: Number>(v: &TVec3<T>) -> TMat3x4<T> { pub fn diagonal3x4<T: Number>(v: &TVec3<T>) -> TMat3x4<T> {
TMat3x4::from_partial_diagonal(v.as_slice()) TMat3x4::from_partial_diagonal(v.as_slice())
} }
@ -103,14 +103,14 @@ pub fn diagonal3x4<T: Number>(v: &TVec3<T>) -> TMat3x4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`diagonal2x2`](fn.diagonal2x2.html) /// * [`diagonal2x2()`]
/// * [`diagonal2x3`](fn.diagonal2x3.html) /// * [`diagonal2x3()`]
/// * [`diagonal2x4`](fn.diagonal2x4.html) /// * [`diagonal2x4()`]
/// * [`diagonal3x2`](fn.diagonal3x2.html) /// * [`diagonal3x2()`]
/// * [`diagonal3x3`](fn.diagonal3x3.html) /// * [`diagonal3x3()`]
/// * [`diagonal3x4`](fn.diagonal3x4.html) /// * [`diagonal3x4()`]
/// * [`diagonal4x3`](fn.diagonal4x3.html) /// * [`diagonal4x3()`]
/// * [`diagonal4x4`](fn.diagonal4x4.html) /// * [`diagonal4x4()`]
pub fn diagonal4x2<T: Number>(v: &TVec2<T>) -> TMat4x2<T> { pub fn diagonal4x2<T: Number>(v: &TVec2<T>) -> TMat4x2<T> {
TMat4x2::from_partial_diagonal(v.as_slice()) TMat4x2::from_partial_diagonal(v.as_slice())
} }
@ -119,14 +119,14 @@ pub fn diagonal4x2<T: Number>(v: &TVec2<T>) -> TMat4x2<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`diagonal2x2`](fn.diagonal2x2.html) /// * [`diagonal2x2()`]
/// * [`diagonal2x3`](fn.diagonal2x3.html) /// * [`diagonal2x3()`]
/// * [`diagonal2x4`](fn.diagonal2x4.html) /// * [`diagonal2x4()`]
/// * [`diagonal3x2`](fn.diagonal3x2.html) /// * [`diagonal3x2()`]
/// * [`diagonal3x3`](fn.diagonal3x3.html) /// * [`diagonal3x3()`]
/// * [`diagonal3x4`](fn.diagonal3x4.html) /// * [`diagonal3x4()`]
/// * [`diagonal4x2`](fn.diagonal4x2.html) /// * [`diagonal4x2()`]
/// * [`diagonal4x4`](fn.diagonal4x4.html) /// * [`diagonal4x4()`]
pub fn diagonal4x3<T: Number>(v: &TVec3<T>) -> TMat4x3<T> { pub fn diagonal4x3<T: Number>(v: &TVec3<T>) -> TMat4x3<T> {
TMat4x3::from_partial_diagonal(v.as_slice()) TMat4x3::from_partial_diagonal(v.as_slice())
} }
@ -135,14 +135,14 @@ pub fn diagonal4x3<T: Number>(v: &TVec3<T>) -> TMat4x3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`diagonal2x2`](fn.diagonal2x2.html) /// * [`diagonal2x2()`]
/// * [`diagonal2x3`](fn.diagonal2x3.html) /// * [`diagonal2x3()`]
/// * [`diagonal2x4`](fn.diagonal2x4.html) /// * [`diagonal2x4()`]
/// * [`diagonal3x2`](fn.diagonal3x2.html) /// * [`diagonal3x2()`]
/// * [`diagonal3x3`](fn.diagonal3x3.html) /// * [`diagonal3x3()`]
/// * [`diagonal3x4`](fn.diagonal3x4.html) /// * [`diagonal3x4()`]
/// * [`diagonal4x2`](fn.diagonal4x2.html) /// * [`diagonal4x2()`]
/// * [`diagonal4x3`](fn.diagonal4x3.html) /// * [`diagonal4x3()`]
pub fn diagonal4x4<T: Number>(v: &TVec4<T>) -> TMat4<T> { pub fn diagonal4x4<T: Number>(v: &TVec4<T>) -> TMat4<T> {
TMat4::from_diagonal(v) TMat4::from_diagonal(v)
} }

View File

@ -5,7 +5,7 @@ use crate::RealNumber;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`distance`](fn.distance.html) /// * [`distance()`](crate::distance)
pub fn distance2<T: RealNumber, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T { pub fn distance2<T: RealNumber, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T {
(p1 - p0).norm_squared() (p1 - p0).norm_squared()
} }
@ -14,9 +14,9 @@ pub fn distance2<T: RealNumber, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>
/// ///
/// # See also: /// # See also:
/// ///
/// * [`l1_norm`](fn.l1_norm.html) /// * [`l1_norm()`]
/// * [`l2_distance`](fn.l2_distance.html) /// * [`l2_distance()`]
/// * [`l2_norm`](fn.l2_norm.html) /// * [`l2_norm()`]
pub fn l1_distance<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T { pub fn l1_distance<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
l1_norm(&(y - x)) l1_norm(&(y - x))
} }
@ -28,27 +28,27 @@ pub fn l1_distance<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>
/// ///
/// # See also: /// # See also:
/// ///
/// * [`l1_distance`](fn.l1_distance.html) /// * [`l1_distance()`]
/// * [`l2_distance`](fn.l2_distance.html) /// * [`l2_distance()`]
/// * [`l2_norm`](fn.l2_norm.html) /// * [`l2_norm()`]
pub fn l1_norm<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> T { pub fn l1_norm<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> T {
crate::comp_add(&v.abs()) crate::comp_add(&v.abs())
} }
/// The l2-norm of `x - y`. /// The l2-norm of `x - y`.
/// ///
/// This is the same value as returned by [`length2`](fn.length2.html) and /// This is the same value as returned by [`length2()`] and
/// [`magnitude2`](fn.magnitude2.html). /// [`magnitude2()`].
/// ///
/// # See also: /// # See also:
/// ///
/// * [`l1_distance`](fn.l1_distance.html) /// * [`l1_distance()`]
/// * [`l1_norm`](fn.l1_norm.html) /// * [`l1_norm()`]
/// * [`l2_norm`](fn.l2_norm.html) /// * [`l2_norm()`]
/// * [`length`](fn.length.html) /// * [`length()`](crate::length)
/// * [`length2`](fn.length2.html) /// * [`length2()`]
/// * [`magnitude`](fn.magnitude.html) /// * [`magnitude()`](crate::magnitude)
/// * [`magnitude2`](fn.magnitude2.html) /// * [`magnitude2()`]
pub fn l2_distance<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T { pub fn l2_distance<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
l2_norm(&(y - x)) l2_norm(&(y - x))
} }
@ -57,33 +57,33 @@ pub fn l2_distance<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>
/// ///
/// This is also known as the Euclidean norm. /// This is also known as the Euclidean norm.
/// ///
/// This is the same value as returned by [`length`](fn.length.html) and /// This is the same value as returned by [`length()`](crate::length) and
/// [`magnitude`](fn.magnitude.html). /// [`magnitude()`](crate::magnitude).
/// ///
/// # See also: /// # See also:
/// ///
/// * [`l1_distance`](fn.l1_distance.html) /// * [`l1_distance()`]
/// * [`l1_norm`](fn.l1_norm.html) /// * [`l1_norm()`]
/// * [`l2_distance`](fn.l2_distance.html) /// * [`l2_distance()`]
/// * [`length`](fn.length.html) /// * [`length()`](crate::length)
/// * [`length2`](fn.length2.html) /// * [`length2()`]
/// * [`magnitude`](fn.magnitude.html) /// * [`magnitude()`](crate::magnitude)
/// * [`magnitude2`](fn.magnitude2.html) /// * [`magnitude2()`]
pub fn l2_norm<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T { pub fn l2_norm<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
x.norm() x.norm()
} }
/// The squared magnitude of `x`. /// The squared magnitude of `x`.
/// ///
/// A synonym for [`magnitude2`](fn.magnitude2.html). /// A synonym for [`magnitude2()`].
/// ///
/// # See also: /// # See also:
/// ///
/// * [`distance`](fn.distance.html) /// * [`distance()`](crate::distance)
/// * [`distance2`](fn.distance2.html) /// * [`distance2()`]
/// * [`length`](fn.length.html) /// * [`length()`](crate::length)
/// * [`magnitude`](fn.magnitude.html) /// * [`magnitude()`](crate::magnitude)
/// * [`magnitude2`](fn.magnitude2.html) /// * [`magnitude2()`]
pub fn length2<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T { pub fn length2<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
x.norm_squared() x.norm_squared()
} }
@ -94,10 +94,10 @@ pub fn length2<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`distance`](fn.distance.html) /// * [`distance()`](crate::distance)
/// * [`distance2`](fn.distance2.html) /// * [`distance2()`]
/// * [`length2`](fn.length2.html) /// * [`length2()`]
/// * [`magnitude`](fn.magnitude.html) /// * [`magnitude()`](crate::magnitude)
/// * [`nalgebra::norm_squared`](../nalgebra/fn.norm_squared.html) /// * [`nalgebra::norm_squared`](../nalgebra/fn.norm_squared.html)
pub fn magnitude2<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T { pub fn magnitude2<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
x.norm_squared() x.norm_squared()

View File

@ -4,11 +4,11 @@ use crate::aliases::TVec;
/// The dot product of the normalized version of `x` and `y`. /// The dot product of the normalized version of `x` and `y`.
/// ///
/// This is currently the same as [`normalize_dot`](fn.normalize_dot.html). /// This is currently the same as [`normalize_dot()`]
/// ///
/// # See also: /// # See also:
/// ///
/// * [`normalize_dot`](fn.normalize_dot.html`) /// * [`normalize_dot()`]
pub fn fast_normalize_dot<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T { pub fn fast_normalize_dot<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
// XXX: improve those. // XXX: improve those.
x.normalize().dot(&y.normalize()) x.normalize().dot(&y.normalize())
@ -18,7 +18,7 @@ pub fn fast_normalize_dot<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVe
/// ///
/// # See also: /// # See also:
/// ///
/// * [`fast_normalize_dot`](fn.fast_normalize_dot.html`) /// * [`fast_normalize_dot()`]
pub fn normalize_dot<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T { pub fn normalize_dot<T: RealNumber, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
// XXX: improve those. // XXX: improve those.
x.normalize().dot(&y.normalize()) x.normalize().dot(&y.normalize())

View File

@ -80,7 +80,7 @@ pub fn quat_to_mat3<T: RealNumber>(x: &Qua<T>) -> TMat3<T> {
.into_inner() .into_inner()
} }
/// Converts a quaternion to a rotation matrix in homogenous coordinates. /// Converts a quaternion to a rotation matrix in homogeneous coordinates.
pub fn quat_to_mat4<T: RealNumber>(x: &Qua<T>) -> TMat4<T> { pub fn quat_to_mat4<T: RealNumber>(x: &Qua<T>) -> TMat4<T> {
UnitQuaternion::new_unchecked(*x).to_homogeneous() UnitQuaternion::new_unchecked(*x).to_homogeneous()
} }
@ -93,6 +93,6 @@ pub fn mat3_to_quat<T: RealNumber>(x: &TMat3<T>) -> Qua<T> {
/// Converts a rotation matrix in homogeneous coordinates to a quaternion. /// Converts a rotation matrix in homogeneous coordinates to a quaternion.
pub fn to_quat<T: RealNumber>(x: &TMat4<T>) -> Qua<T> { pub fn to_quat<T: RealNumber>(x: &TMat4<T>) -> Qua<T> {
let rot = x.fixed_slice::<3, 3>(0, 0).into_owned(); let rot = x.fixed_view::<3, 3>(0, 0).into_owned();
mat3_to_quat(&rot) mat3_to_quat(&rot)
} }

View File

@ -7,11 +7,11 @@ use crate::traits::{Number, RealNumber};
/// ///
/// # See also: /// # See also:
/// ///
/// * [`scaling`](fn.scaling.html) /// * [`scaling()`]
/// * [`translation`](fn.translation.html) /// * [`translation()`]
/// * [`rotation2d`](fn.rotation2d.html) /// * [`rotation2d()`]
/// * [`scaling2d`](fn.scaling2d.html) /// * [`scaling2d()`]
/// * [`translation2d`](fn.translation2d.html) /// * [`translation2d()`]
pub fn rotation<T: RealNumber>(angle: T, v: &TVec3<T>) -> TMat4<T> { pub fn rotation<T: RealNumber>(angle: T, v: &TVec3<T>) -> TMat4<T> {
Rotation3::from_axis_angle(&Unit::new_normalize(*v), angle).to_homogeneous() Rotation3::from_axis_angle(&Unit::new_normalize(*v), angle).to_homogeneous()
} }
@ -20,11 +20,11 @@ pub fn rotation<T: RealNumber>(angle: T, v: &TVec3<T>) -> TMat4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotation`](fn.rotation.html) /// * [`rotation()`]
/// * [`translation`](fn.translation.html) /// * [`translation()`]
/// * [`rotation2d`](fn.rotation2d.html) /// * [`rotation2d()`]
/// * [`scaling2d`](fn.scaling2d.html) /// * [`scaling2d()`]
/// * [`translation2d`](fn.translation2d.html) /// * [`translation2d()`]
pub fn scaling<T: Number>(v: &TVec3<T>) -> TMat4<T> { pub fn scaling<T: Number>(v: &TVec3<T>) -> TMat4<T> {
TMat4::new_nonuniform_scaling(v) TMat4::new_nonuniform_scaling(v)
} }
@ -33,11 +33,11 @@ pub fn scaling<T: Number>(v: &TVec3<T>) -> TMat4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotation`](fn.rotation.html) /// * [`rotation()`]
/// * [`scaling`](fn.scaling.html) /// * [`scaling()`]
/// * [`rotation2d`](fn.rotation2d.html) /// * [`rotation2d()`]
/// * [`scaling2d`](fn.scaling2d.html) /// * [`scaling2d()`]
/// * [`translation2d`](fn.translation2d.html) /// * [`translation2d()`]
pub fn translation<T: Number>(v: &TVec3<T>) -> TMat4<T> { pub fn translation<T: Number>(v: &TVec3<T>) -> TMat4<T> {
TMat4::new_translation(v) TMat4::new_translation(v)
} }
@ -46,11 +46,11 @@ pub fn translation<T: Number>(v: &TVec3<T>) -> TMat4<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotation`](fn.rotation.html) /// * [`rotation()`]
/// * [`scaling`](fn.scaling.html) /// * [`scaling()`]
/// * [`translation`](fn.translation.html) /// * [`translation()`]
/// * [`scaling2d`](fn.scaling2d.html) /// * [`scaling2d()`]
/// * [`translation2d`](fn.translation2d.html) /// * [`translation2d()`]
pub fn rotation2d<T: RealNumber>(angle: T) -> TMat3<T> { pub fn rotation2d<T: RealNumber>(angle: T) -> TMat3<T> {
Rotation2::new(angle).to_homogeneous() Rotation2::new(angle).to_homogeneous()
} }
@ -59,11 +59,11 @@ pub fn rotation2d<T: RealNumber>(angle: T) -> TMat3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotation`](fn.rotation.html) /// * [`rotation()`]
/// * [`scaling`](fn.scaling.html) /// * [`scaling()`]
/// * [`translation`](fn.translation.html) /// * [`translation()`]
/// * [`rotation2d`](fn.rotation2d.html) /// * [`rotation2d()`]
/// * [`translation2d`](fn.translation2d.html) /// * [`translation2d()`]
pub fn scaling2d<T: Number>(v: &TVec2<T>) -> TMat3<T> { pub fn scaling2d<T: Number>(v: &TVec2<T>) -> TMat3<T> {
TMat3::new_nonuniform_scaling(v) TMat3::new_nonuniform_scaling(v)
} }
@ -72,11 +72,11 @@ pub fn scaling2d<T: Number>(v: &TVec2<T>) -> TMat3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotation`](fn.rotation.html) /// * [`rotation()`]
/// * [`scaling`](fn.scaling.html) /// * [`scaling()`]
/// * [`translation`](fn.translation.html) /// * [`translation()`]
/// * [`rotation2d`](fn.rotation2d.html) /// * [`rotation2d()`]
/// * [`scaling2d`](fn.scaling2d.html) /// * [`scaling2d()`]
pub fn translation2d<T: Number>(v: &TVec2<T>) -> TMat3<T> { pub fn translation2d<T: Number>(v: &TVec2<T>) -> TMat3<T> {
TMat3::new_translation(v) TMat3::new_translation(v)
} }

View File

@ -7,7 +7,7 @@ pub fn proj2d<T: Number>(m: &TMat3<T>, normal: &TVec2<T>) -> TMat3<T> {
let mut res = TMat3::identity(); let mut res = TMat3::identity();
{ {
let mut part = res.fixed_slice_mut::<2, 2>(0, 0); let mut part = res.fixed_view_mut::<2, 2>(0, 0);
part -= normal * normal.transpose(); part -= normal * normal.transpose();
} }
@ -19,7 +19,7 @@ pub fn proj<T: Number>(m: &TMat4<T>, normal: &TVec3<T>) -> TMat4<T> {
let mut res = TMat4::identity(); let mut res = TMat4::identity();
{ {
let mut part = res.fixed_slice_mut::<3, 3>(0, 0); let mut part = res.fixed_view_mut::<3, 3>(0, 0);
part -= normal * normal.transpose(); part -= normal * normal.transpose();
} }
@ -31,7 +31,7 @@ pub fn reflect2d<T: RealNumber>(m: &TMat3<T>, normal: &TVec2<T>) -> TMat3<T> {
let mut res = TMat3::identity(); let mut res = TMat3::identity();
{ {
let mut part = res.fixed_slice_mut::<2, 2>(0, 0); let mut part = res.fixed_view_mut::<2, 2>(0, 0);
part -= (normal * T::from_subset(&2.0)) * normal.transpose(); part -= (normal * T::from_subset(&2.0)) * normal.transpose();
} }
@ -43,7 +43,7 @@ pub fn reflect<T: RealNumber>(m: &TMat4<T>, normal: &TVec3<T>) -> TMat4<T> {
let mut res = TMat4::identity(); let mut res = TMat4::identity();
{ {
let mut part = res.fixed_slice_mut::<3, 3>(0, 0); let mut part = res.fixed_view_mut::<3, 3>(0, 0);
part -= (normal * T::from_subset(&2.0)) * normal.transpose(); part -= (normal * T::from_subset(&2.0)) * normal.transpose();
} }

View File

@ -7,11 +7,11 @@ use crate::traits::{Number, RealNumber};
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotation2d`](fn.rotation2d.html) /// * [`rotation2d()`](crate::rotation2d)
/// * [`scale2d`](fn.scale2d.html) /// * [`scale2d()`]
/// * [`scaling2d`](fn.scaling2d.html) /// * [`scaling2d()`](crate::scaling2d)
/// * [`translate2d`](fn.translate2d.html) /// * [`translate2d()`]
/// * [`translation2d`](fn.translation2d.html) /// * [`translation2d()`](crate::translation2d)
pub fn rotate2d<T: RealNumber>(m: &TMat3<T>, angle: T) -> TMat3<T> { pub fn rotate2d<T: RealNumber>(m: &TMat3<T>, angle: T) -> TMat3<T> {
m * UnitComplex::new(angle).to_homogeneous() m * UnitComplex::new(angle).to_homogeneous()
} }
@ -20,11 +20,11 @@ pub fn rotate2d<T: RealNumber>(m: &TMat3<T>, angle: T) -> TMat3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotate2d`](fn.rotate2d.html) /// * [`rotate2d()`]
/// * [`rotation2d`](fn.rotation2d.html) /// * [`rotation2d()`](crate::rotation2d)
/// * [`scaling2d`](fn.scaling2d.html) /// * [`scaling2d()`](crate::scaling2d)
/// * [`translate2d`](fn.translate2d.html) /// * [`translate2d()`]
/// * [`translation2d`](fn.translation2d.html) /// * [`translation2d()`](crate::translation2d)
pub fn scale2d<T: Number>(m: &TMat3<T>, v: &TVec2<T>) -> TMat3<T> { pub fn scale2d<T: Number>(m: &TMat3<T>, v: &TVec2<T>) -> TMat3<T> {
m.prepend_nonuniform_scaling(v) m.prepend_nonuniform_scaling(v)
} }
@ -33,11 +33,11 @@ pub fn scale2d<T: Number>(m: &TMat3<T>, v: &TVec2<T>) -> TMat3<T> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`rotate2d`](fn.rotate2d.html) /// * [`rotate2d()`]
/// * [`rotation2d`](fn.rotation2d.html) /// * [`rotation2d()`](crate::rotation2d)
/// * [`scale2d`](fn.scale2d.html) /// * [`scale2d()`]
/// * [`scaling2d`](fn.scaling2d.html) /// * [`scaling2d()`](crate::scaling2d)
/// * [`translation2d`](fn.translation2d.html) /// * [`translation2d()`](crate::translation2d)
pub fn translate2d<T: Number>(m: &TMat3<T>, v: &TVec2<T>) -> TMat3<T> { pub fn translate2d<T: Number>(m: &TMat3<T>, v: &TVec2<T>) -> TMat3<T> {
m.prepend_translation(v) m.prepend_translation(v)
} }

View File

@ -7,7 +7,7 @@ use crate::traits::Number;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`are_collinear2d`](fn.are_collinear2d.html) /// * [`are_collinear2d()`]
pub fn are_collinear<T: Number>(v0: &TVec3<T>, v1: &TVec3<T>, epsilon: T) -> bool { pub fn are_collinear<T: Number>(v0: &TVec3<T>, v1: &TVec3<T>, epsilon: T) -> bool {
is_null(&v0.cross(v1), epsilon) is_null(&v0.cross(v1), epsilon)
} }
@ -16,7 +16,7 @@ pub fn are_collinear<T: Number>(v0: &TVec3<T>, v1: &TVec3<T>, epsilon: T) -> boo
/// ///
/// # See also: /// # See also:
/// ///
/// * [`are_collinear`](fn.are_collinear.html) /// * [`are_collinear()`]
pub fn are_collinear2d<T: Number>(v0: &TVec2<T>, v1: &TVec2<T>, epsilon: T) -> bool { pub fn are_collinear2d<T: Number>(v0: &TVec2<T>, v1: &TVec2<T>, epsilon: T) -> bool {
abs_diff_eq!(v0.perp(v1), T::zero(), epsilon = epsilon) abs_diff_eq!(v0.perp(v1), T::zero(), epsilon = epsilon)
} }
@ -41,7 +41,10 @@ pub fn is_comp_null<T: Number, const D: usize>(v: &TVec<T, D>, epsilon: T) -> TV
/// Returns `true` if `v` has a magnitude of 1 (up to an epsilon). /// Returns `true` if `v` has a magnitude of 1 (up to an epsilon).
pub fn is_normalized<T: RealNumber, const D: usize>(v: &TVec<T, D>, epsilon: T) -> bool { pub fn is_normalized<T: RealNumber, const D: usize>(v: &TVec<T, D>, epsilon: T) -> bool {
abs_diff_eq!(v.norm_squared(), T::one(), epsilon = epsilon * epsilon) // sqrt(1 + epsilon_{norm²} = 1 + epsilon_{norm}
// ==> epsilon_{norm²} = epsilon_{norm}² + 2*epsilon_{norm}
// For small epsilon, epsilon² is basically zero, so use 2*epsilon.
abs_diff_eq!(v.norm_squared(), T::one(), epsilon = epsilon + epsilon)
} }
/// Returns `true` if `v` is zero (up to an epsilon). /// Returns `true` if `v` is zero (up to an epsilon).

View File

@ -38,7 +38,7 @@
* All function names use `snake_case`, which is the Rust convention. * All function names use `snake_case`, which is the Rust convention.
* All type names use `CamelCase`, which is the Rust convention. * All type names use `CamelCase`, which is the Rust convention.
* All function arguments, except for scalars, are all passed by-reference. * All function arguments, except for scalars, are all passed by-reference.
* The most generic vector and matrix types are [`TMat`](type.TMat.html) and [`TVec`](type.TVec.html) instead of `mat` and `vec`. * The most generic vector and matrix types are [`TMat`] and [`TVec`] instead of `mat` and `vec`.
* Some feature are not yet implemented and should be added in the future. In particular, no packing * Some feature are not yet implemented and should be added in the future. In particular, no packing
functions are available. functions are available.
* A few features are not implemented and will never be. This includes functions related to color * A few features are not implemented and will never be. This includes functions related to color
@ -47,17 +47,17 @@
In addition, because Rust does not allows function overloading, all functions must be given a unique name. In addition, because Rust does not allows function overloading, all functions must be given a unique name.
Here are a few rules chosen arbitrarily for **nalgebra-glm**: Here are a few rules chosen arbitrarily for **nalgebra-glm**:
* Functions operating in 2d will usually end with the `2d` suffix, e.g., [`glm::rotate2d`](fn.rotate2d.html) is for 2D while [`glm::rotate`](fn.rotate.html) is for 3D. * Functions operating in 2d will usually end with the `2d` suffix, e.g., [`glm::rotate2d()`](crate::rotate2d) is for 2D while [`glm::rotate()`](crate::rotate) is for 3D.
* Functions operating on vectors will often end with the `_vec` suffix, possibly followed by the dimension of vector, e.g., [`glm::rotate_vec2`](fn.rotate_vec2.html). * Functions operating on vectors will often end with the `_vec` suffix, possibly followed by the dimension of vector, e.g., [`glm::rotate_vec2()`](crate::rotate_vec2).
* Every function related to quaternions start with the `quat_` prefix, e.g., [`glm::quat_dot(q1, q2)`](fn.quat_dot.html). * Every function related to quaternions start with the `quat_` prefix, e.g., [`glm::quat_dot(q1, q2)`](crate::quat_dot).
* All the conversion functions have unique names as described [below](#conversions). * All the conversion functions have unique names as described [below](#conversions).
### Vector and matrix construction ### Vector and matrix construction
Vectors, matrices, and quaternions can be constructed using several approaches: Vectors, matrices, and quaternions can be constructed using several approaches:
* Using functions with the same name as their type in lower-case. For example [`glm::vec3(x, y, z)`](fn.vec3.html) will create a 3D vector. * Using functions with the same name as their type in lower-case. For example [`glm::vec3(x, y, z)`](crate::vec3) will create a 3D vector.
* Using the `::new` constructor. For example [`Vec3::new(x, y, z)`](../nalgebra/base/type.OMatrix.html#method.new-27) will create a 3D vector. * Using the `::new` constructor. For example [`Vec3::new(x, y, z)`](../nalgebra/base/type.OMatrix.html#method.new-27) will create a 3D vector.
* Using the functions prefixed by `make_` to build a vector a matrix from a slice. For example [`glm::make_vec3(&[x, y, z])`](fn.make_vec3.html) will create a 3D vector. * Using the functions prefixed by `make_` to build a vector a matrix from a slice. For example [`glm::make_vec3(&[x, y, z])`](crate::make_vec3) will create a 3D vector.
Keep in mind that constructing a matrix using this type of functions require its components to be arranged in column-major order on the slice. Keep in mind that constructing a matrix using this type of functions require its components to be arranged in column-major order on the slice.
* Using a geometric construction function. For example [`glm::rotation(angle, axis)`](fn.rotation.html) will build a 4x4 homogeneous rotation matrix from an angle (in radians) and an axis. * Using a geometric construction function. For example [`glm::rotation(angle, axis)`](crate::rotation) will build a 4x4 homogeneous rotation matrix from an angle (in radians) and an axis.
* Using swizzling and conversions as described in the next sections. * Using swizzling and conversions as described in the next sections.
### Swizzling ### Swizzling
Vector swizzling is a native feature of **nalgebra** itself. Therefore, you can use it with all Vector swizzling is a native feature of **nalgebra** itself. Therefore, you can use it with all
@ -75,9 +75,9 @@
It is often useful to convert one algebraic type to another. There are two main approaches for converting It is often useful to convert one algebraic type to another. There are two main approaches for converting
between types in `nalgebra-glm`: between types in `nalgebra-glm`:
* Using function with the form `type1_to_type2` in order to convert an instance of `type1` into an instance of `type2`. * Using function with the form `type1_to_type2` in order to convert an instance of `type1` into an instance of `type2`.
For example [`glm::mat3_to_mat4(m)`](fn.mat3_to_mat4.html) will convert the 3x3 matrix `m` to a 4x4 matrix by appending one column on the right For example [`glm::mat3_to_mat4(m)`](crate::mat3_to_mat4) will convert the 3x3 matrix `m` to a 4x4 matrix by appending one column on the right
and one row on the left. Those now row and columns are filled with 0 except for the diagonal element which is set to 1. and one row on the left. Those now row and columns are filled with 0 except for the diagonal element which is set to 1.
* Using one of the [`convert`](fn.convert.html), [`try_convert`](fn.try_convert.html), or [`convert_unchecked`](fn.convert_unchecked.html) functions. * Using one of the [`convert`](crate::convert), [`try_convert`](crate::try_convert), or [`convert_unchecked`](crate::convert_unchecked) functions.
These functions are directly re-exported from nalgebra and are extremely versatile: These functions are directly re-exported from nalgebra and are extremely versatile:
1. The `convert` function can convert any type (especially geometric types from nalgebra like `Isometry3`) into another algebraic type which is equivalent but more general. For example, 1. The `convert` function can convert any type (especially geometric types from nalgebra like `Isometry3`) into another algebraic type which is equivalent but more general. For example,
`let sim: Similarity3<_> = na::convert(isometry)` will convert an `Isometry3` into a `Similarity3`. `let sim: Similarity3<_> = na::convert(isometry)` will convert an `Isometry3` into a `Similarity3`.

View File

@ -1,7 +1,6 @@
use approx::AbsDiffEq; use approx::AbsDiffEq;
use num::{Bounded, Signed}; use num::{Bounded, Signed};
use core::cmp::PartialOrd;
use na::Scalar; use na::Scalar;
use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub, RealField}; use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub, RealField};

View File

@ -1,5 +1,3 @@
use na;
use crate::aliases::TVec; use crate::aliases::TVec;
use crate::RealNumber; use crate::RealNumber;

View File

@ -16,8 +16,8 @@ use crate::traits::Number;
/// ///
/// # See also: /// # See also:
/// ///
/// * [`any`](fn.any.html) /// * [`any()`]
/// * [`not`](fn.not.html) /// * [`not()`]
pub fn all<const D: usize>(v: &TVec<bool, D>) -> bool { pub fn all<const D: usize>(v: &TVec<bool, D>) -> bool {
v.iter().all(|x| *x) v.iter().all(|x| *x)
} }
@ -40,8 +40,8 @@ pub fn all<const D: usize>(v: &TVec<bool, D>) -> bool {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`all`](fn.all.html) /// * [`all()`]
/// * [`not`](fn.not.html) /// * [`not()`]
pub fn any<const D: usize>(v: &TVec<bool, D>) -> bool { pub fn any<const D: usize>(v: &TVec<bool, D>) -> bool {
v.iter().any(|x| *x) v.iter().any(|x| *x)
} }
@ -59,12 +59,12 @@ pub fn any<const D: usize>(v: &TVec<bool, D>) -> bool {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`greater_than`](fn.greater_than.html) /// * [`greater_than()`]
/// * [`greater_than_equal`](fn.greater_than_equal.html) /// * [`greater_than_equal()`]
/// * [`less_than`](fn.less_than.html) /// * [`less_than()`]
/// * [`less_than_equal`](fn.less_than_equal.html) /// * [`less_than_equal()`]
/// * [`not`](fn.not.html) /// * [`not()`]
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal()`]
pub fn equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> { pub fn equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
x.zip_map(y, |x, y| x == y) x.zip_map(y, |x, y| x == y)
} }
@ -82,12 +82,12 @@ pub fn equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<
/// ///
/// # See also: /// # See also:
/// ///
/// * [`equal`](fn.equal.html) /// * [`equal()`]
/// * [`greater_than_equal`](fn.greater_than_equal.html) /// * [`greater_than_equal()`]
/// * [`less_than`](fn.less_than.html) /// * [`less_than()`]
/// * [`less_than_equal`](fn.less_than_equal.html) /// * [`less_than_equal()`]
/// * [`not`](fn.not.html) /// * [`not()`]
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal()`]
pub fn greater_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> { pub fn greater_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
x.zip_map(y, |x, y| x > y) x.zip_map(y, |x, y| x > y)
} }
@ -105,12 +105,12 @@ pub fn greater_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -
/// ///
/// # See also: /// # See also:
/// ///
/// * [`equal`](fn.equal.html) /// * [`equal()`]
/// * [`greater_than`](fn.greater_than.html) /// * [`greater_than()`]
/// * [`less_than`](fn.less_than.html) /// * [`less_than()`]
/// * [`less_than_equal`](fn.less_than_equal.html) /// * [`less_than_equal()`]
/// * [`not`](fn.not.html) /// * [`not()`]
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal()`]
pub fn greater_than_equal<T: Number, const D: usize>( pub fn greater_than_equal<T: Number, const D: usize>(
x: &TVec<T, D>, x: &TVec<T, D>,
y: &TVec<T, D>, y: &TVec<T, D>,
@ -131,17 +131,17 @@ pub fn greater_than_equal<T: Number, const D: usize>(
/// ///
/// # See also: /// # See also:
/// ///
/// * [`equal`](fn.equal.html) /// * [`equal()`]
/// * [`greater_than`](fn.greater_than.html) /// * [`greater_than()`]
/// * [`greater_than_equal`](fn.greater_than_equal.html) /// * [`greater_than_equal()`]
/// * [`less_than_equal`](fn.less_than_equal.html) /// * [`less_than_equal()`]
/// * [`not`](fn.not.html) /// * [`not()`]
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal()`]
pub fn less_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> { pub fn less_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
x.zip_map(y, |x, y| x < y) x.zip_map(y, |x, y| x < y)
} }
/// Component-wise `>=` comparison. /// Component-wise `<=` comparison.
/// ///
/// # Examples: /// # Examples:
/// ///
@ -154,12 +154,12 @@ pub fn less_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T
/// ///
/// # See also: /// # See also:
/// ///
/// * [`equal`](fn.equal.html) /// * [`equal()`]
/// * [`greater_than`](fn.greater_than.html) /// * [`greater_than()`]
/// * [`greater_than_equal`](fn.greater_than_equal.html) /// * [`greater_than_equal()`]
/// * [`less_than`](fn.less_than.html) /// * [`less_than()`]
/// * [`not`](fn.not.html) /// * [`not()`]
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal()`]
pub fn less_than_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> { pub fn less_than_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
x.zip_map(y, |x, y| x <= y) x.zip_map(y, |x, y| x <= y)
} }
@ -176,14 +176,14 @@ pub fn less_than_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>
/// ///
/// # See also: /// # See also:
/// ///
/// * [`all`](fn.all.html) /// * [`all()`]
/// * [`any`](fn.any.html) /// * [`any()`]
/// * [`equal`](fn.equal.html) /// * [`equal()`]
/// * [`greater_than`](fn.greater_than.html) /// * [`greater_than()`]
/// * [`greater_than_equal`](fn.greater_than_equal.html) /// * [`greater_than_equal()`]
/// * [`less_than`](fn.less_than.html) /// * [`less_than()`]
/// * [`less_than_equal`](fn.less_than_equal.html) /// * [`less_than_equal()`]
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal()`]
pub fn not<const D: usize>(v: &TVec<bool, D>) -> TVec<bool, D> { pub fn not<const D: usize>(v: &TVec<bool, D>) -> TVec<bool, D> {
v.map(|x| !x) v.map(|x| !x)
} }
@ -201,12 +201,12 @@ pub fn not<const D: usize>(v: &TVec<bool, D>) -> TVec<bool, D> {
/// ///
/// # See also: /// # See also:
/// ///
/// * [`equal`](fn.equal.html) /// * [`equal()`]
/// * [`greater_than`](fn.greater_than.html) /// * [`greater_than()`]
/// * [`greater_than_equal`](fn.greater_than_equal.html) /// * [`greater_than_equal()`]
/// * [`less_than`](fn.less_than.html) /// * [`less_than()`]
/// * [`less_than_equal`](fn.less_than_equal.html) /// * [`less_than_equal()`]
/// * [`not`](fn.not.html) /// * [`not()`]
pub fn not_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> { pub fn not_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
x.zip_map(y, |x, y| x != y) x.zip_map(y, |x, y| x != y)
} }

View File

@ -1,6 +1,6 @@
[package] [package]
name = "nalgebra-lapack" name = "nalgebra-lapack"
version = "0.21.0" version = "0.24.0"
authors = [ "Sébastien Crozet <developer@crozet.re>", "Andrew Straw <strawman@astraw.com>" ] authors = [ "Sébastien Crozet <developer@crozet.re>", "Andrew Straw <strawman@astraw.com>" ]
description = "Matrix decompositions using nalgebra matrices and Lapack bindings." description = "Matrix decompositions using nalgebra matrices and Lapack bindings."
@ -10,7 +10,7 @@ repository = "https://github.com/dimforge/nalgebra"
readme = "../README.md" readme = "../README.md"
categories = [ "science", "mathematics" ] categories = [ "science", "mathematics" ]
keywords = [ "linear", "algebra", "matrix", "vector", "lapack" ] keywords = [ "linear", "algebra", "matrix", "vector", "lapack" ]
license = "BSD-3-Clause" license = "MIT"
edition = "2018" edition = "2018"
[badges] [badges]
@ -29,18 +29,19 @@ accelerate = ["lapack-src/accelerate"]
intel-mkl = ["lapack-src/intel-mkl"] intel-mkl = ["lapack-src/intel-mkl"]
[dependencies] [dependencies]
nalgebra = { version = "0.30", path = ".." } nalgebra = { version = "0.32", path = ".." }
num-traits = "0.2" num-traits = "0.2"
num-complex = { version = "0.4", default-features = false } num-complex = { version = "0.4", default-features = false }
simba = "0.7" simba = "0.8"
serde = { version = "1.0", features = [ "derive" ], optional = true } serde = { version = "1.0", features = [ "derive" ], optional = true }
lapack = { version = "0.19", default-features = false } lapack = { version = "0.19", default-features = false }
lapack-src = { version = "0.8", default-features = false } lapack-src = { version = "0.8", default-features = false }
# clippy = "*" # clippy = "*"
[dev-dependencies] [dev-dependencies]
nalgebra = { version = "0.30", features = [ "arbitrary", "rand" ], path = ".." } nalgebra = { version = "0.32", features = [ "arbitrary", "rand" ], path = ".." }
proptest = { version = "1", default-features = false, features = ["std"] } proptest = { version = "1", default-features = false, features = ["std"] }
quickcheck = "1" quickcheck = "1"
approx = "0.5" approx = "0.5"
rand = "0.8" rand = "0.8"

View File

@ -7,13 +7,12 @@ use num_complex::Complex;
use simba::scalar::RealField; use simba::scalar::RealField;
use crate::ComplexHelper; use crate::ComplexHelper;
use na::allocator::Allocator;
use na::dimension::{Const, Dim}; use na::dimension::{Const, Dim};
use na::{DefaultAllocator, Matrix, OMatrix, OVector, Scalar}; use na::{allocator::Allocator, DefaultAllocator, Matrix, OMatrix, OVector, Scalar};
use lapack; use lapack;
/// Eigendecomposition of a real square matrix with real eigenvalues. /// Eigendecomposition of a real square matrix with real or complex eigenvalues.
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
@ -36,8 +35,10 @@ pub struct Eigen<T: Scalar, D: Dim>
where where
DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>, DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
{ {
/// The eigenvalues of the decomposed matrix. /// The real parts of eigenvalues of the decomposed matrix.
pub eigenvalues: OVector<T, D>, pub eigenvalues_re: OVector<T, D>,
/// The imaginary parts of the eigenvalues of the decomposed matrix.
pub eigenvalues_im: OVector<T, D>,
/// The (right) eigenvectors of the decomposed matrix. /// The (right) eigenvectors of the decomposed matrix.
pub eigenvectors: Option<OMatrix<T, D, D>>, pub eigenvectors: Option<OMatrix<T, D, D>>,
/// The left eigenvectors of the decomposed matrix. /// The left eigenvectors of the decomposed matrix.
@ -69,8 +70,8 @@ where
"Unable to compute the eigenvalue decomposition of a non-square matrix." "Unable to compute the eigenvalue decomposition of a non-square matrix."
); );
let ljob = if left_eigenvectors { b'V' } else { b'T' }; let ljob = if left_eigenvectors { b'V' } else { b'N' };
let rjob = if eigenvectors { b'V' } else { b'T' }; let rjob = if eigenvectors { b'V' } else { b'N' };
let (nrows, ncols) = m.shape_generic(); let (nrows, ncols) = m.shape_generic();
let n = nrows.value(); let n = nrows.value();
@ -104,213 +105,231 @@ where
lapack_check!(info); lapack_check!(info);
let mut work = vec![T::zero(); lwork as usize]; let mut work = vec![T::zero(); lwork as usize];
let mut vl = if left_eigenvectors {
match (left_eigenvectors, eigenvectors) { Some(Matrix::zeros_generic(nrows, ncols))
(true, true) => { } else {
// TODO: avoid the initializations?
let mut vl = Matrix::zeros_generic(nrows, ncols);
let mut vr = Matrix::zeros_generic(nrows, ncols);
T::xgeev(
ljob,
rjob,
n as i32,
m.as_mut_slice(),
lda,
wr.as_mut_slice(),
wi.as_mut_slice(),
&mut vl.as_mut_slice(),
n as i32,
&mut vr.as_mut_slice(),
n as i32,
&mut work,
lwork,
&mut info,
);
lapack_check!(info);
if wi.iter().all(|e| e.is_zero()) {
return Some(Self {
eigenvalues: wr,
left_eigenvectors: Some(vl),
eigenvectors: Some(vr),
});
}
}
(true, false) => {
// TODO: avoid the initialization?
let mut vl = Matrix::zeros_generic(nrows, ncols);
T::xgeev(
ljob,
rjob,
n as i32,
m.as_mut_slice(),
lda,
wr.as_mut_slice(),
wi.as_mut_slice(),
&mut vl.as_mut_slice(),
n as i32,
&mut placeholder2,
1 as i32,
&mut work,
lwork,
&mut info,
);
lapack_check!(info);
if wi.iter().all(|e| e.is_zero()) {
return Some(Self {
eigenvalues: wr,
left_eigenvectors: Some(vl),
eigenvectors: None,
});
}
}
(false, true) => {
// TODO: avoid the initialization?
let mut vr = Matrix::zeros_generic(nrows, ncols);
T::xgeev(
ljob,
rjob,
n as i32,
m.as_mut_slice(),
lda,
wr.as_mut_slice(),
wi.as_mut_slice(),
&mut placeholder1,
1 as i32,
&mut vr.as_mut_slice(),
n as i32,
&mut work,
lwork,
&mut info,
);
lapack_check!(info);
if wi.iter().all(|e| e.is_zero()) {
return Some(Self {
eigenvalues: wr,
left_eigenvectors: None,
eigenvectors: Some(vr),
});
}
}
(false, false) => {
T::xgeev(
ljob,
rjob,
n as i32,
m.as_mut_slice(),
lda,
wr.as_mut_slice(),
wi.as_mut_slice(),
&mut placeholder1,
1 as i32,
&mut placeholder2,
1 as i32,
&mut work,
lwork,
&mut info,
);
lapack_check!(info);
if wi.iter().all(|e| e.is_zero()) {
return Some(Self {
eigenvalues: wr,
left_eigenvectors: None,
eigenvectors: None,
});
}
}
}
None None
} };
let mut vr = if eigenvectors {
Some(Matrix::zeros_generic(nrows, ncols))
} else {
None
};
/// The complex eigenvalues of the given matrix. let vl_ref = vl
/// .as_mut()
/// Panics if the eigenvalue computation does not converge. .map(|m| m.as_mut_slice())
pub fn complex_eigenvalues(mut m: OMatrix<T, D, D>) -> OVector<Complex<T>, D> .unwrap_or(&mut placeholder1);
where let vr_ref = vr
DefaultAllocator: Allocator<Complex<T>, D>, .as_mut()
{ .map(|m| m.as_mut_slice())
assert!( .unwrap_or(&mut placeholder2);
m.is_square(),
"Unable to compute the eigenvalue decomposition of a non-square matrix."
);
let nrows = m.shape_generic().0;
let n = nrows.value();
let lda = n as i32;
// TODO: avoid the initialization?
let mut wr = Matrix::zeros_generic(nrows, Const::<1>);
let mut wi = Matrix::zeros_generic(nrows, Const::<1>);
let mut info = 0;
let mut placeholder1 = [T::zero()];
let mut placeholder2 = [T::zero()];
let lwork = T::xgeev_work_size(
b'T',
b'T',
n as i32,
m.as_mut_slice(),
lda,
wr.as_mut_slice(),
wi.as_mut_slice(),
&mut placeholder1,
n as i32,
&mut placeholder2,
n as i32,
&mut info,
);
lapack_panic!(info);
let mut work = vec![T::zero(); lwork as usize];
T::xgeev( T::xgeev(
b'T', ljob,
b'T', rjob,
n as i32, n as i32,
m.as_mut_slice(), m.as_mut_slice(),
lda, lda,
wr.as_mut_slice(), wr.as_mut_slice(),
wi.as_mut_slice(), wi.as_mut_slice(),
&mut placeholder1, vl_ref,
1 as i32, if left_eigenvectors { n as i32 } else { 1 },
&mut placeholder2, vr_ref,
1 as i32, if eigenvectors { n as i32 } else { 1 },
&mut work, &mut work,
lwork, lwork,
&mut info, &mut info,
); );
lapack_panic!(info); lapack_check!(info);
let mut res = Matrix::zeros_generic(nrows, Const::<1>); Some(Self {
eigenvalues_re: wr,
for i in 0..res.len() { eigenvalues_im: wi,
res[i] = Complex::new(wr[i].clone(), wi[i].clone()); left_eigenvectors: vl,
eigenvectors: vr,
})
} }
res /// Returns `true` if all the eigenvalues are real.
pub fn eigenvalues_are_real(&self) -> bool {
self.eigenvalues_im.iter().all(|e| e.is_zero())
} }
/// The determinant of the decomposed matrix. /// The determinant of the decomposed matrix.
#[inline] #[inline]
#[must_use] #[must_use]
pub fn determinant(&self) -> T { pub fn determinant(&self) -> Complex<T> {
let mut det = T::one(); let mut det: Complex<T> = na::one();
for e in self.eigenvalues.iter() { for (re, im) in self.eigenvalues_re.iter().zip(self.eigenvalues_im.iter()) {
det *= e.clone(); det *= Complex::new(re.clone(), im.clone());
} }
det det
} }
/// Returns a tuple of vectors. The elements of the tuple are the real parts of the eigenvalues, left eigenvectors and right eigenvectors respectively.
pub fn get_real_elements(
&self,
) -> (
Vec<T>,
Option<Vec<OVector<T, D>>>,
Option<Vec<OVector<T, D>>>,
)
where
DefaultAllocator: Allocator<T, D>,
{
let (number_of_elements, _) = self.eigenvalues_re.shape_generic();
let number_of_elements_value = number_of_elements.value();
let mut eigenvalues = Vec::<T>::with_capacity(number_of_elements_value);
let mut eigenvectors = match self.eigenvectors.is_some() {
true => Some(Vec::<OVector<T, D>>::with_capacity(
number_of_elements_value,
)),
false => None,
};
let mut left_eigenvectors = match self.left_eigenvectors.is_some() {
true => Some(Vec::<OVector<T, D>>::with_capacity(
number_of_elements_value,
)),
false => None,
};
let mut c = 0;
while c < number_of_elements_value {
eigenvalues.push(self.eigenvalues_re[c].clone());
if eigenvectors.is_some() {
eigenvectors
.as_mut()
.unwrap()
.push(self.eigenvectors.as_ref().unwrap().column(c).into_owned());
}
if left_eigenvectors.is_some() {
left_eigenvectors.as_mut().unwrap().push(
self.left_eigenvectors
.as_ref()
.unwrap()
.column(c)
.into_owned(),
);
}
if self.eigenvalues_im[c] != T::zero() {
//skip next entry
c += 1;
}
c += 1;
}
(eigenvalues, left_eigenvectors, eigenvectors)
}
/// Returns a tuple of vectors. The elements of the tuple are the complex eigenvalues, complex left eigenvectors and complex right eigenvectors respectively.
/// The elements appear as conjugate pairs within each vector, with the positive of the pair always being first.
pub fn get_complex_elements(
&self,
) -> (
Option<Vec<Complex<T>>>,
Option<Vec<OVector<Complex<T>, D>>>,
Option<Vec<OVector<Complex<T>, D>>>,
)
where
DefaultAllocator: Allocator<Complex<T>, D>,
{
match self.eigenvalues_are_real() {
true => (None, None, None),
false => {
let (number_of_elements, _) = self.eigenvalues_re.shape_generic();
let number_of_elements_value = number_of_elements.value();
let number_of_complex_entries =
self.eigenvalues_im
.iter()
.fold(0, |acc, e| if !e.is_zero() { acc + 1 } else { acc });
let mut eigenvalues = Vec::<Complex<T>>::with_capacity(number_of_complex_entries);
let mut eigenvectors = match self.eigenvectors.is_some() {
true => Some(Vec::<OVector<Complex<T>, D>>::with_capacity(
number_of_complex_entries,
)),
false => None,
};
let mut left_eigenvectors = match self.left_eigenvectors.is_some() {
true => Some(Vec::<OVector<Complex<T>, D>>::with_capacity(
number_of_complex_entries,
)),
false => None,
};
let mut c = 0;
while c < number_of_elements_value {
if self.eigenvalues_im[c] != T::zero() {
//Complex conjugate pairs of eigenvalues appear consecutively with the eigenvalue having the positive imaginary part first.
eigenvalues.push(Complex::<T>::new(
self.eigenvalues_re[c].clone(),
self.eigenvalues_im[c].clone(),
));
eigenvalues.push(Complex::<T>::new(
self.eigenvalues_re[c + 1].clone(),
self.eigenvalues_im[c + 1].clone(),
));
if eigenvectors.is_some() {
let mut vec = OVector::<Complex<T>, D>::zeros_generic(
number_of_elements,
Const::<1>,
);
let mut vec_conj = OVector::<Complex<T>, D>::zeros_generic(
number_of_elements,
Const::<1>,
);
for r in 0..number_of_elements_value {
vec[r] = Complex::<T>::new(
self.eigenvectors.as_ref().unwrap()[(r, c)].clone(),
self.eigenvectors.as_ref().unwrap()[(r, c + 1)].clone(),
);
vec_conj[r] = Complex::<T>::new(
self.eigenvectors.as_ref().unwrap()[(r, c)].clone(),
self.eigenvectors.as_ref().unwrap()[(r, c + 1)].clone(),
);
}
eigenvectors.as_mut().unwrap().push(vec);
eigenvectors.as_mut().unwrap().push(vec_conj);
}
if left_eigenvectors.is_some() {
let mut vec = OVector::<Complex<T>, D>::zeros_generic(
number_of_elements,
Const::<1>,
);
let mut vec_conj = OVector::<Complex<T>, D>::zeros_generic(
number_of_elements,
Const::<1>,
);
for r in 0..number_of_elements_value {
vec[r] = Complex::<T>::new(
self.left_eigenvectors.as_ref().unwrap()[(r, c)].clone(),
self.left_eigenvectors.as_ref().unwrap()[(r, c + 1)].clone(),
);
vec_conj[r] = Complex::<T>::new(
self.left_eigenvectors.as_ref().unwrap()[(r, c)].clone(),
self.left_eigenvectors.as_ref().unwrap()[(r, c + 1)].clone(),
);
}
left_eigenvectors.as_mut().unwrap().push(vec);
left_eigenvectors.as_mut().unwrap().push(vec_conj);
}
//skip next entry
c += 1;
}
c += 1;
}
(Some(eigenvalues), left_eigenvectors, eigenvectors)
}
}
}
} }
/* /*

View File

@ -0,0 +1,350 @@
#[cfg(feature = "serde-serialize")]
use serde::{Deserialize, Serialize};
use num::Zero;
use num_complex::Complex;
use simba::scalar::RealField;
use crate::ComplexHelper;
use na::allocator::Allocator;
use na::dimension::{Const, Dim};
use na::{DefaultAllocator, Matrix, OMatrix, OVector, Scalar};
use lapack;
/// Generalized eigenvalues and generalized eigenvectors (left and right) of a pair of N*N real square matrices.
///
/// Each generalized eigenvalue (lambda) satisfies determinant(A - lambda*B) = 0
///
/// The right eigenvector v(j) corresponding to the eigenvalue lambda(j)
/// of (A,B) satisfies
///
/// A * v(j) = lambda(j) * B * v(j).
///
/// The left eigenvector u(j) corresponding to the eigenvalue lambda(j)
/// of (A,B) satisfies
///
/// u(j)**H * A = lambda(j) * u(j)**H * B .
/// where u(j)**H is the conjugate-transpose of u(j).
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-serialize",
serde(
bound(serialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OVector<T, D>: Serialize,
OMatrix<T, D, D>: Serialize")
)
)]
#[cfg_attr(
feature = "serde-serialize",
serde(
bound(deserialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OVector<T, D>: Deserialize<'de>,
OMatrix<T, D, D>: Deserialize<'de>")
)
)]
#[derive(Clone, Debug)]
pub struct GeneralizedEigen<T: Scalar, D: Dim>
where
DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
{
alphar: OVector<T, D>,
alphai: OVector<T, D>,
beta: OVector<T, D>,
vsl: OMatrix<T, D, D>,
vsr: OMatrix<T, D, D>,
}
impl<T: Scalar + Copy, D: Dim> Copy for GeneralizedEigen<T, D>
where
DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OMatrix<T, D, D>: Copy,
OVector<T, D>: Copy,
{
}
impl<T: GeneralizedEigenScalar + RealField + Copy, D: Dim> GeneralizedEigen<T, D>
where
DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
{
/// Attempts to compute the generalized eigenvalues, and left and right associated eigenvectors
/// via the raw returns from LAPACK's dggev and sggev routines
///
/// Panics if the method did not converge.
pub fn new(a: OMatrix<T, D, D>, b: OMatrix<T, D, D>) -> Self {
Self::try_new(a, b).expect("Calculation of generalized eigenvalues failed.")
}
/// Attempts to compute the generalized eigenvalues (and eigenvectors) via the raw returns from LAPACK's
/// dggev and sggev routines
///
/// Returns `None` if the method did not converge.
pub fn try_new(mut a: OMatrix<T, D, D>, mut b: OMatrix<T, D, D>) -> Option<Self> {
assert!(
a.is_square() && b.is_square(),
"Unable to compute the generalized eigenvalues of non-square matrices."
);
assert!(
a.shape_generic() == b.shape_generic(),
"Unable to compute the generalized eigenvalues of two square matrices of different dimensions."
);
let (nrows, ncols) = a.shape_generic();
let n = nrows.value();
let mut info = 0;
let mut alphar = Matrix::zeros_generic(nrows, Const::<1>);
let mut alphai = Matrix::zeros_generic(nrows, Const::<1>);
let mut beta = Matrix::zeros_generic(nrows, Const::<1>);
let mut vsl = Matrix::zeros_generic(nrows, ncols);
let mut vsr = Matrix::zeros_generic(nrows, ncols);
let lwork = T::xggev_work_size(
b'V',
b'V',
n as i32,
a.as_mut_slice(),
n as i32,
b.as_mut_slice(),
n as i32,
alphar.as_mut_slice(),
alphai.as_mut_slice(),
beta.as_mut_slice(),
vsl.as_mut_slice(),
n as i32,
vsr.as_mut_slice(),
n as i32,
&mut info,
);
lapack_check!(info);
let mut work = vec![T::zero(); lwork as usize];
T::xggev(
b'V',
b'V',
n as i32,
a.as_mut_slice(),
n as i32,
b.as_mut_slice(),
n as i32,
alphar.as_mut_slice(),
alphai.as_mut_slice(),
beta.as_mut_slice(),
vsl.as_mut_slice(),
n as i32,
vsr.as_mut_slice(),
n as i32,
&mut work,
lwork,
&mut info,
);
lapack_check!(info);
Some(GeneralizedEigen {
alphar,
alphai,
beta,
vsl,
vsr,
})
}
/// Calculates the generalized eigenvectors (left and right) associated with the generalized eigenvalues
///
/// Outputs two matrices.
/// The first output matrix contains the left eigenvectors of the generalized eigenvalues
/// as columns.
/// The second matrix contains the right eigenvectors of the generalized eigenvalues
/// as columns.
pub fn eigenvectors(&self) -> (OMatrix<Complex<T>, D, D>, OMatrix<Complex<T>, D, D>)
where
DefaultAllocator:
Allocator<Complex<T>, D, D> + Allocator<Complex<T>, D> + Allocator<(Complex<T>, T), D>,
{
/*
How the eigenvectors are built up:
Since the input entries are all real, the generalized eigenvalues if complex come in pairs
as a consequence of the [complex conjugate root thorem](https://en.wikipedia.org/wiki/Complex_conjugate_root_theorem)
The Lapack routine output reflects this by expecting the user to unpack the real and complex eigenvalues associated
eigenvectors from the real matrix output via the following procedure
(Note: VL stands for the lapack real matrix output containing the left eigenvectors as columns,
VR stands for the lapack real matrix output containing the right eigenvectors as columns)
If the j-th and (j+1)-th eigenvalues form a complex conjugate pair,
then
u(j) = VL(:,j)+i*VL(:,j+1)
u(j+1) = VL(:,j)-i*VL(:,j+1)
and
u(j) = VR(:,j)+i*VR(:,j+1)
v(j+1) = VR(:,j)-i*VR(:,j+1).
*/
let n = self.vsl.shape().0;
let mut l = self.vsl.map(|x| Complex::new(x, T::RealField::zero()));
let mut r = self.vsr.map(|x| Complex::new(x, T::RealField::zero()));
let eigenvalues = self.raw_eigenvalues();
let mut c = 0;
while c < n {
if eigenvalues[c].0.im.abs() != T::RealField::zero() && c + 1 < n {
// taking care of the left eigenvector matrix
l.column_mut(c).zip_apply(&self.vsl.column(c + 1), |r, i| {
*r = Complex::new(r.re.clone(), i.clone());
});
l.column_mut(c + 1).zip_apply(&self.vsl.column(c), |i, r| {
*i = Complex::new(r.clone(), -i.re.clone());
});
// taking care of the right eigenvector matrix
r.column_mut(c).zip_apply(&self.vsr.column(c + 1), |r, i| {
*r = Complex::new(r.re.clone(), i.clone());
});
r.column_mut(c + 1).zip_apply(&self.vsr.column(c), |i, r| {
*i = Complex::new(r.clone(), -i.re.clone());
});
c += 2;
} else {
c += 1;
}
}
(l, r)
}
/// Outputs the unprocessed (almost) version of generalized eigenvalues ((alphar, alphai), beta)
/// straight from LAPACK
#[must_use]
pub fn raw_eigenvalues(&self) -> OVector<(Complex<T>, T), D>
where
DefaultAllocator: Allocator<(Complex<T>, T), D>,
{
let mut out = Matrix::from_element_generic(
self.vsl.shape_generic().0,
Const::<1>,
(Complex::zero(), T::RealField::zero()),
);
for i in 0..out.len() {
out[i] = (Complex::new(self.alphar[i], self.alphai[i]), self.beta[i])
}
out
}
}
/*
*
* Lapack functions dispatch.
*
*/
/// Trait implemented by scalars for which Lapack implements the RealField GeneralizedEigen decomposition.
pub trait GeneralizedEigenScalar: Scalar {
#[allow(missing_docs)]
fn xggev(
jobvsl: u8,
jobvsr: u8,
n: i32,
a: &mut [Self],
lda: i32,
b: &mut [Self],
ldb: i32,
alphar: &mut [Self],
alphai: &mut [Self],
beta: &mut [Self],
vsl: &mut [Self],
ldvsl: i32,
vsr: &mut [Self],
ldvsr: i32,
work: &mut [Self],
lwork: i32,
info: &mut i32,
);
#[allow(missing_docs)]
fn xggev_work_size(
jobvsl: u8,
jobvsr: u8,
n: i32,
a: &mut [Self],
lda: i32,
b: &mut [Self],
ldb: i32,
alphar: &mut [Self],
alphai: &mut [Self],
beta: &mut [Self],
vsl: &mut [Self],
ldvsl: i32,
vsr: &mut [Self],
ldvsr: i32,
info: &mut i32,
) -> i32;
}
macro_rules! generalized_eigen_scalar_impl (
($N: ty, $xggev: path) => (
impl GeneralizedEigenScalar for $N {
#[inline]
fn xggev(jobvsl: u8,
jobvsr: u8,
n: i32,
a: &mut [$N],
lda: i32,
b: &mut [$N],
ldb: i32,
alphar: &mut [$N],
alphai: &mut [$N],
beta : &mut [$N],
vsl: &mut [$N],
ldvsl: i32,
vsr: &mut [$N],
ldvsr: i32,
work: &mut [$N],
lwork: i32,
info: &mut i32) {
unsafe { $xggev(jobvsl, jobvsr, n, a, lda, b, ldb, alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr, work, lwork, info); }
}
#[inline]
fn xggev_work_size(jobvsl: u8,
jobvsr: u8,
n: i32,
a: &mut [$N],
lda: i32,
b: &mut [$N],
ldb: i32,
alphar: &mut [$N],
alphai: &mut [$N],
beta : &mut [$N],
vsl: &mut [$N],
ldvsl: i32,
vsr: &mut [$N],
ldvsr: i32,
info: &mut i32)
-> i32 {
let mut work = [ Zero::zero() ];
let lwork = -1 as i32;
unsafe { $xggev(jobvsl, jobvsr, n, a, lda, b, ldb, alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr, &mut work, lwork, info); }
ComplexHelper::real_part(work[0]) as i32
}
}
)
);
generalized_eigen_scalar_impl!(f32, lapack::sggev);
generalized_eigen_scalar_impl!(f64, lapack::dggev);

View File

@ -83,9 +83,11 @@ mod lapack_check;
mod cholesky; mod cholesky;
mod eigen; mod eigen;
mod generalized_eigenvalues;
mod hessenberg; mod hessenberg;
mod lu; mod lu;
mod qr; mod qr;
mod qz;
mod schur; mod schur;
mod svd; mod svd;
mod symmetric_eigen; mod symmetric_eigen;
@ -94,9 +96,11 @@ use num_complex::Complex;
pub use self::cholesky::{Cholesky, CholeskyScalar}; pub use self::cholesky::{Cholesky, CholeskyScalar};
pub use self::eigen::Eigen; pub use self::eigen::Eigen;
pub use self::generalized_eigenvalues::GeneralizedEigen;
pub use self::hessenberg::Hessenberg; pub use self::hessenberg::Hessenberg;
pub use self::lu::{LUScalar, LU}; pub use self::lu::{LUScalar, LU};
pub use self::qr::QR; pub use self::qr::QR;
pub use self::qz::QZ;
pub use self::schur::Schur; pub use self::schur::Schur;
pub use self::svd::SVD; pub use self::svd::SVD;
pub use self::symmetric_eigen::SymmetricEigen; pub use self::symmetric_eigen::SymmetricEigen;

View File

@ -126,7 +126,7 @@ where
let mut q = self let mut q = self
.qr .qr
.generic_slice((0, 0), (nrows, min_nrows_ncols)) .generic_view((0, 0), (nrows, min_nrows_ncols))
.into_owned(); .into_owned();
let mut info = 0; let mut info = 0;

321
nalgebra-lapack/src/qz.rs Normal file
View File

@ -0,0 +1,321 @@
#[cfg(feature = "serde-serialize")]
use serde::{Deserialize, Serialize};
use num::Zero;
use num_complex::Complex;
use simba::scalar::RealField;
use crate::ComplexHelper;
use na::allocator::Allocator;
use na::dimension::{Const, Dim};
use na::{DefaultAllocator, Matrix, OMatrix, OVector, Scalar};
use lapack;
/// QZ decomposition of a pair of N*N square matrices.
///
/// Retrieves the left and right matrices of Schur Vectors (VSL and VSR)
/// the upper-quasitriangular matrix `S` and upper triangular matrix `T` such that the
/// decomposed input matrix `a` equals `VSL * S * VSL.transpose()` and
/// decomposed input matrix `b` equals `VSL * T * VSL.transpose()`.
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "serde-serialize",
serde(
bound(serialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OVector<T, D>: Serialize,
OMatrix<T, D, D>: Serialize")
)
)]
#[cfg_attr(
feature = "serde-serialize",
serde(
bound(deserialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OVector<T, D>: Deserialize<'de>,
OMatrix<T, D, D>: Deserialize<'de>")
)
)]
#[derive(Clone, Debug)]
pub struct QZ<T: Scalar, D: Dim>
where
DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
{
alphar: OVector<T, D>,
alphai: OVector<T, D>,
beta: OVector<T, D>,
vsl: OMatrix<T, D, D>,
s: OMatrix<T, D, D>,
vsr: OMatrix<T, D, D>,
t: OMatrix<T, D, D>,
}
impl<T: Scalar + Copy, D: Dim> Copy for QZ<T, D>
where
DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
OMatrix<T, D, D>: Copy,
OVector<T, D>: Copy,
{
}
impl<T: QZScalar + RealField, D: Dim> QZ<T, D>
where
DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
{
/// Attempts to compute the QZ decomposition of input real square matrices `a` and `b`.
///
/// i.e retrieves the left and right matrices of Schur Vectors (VSL and VSR)
/// the upper-quasitriangular matrix `S` and upper triangular matrix `T` such that the
/// decomposed matrix `a` equals `VSL * S * VSL.transpose()` and
/// decomposed matrix `b` equals `VSL * T * VSL.transpose()`.
///
/// Panics if the method did not converge.
pub fn new(a: OMatrix<T, D, D>, b: OMatrix<T, D, D>) -> Self {
Self::try_new(a, b).expect("QZ decomposition: convergence failed.")
}
/// Computes the decomposition of input matrices `a` and `b` into a pair of matrices of Schur vectors
/// , a quasi-upper triangular matrix and an upper-triangular matrix .
///
/// Returns `None` if the method did not converge.
pub fn try_new(mut a: OMatrix<T, D, D>, mut b: OMatrix<T, D, D>) -> Option<Self> {
assert!(
a.is_square() && b.is_square(),
"Unable to compute the qz decomposition of non-square matrices."
);
assert!(
a.shape_generic() == b.shape_generic(),
"Unable to compute the qz decomposition of two square matrices of different dimensions."
);
let (nrows, ncols) = a.shape_generic();
let n = nrows.value();
let mut info = 0;
let mut alphar = Matrix::zeros_generic(nrows, Const::<1>);
let mut alphai = Matrix::zeros_generic(nrows, Const::<1>);
let mut beta = Matrix::zeros_generic(nrows, Const::<1>);
let mut vsl = Matrix::zeros_generic(nrows, ncols);
let mut vsr = Matrix::zeros_generic(nrows, ncols);
// Placeholders:
let mut bwork = [0i32];
let mut unused = 0;
let lwork = T::xgges_work_size(
b'V',
b'V',
b'N',
n as i32,
a.as_mut_slice(),
n as i32,
b.as_mut_slice(),
n as i32,
&mut unused,
alphar.as_mut_slice(),
alphai.as_mut_slice(),
beta.as_mut_slice(),
vsl.as_mut_slice(),
n as i32,
vsr.as_mut_slice(),
n as i32,
&mut bwork,
&mut info,
);
lapack_check!(info);
let mut work = vec![T::zero(); lwork as usize];
T::xgges(
b'V',
b'V',
b'N',
n as i32,
a.as_mut_slice(),
n as i32,
b.as_mut_slice(),
n as i32,
&mut unused,
alphar.as_mut_slice(),
alphai.as_mut_slice(),
beta.as_mut_slice(),
vsl.as_mut_slice(),
n as i32,
vsr.as_mut_slice(),
n as i32,
&mut work,
lwork,
&mut bwork,
&mut info,
);
lapack_check!(info);
Some(QZ {
alphar,
alphai,
beta,
vsl,
s: a,
vsr,
t: b,
})
}
/// Retrieves the left and right matrices of Schur Vectors (VSL and VSR)
/// the upper-quasitriangular matrix `S` and upper triangular matrix `T` such that the
/// decomposed input matrix `a` equals `VSL * S * VSL.transpose()` and
/// decomposed input matrix `b` equals `VSL * T * VSL.transpose()`.
pub fn unpack(
self,
) -> (
OMatrix<T, D, D>,
OMatrix<T, D, D>,
OMatrix<T, D, D>,
OMatrix<T, D, D>,
) {
(self.vsl, self.s, self.t, self.vsr)
}
/// outputs the unprocessed (almost) version of generalized eigenvalues ((alphar, alpai), beta)
/// straight from LAPACK
#[must_use]
pub fn raw_eigenvalues(&self) -> OVector<(Complex<T>, T), D>
where
DefaultAllocator: Allocator<(Complex<T>, T), D>,
{
let mut out = Matrix::from_element_generic(
self.vsl.shape_generic().0,
Const::<1>,
(Complex::zero(), T::RealField::zero()),
);
for i in 0..out.len() {
out[i] = (
Complex::new(self.alphar[i].clone(), self.alphai[i].clone()),
self.beta[i].clone(),
)
}
out
}
}
/*
*
* Lapack functions dispatch.
*
*/
/// Trait implemented by scalars for which Lapack implements the RealField QZ decomposition.
pub trait QZScalar: Scalar {
#[allow(missing_docs)]
fn xgges(
jobvsl: u8,
jobvsr: u8,
sort: u8,
// select: ???
n: i32,
a: &mut [Self],
lda: i32,
b: &mut [Self],
ldb: i32,
sdim: &mut i32,
alphar: &mut [Self],
alphai: &mut [Self],
beta: &mut [Self],
vsl: &mut [Self],
ldvsl: i32,
vsr: &mut [Self],
ldvsr: i32,
work: &mut [Self],
lwork: i32,
bwork: &mut [i32],
info: &mut i32,
);
#[allow(missing_docs)]
fn xgges_work_size(
jobvsl: u8,
jobvsr: u8,
sort: u8,
// select: ???
n: i32,
a: &mut [Self],
lda: i32,
b: &mut [Self],
ldb: i32,
sdim: &mut i32,
alphar: &mut [Self],
alphai: &mut [Self],
beta: &mut [Self],
vsl: &mut [Self],
ldvsl: i32,
vsr: &mut [Self],
ldvsr: i32,
bwork: &mut [i32],
info: &mut i32,
) -> i32;
}
macro_rules! qz_scalar_impl (
($N: ty, $xgges: path) => (
impl QZScalar for $N {
#[inline]
fn xgges(jobvsl: u8,
jobvsr: u8,
sort: u8,
// select: ???
n: i32,
a: &mut [$N],
lda: i32,
b: &mut [$N],
ldb: i32,
sdim: &mut i32,
alphar: &mut [$N],
alphai: &mut [$N],
beta : &mut [$N],
vsl: &mut [$N],
ldvsl: i32,
vsr: &mut [$N],
ldvsr: i32,
work: &mut [$N],
lwork: i32,
bwork: &mut [i32],
info: &mut i32) {
unsafe { $xgges(jobvsl, jobvsr, sort, None, n, a, lda, b, ldb, sdim, alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr, work, lwork, bwork, info); }
}
#[inline]
fn xgges_work_size(jobvsl: u8,
jobvsr: u8,
sort: u8,
// select: ???
n: i32,
a: &mut [$N],
lda: i32,
b: &mut [$N],
ldb: i32,
sdim: &mut i32,
alphar: &mut [$N],
alphai: &mut [$N],
beta : &mut [$N],
vsl: &mut [$N],
ldvsl: i32,
vsr: &mut [$N],
ldvsr: i32,
bwork: &mut [i32],
info: &mut i32)
-> i32 {
let mut work = [ Zero::zero() ];
let lwork = -1 as i32;
unsafe { $xgges(jobvsl, jobvsr, sort, None, n, a, lda, b, ldb, sdim, alphar, alphai, beta, vsl, ldvsl, vsr, ldvsr, &mut work, lwork, bwork, info); }
ComplexHelper::real_part(work[0]) as i32
}
}
)
);
qz_scalar_impl!(f32, lapack::sgges);
qz_scalar_impl!(f64, lapack::dgges);

View File

@ -157,7 +157,7 @@ macro_rules! svd_impl(
let mut res: OMatrix<_, R, C> = Matrix::zeros_generic(nrows, ncols); let mut res: OMatrix<_, R, C> = Matrix::zeros_generic(nrows, ncols);
{ {
let mut sres = res.generic_slice_mut((0, 0), (min_nrows_ncols, ncols)); let mut sres = res.generic_view_mut((0, 0), (min_nrows_ncols, ncols));
sres.copy_from(&self.vt.rows_generic(0, min_nrows_ncols)); sres.copy_from(&self.vt.rows_generic(0, min_nrows_ncols));
for i in 0 .. min_nrows_ncols.value() { for i in 0 .. min_nrows_ncols.value() {
@ -183,7 +183,7 @@ macro_rules! svd_impl(
let mut res: OMatrix<_, C, R> = Matrix::zeros_generic(ncols, nrows); let mut res: OMatrix<_, C, R> = Matrix::zeros_generic(ncols, nrows);
{ {
let mut sres = res.generic_slice_mut((0, 0), (min_nrows_ncols, nrows)); let mut sres = res.generic_view_mut((0, 0), (min_nrows_ncols, nrows));
self.u.columns_generic(0, min_nrows_ncols).transpose_to(&mut sres); self.u.columns_generic(0, min_nrows_ncols).transpose_to(&mut sres);
for i in 0 .. min_nrows_ncols.value() { for i in 0 .. min_nrows_ncols.value() {

View File

@ -58,8 +58,8 @@ proptest! {
let sol1 = chol.solve(&b1).unwrap(); let sol1 = chol.solve(&b1).unwrap();
let sol2 = chol.solve(&b2).unwrap(); let sol2 = chol.solve(&b2).unwrap();
prop_assert!(relative_eq!(m * sol1, b1, epsilon = 1.0e-7)); prop_assert!(relative_eq!(m * sol1, b1, epsilon = 1.0e-4));
prop_assert!(relative_eq!(m * sol2, b2, epsilon = 1.0e-7)); prop_assert!(relative_eq!(m * sol2, b2, epsilon = 1.0e-4));
} }
} }
@ -84,7 +84,7 @@ proptest! {
let id1 = &m * &m1; let id1 = &m * &m1;
let id2 = &m1 * &m; let id2 = &m1 * &m;
prop_assert!(id1.is_identity(1.0e-5) && id2.is_identity(1.0e-5)) prop_assert!(id1.is_identity(1.0e-4) && id2.is_identity(1.0e-4))
} }
} }
} }

View File

@ -0,0 +1,47 @@
use na::Matrix3;
use nalgebra_lapack::Eigen;
use num_complex::Complex;
#[test]
fn complex_eigen() {
let m = Matrix3::<f64>::new(
4.0 / 5.0,
-3.0 / 5.0,
0.0,
3.0 / 5.0,
4.0 / 5.0,
0.0,
1.0,
2.0,
2.0,
);
let eigen = Eigen::new(m, true, true).expect("Eigen Creation Failed!");
let (some_eigenvalues, some_left_vec, some_right_vec) = eigen.get_complex_elements();
let eigenvalues = some_eigenvalues.expect("Eigenvalues Failed");
let _left_eigenvectors = some_left_vec.expect("Left Eigenvectors Failed");
let eigenvectors = some_right_vec.expect("Right Eigenvectors Failed");
assert_relative_eq!(
eigenvalues[0].re,
Complex::<f64>::new(4.0 / 5.0, 3.0 / 5.0).re
);
assert_relative_eq!(
eigenvalues[0].im,
Complex::<f64>::new(4.0 / 5.0, 3.0 / 5.0).im
);
assert_relative_eq!(
eigenvalues[1].re,
Complex::<f64>::new(4.0 / 5.0, -3.0 / 5.0).re
);
assert_relative_eq!(
eigenvalues[1].im,
Complex::<f64>::new(4.0 / 5.0, -3.0 / 5.0).im
);
assert_relative_eq!(eigenvectors[0][0].re, -12.0 / 32.7871926215100059134410999);
assert_relative_eq!(eigenvectors[0][0].im, -9.0 / 32.7871926215100059134410999);
assert_relative_eq!(eigenvectors[0][1].re, -9.0 / 32.7871926215100059134410999);
assert_relative_eq!(eigenvectors[0][1].im, 12.0 / 32.7871926215100059134410999);
assert_relative_eq!(eigenvectors[0][2].re, 25.0 / 32.7871926215100059134410999);
assert_relative_eq!(eigenvectors[0][2].im, 0.0);
}

View File

@ -0,0 +1,72 @@
use na::dimension::Const;
use na::{DMatrix, OMatrix};
use nl::GeneralizedEigen;
use num_complex::Complex;
use simba::scalar::ComplexField;
use crate::proptest::*;
use proptest::{prop_assert, prop_compose, proptest};
prop_compose! {
fn f64_dynamic_dim_squares()
(n in PROPTEST_MATRIX_DIM)
(a in matrix(PROPTEST_F64,n,n), b in matrix(PROPTEST_F64,n,n)) -> (DMatrix<f64>, DMatrix<f64>){
(a,b)
}}
proptest! {
#[test]
fn ge((a,b) in f64_dynamic_dim_squares()){
let a_c = a.clone().map(|x| Complex::new(x, 0.0));
let b_c = b.clone().map(|x| Complex::new(x, 0.0));
let n = a.shape_generic().0;
let ge = GeneralizedEigen::new(a.clone(), b.clone());
let (vsl,vsr) = ge.clone().eigenvectors();
for (i,(alpha,beta)) in ge.raw_eigenvalues().iter().enumerate() {
let l_a = a_c.clone() * Complex::new(*beta, 0.0);
let l_b = b_c.clone() * *alpha;
prop_assert!(
relative_eq!(
((&l_a - &l_b)*vsr.column(i)).map(|x| x.modulus()),
OMatrix::zeros_generic(n, Const::<1>),
epsilon = 1.0e-5));
prop_assert!(
relative_eq!(
(vsl.column(i).adjoint()*(&l_a - &l_b)).map(|x| x.modulus()),
OMatrix::zeros_generic(Const::<1>, n),
epsilon = 1.0e-5))
};
}
#[test]
fn ge_static(a in matrix4(), b in matrix4()) {
let ge = GeneralizedEigen::new(a.clone(), b.clone());
let a_c =a.clone().map(|x| Complex::new(x, 0.0));
let b_c = b.clone().map(|x| Complex::new(x, 0.0));
let (vsl,vsr) = ge.eigenvectors();
let eigenvalues = ge.raw_eigenvalues();
for (i,(alpha,beta)) in eigenvalues.iter().enumerate() {
let l_a = a_c.clone() * Complex::new(*beta, 0.0);
let l_b = b_c.clone() * *alpha;
prop_assert!(
relative_eq!(
((&l_a - &l_b)*vsr.column(i)).map(|x| x.modulus()),
OMatrix::zeros_generic(Const::<4>, Const::<1>),
epsilon = 1.0e-5));
prop_assert!(
relative_eq!((vsl.column(i).adjoint()*(&l_a - &l_b)).map(|x| x.modulus()),
OMatrix::zeros_generic(Const::<1>, Const::<4>),
epsilon = 1.0e-5))
}
}
}

View File

@ -51,10 +51,10 @@ proptest! {
let tr_sol1 = lup.solve_transpose(&b1).unwrap(); let tr_sol1 = lup.solve_transpose(&b1).unwrap();
let tr_sol2 = lup.solve_transpose(&b2).unwrap(); let tr_sol2 = lup.solve_transpose(&b2).unwrap();
prop_assert!(relative_eq!(&m * sol1, b1, epsilon = 1.0e-7)); prop_assert!(relative_eq!(&m * sol1, b1, epsilon = 1.0e-5));
prop_assert!(relative_eq!(&m * sol2, b2, epsilon = 1.0e-7)); prop_assert!(relative_eq!(&m * sol2, b2, epsilon = 1.0e-5));
prop_assert!(relative_eq!(m.transpose() * tr_sol1, b1, epsilon = 1.0e-7)); prop_assert!(relative_eq!(m.transpose() * tr_sol1, b1, epsilon = 1.0e-5));
prop_assert!(relative_eq!(m.transpose() * tr_sol2, b2, epsilon = 1.0e-7)); prop_assert!(relative_eq!(m.transpose() * tr_sol2, b2, epsilon = 1.0e-5));
} }
#[test] #[test]
@ -68,10 +68,10 @@ proptest! {
let tr_sol1 = lup.solve_transpose(&b1).unwrap(); let tr_sol1 = lup.solve_transpose(&b1).unwrap();
let tr_sol2 = lup.solve_transpose(&b2).unwrap(); let tr_sol2 = lup.solve_transpose(&b2).unwrap();
prop_assert!(relative_eq!(m * sol1, b1, epsilon = 1.0e-7)); prop_assert!(relative_eq!(m * sol1, b1, epsilon = 1.0e-5));
prop_assert!(relative_eq!(m * sol2, b2, epsilon = 1.0e-7)); prop_assert!(relative_eq!(m * sol2, b2, epsilon = 1.0e-5));
prop_assert!(relative_eq!(m.transpose() * tr_sol1, b1, epsilon = 1.0e-7)); prop_assert!(relative_eq!(m.transpose() * tr_sol1, b1, epsilon = 1.0e-5));
prop_assert!(relative_eq!(m.transpose() * tr_sol2, b2, epsilon = 1.0e-7)); prop_assert!(relative_eq!(m.transpose() * tr_sol2, b2, epsilon = 1.0e-5));
} }
#[test] #[test]

View File

@ -1,6 +1,9 @@
mod cholesky; mod cholesky;
mod complex_eigen;
mod generalized_eigenvalues;
mod lu; mod lu;
mod qr; mod qr;
mod qz;
mod real_eigensystem; mod real_eigensystem;
mod schur; mod schur;
mod svd; mod svd;

View File

@ -0,0 +1,34 @@
use na::DMatrix;
use nl::QZ;
use crate::proptest::*;
use proptest::{prop_assert, prop_compose, proptest};
prop_compose! {
fn f64_dynamic_dim_squares()
(n in PROPTEST_MATRIX_DIM)
(a in matrix(PROPTEST_F64,n,n), b in matrix(PROPTEST_F64,n,n)) -> (DMatrix<f64>, DMatrix<f64>){
(a,b)
}}
proptest! {
#[test]
fn qz((a,b) in f64_dynamic_dim_squares()) {
let qz = QZ::new(a.clone(), b.clone());
let (vsl,s,t,vsr) = qz.clone().unpack();
prop_assert!(relative_eq!(&vsl * s * vsr.transpose(), a, epsilon = 1.0e-7));
prop_assert!(relative_eq!(vsl * t * vsr.transpose(), b, epsilon = 1.0e-7));
}
#[test]
fn qz_static(a in matrix4(), b in matrix4()) {
let qz = QZ::new(a.clone(), b.clone());
let (vsl,s,t,vsr) = qz.unpack();
prop_assert!(relative_eq!(&vsl * s * vsr.transpose(), a, epsilon = 1.0e-7));
prop_assert!(relative_eq!(vsl * t * vsr.transpose(), b, epsilon = 1.0e-7));
}
}

View File

@ -13,30 +13,36 @@ proptest! {
let m = DMatrix::<f64>::new_random(n, n); let m = DMatrix::<f64>::new_random(n, n);
if let Some(eig) = Eigen::new(m.clone(), true, true) { if let Some(eig) = Eigen::new(m.clone(), true, true) {
let eigvals = DMatrix::from_diagonal(&eig.eigenvalues); // TODO: test the complex case too.
if eig.eigenvalues_are_real() {
let eigvals = DMatrix::from_diagonal(&eig.eigenvalues_re);
let transformed_eigvectors = &m * eig.eigenvectors.as_ref().unwrap(); let transformed_eigvectors = &m * eig.eigenvectors.as_ref().unwrap();
let scaled_eigvectors = eig.eigenvectors.as_ref().unwrap() * &eigvals; let scaled_eigvectors = eig.eigenvectors.as_ref().unwrap() * &eigvals;
let transformed_left_eigvectors = m.transpose() * eig.left_eigenvectors.as_ref().unwrap(); let transformed_left_eigvectors = m.transpose() * eig.left_eigenvectors.as_ref().unwrap();
let scaled_left_eigvectors = eig.left_eigenvectors.as_ref().unwrap() * &eigvals; let scaled_left_eigvectors = eig.left_eigenvectors.as_ref().unwrap() * &eigvals;
prop_assert!(relative_eq!(transformed_eigvectors, scaled_eigvectors, epsilon = 1.0e-7)); prop_assert!(relative_eq!(transformed_eigvectors, scaled_eigvectors, epsilon = 1.0e-5));
prop_assert!(relative_eq!(transformed_left_eigvectors, scaled_left_eigvectors, epsilon = 1.0e-7)); prop_assert!(relative_eq!(transformed_left_eigvectors, scaled_left_eigvectors, epsilon = 1.0e-5));
}
} }
} }
#[test] #[test]
fn eigensystem_static(m in matrix4()) { fn eigensystem_static(m in matrix4()) {
if let Some(eig) = Eigen::new(m, true, true) { if let Some(eig) = Eigen::new(m, true, true) {
let eigvals = Matrix4::from_diagonal(&eig.eigenvalues); // TODO: test the complex case too.
if eig.eigenvalues_are_real() {
let eigvals = Matrix4::from_diagonal(&eig.eigenvalues_re);
let transformed_eigvectors = m * eig.eigenvectors.unwrap(); let transformed_eigvectors = m * eig.eigenvectors.unwrap();
let scaled_eigvectors = eig.eigenvectors.unwrap() * eigvals; let scaled_eigvectors = eig.eigenvectors.unwrap() * eigvals;
let transformed_left_eigvectors = m.transpose() * eig.left_eigenvectors.unwrap(); let transformed_left_eigvectors = m.transpose() * eig.left_eigenvectors.unwrap();
let scaled_left_eigvectors = eig.left_eigenvectors.unwrap() * eigvals; let scaled_left_eigvectors = eig.left_eigenvectors.unwrap() * eigvals;
prop_assert!(relative_eq!(transformed_eigvectors, scaled_eigvectors, epsilon = 1.0e-7)); prop_assert!(relative_eq!(transformed_eigvectors, scaled_eigvectors, epsilon = 1.0e-5));
prop_assert!(relative_eq!(transformed_left_eigvectors, scaled_left_eigvectors, epsilon = 1.0e-7)); prop_assert!(relative_eq!(transformed_left_eigvectors, scaled_left_eigvectors, epsilon = 1.0e-5));
}
} }
} }
} }

View File

@ -11,14 +11,17 @@ proptest! {
let n = cmp::max(1, cmp::min(n, 10)); let n = cmp::max(1, cmp::min(n, 10));
let m = DMatrix::<f64>::new_random(n, n); let m = DMatrix::<f64>::new_random(n, n);
let (vecs, vals) = Schur::new(m.clone()).unpack(); if let Some(schur) = Schur::try_new(m.clone()) {
let (vecs, vals) = schur.unpack();
prop_assert!(relative_eq!(&vecs * vals * vecs.transpose(), m, epsilon = 1.0e-7)) prop_assert!(relative_eq!(&vecs * vals * vecs.transpose(), m, epsilon = 1.0e-5))
}
} }
#[test] #[test]
fn schur_static(m in matrix4()) { fn schur_static(m in matrix4()) {
let (vecs, vals) = Schur::new(m.clone()).unpack(); if let Some(schur) = Schur::try_new(m.clone()) {
prop_assert!(relative_eq!(vecs * vals * vecs.transpose(), m, epsilon = 1.0e-7)) let (vecs, vals) = schur.unpack();
prop_assert!(relative_eq!(vecs * vals * vecs.transpose(), m, epsilon = 1.0e-5))
}
} }
} }

View File

@ -1,6 +1,6 @@
[package] [package]
name = "nalgebra-macros" name = "nalgebra-macros"
version = "0.1.0" version = "0.2.1"
authors = [ "Andreas Longva", "Sébastien Crozet <developer@crozet.re>" ] authors = [ "Andreas Longva", "Sébastien Crozet <developer@crozet.re>" ]
edition = "2018" edition = "2018"
description = "Procedural macros for nalgebra" description = "Procedural macros for nalgebra"
@ -21,5 +21,5 @@ quote = "1.0"
proc-macro2 = "1.0" proc-macro2 = "1.0"
[dev-dependencies] [dev-dependencies]
nalgebra = { version = "0.30.0", path = ".." } nalgebra = { version = "0.32.0", path = ".." }
trybuild = "1.0.42" trybuild = "1.0.42"

1
nalgebra-macros/LICENSE Symbolic link
View File

@ -0,0 +1 @@
../LICENSE

View File

@ -191,8 +191,8 @@ pub fn dmatrix(stream: TokenStream) -> TokenStream {
let output = quote! { let output = quote! {
nalgebra::DMatrix::<_> nalgebra::DMatrix::<_>
::from_vec_storage(nalgebra::VecStorage::new( ::from_vec_storage(nalgebra::VecStorage::new(
nalgebra::Dynamic::new(#row_dim), nalgebra::Dyn(#row_dim),
nalgebra::Dynamic::new(#col_dim), nalgebra::Dyn(#col_dim),
vec!#array_tokens)) vec!#array_tokens))
}; };
@ -223,7 +223,7 @@ impl Parse for Vector {
elements: Vec::new(), elements: Vec::new(),
}) })
} else { } else {
let elements = MatrixRowSyntax::parse_separated_nonempty(input)? let elements = MatrixRowSyntax::parse_terminated(input)?
.into_iter() .into_iter()
.collect(); .collect();
Ok(Self { elements }) Ok(Self { elements })
@ -285,7 +285,7 @@ pub fn dvector(stream: TokenStream) -> TokenStream {
let output = quote! { let output = quote! {
nalgebra::DVector::<_> nalgebra::DVector::<_>
::from_vec_storage(nalgebra::VecStorage::new( ::from_vec_storage(nalgebra::VecStorage::new(
nalgebra::Dynamic::new(#len), nalgebra::Dyn(#len),
nalgebra::Const::<1>, nalgebra::Const::<1>,
vec!#array_tokens)) vec!#array_tokens))
}; };

View File

@ -94,6 +94,12 @@ fn dmatrix_small_dims_exhaustive() {
DMatrix::from_row_slice(4, 4, &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16])); DMatrix::from_row_slice(4, 4, &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]));
} }
#[test]
fn matrix_trailing_semi() {
matrix![1, 2;];
dmatrix![1, 2;];
}
// Skip rustfmt because it just makes the test bloated without making it more readable // Skip rustfmt because it just makes the test bloated without making it more readable
#[rustfmt::skip] #[rustfmt::skip]
#[test] #[test]
@ -151,6 +157,13 @@ fn dvector_small_dims_exhaustive() {
assert_eq_and_type!(dvector![1, 2, 3, 4, 5, 6], DVector::from_column_slice(&[1, 2, 3, 4, 5, 6])); assert_eq_and_type!(dvector![1, 2, 3, 4, 5, 6], DVector::from_column_slice(&[1, 2, 3, 4, 5, 6]));
} }
#[test]
fn vector_trailing_comma() {
vector![1, 2,];
point![1, 2,];
dvector![1, 2,];
}
#[test] #[test]
fn matrix_trybuild_tests() { fn matrix_trybuild_tests() {
let t = trybuild::TestCases::new(); let t = trybuild::TestCases::new();

View File

@ -1,6 +1,6 @@
[package] [package]
name = "nalgebra-sparse" name = "nalgebra-sparse"
version = "0.6.0" version = "0.9.0"
authors = [ "Andreas Longva", "Sébastien Crozet <developer@crozet.re>" ] authors = [ "Andreas Longva", "Sébastien Crozet <developer@crozet.re>" ]
edition = "2018" edition = "2018"
description = "Sparse matrix computation based on nalgebra." description = "Sparse matrix computation based on nalgebra."
@ -24,7 +24,7 @@ io = [ "pest", "pest_derive" ]
slow-tests = [] slow-tests = []
[dependencies] [dependencies]
nalgebra = { version="0.30", path = "../" } nalgebra = { version="0.32", path = "../" }
num-traits = { version = "0.2", default-features = false } num-traits = { version = "0.2", default-features = false }
proptest = { version = "1.0", optional = true } proptest = { version = "1.0", optional = true }
matrixcompare-core = { version = "0.1.0", optional = true } matrixcompare-core = { version = "0.1.0", optional = true }
@ -35,9 +35,10 @@ serde = { version = "1.0", default-features = false, features = [ "derive" ], op
[dev-dependencies] [dev-dependencies]
itertools = "0.10" itertools = "0.10"
matrixcompare = { version = "0.3.0", features = [ "proptest-support" ] } matrixcompare = { version = "0.3.0", features = [ "proptest-support" ] }
nalgebra = { version="0.30", path = "../", features = ["compare"] } nalgebra = { version="0.32", path = "../", features = ["compare"] }
tempfile = "3.3"
serde_json = "1.0" serde_json = "1.0"
[package.metadata.docs.rs] [package.metadata.docs.rs]
# Enable certain features when building docs for docs.rs # Enable certain features when building docs for docs.rs
features = [ "proptest-support", "compare" ] features = [ "proptest-support", "compare", "io"]

1
nalgebra-sparse/LICENSE Symbolic link
View File

@ -0,0 +1 @@
../LICENSE

View File

@ -306,7 +306,7 @@ where
|val| sorted_vals.push(val), |val| sorted_vals.push(val),
&idx_workspace[..count], &idx_workspace[..count],
&values_workspace[..count], &values_workspace[..count],
&Add::add, Add::add,
); );
let new_col_count = sorted_minor_idx.len() - sorted_ja_current_len; let new_col_count = sorted_minor_idx.len() - sorted_ja_current_len;

View File

@ -160,6 +160,25 @@ impl<T> CooMatrix<T> {
} }
} }
/// Try to construct a COO matrix from the given dimensions and a finite iterator of
/// (i, j, v) triplets.
///
/// Returns an error if either row or column indices contain indices out of bounds.
/// Note that the COO format inherently supports duplicate entries, but they are not
/// eagerly summed.
///
/// Implementation note:
/// Calls try_from_triplets so each value is scanned twice.
pub fn try_from_triplets_iter(
nrows: usize,
ncols: usize,
triplets: impl IntoIterator<Item = (usize, usize, T)>,
) -> Result<Self, SparseFormatError> {
let (row_indices, (col_indices, values)) =
triplets.into_iter().map(|(r, c, v)| (r, (c, v))).unzip();
Self::try_from_triplets(nrows, ncols, row_indices, col_indices, values)
}
/// An iterator over triplets (i, j, v). /// An iterator over triplets (i, j, v).
// TODO: Consider giving the iterator a concrete type instead of impl trait...? // TODO: Consider giving the iterator a concrete type instead of impl trait...?
pub fn triplet_iter(&self) -> impl Iterator<Item = (usize, usize, &T)> { pub fn triplet_iter(&self) -> impl Iterator<Item = (usize, usize, &T)> {
@ -170,6 +189,16 @@ impl<T> CooMatrix<T> {
.map(|((i, j), v)| (*i, *j, v)) .map(|((i, j), v)| (*i, *j, v))
} }
/// A mutable iterator over triplets (i, j, v).
// TODO: Consider giving the iterator a concrete type instead of impl trait...?
pub fn triplet_iter_mut(&mut self) -> impl Iterator<Item = (usize, usize, &mut T)> {
self.row_indices
.iter()
.zip(&self.col_indices)
.zip(self.values.iter_mut())
.map(|((i, j), v)| (*i, *j, v))
}
/// Reserves capacity for COO matrix by at least `additional` elements. /// Reserves capacity for COO matrix by at least `additional` elements.
/// ///
/// This increase the capacities of triplet holding arrays by reserving more space to avoid /// This increase the capacities of triplet holding arrays by reserving more space to avoid
@ -211,6 +240,13 @@ impl<T> CooMatrix<T> {
self.values.push(v); self.values.push(v);
} }
/// Clear all triplets from the matrix.
pub fn clear_triplets(&mut self) {
self.col_indices.clear();
self.row_indices.clear();
self.values.clear();
}
/// The number of rows in the matrix. /// The number of rows in the matrix.
#[inline] #[inline]
#[must_use] #[must_use]

View File

@ -1,4 +1,3 @@
use std::mem::replace;
use std::ops::Range; use std::ops::Range;
use num_traits::One; use num_traits::One;
@ -226,6 +225,15 @@ impl<T> CsMatrix<T> {
} }
} }
impl<T> Default for CsMatrix<T> {
fn default() -> Self {
Self {
sparsity_pattern: Default::default(),
values: vec![],
}
}
}
impl<T: Scalar + One> CsMatrix<T> { impl<T: Scalar + One> CsMatrix<T> {
#[inline] #[inline]
pub fn identity(n: usize) -> Self { pub fn identity(n: usize) -> Self {
@ -360,7 +368,7 @@ where
if let Some(minor_indices) = lane { if let Some(minor_indices) = lane {
let count = minor_indices.len(); let count = minor_indices.len();
let remaining = replace(&mut self.remaining_values, &mut []); let remaining = std::mem::take(&mut self.remaining_values);
let (values_in_lane, remaining) = remaining.split_at_mut(count); let (values_in_lane, remaining) = remaining.split_at_mut(count);
self.remaining_values = remaining; self.remaining_values = remaining;
self.current_lane_idx += 1; self.current_lane_idx += 1;
@ -494,7 +502,7 @@ where
assert_eq!(source_minor_indices.len(), values.len()); assert_eq!(source_minor_indices.len(), values.len());
let nnz = values.len(); let nnz = values.len();
// Count the number of occurences of each minor index // Count the number of occurrences of each minor index
let mut minor_counts = vec![0; minor_dim]; let mut minor_counts = vec![0; minor_dim];
for minor_idx in source_minor_indices { for minor_idx in source_minor_indices {
minor_counts[*minor_idx] += 1; minor_counts[*minor_idx] += 1;
@ -569,7 +577,7 @@ where
} else if sort { } else if sort {
unreachable!("Internal error: Sorting currently not supported if no values are present."); unreachable!("Internal error: Sorting currently not supported if no values are present.");
} }
if major_offsets.len() == 0 { if major_offsets.is_empty() {
return Err(SparseFormatError::from_kind_and_msg( return Err(SparseFormatError::from_kind_and_msg(
SparseFormatErrorKind::InvalidStructure, SparseFormatErrorKind::InvalidStructure,
"Number of offsets should be greater than 0.", "Number of offsets should be greater than 0.",
@ -615,12 +623,12 @@ where
)); ));
} }
let minor_idx_in_lane = minor_indices.get(range_start..range_end).ok_or( let minor_idx_in_lane = minor_indices.get(range_start..range_end).ok_or_else(|| {
SparseFormatError::from_kind_and_msg( SparseFormatError::from_kind_and_msg(
SparseFormatErrorKind::IndexOutOfBounds, SparseFormatErrorKind::IndexOutOfBounds,
"A major offset is out of bounds.", "A major offset is out of bounds.",
), )
)?; })?;
// We test for in-bounds, uniqueness and monotonicity at the same time // We test for in-bounds, uniqueness and monotonicity at the same time
// to ensure that we only visit each minor index once // to ensure that we only visit each minor index once
@ -653,9 +661,9 @@ where
if !monotonic && sort { if !monotonic && sort {
let range_size = range_end - range_start; let range_size = range_end - range_start;
minor_index_permutation.resize(range_size, 0); minor_index_permutation.resize(range_size, 0);
compute_sort_permutation(&mut minor_index_permutation, &minor_idx_in_lane); compute_sort_permutation(&mut minor_index_permutation, minor_idx_in_lane);
minor_idx_buffer.clear(); minor_idx_buffer.clear();
minor_idx_buffer.extend_from_slice(&minor_idx_in_lane); minor_idx_buffer.extend_from_slice(minor_idx_in_lane);
apply_permutation( apply_permutation(
&mut minor_indices[range_start..range_end], &mut minor_indices[range_start..range_end],
&minor_idx_buffer, &minor_idx_buffer,

View File

@ -24,6 +24,7 @@ use std::slice::{Iter, IterMut};
/// # Usage /// # Usage
/// ///
/// ``` /// ```
/// use nalgebra_sparse::coo::CooMatrix;
/// use nalgebra_sparse::csc::CscMatrix; /// use nalgebra_sparse::csc::CscMatrix;
/// use nalgebra::{DMatrix, Matrix3x4}; /// use nalgebra::{DMatrix, Matrix3x4};
/// use matrixcompare::assert_matrix_eq; /// use matrixcompare::assert_matrix_eq;
@ -32,8 +33,9 @@ use std::slice::{Iter, IterMut};
/// // change the sparsity pattern of the matrix after it has been constructed. The easiest /// // change the sparsity pattern of the matrix after it has been constructed. The easiest
/// // way to construct a CSC matrix is to first incrementally construct a COO matrix, /// // way to construct a CSC matrix is to first incrementally construct a COO matrix,
/// // and then convert it to CSC. /// // and then convert it to CSC.
/// # use nalgebra_sparse::coo::CooMatrix; ///
/// # let coo = CooMatrix::<f64>::new(3, 3); /// let mut coo = CooMatrix::<f64>::new(3, 3);
/// coo.push(2, 0, 1.0);
/// let csc = CscMatrix::from(&coo); /// let csc = CscMatrix::from(&coo);
/// ///
/// // Alternatively, a CSC matrix can be constructed directly from raw CSC data. /// // Alternatively, a CSC matrix can be constructed directly from raw CSC data.
@ -156,7 +158,7 @@ impl<T> CscMatrix<T> {
/// an error is returned to indicate the failure. /// an error is returned to indicate the failure.
/// ///
/// An error is returned if the data given does not conform to the CSC storage format. /// An error is returned if the data given does not conform to the CSC storage format.
/// See the documentation for [CscMatrix](struct.CscMatrix.html) for more information. /// See the documentation for [`CscMatrix`] for more information.
pub fn try_from_csc_data( pub fn try_from_csc_data(
num_rows: usize, num_rows: usize,
num_cols: usize, num_cols: usize,
@ -182,7 +184,7 @@ impl<T> CscMatrix<T> {
/// ///
/// An error is returned if the data given does not conform to the CSC storage format /// An error is returned if the data given does not conform to the CSC storage format
/// with the exception of having unsorted row indices and values. /// with the exception of having unsorted row indices and values.
/// See the documentation for [CscMatrix](struct.CscMatrix.html) for more information. /// See the documentation for [`CscMatrix`] for more information.
pub fn try_from_unsorted_csc_data( pub fn try_from_unsorted_csc_data(
num_rows: usize, num_rows: usize,
num_cols: usize, num_cols: usize,
@ -572,6 +574,14 @@ impl<T> CscMatrix<T> {
} }
} }
impl<T> Default for CscMatrix<T> {
fn default() -> Self {
Self {
cs: Default::default(),
}
}
}
/// Convert pattern format errors into more meaningful CSC-specific errors. /// Convert pattern format errors into more meaningful CSC-specific errors.
/// ///
/// This ensures that the terminology is consistent: we are talking about rows and columns, /// This ensures that the terminology is consistent: we are talking about rows and columns,
@ -615,6 +625,15 @@ pub struct CscTripletIter<'a, T> {
values_iter: Iter<'a, T>, values_iter: Iter<'a, T>,
} }
impl<'a, T> Clone for CscTripletIter<'a, T> {
fn clone(&self) -> Self {
CscTripletIter {
pattern_iter: self.pattern_iter.clone(),
values_iter: self.values_iter.clone(),
}
}
}
impl<'a, T: Clone> CscTripletIter<'a, T> { impl<'a, T: Clone> CscTripletIter<'a, T> {
/// Adapts the triplet iterator to return owned values. /// Adapts the triplet iterator to return owned values.
/// ///
@ -746,7 +765,7 @@ impl<'a, T> CscColMut<'a, T> {
} }
} }
/// Column iterator for [CscMatrix](struct.CscMatrix.html). /// Column iterator for [`CscMatrix`].
pub struct CscColIter<'a, T> { pub struct CscColIter<'a, T> {
lane_iter: CsLaneIter<'a, T>, lane_iter: CsLaneIter<'a, T>,
} }
@ -759,7 +778,7 @@ impl<'a, T> Iterator for CscColIter<'a, T> {
} }
} }
/// Mutable column iterator for [CscMatrix](struct.CscMatrix.html). /// Mutable column iterator for [`CscMatrix`].
pub struct CscColIterMut<'a, T> { pub struct CscColIterMut<'a, T> {
lane_iter: CsLaneIterMut<'a, T>, lane_iter: CsLaneIterMut<'a, T>,
} }

View File

@ -25,6 +25,7 @@ use std::slice::{Iter, IterMut};
/// # Usage /// # Usage
/// ///
/// ``` /// ```
/// use nalgebra_sparse::coo::CooMatrix;
/// use nalgebra_sparse::csr::CsrMatrix; /// use nalgebra_sparse::csr::CsrMatrix;
/// use nalgebra::{DMatrix, Matrix3x4}; /// use nalgebra::{DMatrix, Matrix3x4};
/// use matrixcompare::assert_matrix_eq; /// use matrixcompare::assert_matrix_eq;
@ -33,8 +34,9 @@ use std::slice::{Iter, IterMut};
/// // change the sparsity pattern of the matrix after it has been constructed. The easiest /// // change the sparsity pattern of the matrix after it has been constructed. The easiest
/// // way to construct a CSR matrix is to first incrementally construct a COO matrix, /// // way to construct a CSR matrix is to first incrementally construct a COO matrix,
/// // and then convert it to CSR. /// // and then convert it to CSR.
/// # use nalgebra_sparse::coo::CooMatrix; ///
/// # let coo = CooMatrix::<f64>::new(3, 3); /// let mut coo = CooMatrix::<f64>::new(3, 3);
/// coo.push(2, 0, 1.0);
/// let csr = CsrMatrix::from(&coo); /// let csr = CsrMatrix::from(&coo);
/// ///
/// // Alternatively, a CSR matrix can be constructed directly from raw CSR data. /// // Alternatively, a CSR matrix can be constructed directly from raw CSR data.
@ -157,7 +159,7 @@ impl<T> CsrMatrix<T> {
/// an error is returned to indicate the failure. /// an error is returned to indicate the failure.
/// ///
/// An error is returned if the data given does not conform to the CSR storage format. /// An error is returned if the data given does not conform to the CSR storage format.
/// See the documentation for [CsrMatrix](struct.CsrMatrix.html) for more information. /// See the documentation for [`CsrMatrix`] for more information.
pub fn try_from_csr_data( pub fn try_from_csr_data(
num_rows: usize, num_rows: usize,
num_cols: usize, num_cols: usize,
@ -183,7 +185,7 @@ impl<T> CsrMatrix<T> {
/// ///
/// An error is returned if the data given does not conform to the CSR storage format /// An error is returned if the data given does not conform to the CSR storage format
/// with the exception of having unsorted column indices and values. /// with the exception of having unsorted column indices and values.
/// See the documentation for [CsrMatrix](struct.CsrMatrix.html) for more information. /// See the documentation for [`CsrMatrix`] for more information.
pub fn try_from_unsorted_csr_data( pub fn try_from_unsorted_csr_data(
num_rows: usize, num_rows: usize,
num_cols: usize, num_cols: usize,
@ -573,6 +575,14 @@ impl<T> CsrMatrix<T> {
} }
} }
impl<T> Default for CsrMatrix<T> {
fn default() -> Self {
Self {
cs: Default::default(),
}
}
}
/// Convert pattern format errors into more meaningful CSR-specific errors. /// Convert pattern format errors into more meaningful CSR-specific errors.
/// ///
/// This ensures that the terminology is consistent: we are talking about rows and columns, /// This ensures that the terminology is consistent: we are talking about rows and columns,
@ -616,6 +626,15 @@ pub struct CsrTripletIter<'a, T> {
values_iter: Iter<'a, T>, values_iter: Iter<'a, T>,
} }
impl<'a, T> Clone for CsrTripletIter<'a, T> {
fn clone(&self) -> Self {
CsrTripletIter {
pattern_iter: self.pattern_iter.clone(),
values_iter: self.values_iter.clone(),
}
}
}
impl<'a, T: Clone> CsrTripletIter<'a, T> { impl<'a, T: Clone> CsrTripletIter<'a, T> {
/// Adapts the triplet iterator to return owned values. /// Adapts the triplet iterator to return owned values.
/// ///
@ -751,7 +770,7 @@ impl<'a, T> CsrRowMut<'a, T> {
} }
} }
/// Row iterator for [CsrMatrix](struct.CsrMatrix.html). /// Row iterator for [`CsrMatrix`].
pub struct CsrRowIter<'a, T> { pub struct CsrRowIter<'a, T> {
lane_iter: CsLaneIter<'a, T>, lane_iter: CsLaneIter<'a, T>,
} }
@ -764,7 +783,7 @@ impl<'a, T> Iterator for CsrRowIter<'a, T> {
} }
} }
/// Mutable row iterator for [CsrMatrix](struct.CsrMatrix.html). /// Mutable row iterator for [`CsrMatrix`].
pub struct CsrRowIterMut<'a, T> { pub struct CsrRowIterMut<'a, T> {
lane_iter: CsLaneIterMut<'a, T>, lane_iter: CsLaneIterMut<'a, T>,
} }

View File

@ -3,7 +3,7 @@ use crate::ops::serial::spsolve_csc_lower_triangular;
use crate::ops::Op; use crate::ops::Op;
use crate::pattern::SparsityPattern; use crate::pattern::SparsityPattern;
use core::{iter, mem}; use core::{iter, mem};
use nalgebra::{DMatrix, DMatrixSlice, DMatrixSliceMut, RealField}; use nalgebra::{DMatrix, DMatrixView, DMatrixViewMut, RealField};
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
/// A symbolic sparse Cholesky factorization of a CSC matrix. /// A symbolic sparse Cholesky factorization of a CSC matrix.
@ -264,7 +264,7 @@ impl<T: RealField> CscCholesky<T> {
/// ///
/// Panics if `B` is not square. /// Panics if `B` is not square.
#[must_use = "Did you mean to use solve_mut()?"] #[must_use = "Did you mean to use solve_mut()?"]
pub fn solve<'a>(&'a self, b: impl Into<DMatrixSlice<'a, T>>) -> DMatrix<T> { pub fn solve<'a>(&'a self, b: impl Into<DMatrixView<'a, T>>) -> DMatrix<T> {
let b = b.into(); let b = b.into();
let mut output = b.clone_owned(); let mut output = b.clone_owned();
self.solve_mut(&mut output); self.solve_mut(&mut output);
@ -278,7 +278,7 @@ impl<T: RealField> CscCholesky<T> {
/// # Panics /// # Panics
/// ///
/// Panics if `b` is not square. /// Panics if `b` is not square.
pub fn solve_mut<'a>(&'a self, b: impl Into<DMatrixSliceMut<'a, T>>) { pub fn solve_mut<'a>(&'a self, b: impl Into<DMatrixViewMut<'a, T>>) {
let expect_msg = "If the Cholesky factorization succeeded,\ let expect_msg = "If the Cholesky factorization succeeded,\
then the triangular solve should never fail"; then the triangular solve should never fail";
// Solve LY = B // Solve LY = B

View File

@ -1,9 +1,9 @@
//! Implementation of matrix market io code. //! Implementation of matrix market io code.
//! //!
//! See the [website](https://math.nist.gov/MatrixMarket/formats.html) or the [paper](https://www.researchgate.net/publication/2630533_The_Matrix_Market_Exchange_Formats_Initial_Design) for more details about matrix market. //! See the [website](https://math.nist.gov/MatrixMarket/formats.html) or the [paper](https://www.researchgate.net/publication/2630533_The_Matrix_Market_Exchange_Formats_Initial_Design) for more details about matrix market.
use crate::coo::CooMatrix;
use crate::SparseFormatError; use crate::SparseFormatError;
use crate::SparseFormatErrorKind; use crate::SparseFormatErrorKind;
use crate::{CooMatrix, CscMatrix, CsrMatrix};
use nalgebra::Complex; use nalgebra::Complex;
use pest::iterators::Pairs; use pest::iterators::Pairs;
use pest::Parser; use pest::Parser;
@ -12,7 +12,8 @@ use std::convert::Infallible;
use std::convert::TryFrom; use std::convert::TryFrom;
use std::fmt; use std::fmt;
use std::fmt::Formatter; use std::fmt::Formatter;
use std::fs; use std::fs::{self, File};
use std::io::{BufWriter, Write};
use std::num::ParseIntError; use std::num::ParseIntError;
use std::num::TryFromIntError; use std::num::TryFromIntError;
use std::path::Path; use std::path::Path;
@ -267,7 +268,7 @@ impl fmt::Display for MatrixMarketError {
write!(f, "InvalidHeader,")?; write!(f, "InvalidHeader,")?;
} }
MatrixMarketErrorKind::EntryMismatch => { MatrixMarketErrorKind::EntryMismatch => {
write!(f, "EntryNumUnmatched,")?; write!(f, "EntryMismatch,")?;
} }
MatrixMarketErrorKind::TypeMismatch => { MatrixMarketErrorKind::TypeMismatch => {
write!(f, "TypeMismatch,")?; write!(f, "TypeMismatch,")?;
@ -288,7 +289,7 @@ impl fmt::Display for MatrixMarketError {
write!(f, "NotLowerTriangle,")?; write!(f, "NotLowerTriangle,")?;
} }
MatrixMarketErrorKind::NonSquare => { MatrixMarketErrorKind::NonSquare => {
write!(f, "NotSquareMatrix,")?; write!(f, "NonSquare,")?;
} }
} }
write!(f, " message: {}", self.message) write!(f, " message: {}", self.message)
@ -506,6 +507,21 @@ mod internal {
fn negative(self) -> Result<Self, MatrixMarketError>; fn negative(self) -> Result<Self, MatrixMarketError>;
/// When matrix is a Hermitian matrix, it will convert itself to its conjugate. /// When matrix is a Hermitian matrix, it will convert itself to its conjugate.
fn conjugate(self) -> Result<Self, MatrixMarketError>; fn conjugate(self) -> Result<Self, MatrixMarketError>;
/// Returns the name of SupportedMatrixMarketScalar, used when write the matrix
fn typename() -> &'static str;
/// Write the data self to w
fn write_matrix_market<W: std::fmt::Write>(&self, w: W) -> Result<(), std::fmt::Error>;
}
pub trait SupportedMatrixMarketExport<T: SupportedMatrixMarketScalar> {
/// iterate over triplets
fn triplet_iter(&self) -> Box<dyn Iterator<Item = (usize, usize, &T)> + '_>;
/// number of rows
fn nrows(&self) -> usize;
/// number of columns
fn ncols(&self) -> usize;
/// number of non-zeros
fn nnz(&self) -> usize;
} }
} }
@ -557,6 +573,17 @@ macro_rules! mm_int_impl {
fn negative(self) -> Result<Self, MatrixMarketError> { fn negative(self) -> Result<Self, MatrixMarketError> {
Ok(-self) Ok(-self)
} }
#[inline]
fn typename() -> &'static str {
"integer"
}
#[inline]
fn write_matrix_market<W: std::fmt::Write>(
&self,
mut w: W,
) -> Result<(), std::fmt::Error> {
write!(w, "{}", self)
}
} }
}; };
} }
@ -602,6 +629,17 @@ macro_rules! mm_real_impl {
fn negative(self) -> Result<Self, MatrixMarketError> { fn negative(self) -> Result<Self, MatrixMarketError> {
Ok(-self) Ok(-self)
} }
#[inline]
fn typename() -> &'static str {
"real"
}
#[inline]
fn write_matrix_market<W: std::fmt::Write>(
&self,
mut w: W,
) -> Result<(), std::fmt::Error> {
write!(w, "{}", self)
}
} }
}; };
} }
@ -648,6 +686,17 @@ macro_rules! mm_complex_impl {
fn negative(self) -> Result<Self, MatrixMarketError> { fn negative(self) -> Result<Self, MatrixMarketError> {
Ok(-self) Ok(-self)
} }
#[inline]
fn typename() -> &'static str {
"complex"
}
#[inline]
fn write_matrix_market<W: std::fmt::Write>(
&self,
mut w: W,
) -> Result<(), std::fmt::Error> {
write!(w, "{} {}", self.re, self.im)
}
} }
}; };
} }
@ -697,6 +746,17 @@ macro_rules! mm_pattern_impl {
format!("Pattern type has no negative"), format!("Pattern type has no negative"),
)) ))
} }
#[inline]
fn typename() -> &'static str {
"pattern"
}
#[inline]
fn write_matrix_market<W: std::fmt::Write>(
&self,
mut _w: W,
) -> Result<(), std::fmt::Error> {
Ok(())
}
} }
}; };
} }
@ -715,6 +775,46 @@ mm_complex_impl!(f64);
mm_pattern_impl!(()); mm_pattern_impl!(());
/// A marker trait for sparse matrix types that can be exported to the matrix market format.
///
/// This is a sealed trait; it cannot be implemented by external crates. This is done in order to prevent leaking
/// some of the implementation details we currently rely on. We may relax this restriction in the future.
pub trait MatrixMarketExport<T: MatrixMarketScalar>:
internal::SupportedMatrixMarketExport<T>
{
}
macro_rules! mm_matrix_impl {
($T_MATRIX:ty) => {
impl<T: MatrixMarketScalar> MatrixMarketExport<T> for $T_MATRIX {}
impl<T: internal::SupportedMatrixMarketScalar> internal::SupportedMatrixMarketExport<T>
for $T_MATRIX
{
#[inline]
fn triplet_iter(&self) -> Box<dyn Iterator<Item = (usize, usize, &T)> + '_> {
Box::new(self.triplet_iter())
}
#[inline]
fn nrows(&self) -> usize {
self.nrows()
}
#[inline]
fn ncols(&self) -> usize {
self.ncols()
}
#[inline]
fn nnz(&self) -> usize {
self.nnz()
}
}
};
}
mm_matrix_impl!(CooMatrix<T>);
mm_matrix_impl!(CsrMatrix<T>);
mm_matrix_impl!(CscMatrix<T>);
#[derive(Parser)] #[derive(Parser)]
#[grammar = "io/matrix_market.pest"] #[grammar = "io/matrix_market.pest"]
struct MatrixMarketParser; struct MatrixMarketParser;
@ -1329,3 +1429,123 @@ fn next_dense_coordinate(
} }
} }
} }
/// Save a sparse matrix as a Matrix Market format string.
///
/// The exporter only writes the matrix into `coordinate` and `general` format.
///
///
/// Examples
/// --------
/// ```
/// # use nalgebra_sparse::CooMatrix;
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// use nalgebra_sparse::io::{save_to_matrix_market_str};
/// let expected_str = r#"%%matrixmarket matrix coordinate integer general
/// % matrixmarket file generated by nalgebra-sparse.
/// 5 4 2
/// 1 1 10
/// 2 3 5
/// "#;
/// let row_indices = vec![0,1];
/// let col_indices = vec![0,2];
/// let values = vec![10,5];
/// let matrix = CooMatrix::try_from_triplets(5,4,row_indices,col_indices,values)?;
/// let generated_matrixmarket_str = save_to_matrix_market_str(&matrix);
/// assert_eq!(expected_str,generated_matrixmarket_str);
/// # Ok(()) }
/// ```
pub fn save_to_matrix_market_str<T, S>(sparse_matrix: &S) -> String
where
T: MatrixMarketScalar,
S: MatrixMarketExport<T>,
{
let mut bytes = Vec::<u8>::new();
// This will call impl<A: Allocator> Write for Vec<u8, A>
// The vector will grow as needed.
// So, unwrap here won't cause any issue.
save_to_matrix_market(&mut bytes, sparse_matrix).unwrap();
String::from_utf8(bytes)
.expect("Unexpected non UTF-8 data was generated when export to matrix market string")
}
/// Save a sparse matrix to a Matrix Market format file.
///
/// The exporter only saves the matrix with the `coordinate` and `general` matrix market formats.
///
/// Errors
/// --------
///
/// See [MatrixMarketErrorKind] for a list of possible error conditions.
///
/// Examples
/// --------
/// ```no_run
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// use nalgebra_sparse::io::{save_to_matrix_market_file,load_coo_from_matrix_market_str};
/// let str = r#"
/// %%matrixmarket matrix coordinate integer general
/// 5 4 2
/// 1 1 10
/// 2 3 5
/// "#;
/// let matrix = load_coo_from_matrix_market_str::<i32>(&str)?;
/// save_to_matrix_market_file(&matrix,"path/to/matrix.mtx")?;
/// # Ok(()) }
/// ```
pub fn save_to_matrix_market_file<T, S, P>(sparse_matrix: &S, path: P) -> Result<(), std::io::Error>
where
T: MatrixMarketScalar,
S: MatrixMarketExport<T>,
P: AsRef<Path>,
{
let file = File::create(path)?;
let mut file = BufWriter::new(file);
save_to_matrix_market(&mut file, sparse_matrix)?;
// Quote from BufWriter doc.
// > It is critical to call flush before BufWriter<W> is dropped. Though dropping will attempt to flush the contents of the buffer, any errors that happen in the process of dropping will be ignored. Calling flush ensures that the buffer is empty and thus dropping will not even attempt file operations.
file.flush()
.expect("Unexpected error when flushing the buffer data to File");
Ok(())
}
/// Save a sparse matrix to an [std::io::Write] instance.
///
/// This is the most general save functionality. See [save_to_matrix_market_file] and
/// [save_to_matrix_market_str] for higher-level functionality.
pub fn save_to_matrix_market<T, S, W>(mut w: W, sparse_matrix: &S) -> Result<(), std::io::Error>
where
T: MatrixMarketScalar,
S: MatrixMarketExport<T>,
W: Write,
{
// write header
writeln!(
w,
"%%matrixmarket matrix coordinate {} general",
T::typename()
)?;
//write comment
writeln!(w, "% matrixmarket file generated by nalgebra-sparse.")?;
// write shape information
writeln!(
w,
"{} {} {}",
sparse_matrix.nrows(),
sparse_matrix.ncols(),
sparse_matrix.nnz()
)?;
//write triplets
let mut buffer = String::new();
for (r, c, d) in sparse_matrix.triplet_iter() {
buffer.clear();
d.write_matrix_market(&mut buffer)
.expect("Unexpected format error was generated when write to String");
writeln!(w, "{} {} {}", r + 1, c + 1, buffer)?;
}
Ok(())
}

View File

@ -6,7 +6,7 @@
//! //!
//! | Format | Import | Export | //! | Format | Import | Export |
//! | ------------------------------------------------|------------|------------| //! | ------------------------------------------------|------------|------------|
//! | [Matrix market](#matrix-market-format) | Yes | No | //! | [Matrix market](#matrix-market-format) | Yes | Yes |
//! //!
//! [Matrix market]: https://math.nist.gov/MatrixMarket/formats.html //! [Matrix market]: https://math.nist.gov/MatrixMarket/formats.html
//! //!
@ -19,10 +19,12 @@
//! which also uses the Matrix Market file format. //! which also uses the Matrix Market file format.
//! //!
//! We currently offer functionality for importing a Matrix market file to an instance of a //! We currently offer functionality for importing a Matrix market file to an instance of a
//! [CooMatrix](crate::CooMatrix) through the function [load_coo_from_matrix_market_file]. It is also possible to load //! [CooMatrix](crate::CooMatrix) through the function [load_coo_from_matrix_market_file],
//! a matrix stored in the matrix market format with the function [load_coo_from_matrix_market_str]. //! as well as functionality for writing various sparse matrices to the matrix market format
//! //! through [save_to_matrix_market_file]. It is also possible to load
//! Export is currently not implemented, but [planned](https://github.com/dimforge/nalgebra/issues/1037). //! a matrix stored as a string in the matrix market format with the function
//! [load_coo_from_matrix_market_str], or similarly write to a string with
//! [save_to_matrix_market_str].
//! //!
//! Our implementation is based on the [format description](https://math.nist.gov/MatrixMarket/formats.html) //! Our implementation is based on the [format description](https://math.nist.gov/MatrixMarket/formats.html)
//! on the Matrix Market website and the //! on the Matrix Market website and the
@ -32,7 +34,8 @@
//! > "*The Matrix Market Exchange Formats: Initial Design.*" (1996). //! > "*The Matrix Market Exchange Formats: Initial Design.*" (1996).
pub use self::matrix_market::{ pub use self::matrix_market::{
load_coo_from_matrix_market_file, load_coo_from_matrix_market_str, MatrixMarketError, load_coo_from_matrix_market_file, load_coo_from_matrix_market_str, save_to_matrix_market,
MatrixMarketErrorKind, MatrixMarketScalar, save_to_matrix_market_file, save_to_matrix_market_str, MatrixMarketError,
MatrixMarketErrorKind, MatrixMarketExport, MatrixMarketScalar,
}; };
mod matrix_market; mod matrix_market;

View File

@ -143,8 +143,6 @@
)] )]
pub extern crate nalgebra as na; pub extern crate nalgebra as na;
#[cfg(feature = "io")]
extern crate pest;
#[macro_use] #[macro_use]
#[cfg(feature = "io")] #[cfg(feature = "io")]
extern crate pest_derive; extern crate pest_derive;
@ -201,7 +199,7 @@ impl SparseFormatError {
} }
} }
/// The type of format error described by a [SparseFormatError](struct.SparseFormatError.html). /// The type of format error described by a [`SparseFormatError`].
#[non_exhaustive] #[non_exhaustive]
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum SparseFormatErrorKind { pub enum SparseFormatErrorKind {

View File

@ -3,14 +3,14 @@ use crate::csr::CsrMatrix;
use crate::ops::serial::{ use crate::ops::serial::{
spadd_csc_prealloc, spadd_csr_prealloc, spadd_pattern, spmm_csc_dense, spmm_csc_pattern, spadd_csc_prealloc, spadd_csr_prealloc, spadd_pattern, spmm_csc_dense, spmm_csc_pattern,
spmm_csc_prealloc, spmm_csr_dense, spmm_csr_pattern, spmm_csr_prealloc, spmm_csc_prealloc_unchecked, spmm_csr_dense, spmm_csr_pattern, spmm_csr_prealloc_unchecked,
}; };
use crate::ops::Op; use crate::ops::Op;
use nalgebra::allocator::Allocator; use nalgebra::allocator::Allocator;
use nalgebra::base::storage::RawStorage; use nalgebra::base::storage::RawStorage;
use nalgebra::constraint::{DimEq, ShapeConstraint}; use nalgebra::constraint::{DimEq, ShapeConstraint};
use nalgebra::{ use nalgebra::{
ClosedAdd, ClosedDiv, ClosedMul, ClosedSub, DefaultAllocator, Dim, Dynamic, Matrix, OMatrix, ClosedAdd, ClosedDiv, ClosedMul, ClosedSub, DefaultAllocator, Dim, Dyn, Matrix, OMatrix,
Scalar, U1, Scalar, U1,
}; };
use num_traits::{One, Zero}; use num_traits::{One, Zero};
@ -59,7 +59,7 @@ macro_rules! impl_sp_plus_minus {
let mut result = $matrix_type::try_from_pattern_and_values(pattern, values) let mut result = $matrix_type::try_from_pattern_and_values(pattern, values)
.unwrap(); .unwrap();
$spadd_fn(T::zero(), &mut result, T::one(), Op::NoOp(&a)).unwrap(); $spadd_fn(T::zero(), &mut result, T::one(), Op::NoOp(&a)).unwrap();
$spadd_fn(T::one(), &mut result, $factor * T::one(), Op::NoOp(&b)).unwrap(); $spadd_fn(T::one(), &mut result, $factor, Op::NoOp(&b)).unwrap();
result result
}); });
@ -112,9 +112,9 @@ macro_rules! impl_spmm {
} }
} }
impl_spmm!(CsrMatrix, spmm_csr_pattern, spmm_csr_prealloc); impl_spmm!(CsrMatrix, spmm_csr_pattern, spmm_csr_prealloc_unchecked);
// Need to switch order of operations for CSC pattern // Need to switch order of operations for CSC pattern
impl_spmm!(CscMatrix, spmm_csc_pattern, spmm_csc_prealloc); impl_spmm!(CscMatrix, spmm_csc_pattern, spmm_csc_prealloc_unchecked);
/// Implements Scalar * Matrix operations for *concrete* scalar types. The reason this is necessary /// Implements Scalar * Matrix operations for *concrete* scalar types. The reason this is necessary
/// is that we are not able to implement Mul<Matrix<T>> for all T generically due to orphan rules. /// is that we are not able to implement Mul<Matrix<T>> for all T generically due to orphan rules.
@ -273,8 +273,8 @@ macro_rules! impl_spmm_cs_dense {
// Implement ref-ref // Implement ref-ref
impl_spmm_cs_dense!(&'a $matrix_type_name<T>, &'a Matrix<T, R, C, S>, $spmm_fn, |lhs, rhs| { impl_spmm_cs_dense!(&'a $matrix_type_name<T>, &'a Matrix<T, R, C, S>, $spmm_fn, |lhs, rhs| {
let (_, ncols) = rhs.shape_generic(); let (_, ncols) = rhs.shape_generic();
let nrows = Dynamic::new(lhs.nrows()); let nrows = Dyn(lhs.nrows());
let mut result = OMatrix::<T, Dynamic, C>::zeros_generic(nrows, ncols); let mut result = OMatrix::<T, Dyn, C>::zeros_generic(nrows, ncols);
$spmm_fn(T::zero(), &mut result, T::one(), Op::NoOp(lhs), Op::NoOp(rhs)); $spmm_fn(T::zero(), &mut result, T::one(), Op::NoOp(lhs), Op::NoOp(rhs));
result result
}); });
@ -302,21 +302,21 @@ macro_rules! impl_spmm_cs_dense {
R: Dim, R: Dim,
C: Dim, C: Dim,
S: RawStorage<T, R, C>, S: RawStorage<T, R, C>,
DefaultAllocator: Allocator<T, Dynamic, C>, DefaultAllocator: Allocator<T, Dyn, C>,
// TODO: Is it possible to simplify these bounds? // TODO: Is it possible to simplify these bounds?
ShapeConstraint: ShapeConstraint:
// Bounds so that we can turn OMatrix<T, Dynamic, C> into a DMatrixSliceMut // Bounds so that we can turn OMatrix<T, Dyn, C> into a DMatrixSliceMut
DimEq<U1, <<DefaultAllocator as Allocator<T, Dynamic, C>>::Buffer as RawStorage<T, Dynamic, C>>::RStride> DimEq<U1, <<DefaultAllocator as Allocator<T, Dyn, C>>::Buffer as RawStorage<T, Dyn, C>>::RStride>
+ DimEq<C, Dynamic> + DimEq<C, Dyn>
+ DimEq<Dynamic, <<DefaultAllocator as Allocator<T, Dynamic, C>>::Buffer as RawStorage<T, Dynamic, C>>::CStride> + DimEq<Dyn, <<DefaultAllocator as Allocator<T, Dyn, C>>::Buffer as RawStorage<T, Dyn, C>>::CStride>
// Bounds so that we can turn &Matrix<T, R, C, S> into a DMatrixSlice // Bounds so that we can turn &Matrix<T, R, C, S> into a DMatrixSlice
+ DimEq<U1, S::RStride> + DimEq<U1, S::RStride>
+ DimEq<R, Dynamic> + DimEq<R, Dyn>
+ DimEq<Dynamic, S::CStride> + DimEq<Dyn, S::CStride>
{ {
// We need the column dimension to be generic, so that if RHS is a vector, then // We need the column dimension to be generic, so that if RHS is a vector, then
// we also get a vector (and not a matrix) // we also get a vector (and not a matrix)
type Output = OMatrix<T, Dynamic, C>; type Output = OMatrix<T, Dyn, C>;
fn mul(self, rhs: $dense_matrix_type) -> Self::Output { fn mul(self, rhs: $dense_matrix_type) -> Self::Output {
let $lhs = self; let $lhs = self;

View File

@ -149,8 +149,8 @@ impl<T> Op<T> {
#[must_use] #[must_use]
pub fn as_ref(&self) -> Op<&T> { pub fn as_ref(&self) -> Op<&T> {
match self { match self {
Op::NoOp(obj) => Op::NoOp(&obj), Op::NoOp(obj) => Op::NoOp(obj),
Op::Transpose(obj) => Op::Transpose(&obj), Op::Transpose(obj) => Op::Transpose(obj),
} }
} }

View File

@ -2,7 +2,7 @@ use crate::cs::CsMatrix;
use crate::ops::serial::{OperationError, OperationErrorKind}; use crate::ops::serial::{OperationError, OperationErrorKind};
use crate::ops::Op; use crate::ops::Op;
use crate::SparseEntryMut; use crate::SparseEntryMut;
use nalgebra::{ClosedAdd, ClosedMul, DMatrixSlice, DMatrixSliceMut, Scalar}; use nalgebra::{ClosedAdd, ClosedMul, DMatrixView, DMatrixViewMut, Scalar};
use num_traits::{One, Zero}; use num_traits::{One, Zero};
fn spmm_cs_unexpected_entry() -> OperationError { fn spmm_cs_unexpected_entry() -> OperationError {
@ -20,6 +20,51 @@ fn spmm_cs_unexpected_entry() -> OperationError {
/// reversed (since transpose(AB) = transpose(B) * transpose(A) and CSC(A) = transpose(CSR(A)). /// reversed (since transpose(AB) = transpose(B) * transpose(A) and CSC(A) = transpose(CSR(A)).
/// ///
/// We assume here that the matrices have already been verified to be dimensionally compatible. /// We assume here that the matrices have already been verified to be dimensionally compatible.
pub fn spmm_cs_prealloc_unchecked<T>(
beta: T,
c: &mut CsMatrix<T>,
alpha: T,
a: &CsMatrix<T>,
b: &CsMatrix<T>,
) -> Result<(), OperationError>
where
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{
assert_eq!(c.pattern().major_dim(), a.pattern().major_dim());
assert_eq!(c.pattern().minor_dim(), b.pattern().minor_dim());
let some_val = Zero::zero();
let mut scratchpad_values: Vec<T> = vec![some_val; b.pattern().minor_dim()];
for i in 0..c.pattern().major_dim() {
let a_lane_i = a.get_lane(i).unwrap();
let mut c_lane_i = c.get_lane_mut(i).unwrap();
for (&k, a_ik) in a_lane_i.minor_indices().iter().zip(a_lane_i.values()) {
let b_lane_k = b.get_lane(k).unwrap();
let alpha_aik = alpha.clone() * a_ik.clone();
for (j, b_kj) in b_lane_k.minor_indices().iter().zip(b_lane_k.values()) {
// use a dense scatter vector to accumulate non-zeros quickly
unsafe {
*scratchpad_values.get_unchecked_mut(*j) += alpha_aik.clone() * b_kj.clone();
}
}
}
//Get indices from C pattern and gather from the dense scratchpad_values
let (indices, values) = c_lane_i.indices_and_values_mut();
values
.iter_mut()
.zip(indices)
.for_each(|(output_ref, index)| unsafe {
*output_ref = beta.clone() * output_ref.clone()
+ scratchpad_values.get_unchecked(*index).clone();
*scratchpad_values.get_unchecked_mut(*index) = Zero::zero();
});
}
Ok(())
}
pub fn spmm_cs_prealloc<T>( pub fn spmm_cs_prealloc<T>(
beta: T, beta: T,
c: &mut CsMatrix<T>, c: &mut CsMatrix<T>,
@ -131,10 +176,10 @@ where
/// the transposed operation must be specified for the CSC matrix. /// the transposed operation must be specified for the CSC matrix.
pub fn spmm_cs_dense<T>( pub fn spmm_cs_dense<T>(
beta: T, beta: T,
mut c: DMatrixSliceMut<'_, T>, mut c: DMatrixViewMut<'_, T>,
alpha: T, alpha: T,
a: Op<&CsMatrix<T>>, a: Op<&CsMatrix<T>>,
b: Op<DMatrixSlice<'_, T>>, b: Op<DMatrixView<'_, T>>,
) where ) where
T: Scalar + ClosedAdd + ClosedMul + Zero + One, T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{ {

View File

@ -1,8 +1,10 @@
use crate::csc::CscMatrix; use crate::csc::CscMatrix;
use crate::ops::serial::cs::{spadd_cs_prealloc, spmm_cs_dense, spmm_cs_prealloc}; use crate::ops::serial::cs::{
spadd_cs_prealloc, spmm_cs_dense, spmm_cs_prealloc, spmm_cs_prealloc_unchecked,
};
use crate::ops::serial::{OperationError, OperationErrorKind}; use crate::ops::serial::{OperationError, OperationErrorKind};
use crate::ops::Op; use crate::ops::Op;
use nalgebra::{ClosedAdd, ClosedMul, DMatrixSlice, DMatrixSliceMut, RealField, Scalar}; use nalgebra::{ClosedAdd, ClosedMul, DMatrixView, DMatrixViewMut, RealField, Scalar};
use num_traits::{One, Zero}; use num_traits::{One, Zero};
use std::borrow::Cow; use std::borrow::Cow;
@ -14,10 +16,10 @@ use std::borrow::Cow;
/// Panics if the dimensions of the matrices involved are not compatible with the expression. /// Panics if the dimensions of the matrices involved are not compatible with the expression.
pub fn spmm_csc_dense<'a, T>( pub fn spmm_csc_dense<'a, T>(
beta: T, beta: T,
c: impl Into<DMatrixSliceMut<'a, T>>, c: impl Into<DMatrixViewMut<'a, T>>,
alpha: T, alpha: T,
a: Op<&CscMatrix<T>>, a: Op<&CscMatrix<T>>,
b: Op<impl Into<DMatrixSlice<'a, T>>>, b: Op<impl Into<DMatrixView<'a, T>>>,
) where ) where
T: Scalar + ClosedAdd + ClosedMul + Zero + One, T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{ {
@ -27,10 +29,10 @@ pub fn spmm_csc_dense<'a, T>(
fn spmm_csc_dense_<T>( fn spmm_csc_dense_<T>(
beta: T, beta: T,
c: DMatrixSliceMut<'_, T>, c: DMatrixViewMut<'_, T>,
alpha: T, alpha: T,
a: Op<&CscMatrix<T>>, a: Op<&CscMatrix<T>>,
b: Op<DMatrixSlice<'_, T>>, b: Op<DMatrixView<'_, T>>,
) where ) where
T: Scalar + ClosedAdd + ClosedMul + Zero + One, T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{ {
@ -83,14 +85,65 @@ where
{ {
assert_compatible_spmm_dims!(c, a, b); assert_compatible_spmm_dims!(c, a, b);
use Op::{NoOp, Transpose}; use Op::NoOp;
match (&a, &b) { match (&a, &b) {
(NoOp(ref a), NoOp(ref b)) => { (NoOp(a), NoOp(b)) => {
// Note: We have to reverse the order for CSC matrices // Note: We have to reverse the order for CSC matrices
spmm_cs_prealloc(beta, &mut c.cs, alpha, &b.cs, &a.cs) spmm_cs_prealloc(beta, &mut c.cs, alpha, &b.cs, &a.cs)
} }
_ => { _ => spmm_csc_transposed(beta, c, alpha, a, b, spmm_csc_prealloc),
}
}
/// Faster sparse-sparse matrix multiplication, `C <- beta * C + alpha * op(A) * op(B)`.
/// This will not return an error even if the patterns don't match.
/// Should be used for situations where pattern creation immediately precedes multiplication.
///
/// Panics if the dimensions of the matrices involved are not compatible with the expression.
pub fn spmm_csc_prealloc_unchecked<T>(
beta: T,
c: &mut CscMatrix<T>,
alpha: T,
a: Op<&CscMatrix<T>>,
b: Op<&CscMatrix<T>>,
) -> Result<(), OperationError>
where
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{
assert_compatible_spmm_dims!(c, a, b);
use Op::NoOp;
match (&a, &b) {
(NoOp(a), NoOp(b)) => {
// Note: We have to reverse the order for CSC matrices
spmm_cs_prealloc_unchecked(beta, &mut c.cs, alpha, &b.cs, &a.cs)
}
_ => spmm_csc_transposed(beta, c, alpha, a, b, spmm_csc_prealloc_unchecked),
}
}
fn spmm_csc_transposed<T, F>(
beta: T,
c: &mut CscMatrix<T>,
alpha: T,
a: Op<&CscMatrix<T>>,
b: Op<&CscMatrix<T>>,
spmm_kernel: F,
) -> Result<(), OperationError>
where
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
F: Fn(
T,
&mut CscMatrix<T>,
T,
Op<&CscMatrix<T>>,
Op<&CscMatrix<T>>,
) -> Result<(), OperationError>,
{
use Op::{NoOp, Transpose};
// Currently we handle transposition by explicitly precomputing transposed matrices // Currently we handle transposition by explicitly precomputing transposed matrices
// and calling the operation again without transposition // and calling the operation again without transposition
let a_ref: &CscMatrix<T> = a.inner_ref(); let a_ref: &CscMatrix<T> = a.inner_ref();
@ -99,17 +152,12 @@ where
use Cow::*; use Cow::*;
match (&a, &b) { match (&a, &b) {
(NoOp(_), NoOp(_)) => unreachable!(), (NoOp(_), NoOp(_)) => unreachable!(),
(Transpose(ref a), NoOp(_)) => (Owned(a.transpose()), Borrowed(b_ref)), (Transpose(a), NoOp(_)) => (Owned(a.transpose()), Borrowed(b_ref)),
(NoOp(_), Transpose(ref b)) => (Borrowed(a_ref), Owned(b.transpose())), (NoOp(_), Transpose(b)) => (Borrowed(a_ref), Owned(b.transpose())),
(Transpose(ref a), Transpose(ref b)) => { (Transpose(a), Transpose(b)) => (Owned(a.transpose()), Owned(b.transpose())),
(Owned(a.transpose()), Owned(b.transpose()))
}
} }
}; };
spmm_kernel(beta, c, alpha, NoOp(a.as_ref()), NoOp(b.as_ref()))
spmm_csc_prealloc(beta, c, alpha, NoOp(a.as_ref()), NoOp(b.as_ref()))
}
}
} }
/// Solve the lower triangular system `op(L) X = B`. /// Solve the lower triangular system `op(L) X = B`.
@ -125,7 +173,7 @@ where
/// Panics if `L` is not square, or if `L` and `B` are not dimensionally compatible. /// Panics if `L` is not square, or if `L` and `B` are not dimensionally compatible.
pub fn spsolve_csc_lower_triangular<'a, T: RealField>( pub fn spsolve_csc_lower_triangular<'a, T: RealField>(
l: Op<&CscMatrix<T>>, l: Op<&CscMatrix<T>>,
b: impl Into<DMatrixSliceMut<'a, T>>, b: impl Into<DMatrixViewMut<'a, T>>,
) -> Result<(), OperationError> { ) -> Result<(), OperationError> {
let b = b.into(); let b = b.into();
let l_matrix = l.into_inner(); let l_matrix = l.into_inner();
@ -147,7 +195,7 @@ pub fn spsolve_csc_lower_triangular<'a, T: RealField>(
fn spsolve_csc_lower_triangular_no_transpose<T: RealField>( fn spsolve_csc_lower_triangular_no_transpose<T: RealField>(
l: &CscMatrix<T>, l: &CscMatrix<T>,
b: DMatrixSliceMut<'_, T>, b: DMatrixViewMut<'_, T>,
) -> Result<(), OperationError> { ) -> Result<(), OperationError> {
let mut x = b; let mut x = b;
@ -205,7 +253,7 @@ fn spsolve_encountered_zero_diagonal() -> Result<(), OperationError> {
fn spsolve_csc_lower_triangular_transpose<T: RealField>( fn spsolve_csc_lower_triangular_transpose<T: RealField>(
l: &CscMatrix<T>, l: &CscMatrix<T>,
b: DMatrixSliceMut<'_, T>, b: DMatrixViewMut<'_, T>,
) -> Result<(), OperationError> { ) -> Result<(), OperationError> {
let mut x = b; let mut x = b;

View File

@ -1,18 +1,20 @@
use crate::csr::CsrMatrix; use crate::csr::CsrMatrix;
use crate::ops::serial::cs::{spadd_cs_prealloc, spmm_cs_dense, spmm_cs_prealloc}; use crate::ops::serial::cs::{
spadd_cs_prealloc, spmm_cs_dense, spmm_cs_prealloc, spmm_cs_prealloc_unchecked,
};
use crate::ops::serial::OperationError; use crate::ops::serial::OperationError;
use crate::ops::Op; use crate::ops::Op;
use nalgebra::{ClosedAdd, ClosedMul, DMatrixSlice, DMatrixSliceMut, Scalar}; use nalgebra::{ClosedAdd, ClosedMul, DMatrixView, DMatrixViewMut, Scalar};
use num_traits::{One, Zero}; use num_traits::{One, Zero};
use std::borrow::Cow; use std::borrow::Cow;
/// Sparse-dense matrix-matrix multiplication `C <- beta * C + alpha * op(A) * op(B)`. /// Sparse-dense matrix-matrix multiplication `C <- beta * C + alpha * op(A) * op(B)`.
pub fn spmm_csr_dense<'a, T>( pub fn spmm_csr_dense<'a, T>(
beta: T, beta: T,
c: impl Into<DMatrixSliceMut<'a, T>>, c: impl Into<DMatrixViewMut<'a, T>>,
alpha: T, alpha: T,
a: Op<&CsrMatrix<T>>, a: Op<&CsrMatrix<T>>,
b: Op<impl Into<DMatrixSlice<'a, T>>>, b: Op<impl Into<DMatrixView<'a, T>>>,
) where ) where
T: Scalar + ClosedAdd + ClosedMul + Zero + One, T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{ {
@ -22,10 +24,10 @@ pub fn spmm_csr_dense<'a, T>(
fn spmm_csr_dense_<T>( fn spmm_csr_dense_<T>(
beta: T, beta: T,
c: DMatrixSliceMut<'_, T>, c: DMatrixViewMut<'_, T>,
alpha: T, alpha: T,
a: Op<&CsrMatrix<T>>, a: Op<&CsrMatrix<T>>,
b: Op<DMatrixSlice<'_, T>>, b: Op<DMatrixView<'_, T>>,
) where ) where
T: Scalar + ClosedAdd + ClosedMul + Zero + One, T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{ {
@ -77,30 +79,71 @@ where
{ {
assert_compatible_spmm_dims!(c, a, b); assert_compatible_spmm_dims!(c, a, b);
use Op::{NoOp, Transpose}; use Op::NoOp;
match (&a, &b) { match (&a, &b) {
(NoOp(ref a), NoOp(ref b)) => spmm_cs_prealloc(beta, &mut c.cs, alpha, &a.cs, &b.cs), (NoOp(a), NoOp(b)) => spmm_cs_prealloc(beta, &mut c.cs, alpha, &a.cs, &b.cs),
_ => { _ => spmm_csr_transposed(beta, c, alpha, a, b, spmm_csr_prealloc),
}
}
/// Faster sparse-sparse matrix multiplication, `C <- beta * C + alpha * op(A) * op(B)`.
/// This will not return an error even if the patterns don't match.
/// Should be used for situations where pattern creation immediately precedes multiplication.
///
/// Panics if the dimensions of the matrices involved are not compatible with the expression.
pub fn spmm_csr_prealloc_unchecked<T>(
beta: T,
c: &mut CsrMatrix<T>,
alpha: T,
a: Op<&CsrMatrix<T>>,
b: Op<&CsrMatrix<T>>,
) -> Result<(), OperationError>
where
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{
assert_compatible_spmm_dims!(c, a, b);
use Op::NoOp;
match (&a, &b) {
(NoOp(a), NoOp(b)) => spmm_cs_prealloc_unchecked(beta, &mut c.cs, alpha, &a.cs, &b.cs),
_ => spmm_csr_transposed(beta, c, alpha, a, b, spmm_csr_prealloc_unchecked),
}
}
fn spmm_csr_transposed<T, F>(
beta: T,
c: &mut CsrMatrix<T>,
alpha: T,
a: Op<&CsrMatrix<T>>,
b: Op<&CsrMatrix<T>>,
spmm_kernel: F,
) -> Result<(), OperationError>
where
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
F: Fn(
T,
&mut CsrMatrix<T>,
T,
Op<&CsrMatrix<T>>,
Op<&CsrMatrix<T>>,
) -> Result<(), OperationError>,
{
use Op::{NoOp, Transpose};
// Currently we handle transposition by explicitly precomputing transposed matrices // Currently we handle transposition by explicitly precomputing transposed matrices
// and calling the operation again without transposition // and calling the operation again without transposition
// TODO: At least use workspaces to allow control of allocations. Maybe
// consider implementing certain patterns (like A^T * B) explicitly
let a_ref: &CsrMatrix<T> = a.inner_ref(); let a_ref: &CsrMatrix<T> = a.inner_ref();
let b_ref: &CsrMatrix<T> = b.inner_ref(); let b_ref: &CsrMatrix<T> = b.inner_ref();
let (a, b) = { let (a, b) = {
use Cow::*; use Cow::*;
match (&a, &b) { match (&a, &b) {
(NoOp(_), NoOp(_)) => unreachable!(), (NoOp(_), NoOp(_)) => unreachable!(),
(Transpose(ref a), NoOp(_)) => (Owned(a.transpose()), Borrowed(b_ref)), (Transpose(a), NoOp(_)) => (Owned(a.transpose()), Borrowed(b_ref)),
(NoOp(_), Transpose(ref b)) => (Borrowed(a_ref), Owned(b.transpose())), (NoOp(_), Transpose(b)) => (Borrowed(a_ref), Owned(b.transpose())),
(Transpose(ref a), Transpose(ref b)) => { (Transpose(a), Transpose(b)) => (Owned(a.transpose()), Owned(b.transpose())),
(Owned(a.transpose()), Owned(b.transpose()))
}
} }
}; };
spmm_kernel(beta, c, alpha, NoOp(a.as_ref()), NoOp(b.as_ref()))
spmm_csr_prealloc(beta, c, alpha, NoOp(a.as_ref()), NoOp(b.as_ref()))
}
}
} }

View File

@ -125,18 +125,22 @@ fn iterate_union<'a>(
) -> impl Iterator<Item = usize> + 'a { ) -> impl Iterator<Item = usize> + 'a {
iter::from_fn(move || { iter::from_fn(move || {
if let (Some(a_item), Some(b_item)) = (sorted_a.first(), sorted_b.first()) { if let (Some(a_item), Some(b_item)) = (sorted_a.first(), sorted_b.first()) {
let item = if a_item < b_item { let item = match a_item.cmp(b_item) {
std::cmp::Ordering::Less => {
sorted_a = &sorted_a[1..]; sorted_a = &sorted_a[1..];
a_item a_item
} else if b_item < a_item { }
std::cmp::Ordering::Greater => {
sorted_b = &sorted_b[1..]; sorted_b = &sorted_b[1..];
b_item b_item
} else { }
std::cmp::Ordering::Equal => {
// Both lists contain the same element, advance both slices to avoid // Both lists contain the same element, advance both slices to avoid
// duplicate entries in the result // duplicate entries in the result
sorted_a = &sorted_a[1..]; sorted_a = &sorted_a[1..];
sorted_b = &sorted_b[1..]; sorted_b = &sorted_b[1..];
a_item a_item
}
}; };
Some(*item) Some(*item)
} else if let Some(a_item) = sorted_a.first() { } else if let Some(a_item) = sorted_a.first() {

View File

@ -80,7 +80,7 @@ impl SparsityPattern {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn major_dim(&self) -> usize { pub fn major_dim(&self) -> usize {
assert!(self.major_offsets.len() > 0); assert!(!self.major_offsets.is_empty());
self.major_offsets.len() - 1 self.major_offsets.len() - 1
} }
@ -162,7 +162,7 @@ impl SparsityPattern {
// We test for in-bounds, uniqueness and monotonicity at the same time // We test for in-bounds, uniqueness and monotonicity at the same time
// to ensure that we only visit each minor index once // to ensure that we only visit each minor index once
let mut iter = minor_indices.iter(); let mut iter = minor_indices.iter();
let mut prev = None; let mut prev: Option<usize> = None;
while let Some(next) = iter.next().copied() { while let Some(next) = iter.next().copied() {
if next >= minor_dim { if next >= minor_dim {
@ -170,10 +170,10 @@ impl SparsityPattern {
} }
if let Some(prev) = prev { if let Some(prev) = prev {
if prev > next { match prev.cmp(&next) {
return Err(NonmonotonicMinorIndices); std::cmp::Ordering::Greater => return Err(NonmonotonicMinorIndices),
} else if prev == next { std::cmp::Ordering::Equal => return Err(DuplicateEntry),
return Err(DuplicateEntry); std::cmp::Ordering::Less => {}
} }
} }
prev = Some(next); prev = Some(next);
@ -195,6 +195,14 @@ impl SparsityPattern {
/// ///
/// Panics if the number of major offsets is not exactly one greater than the major dimension /// Panics if the number of major offsets is not exactly one greater than the major dimension
/// or if major offsets do not start with 0 and end with the number of minor indices. /// or if major offsets do not start with 0 and end with the number of minor indices.
///
/// # Safety
///
/// Assumes that the major offsets and indices adhere to the requirements of being a valid
/// sparsity pattern.
/// Specifically, that major offsets is monotonically increasing, and
/// `major_offsets[i]..major_offsets[i+1]` refers to a major lane in the sparsity pattern,
/// and `minor_indices[major_offsets[i]..major_offsets[i+1]]` is monotonically increasing.
pub unsafe fn from_offset_and_indices_unchecked( pub unsafe fn from_offset_and_indices_unchecked(
major_dim: usize, major_dim: usize,
minor_dim: usize, minor_dim: usize,
@ -291,6 +299,16 @@ impl SparsityPattern {
} }
} }
impl Default for SparsityPattern {
fn default() -> Self {
Self {
major_offsets: vec![0],
minor_indices: vec![],
minor_dim: 0,
}
}
}
/// Error type for `SparsityPattern` format errors. /// Error type for `SparsityPattern` format errors.
#[non_exhaustive] #[non_exhaustive]
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]

View File

@ -87,6 +87,40 @@ fn coo_construction_for_valid_data() {
} }
} }
#[test]
fn coo_triplets_iter_mut() {
// Arbitrary matrix, with duplicates
let i = vec![0, 1, 0, 0, 0, 0, 2, 1];
let j = vec![0, 2, 0, 1, 0, 3, 3, 2];
let v = vec![2, 3, 4, 7, 1, 3, 1, 5];
let mut coo =
CooMatrix::<i32>::try_from_triplets(3, 5, i.clone(), j.clone(), v.clone()).unwrap();
let actual_triplets: Vec<_> = coo.triplet_iter_mut().map(|(i, j, v)| (i, j, *v)).collect();
let expected_triplets: Vec<_> = i
.iter()
.zip(&j)
.zip(&v)
.map(|((i, j), v)| (*i, *j, *v))
.collect();
assert_eq!(expected_triplets, actual_triplets);
for (_i, _j, v) in coo.triplet_iter_mut() {
*v += *v;
}
let actual_triplets: Vec<_> = coo.triplet_iter_mut().map(|(i, j, v)| (i, j, *v)).collect();
let v = vec![4, 6, 8, 14, 2, 6, 2, 10];
let expected_triplets: Vec<_> = i
.iter()
.zip(&j)
.zip(&v)
.map(|((i, j), v)| (*i, *j, *v))
.collect();
assert_eq!(expected_triplets, actual_triplets);
}
#[test] #[test]
fn coo_try_from_triplets_reports_out_of_bounds_indices() { fn coo_try_from_triplets_reports_out_of_bounds_indices() {
{ {
@ -150,6 +184,31 @@ fn coo_try_from_triplets_reports_out_of_bounds_indices() {
} }
} }
#[test]
fn coo_try_from_triplets_iter() {
// Check that try_from_triplets_iter panics when the triplet vectors have different lengths
macro_rules! assert_errs {
($result:expr) => {
assert!(matches!(
$result.unwrap_err().kind(),
SparseFormatErrorKind::IndexOutOfBounds
))
};
}
assert_errs!(CooMatrix::<f32>::try_from_triplets_iter(
3,
5,
vec![(0, 6, 3.0)].into_iter(),
));
assert!(CooMatrix::<f32>::try_from_triplets_iter(
3,
5,
vec![(0, 3, 3.0), (1, 2, 2.0), (0, 3, 1.0),].into_iter(),
)
.is_ok());
}
#[test] #[test]
fn coo_try_from_triplets_panics_on_mismatched_vectors() { fn coo_try_from_triplets_panics_on_mismatched_vectors() {
// Check that try_from_triplets panics when the triplet vectors have different lengths // Check that try_from_triplets panics when the triplet vectors have different lengths
@ -226,6 +285,29 @@ fn coo_push_valid_entries() {
); );
} }
#[test]
fn coo_clear_triplets_valid_entries() {
let mut coo = CooMatrix::new(3, 3);
coo.push(0, 0, 1);
coo.push(0, 0, 2);
coo.push(2, 2, 3);
assert_eq!(
coo.triplet_iter().collect::<Vec<_>>(),
vec![(0, 0, &1), (0, 0, &2), (2, 2, &3)]
);
coo.clear_triplets();
assert_eq!(coo.triplet_iter().collect::<Vec<_>>(), vec![]);
// making sure everyhting works after clearing
coo.push(0, 0, 1);
coo.push(0, 0, 2);
coo.push(2, 2, 3);
assert_eq!(
coo.triplet_iter().collect::<Vec<_>>(),
vec![(0, 0, &1), (0, 0, &2), (2, 2, &3)]
);
}
#[test] #[test]
fn coo_push_out_of_bounds_entries() { fn coo_push_out_of_bounds_entries() {
{ {
@ -291,8 +373,8 @@ fn coo_push_matrix_valid_entries() {
// Works with sliced // Works with sliced
{ {
let source = nalgebra::SMatrix::<i32, 2, 2>::new(6, 7, 8, 9); let source = nalgebra::SMatrix::<i32, 2, 2>::new(6, 7, 8, 9);
let sliced = source.fixed_slice::<2, 1>(0, 0); let view = source.fixed_view::<2, 1>(0, 0);
coo.push_matrix(1, 0, &sliced); coo.push_matrix(1, 0, &view);
assert_eq!( assert_eq!(
coo.triplet_iter().collect::<Vec<_>>(), coo.triplet_iter().collect::<Vec<_>>(),

View File

@ -12,6 +12,18 @@ use crate::common::csc_strategy;
use std::collections::HashSet; use std::collections::HashSet;
#[test]
fn csc_matrix_default() {
let matrix: CscMatrix<f32> = CscMatrix::default();
assert_eq!(matrix.nrows(), 0);
assert_eq!(matrix.ncols(), 0);
assert_eq!(matrix.nnz(), 0);
assert_eq!(matrix.values(), &[]);
assert!(matrix.get_entry(0, 0).is_none());
}
#[test] #[test]
fn csc_matrix_valid_data() { fn csc_matrix_valid_data() {
// Construct matrix from valid data and check that selected methods return results // Construct matrix from valid data and check that selected methods return results

View File

@ -12,6 +12,18 @@ use crate::common::csr_strategy;
use std::collections::HashSet; use std::collections::HashSet;
#[test]
fn csr_matrix_default() {
let matrix: CsrMatrix<f32> = CsrMatrix::default();
assert_eq!(matrix.nrows(), 0);
assert_eq!(matrix.ncols(), 0);
assert_eq!(matrix.nnz(), 0);
assert_eq!(matrix.values(), &[]);
assert!(matrix.get_entry(0, 0).is_none());
}
#[test] #[test]
fn csr_matrix_valid_data() { fn csr_matrix_valid_data() {
// Construct matrix from valid data and check that selected methods return results // Construct matrix from valid data and check that selected methods return results

View File

@ -1,12 +1,21 @@
use matrixcompare::assert_matrix_eq; use matrixcompare::assert_matrix_eq;
use nalgebra::dmatrix; use nalgebra::matrix;
use nalgebra::Complex; use nalgebra::Complex;
use nalgebra_sparse::io::load_coo_from_matrix_market_str; use nalgebra_sparse::io::{
load_coo_from_matrix_market_file, load_coo_from_matrix_market_str, save_to_matrix_market_file,
save_to_matrix_market_str,
};
use nalgebra_sparse::proptest::coo_no_duplicates;
use nalgebra_sparse::CooMatrix; use nalgebra_sparse::CooMatrix;
use proptest::prelude::*;
use tempfile::tempdir;
type C64 = Complex<f64>;
type C32 = Complex<f32>;
#[test] #[test]
#[rustfmt::skip] #[rustfmt::skip]
fn test_matrixmarket_sparse_real_general_empty() { fn test_matrixmarket_load_sparse_real_general_empty() {
// Test several valid zero-shapes of a sparse matrix // Test several valid zero-shapes of a sparse matrix
let shapes = vec![ (0, 0), (1, 0), (0, 1) ]; let shapes = vec![ (0, 0), (1, 0), (0, 1) ];
let strings: Vec<String> = shapes let strings: Vec<String> = shapes
@ -24,7 +33,7 @@ fn test_matrixmarket_sparse_real_general_empty() {
#[test] #[test]
#[rustfmt::skip] #[rustfmt::skip]
fn test_matrixmarket_dense_real_general_empty() { fn test_matrixmarket_load_dense_real_general_empty() {
// Test several valid zero-shapes of a dense matrix // Test several valid zero-shapes of a dense matrix
let shapes = vec![ (0, 0), (1, 0), (0, 1) ]; let shapes = vec![ (0, 0), (1, 0), (0, 1) ];
let strings: Vec<String> = shapes let strings: Vec<String> = shapes
@ -42,7 +51,7 @@ fn test_matrixmarket_dense_real_general_empty() {
#[test] #[test]
#[rustfmt::skip] #[rustfmt::skip]
fn test_matrixmarket_sparse_real_general() { fn test_matrixmarket_load_sparse_real_general() {
let file_str = r#" let file_str = r#"
%%MatrixMarket matrix CoOrdinate real general %%MatrixMarket matrix CoOrdinate real general
% This is also an example of free-format features. % This is also an example of free-format features.
@ -89,7 +98,7 @@ fn test_matrixmarket_sparse_real_general() {
5 5 1.200e+01 5 5 1.200e+01
"#; "#;
let sparse_mat = load_coo_from_matrix_market_str::<f32>(file_str).unwrap(); let sparse_mat = load_coo_from_matrix_market_str::<f32>(file_str).unwrap();
let expected = dmatrix![ let expected = matrix![
1.0, 0.0, 0.0, 6.0, 0.0; 1.0, 0.0, 0.0, 6.0, 0.0;
0.0, 10.5, 0.0, 0.0, 0.0; 0.0, 10.5, 0.0, 0.0, 0.0;
0.0, 0.0, 0.015, 0.0, 0.0; 0.0, 0.0, 0.015, 0.0, 0.0;
@ -101,7 +110,7 @@ fn test_matrixmarket_sparse_real_general() {
#[test] #[test]
#[rustfmt::skip] #[rustfmt::skip]
fn test_matrixmarket_sparse_int_symmetric() { fn test_matrixmarket_load_sparse_int_symmetric() {
let file_str = r#" let file_str = r#"
%%MatrixMarket matrix coordinate integer symmetric %%MatrixMarket matrix coordinate integer symmetric
% %
@ -117,7 +126,7 @@ fn test_matrixmarket_sparse_int_symmetric() {
5 5 55 5 5 55
"#; "#;
let sparse_mat = load_coo_from_matrix_market_str::<i128>(file_str).unwrap(); let sparse_mat = load_coo_from_matrix_market_str::<i128>(file_str).unwrap();
let expected = dmatrix![ let expected = matrix![
11, 0, 0, 0, -15; 11, 0, 0, 0, -15;
0, 22, 23, 24, 0; 0, 22, 23, 24, 0;
0, 23, 33, 0, 35; 0, 23, 33, 0, 35;
@ -129,7 +138,7 @@ fn test_matrixmarket_sparse_int_symmetric() {
#[test] #[test]
#[rustfmt::skip] #[rustfmt::skip]
fn test_matrixmarket_sparse_complex_hermitian() { fn test_matrixmarket_load_sparse_complex_hermitian() {
let file_str = r#" let file_str = r#"
%%MatrixMarket matrix coordinate complex hermitian %%MatrixMarket matrix coordinate complex hermitian
% %
@ -144,19 +153,19 @@ fn test_matrixmarket_sparse_complex_hermitian() {
"#; "#;
let sparse_mat = load_coo_from_matrix_market_str::<Complex<f64>>(file_str).unwrap(); let sparse_mat = load_coo_from_matrix_market_str::<Complex<f64>>(file_str).unwrap();
let expected = dmatrix![ let expected = matrix![
Complex::<f64>{re:1.0,im:0.0}, Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:0.0,im:0.0},Complex::<f64>{re:0.0,im:0.0}; C64{re:1.0,im:0.0}, C64{re:0.0,im:0.0}, C64{re:0.0,im:0.0}, C64{re:0.0,im:0.0},C64{re:0.0,im:0.0};
Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:10.5,im:0.0}, Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:250.5,im:-22.22},Complex::<f64>{re:0.0,im:0.0}; C64{re:0.0,im:0.0}, C64{re:10.5,im:0.0}, C64{re:0.0,im:0.0}, C64{re:250.5,im:-22.22},C64{re:0.0,im:0.0};
Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:0.015,im:0.0}, Complex::<f64>{re:0.0,im:0.0},Complex::<f64>{re:0.0,im:0.0}; C64{re:0.0,im:0.0}, C64{re:0.0,im:0.0}, C64{re:0.015,im:0.0}, C64{re:0.0,im:0.0},C64{re:0.0,im:0.0};
Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:250.5,im:22.22}, Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:-280.0,im:0.0},Complex::<f64>{re:0.0,im:-33.32}; C64{re:0.0,im:0.0}, C64{re:250.5,im:22.22}, C64{re:0.0,im:0.0}, C64{re:-280.0,im:0.0},C64{re:0.0,im:-33.32};
Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:0.0,im:0.0}, Complex::<f64>{re:0.0,im:33.32},Complex::<f64>{re:12.0,im:0.0}; C64{re:0.0,im:0.0}, C64{re:0.0,im:0.0}, C64{re:0.0,im:0.0}, C64{re:0.0,im:33.32},C64{re:12.0,im:0.0};
]; ];
assert_matrix_eq!(sparse_mat, expected); assert_matrix_eq!(sparse_mat, expected);
} }
#[test] #[test]
#[rustfmt::skip] #[rustfmt::skip]
fn test_matrixmarket_sparse_real_skew() { fn test_matrixmarket_load_sparse_real_skew() {
let file_str = r#" let file_str = r#"
%%MatrixMarket matrix coordinate real skew-symmetric %%MatrixMarket matrix coordinate real skew-symmetric
% %
@ -167,7 +176,7 @@ fn test_matrixmarket_sparse_real_skew() {
5 3 -35.0 5 3 -35.0
"#; "#;
let sparse_mat = load_coo_from_matrix_market_str::<f64>(file_str).unwrap(); let sparse_mat = load_coo_from_matrix_market_str::<f64>(file_str).unwrap();
let expected = dmatrix![ let expected = matrix![
0.0, 0.0, 0.0, 0.0, 15.0; 0.0, 0.0, 0.0, 0.0, 15.0;
0.0, 0.0, 23.0, 24.0, 0.0; 0.0, 0.0, 23.0, 24.0, 0.0;
0.0, -23.0, 0.0, 0.0, 35.0; 0.0, -23.0, 0.0, 0.0, 35.0;
@ -179,7 +188,7 @@ fn test_matrixmarket_sparse_real_skew() {
#[test] #[test]
#[rustfmt::skip] #[rustfmt::skip]
fn test_matrixmarket_sparse_pattern_general() { fn test_matrixmarket_load_sparse_pattern_general() {
let file_str = r#" let file_str = r#"
%%MatrixMarket matrix coordinate pattern general %%MatrixMarket matrix coordinate pattern general
% %
@ -198,10 +207,10 @@ fn test_matrixmarket_sparse_pattern_general() {
let pattern_matrix = load_coo_from_matrix_market_str::<()>(file_str).unwrap(); let pattern_matrix = load_coo_from_matrix_market_str::<()>(file_str).unwrap();
let nrows = pattern_matrix.nrows(); let nrows = pattern_matrix.nrows();
let ncols = pattern_matrix.ncols(); let ncols = pattern_matrix.ncols();
let (row_idx, col_idx, val) = pattern_matrix.disassemble(); let (row_idx, col_idx, val) = pattern_matrix.clone().disassemble();
let values = vec![1; val.len()]; let values = vec![1; val.len()];
let sparse_mat = CooMatrix::try_from_triplets(nrows, ncols, row_idx, col_idx, values).unwrap(); let sparse_mat = CooMatrix::try_from_triplets(nrows, ncols, row_idx, col_idx, values).unwrap();
let expected = dmatrix![ let expected = matrix![
1, 0, 0, 0, 1; 1, 0, 0, 0, 1;
0, 0, 1, 1, 0; 0, 0, 1, 1, 0;
0, 1, 0, 0, 1; 0, 1, 0, 0, 1;
@ -213,7 +222,7 @@ fn test_matrixmarket_sparse_pattern_general() {
#[test] #[test]
#[rustfmt::skip] #[rustfmt::skip]
fn test_matrixmarket_dense_real_general() { fn test_matrixmarket_load_dense_real_general() {
let file_str = r#" let file_str = r#"
%%MatrixMarket matrix array real general %%MatrixMarket matrix array real general
% %
@ -233,7 +242,7 @@ fn test_matrixmarket_dense_real_general() {
"#; "#;
let sparse_mat = load_coo_from_matrix_market_str::<f32>(file_str).unwrap(); let sparse_mat = load_coo_from_matrix_market_str::<f32>(file_str).unwrap();
let expected = dmatrix![ let expected = matrix![
1.0, 5.0, 9.0; 1.0, 5.0, 9.0;
2.0, 6.0, 10.0; 2.0, 6.0, 10.0;
3.0, 7.0, 11.0; 3.0, 7.0, 11.0;
@ -244,7 +253,7 @@ fn test_matrixmarket_dense_real_general() {
#[test] #[test]
#[rustfmt::skip] #[rustfmt::skip]
fn test_matrixmarket_dense_real_symmetric() { fn test_matrixmarket_load_dense_real_symmetric() {
let file_str = r#" let file_str = r#"
%%MatrixMarket matrix array real symmetric %%MatrixMarket matrix array real symmetric
% %
@ -262,7 +271,7 @@ fn test_matrixmarket_dense_real_symmetric() {
"#; "#;
let sparse_mat = load_coo_from_matrix_market_str::<f32>(file_str).unwrap(); let sparse_mat = load_coo_from_matrix_market_str::<f32>(file_str).unwrap();
let expected = dmatrix![ let expected = matrix![
1.0, 2.0, 3.0, 4.0; 1.0, 2.0, 3.0, 4.0;
2.0, 5.0, 6.0, 7.0; 2.0, 5.0, 6.0, 7.0;
3.0, 6.0, 8.0, 9.0; 3.0, 6.0, 8.0, 9.0;
@ -273,7 +282,7 @@ fn test_matrixmarket_dense_real_symmetric() {
#[test] #[test]
#[rustfmt::skip] #[rustfmt::skip]
fn test_matrixmarket_dense_complex_hermitian() { fn test_matrixmarket_load_dense_complex_hermitian() {
let file_str = r#" let file_str = r#"
%%MatrixMarket matrix array complex hermitian %%MatrixMarket matrix array complex hermitian
% %
@ -290,19 +299,19 @@ fn test_matrixmarket_dense_complex_hermitian() {
10.0 0.0 10.0 0.0
"#; "#;
let sparse_mat = load_coo_from_matrix_market_str::<Complex<f64>>(file_str).unwrap(); let sparse_mat = load_coo_from_matrix_market_str::<C64>(file_str).unwrap();
let expected = dmatrix![ let expected = matrix![
Complex::<f64>{re:1.0,im:0.0}, Complex::<f64>{re:2.0,im:-2.0} ,Complex::<f64>{re:3.0,im:-3.0} ,Complex::<f64>{re:4.0,im:-4.0}; C64{re:1.0,im:0.0}, C64{re:2.0,im:-2.0} ,C64{re:3.0,im:-3.0} ,C64{re:4.0,im:-4.0};
Complex::<f64>{re:2.0,im:2.0}, Complex::<f64>{re:5.0,im:0.0} ,Complex::<f64>{re:6.0,im:-6.0} ,Complex::<f64>{re:7.0,im:-7.0}; C64{re:2.0,im:2.0}, C64{re:5.0,im:0.0} ,C64{re:6.0,im:-6.0} ,C64{re:7.0,im:-7.0};
Complex::<f64>{re:3.0,im:3.0}, Complex::<f64>{re:6.0,im:6.0} ,Complex::<f64>{re:8.0,im:0.0} ,Complex::<f64>{re:9.0,im:-9.0}; C64{re:3.0,im:3.0}, C64{re:6.0,im:6.0} ,C64{re:8.0,im:0.0} ,C64{re:9.0,im:-9.0};
Complex::<f64>{re:4.0,im:4.0}, Complex::<f64>{re:7.0,im:7.0} ,Complex::<f64>{re:9.0,im:9.0} ,Complex::<f64>{re:10.0,im:0.0}; C64{re:4.0,im:4.0}, C64{re:7.0,im:7.0} ,C64{re:9.0,im:9.0} ,C64{re:10.0,im:0.0};
]; ];
assert_matrix_eq!(sparse_mat, expected); assert_matrix_eq!(sparse_mat, expected);
} }
#[test] #[test]
#[rustfmt::skip] #[rustfmt::skip]
fn test_matrixmarket_dense_int_skew() { fn test_matrixmarket_load_dense_int_skew() {
let file_str = r#" let file_str = r#"
%%MatrixMarket matrix array integer skew-symmetric %%MatrixMarket matrix array integer skew-symmetric
% %
@ -315,7 +324,7 @@ fn test_matrixmarket_dense_int_skew() {
6 6
"#; "#;
let sparse_mat = load_coo_from_matrix_market_str::<i32>(file_str).unwrap(); let sparse_mat = load_coo_from_matrix_market_str::<i32>(file_str).unwrap();
let expected = dmatrix![ let expected = matrix![
0,-1,-2,-3; 0,-1,-2,-3;
1, 0,-4,-5; 1, 0,-4,-5;
2, 4, 0,-6; 2, 4, 0,-6;
@ -326,7 +335,7 @@ fn test_matrixmarket_dense_int_skew() {
#[test] #[test]
#[rustfmt::skip] #[rustfmt::skip]
fn test_matrixmarket_dense_complex_general() { fn test_matrixmarket_load_dense_complex_general() {
let file_str = r#" let file_str = r#"
%%MatrixMarket matrix array complex general %%MatrixMarket matrix array complex general
% %
@ -336,10 +345,124 @@ fn test_matrixmarket_dense_complex_general() {
1 0 1 0
1 0 1 0
"#; "#;
let sparse_mat = load_coo_from_matrix_market_str::<Complex<f32>>(file_str).unwrap(); let sparse_mat = load_coo_from_matrix_market_str::<C32>(file_str).unwrap();
let expected = dmatrix![ let expected = matrix![
Complex::<f32>{re:1.0,im:0.0},Complex::<f32>{re:1.0,im:0.0}; C32{re:1.0,im:0.0},C32{re:1.0,im:0.0};
Complex::<f32>{re:1.0,im:0.0},Complex::<f32>{re:1.0,im:0.0}; C32{re:1.0,im:0.0},C32{re:1.0,im:0.0};
]; ];
assert_matrix_eq!(sparse_mat, expected); assert_matrix_eq!(sparse_mat, expected);
} }
#[test]
#[rustfmt::skip]
fn test_matrixmarket_write_real(){
let dense_matrix = matrix![
1.0, 2.0, 3.0;
2.0, 0.0, 3.0;
];
let row_indices = vec![0,1,0,0,1];
let col_indices = vec![0,0,1,2,2];
let values = vec![1.0,2.0,2.0,3.0,3.0];
let coo_matrix = CooMatrix::try_from_triplets(2, 3, row_indices, col_indices, values).unwrap();
assert_matrix_eq!(dense_matrix,coo_matrix);
let expected = r#"%%matrixmarket matrix coordinate real general
% matrixmarket file generated by nalgebra-sparse.
2 3 5
1 1 1
2 1 2
1 2 2
1 3 3
2 3 3
"#;
let matrixmarket_str = save_to_matrix_market_str(&coo_matrix);
assert_eq!(matrixmarket_str,expected);
}
#[test]
fn test_matrixmarket_write_int() {
let dense_matrix = matrix![
1,2,3;
2,0,3;
];
let row_indices = vec![0, 1, 0, 0, 1];
let col_indices = vec![0, 0, 1, 2, 2];
let values = vec![1, 2, 2, 3, 3];
let coo_matrix = CooMatrix::try_from_triplets(2, 3, row_indices, col_indices, values).unwrap();
assert_matrix_eq!(dense_matrix, coo_matrix);
let expected = r#"%%matrixmarket matrix coordinate integer general
% matrixmarket file generated by nalgebra-sparse.
2 3 5
1 1 1
2 1 2
1 2 2
1 3 3
2 3 3
"#;
let matrixmarket_str = save_to_matrix_market_str(&coo_matrix);
assert_eq!(matrixmarket_str, expected);
}
#[test]
fn test_matrixmarket_write_pattern() {
let row_indices = vec![0, 1, 0, 0, 1];
let col_indices = vec![0, 0, 1, 2, 2];
let values = vec![(), (), (), (), ()];
let coo_matrix = CooMatrix::try_from_triplets(2, 3, row_indices, col_indices, values).unwrap();
let expected = r#"%%matrixmarket matrix coordinate pattern general
% matrixmarket file generated by nalgebra-sparse.
2 3 5
1 1
2 1
1 2
1 3
2 3
"#;
let matrixmarket_str = save_to_matrix_market_str(&coo_matrix);
assert_eq!(matrixmarket_str, expected);
}
#[test]
fn test_matrixmarket_write_complex() {
let row_indices = vec![0, 1, 0, 0, 1];
let col_indices = vec![0, 0, 1, 2, 2];
let values = vec![
C64 { re: 1.0, im: 2.0 },
C64 { re: 2.0, im: 3.0 },
C64 { re: 3.0, im: 4.0 },
C64 { re: 4.0, im: 5.0 },
C64 { re: 5.0, im: 6.0 },
];
let coo_matrix = CooMatrix::try_from_triplets(2, 3, row_indices, col_indices, values).unwrap();
let expected = r#"%%matrixmarket matrix coordinate complex general
% matrixmarket file generated by nalgebra-sparse.
2 3 5
1 1 1 2
2 1 2 3
1 2 3 4
1 3 4 5
2 3 5 6
"#;
let matrixmarket_str = save_to_matrix_market_str(&coo_matrix);
assert_eq!(matrixmarket_str, expected);
}
proptest! {
#[test]
fn coo_matrix_market_roundtrip_str(coo in coo_no_duplicates(-10 ..= 10, 0 ..= 10, 0..= 10, 100)) {
let generated_matrixmarket_string = save_to_matrix_market_str(&coo);
let generated_matrix = load_coo_from_matrix_market_str(&generated_matrixmarket_string).unwrap();
assert_matrix_eq!(generated_matrix, coo);
}
}
proptest! {
#[test]
fn coo_matrix_market_roundtrip_file(coo in coo_no_duplicates(-10 ..= 10, 0 ..= 10, 0..= 10, 100)) {
let temp_dir = tempdir().expect("Unable to create temporary directory");
let file_path = temp_dir.path().join("temp.mtx");
save_to_matrix_market_file(&coo,&file_path).unwrap();
let generated_matrix = load_coo_from_matrix_market_file(file_path).unwrap();
assert_matrix_eq!(generated_matrix, coo);
temp_dir.close().expect("Unable to delete temporary directory");
}
}

View File

@ -6,14 +6,15 @@ use nalgebra_sparse::csc::CscMatrix;
use nalgebra_sparse::csr::CsrMatrix; use nalgebra_sparse::csr::CsrMatrix;
use nalgebra_sparse::ops::serial::{ use nalgebra_sparse::ops::serial::{
spadd_csc_prealloc, spadd_csr_prealloc, spadd_pattern, spmm_csc_dense, spmm_csc_prealloc, spadd_csc_prealloc, spadd_csr_prealloc, spadd_pattern, spmm_csc_dense, spmm_csc_prealloc,
spmm_csr_dense, spmm_csr_pattern, spmm_csr_prealloc, spsolve_csc_lower_triangular, spmm_csc_prealloc_unchecked, spmm_csr_dense, spmm_csr_pattern, spmm_csr_prealloc,
spmm_csr_prealloc_unchecked, spsolve_csc_lower_triangular,
}; };
use nalgebra_sparse::ops::Op; use nalgebra_sparse::ops::Op;
use nalgebra_sparse::pattern::SparsityPattern; use nalgebra_sparse::pattern::SparsityPattern;
use nalgebra_sparse::proptest::{csc, csr, sparsity_pattern}; use nalgebra_sparse::proptest::{csc, csr, sparsity_pattern};
use nalgebra::proptest::{matrix, vector}; use nalgebra::proptest::{matrix, vector};
use nalgebra::{DMatrix, DMatrixSlice, DMatrixSliceMut, Scalar}; use nalgebra::{DMatrix, DMatrixView, DMatrixViewMut, Scalar};
use proptest::prelude::*; use proptest::prelude::*;
@ -332,10 +333,10 @@ fn csc_square_with_non_zero_diagonals() -> impl Strategy<Value = CscMatrix<f64>>
/// Helper function to help us call dense GEMM with our `Op` type /// Helper function to help us call dense GEMM with our `Op` type
fn dense_gemm<'a>( fn dense_gemm<'a>(
beta: i32, beta: i32,
c: impl Into<DMatrixSliceMut<'a, i32>>, c: impl Into<DMatrixViewMut<'a, i32>>,
alpha: i32, alpha: i32,
a: Op<impl Into<DMatrixSlice<'a, i32>>>, a: Op<impl Into<DMatrixView<'a, i32>>>,
b: Op<impl Into<DMatrixSlice<'a, i32>>>, b: Op<impl Into<DMatrixView<'a, i32>>>,
) { ) {
let mut c = c.into(); let mut c = c.into();
let a = a.convert(); let a = a.convert();
@ -543,6 +544,29 @@ proptest! {
prop_assert_eq!(&c_pattern, c_csr.pattern()); prop_assert_eq!(&c_pattern, c_csr.pattern());
} }
#[test]
fn spmm_csr_prealloc_unchecked_test(SpmmCsrArgs { c, beta, alpha, a, b }
in spmm_csr_prealloc_args_strategy()
) {
// Test that we get the expected result by comparing to an equivalent dense operation
// (here we give in the C matrix, so the sparsity pattern is essentially fixed)
let mut c_sparse = c.clone();
spmm_csr_prealloc_unchecked(beta, &mut c_sparse, alpha, a.as_ref(), b.as_ref()).unwrap();
let mut c_dense = DMatrix::from(&c);
let op_a_dense = match a {
Op::NoOp(ref a) => DMatrix::from(a),
Op::Transpose(ref a) => DMatrix::from(a).transpose(),
};
let op_b_dense = match b {
Op::NoOp(ref b) => DMatrix::from(b),
Op::Transpose(ref b) => DMatrix::from(b).transpose(),
};
c_dense = beta * c_dense + alpha * &op_a_dense * op_b_dense;
prop_assert_eq!(&DMatrix::from(&c_sparse), &c_dense);
}
#[test] #[test]
fn spmm_csr_prealloc_test(SpmmCsrArgs { c, beta, alpha, a, b } fn spmm_csr_prealloc_test(SpmmCsrArgs { c, beta, alpha, a, b }
in spmm_csr_prealloc_args_strategy() in spmm_csr_prealloc_args_strategy()
@ -705,6 +729,29 @@ proptest! {
prop_assert_eq!(&DMatrix::from(&c_sparse), &c_dense); prop_assert_eq!(&DMatrix::from(&c_sparse), &c_dense);
} }
#[test]
fn spmm_csc_prealloc_unchecked_test(SpmmCscArgs { c, beta, alpha, a, b }
in spmm_csc_prealloc_args_strategy()
) {
// Test that we get the expected result by comparing to an equivalent dense operation
// (here we give in the C matrix, so the sparsity pattern is essentially fixed)
let mut c_sparse = c.clone();
spmm_csc_prealloc_unchecked(beta, &mut c_sparse, alpha, a.as_ref(), b.as_ref()).unwrap();
let mut c_dense = DMatrix::from(&c);
let op_a_dense = match a {
Op::NoOp(ref a) => DMatrix::from(a),
Op::Transpose(ref a) => DMatrix::from(a).transpose(),
};
let op_b_dense = match b {
Op::NoOp(ref b) => DMatrix::from(b),
Op::Transpose(ref b) => DMatrix::from(b).transpose(),
};
c_dense = beta * c_dense + alpha * &op_a_dense * op_b_dense;
prop_assert_eq!(&DMatrix::from(&c_sparse), &c_dense);
}
#[test] #[test]
fn spmm_csc_prealloc_panics_on_dim_mismatch( fn spmm_csc_prealloc_panics_on_dim_mismatch(
(alpha, beta, c, a, b) (alpha, beta, c, a, b)

View File

@ -1,5 +1,19 @@
use nalgebra_sparse::pattern::{SparsityPattern, SparsityPatternFormatError}; use nalgebra_sparse::pattern::{SparsityPattern, SparsityPatternFormatError};
#[test]
fn sparsity_pattern_default() {
// Check that the pattern created with `Default::default()` is equivalent to a zero-sized pattern.
let pattern = SparsityPattern::default();
let zero = SparsityPattern::zeros(0, 0);
assert_eq!(pattern.major_dim(), zero.major_dim());
assert_eq!(pattern.minor_dim(), zero.minor_dim());
assert_eq!(pattern.major_offsets(), zero.major_offsets());
assert_eq!(pattern.minor_indices(), zero.minor_indices());
assert_eq!(pattern.nnz(), 0);
}
#[test] #[test]
fn sparsity_pattern_valid_data() { fn sparsity_pattern_valid_data() {
// Construct pattern from valid data and check that selected methods return results // Construct pattern from valid data and check that selected methods return results

View File

@ -1,5 +1,5 @@
#[cfg(any(feature = "alloc", feature = "std"))] #[cfg(any(feature = "alloc", feature = "std"))]
use crate::base::dimension::Dynamic; use crate::base::dimension::Dyn;
use crate::base::dimension::{U1, U2, U3, U4, U5, U6}; use crate::base::dimension::{U1, U2, U3, U4, U5, U6};
use crate::base::storage::Owned; use crate::base::storage::Owned;
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
@ -48,69 +48,69 @@ pub type SMatrix<T, const R: usize, const C: usize> =
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type DMatrix<T> = Matrix<T, Dynamic, Dynamic, VecStorage<T, Dynamic, Dynamic>>; pub type DMatrix<T> = Matrix<T, Dyn, Dyn, VecStorage<T, Dyn, Dyn>>;
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 1 columns. /// A heap-allocated, column-major, matrix with a dynamic number of rows and 1 columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type MatrixXx1<T> = Matrix<T, Dynamic, U1, VecStorage<T, Dynamic, U1>>; pub type MatrixXx1<T> = Matrix<T, Dyn, U1, VecStorage<T, Dyn, U1>>;
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 2 columns. /// A heap-allocated, column-major, matrix with a dynamic number of rows and 2 columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type MatrixXx2<T> = Matrix<T, Dynamic, U2, VecStorage<T, Dynamic, U2>>; pub type MatrixXx2<T> = Matrix<T, Dyn, U2, VecStorage<T, Dyn, U2>>;
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 3 columns. /// A heap-allocated, column-major, matrix with a dynamic number of rows and 3 columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type MatrixXx3<T> = Matrix<T, Dynamic, U3, VecStorage<T, Dynamic, U3>>; pub type MatrixXx3<T> = Matrix<T, Dyn, U3, VecStorage<T, Dyn, U3>>;
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 4 columns. /// A heap-allocated, column-major, matrix with a dynamic number of rows and 4 columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type MatrixXx4<T> = Matrix<T, Dynamic, U4, VecStorage<T, Dynamic, U4>>; pub type MatrixXx4<T> = Matrix<T, Dyn, U4, VecStorage<T, Dyn, U4>>;
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 5 columns. /// A heap-allocated, column-major, matrix with a dynamic number of rows and 5 columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type MatrixXx5<T> = Matrix<T, Dynamic, U5, VecStorage<T, Dynamic, U5>>; pub type MatrixXx5<T> = Matrix<T, Dyn, U5, VecStorage<T, Dyn, U5>>;
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 6 columns. /// A heap-allocated, column-major, matrix with a dynamic number of rows and 6 columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type MatrixXx6<T> = Matrix<T, Dynamic, U6, VecStorage<T, Dynamic, U6>>; pub type MatrixXx6<T> = Matrix<T, Dyn, U6, VecStorage<T, Dyn, U6>>;
/// A heap-allocated, row-major, matrix with 1 rows and a dynamic number of columns. /// A heap-allocated, column-major, matrix with 1 rows and a dynamic number of columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix1xX<T> = Matrix<T, U1, Dynamic, VecStorage<T, U1, Dynamic>>; pub type Matrix1xX<T> = Matrix<T, U1, Dyn, VecStorage<T, U1, Dyn>>;
/// A heap-allocated, row-major, matrix with 2 rows and a dynamic number of columns. /// A heap-allocated, column-major, matrix with 2 rows and a dynamic number of columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix2xX<T> = Matrix<T, U2, Dynamic, VecStorage<T, U2, Dynamic>>; pub type Matrix2xX<T> = Matrix<T, U2, Dyn, VecStorage<T, U2, Dyn>>;
/// A heap-allocated, row-major, matrix with 3 rows and a dynamic number of columns. /// A heap-allocated, column-major, matrix with 3 rows and a dynamic number of columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix3xX<T> = Matrix<T, U3, Dynamic, VecStorage<T, U3, Dynamic>>; pub type Matrix3xX<T> = Matrix<T, U3, Dyn, VecStorage<T, U3, Dyn>>;
/// A heap-allocated, row-major, matrix with 4 rows and a dynamic number of columns. /// A heap-allocated, column-major, matrix with 4 rows and a dynamic number of columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix4xX<T> = Matrix<T, U4, Dynamic, VecStorage<T, U4, Dynamic>>; pub type Matrix4xX<T> = Matrix<T, U4, Dyn, VecStorage<T, U4, Dyn>>;
/// A heap-allocated, row-major, matrix with 5 rows and a dynamic number of columns. /// A heap-allocated, column-major, matrix with 5 rows and a dynamic number of columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix5xX<T> = Matrix<T, U5, Dynamic, VecStorage<T, U5, Dynamic>>; pub type Matrix5xX<T> = Matrix<T, U5, Dyn, VecStorage<T, U5, Dyn>>;
/// A heap-allocated, row-major, matrix with 6 rows and a dynamic number of columns. /// A heap-allocated, column-major, matrix with 6 rows and a dynamic number of columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix6xX<T> = Matrix<T, U6, Dynamic, VecStorage<T, U6, Dynamic>>; pub type Matrix6xX<T> = Matrix<T, U6, Dyn, VecStorage<T, U6, Dyn>>;
/// A stack-allocated, column-major, 1x1 square matrix. /// A stack-allocated, column-major, 1x1 square matrix.
/// ///
@ -276,7 +276,7 @@ pub type Matrix6x5<T> = Matrix<T, U6, U5, ArrayStorage<T, 6, 5>>;
*/ */
/// A dynamically sized column vector. /// A dynamically sized column vector.
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type DVector<T> = Matrix<T, Dynamic, U1, VecStorage<T, Dynamic, U1>>; pub type DVector<T> = Matrix<T, Dyn, U1, VecStorage<T, Dyn, U1>>;
/// An owned D-dimensional column vector. /// An owned D-dimensional column vector.
pub type OVector<T, D> = Matrix<T, D, U1, Owned<T, D, U1>>; pub type OVector<T, D> = Matrix<T, D, U1, Owned<T, D, U1>>;
@ -316,7 +316,7 @@ pub type Vector6<T> = Matrix<T, U6, U1, ArrayStorage<T, 6, 1>>;
*/ */
/// A dynamically sized row vector. /// A dynamically sized row vector.
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type RowDVector<T> = Matrix<T, U1, Dynamic, VecStorage<T, U1, Dynamic>>; pub type RowDVector<T> = Matrix<T, U1, Dyn, VecStorage<T, U1, Dyn>>;
/// An owned D-dimensional row vector. /// An owned D-dimensional row vector.
pub type RowOVector<T, D> = Matrix<T, U1, D, Owned<T, U1, D>>; pub type RowOVector<T, D> = Matrix<T, U1, D, Owned<T, U1, D>>;

View File

@ -1,6 +1,7 @@
use crate::base::dimension::{Dynamic, U1, U2, U3, U4, U5, U6}; use crate::base::dimension::{Dyn, U1, U2, U3, U4, U5, U6};
use crate::base::matrix_slice::{SliceStorage, SliceStorageMut}; use crate::base::matrix_view::{ViewStorage, ViewStorageMut};
use crate::base::{Const, Matrix}; use crate::base::{Const, Matrix};
use crate::slice_deprecation_note;
/* /*
* *
@ -13,286 +14,345 @@ use crate::base::{Const, Matrix};
/// A column-major matrix slice with dimensions known at compile-time. /// A column-major matrix slice with dimensions known at compile-time.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(SMatrixView)]
pub type SMatrixSlice<'a, T, const R: usize, const C: usize> = pub type SMatrixSlice<'a, T, const R: usize, const C: usize> =
Matrix<T, Const<R>, Const<C>, SliceStorage<'a, T, Const<R>, Const<C>, Const<1>, Const<R>>>; Matrix<T, Const<R>, Const<C>, ViewStorage<'a, T, Const<R>, Const<C>, Const<1>, Const<R>>>;
/// A column-major matrix slice dynamic numbers of rows and columns. /// A column-major matrix slice dynamic numbers of rows and columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type DMatrixSlice<'a, T, RStride = U1, CStride = Dynamic> = #[deprecated = slice_deprecation_note!(DMatrixView)]
Matrix<T, Dynamic, Dynamic, SliceStorage<'a, T, Dynamic, Dynamic, RStride, CStride>>; pub type DMatrixSlice<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, Dyn, ViewStorage<'a, T, Dyn, Dyn, RStride, CStride>>;
/// A column-major 1x1 matrix slice. /// A column-major 1x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView1)]
pub type MatrixSlice1<'a, T, RStride = U1, CStride = U1> = pub type MatrixSlice1<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U1, SliceStorage<'a, T, U1, U1, RStride, CStride>>; Matrix<T, U1, U1, ViewStorage<'a, T, U1, U1, RStride, CStride>>;
/// A column-major 2x2 matrix slice. /// A column-major 2x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView2)]
pub type MatrixSlice2<'a, T, RStride = U1, CStride = U2> = pub type MatrixSlice2<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U2, SliceStorage<'a, T, U2, U2, RStride, CStride>>; Matrix<T, U2, U2, ViewStorage<'a, T, U2, U2, RStride, CStride>>;
/// A column-major 3x3 matrix slice. /// A column-major 3x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView3)]
pub type MatrixSlice3<'a, T, RStride = U1, CStride = U3> = pub type MatrixSlice3<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U3, SliceStorage<'a, T, U3, U3, RStride, CStride>>; Matrix<T, U3, U3, ViewStorage<'a, T, U3, U3, RStride, CStride>>;
/// A column-major 4x4 matrix slice. /// A column-major 4x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView4)]
pub type MatrixSlice4<'a, T, RStride = U1, CStride = U4> = pub type MatrixSlice4<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U4, SliceStorage<'a, T, U4, U4, RStride, CStride>>; Matrix<T, U4, U4, ViewStorage<'a, T, U4, U4, RStride, CStride>>;
/// A column-major 5x5 matrix slice. /// A column-major 5x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView5)]
pub type MatrixSlice5<'a, T, RStride = U1, CStride = U5> = pub type MatrixSlice5<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U5, SliceStorage<'a, T, U5, U5, RStride, CStride>>; Matrix<T, U5, U5, ViewStorage<'a, T, U5, U5, RStride, CStride>>;
/// A column-major 6x6 matrix slice. /// A column-major 6x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView6)]
pub type MatrixSlice6<'a, T, RStride = U1, CStride = U6> = pub type MatrixSlice6<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U6, SliceStorage<'a, T, U6, U6, RStride, CStride>>; Matrix<T, U6, U6, ViewStorage<'a, T, U6, U6, RStride, CStride>>;
/// A column-major 1x2 matrix slice. /// A column-major 1x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView1x2)]
pub type MatrixSlice1x2<'a, T, RStride = U1, CStride = U1> = pub type MatrixSlice1x2<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U2, SliceStorage<'a, T, U1, U2, RStride, CStride>>; Matrix<T, U1, U2, ViewStorage<'a, T, U1, U2, RStride, CStride>>;
/// A column-major 1x3 matrix slice. /// A column-major 1x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView1x3)]
pub type MatrixSlice1x3<'a, T, RStride = U1, CStride = U1> = pub type MatrixSlice1x3<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U3, SliceStorage<'a, T, U1, U3, RStride, CStride>>; Matrix<T, U1, U3, ViewStorage<'a, T, U1, U3, RStride, CStride>>;
/// A column-major 1x4 matrix slice. /// A column-major 1x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView1x4)]
pub type MatrixSlice1x4<'a, T, RStride = U1, CStride = U1> = pub type MatrixSlice1x4<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U4, SliceStorage<'a, T, U1, U4, RStride, CStride>>; Matrix<T, U1, U4, ViewStorage<'a, T, U1, U4, RStride, CStride>>;
/// A column-major 1x5 matrix slice. /// A column-major 1x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView1x5)]
pub type MatrixSlice1x5<'a, T, RStride = U1, CStride = U1> = pub type MatrixSlice1x5<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U5, SliceStorage<'a, T, U1, U5, RStride, CStride>>; Matrix<T, U1, U5, ViewStorage<'a, T, U1, U5, RStride, CStride>>;
/// A column-major 1x6 matrix slice. /// A column-major 1x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView1x6)]
pub type MatrixSlice1x6<'a, T, RStride = U1, CStride = U1> = pub type MatrixSlice1x6<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U6, SliceStorage<'a, T, U1, U6, RStride, CStride>>; Matrix<T, U1, U6, ViewStorage<'a, T, U1, U6, RStride, CStride>>;
/// A column-major 2x1 matrix slice. /// A column-major 2x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView2x1)]
pub type MatrixSlice2x1<'a, T, RStride = U1, CStride = U2> = pub type MatrixSlice2x1<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U1, SliceStorage<'a, T, U2, U1, RStride, CStride>>; Matrix<T, U2, U1, ViewStorage<'a, T, U2, U1, RStride, CStride>>;
/// A column-major 2x3 matrix slice. /// A column-major 2x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView2x3)]
pub type MatrixSlice2x3<'a, T, RStride = U1, CStride = U2> = pub type MatrixSlice2x3<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U3, SliceStorage<'a, T, U2, U3, RStride, CStride>>; Matrix<T, U2, U3, ViewStorage<'a, T, U2, U3, RStride, CStride>>;
/// A column-major 2x4 matrix slice. /// A column-major 2x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView2x4)]
pub type MatrixSlice2x4<'a, T, RStride = U1, CStride = U2> = pub type MatrixSlice2x4<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U4, SliceStorage<'a, T, U2, U4, RStride, CStride>>; Matrix<T, U2, U4, ViewStorage<'a, T, U2, U4, RStride, CStride>>;
/// A column-major 2x5 matrix slice. /// A column-major 2x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView2x5)]
pub type MatrixSlice2x5<'a, T, RStride = U1, CStride = U2> = pub type MatrixSlice2x5<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U5, SliceStorage<'a, T, U2, U5, RStride, CStride>>; Matrix<T, U2, U5, ViewStorage<'a, T, U2, U5, RStride, CStride>>;
/// A column-major 2x6 matrix slice. /// A column-major 2x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView2x6)]
pub type MatrixSlice2x6<'a, T, RStride = U1, CStride = U2> = pub type MatrixSlice2x6<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U6, SliceStorage<'a, T, U2, U6, RStride, CStride>>; Matrix<T, U2, U6, ViewStorage<'a, T, U2, U6, RStride, CStride>>;
/// A column-major 3x1 matrix slice. /// A column-major 3x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView3x1)]
pub type MatrixSlice3x1<'a, T, RStride = U1, CStride = U3> = pub type MatrixSlice3x1<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U1, SliceStorage<'a, T, U3, U1, RStride, CStride>>; Matrix<T, U3, U1, ViewStorage<'a, T, U3, U1, RStride, CStride>>;
/// A column-major 3x2 matrix slice. /// A column-major 3x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView3x2)]
pub type MatrixSlice3x2<'a, T, RStride = U1, CStride = U3> = pub type MatrixSlice3x2<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U2, SliceStorage<'a, T, U3, U2, RStride, CStride>>; Matrix<T, U3, U2, ViewStorage<'a, T, U3, U2, RStride, CStride>>;
/// A column-major 3x4 matrix slice. /// A column-major 3x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView3x4)]
pub type MatrixSlice3x4<'a, T, RStride = U1, CStride = U3> = pub type MatrixSlice3x4<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U4, SliceStorage<'a, T, U3, U4, RStride, CStride>>; Matrix<T, U3, U4, ViewStorage<'a, T, U3, U4, RStride, CStride>>;
/// A column-major 3x5 matrix slice. /// A column-major 3x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView3x5)]
pub type MatrixSlice3x5<'a, T, RStride = U1, CStride = U3> = pub type MatrixSlice3x5<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U5, SliceStorage<'a, T, U3, U5, RStride, CStride>>; Matrix<T, U3, U5, ViewStorage<'a, T, U3, U5, RStride, CStride>>;
/// A column-major 3x6 matrix slice. /// A column-major 3x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView3x6)]
pub type MatrixSlice3x6<'a, T, RStride = U1, CStride = U3> = pub type MatrixSlice3x6<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U6, SliceStorage<'a, T, U3, U6, RStride, CStride>>; Matrix<T, U3, U6, ViewStorage<'a, T, U3, U6, RStride, CStride>>;
/// A column-major 4x1 matrix slice. /// A column-major 4x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView4x1)]
pub type MatrixSlice4x1<'a, T, RStride = U1, CStride = U4> = pub type MatrixSlice4x1<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U1, SliceStorage<'a, T, U4, U1, RStride, CStride>>; Matrix<T, U4, U1, ViewStorage<'a, T, U4, U1, RStride, CStride>>;
/// A column-major 4x2 matrix slice. /// A column-major 4x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView4x2)]
pub type MatrixSlice4x2<'a, T, RStride = U1, CStride = U4> = pub type MatrixSlice4x2<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U2, SliceStorage<'a, T, U4, U2, RStride, CStride>>; Matrix<T, U4, U2, ViewStorage<'a, T, U4, U2, RStride, CStride>>;
/// A column-major 4x3 matrix slice. /// A column-major 4x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView4x3)]
pub type MatrixSlice4x3<'a, T, RStride = U1, CStride = U4> = pub type MatrixSlice4x3<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U3, SliceStorage<'a, T, U4, U3, RStride, CStride>>; Matrix<T, U4, U3, ViewStorage<'a, T, U4, U3, RStride, CStride>>;
/// A column-major 4x5 matrix slice. /// A column-major 4x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView4x5)]
pub type MatrixSlice4x5<'a, T, RStride = U1, CStride = U4> = pub type MatrixSlice4x5<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U5, SliceStorage<'a, T, U4, U5, RStride, CStride>>; Matrix<T, U4, U5, ViewStorage<'a, T, U4, U5, RStride, CStride>>;
/// A column-major 4x6 matrix slice. /// A column-major 4x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView4x6)]
pub type MatrixSlice4x6<'a, T, RStride = U1, CStride = U4> = pub type MatrixSlice4x6<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U6, SliceStorage<'a, T, U4, U6, RStride, CStride>>; Matrix<T, U4, U6, ViewStorage<'a, T, U4, U6, RStride, CStride>>;
/// A column-major 5x1 matrix slice. /// A column-major 5x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView5x1)]
pub type MatrixSlice5x1<'a, T, RStride = U1, CStride = U5> = pub type MatrixSlice5x1<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U1, SliceStorage<'a, T, U5, U1, RStride, CStride>>; Matrix<T, U5, U1, ViewStorage<'a, T, U5, U1, RStride, CStride>>;
/// A column-major 5x2 matrix slice. /// A column-major 5x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView5x2)]
pub type MatrixSlice5x2<'a, T, RStride = U1, CStride = U5> = pub type MatrixSlice5x2<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U2, SliceStorage<'a, T, U5, U2, RStride, CStride>>; Matrix<T, U5, U2, ViewStorage<'a, T, U5, U2, RStride, CStride>>;
/// A column-major 5x3 matrix slice. /// A column-major 5x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView5x3)]
pub type MatrixSlice5x3<'a, T, RStride = U1, CStride = U5> = pub type MatrixSlice5x3<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U3, SliceStorage<'a, T, U5, U3, RStride, CStride>>; Matrix<T, U5, U3, ViewStorage<'a, T, U5, U3, RStride, CStride>>;
/// A column-major 5x4 matrix slice. /// A column-major 5x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView5x4)]
pub type MatrixSlice5x4<'a, T, RStride = U1, CStride = U5> = pub type MatrixSlice5x4<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U4, SliceStorage<'a, T, U5, U4, RStride, CStride>>; Matrix<T, U5, U4, ViewStorage<'a, T, U5, U4, RStride, CStride>>;
/// A column-major 5x6 matrix slice. /// A column-major 5x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView5x6)]
pub type MatrixSlice5x6<'a, T, RStride = U1, CStride = U5> = pub type MatrixSlice5x6<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U6, SliceStorage<'a, T, U5, U6, RStride, CStride>>; Matrix<T, U5, U6, ViewStorage<'a, T, U5, U6, RStride, CStride>>;
/// A column-major 6x1 matrix slice. /// A column-major 6x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView6x1)]
pub type MatrixSlice6x1<'a, T, RStride = U1, CStride = U6> = pub type MatrixSlice6x1<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U1, SliceStorage<'a, T, U6, U1, RStride, CStride>>; Matrix<T, U6, U1, ViewStorage<'a, T, U6, U1, RStride, CStride>>;
/// A column-major 6x2 matrix slice. /// A column-major 6x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView6x2)]
pub type MatrixSlice6x2<'a, T, RStride = U1, CStride = U6> = pub type MatrixSlice6x2<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U2, SliceStorage<'a, T, U6, U2, RStride, CStride>>; Matrix<T, U6, U2, ViewStorage<'a, T, U6, U2, RStride, CStride>>;
/// A column-major 6x3 matrix slice. /// A column-major 6x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView6x3)]
pub type MatrixSlice6x3<'a, T, RStride = U1, CStride = U6> = pub type MatrixSlice6x3<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U3, SliceStorage<'a, T, U6, U3, RStride, CStride>>; Matrix<T, U6, U3, ViewStorage<'a, T, U6, U3, RStride, CStride>>;
/// A column-major 6x4 matrix slice. /// A column-major 6x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView6x4)]
pub type MatrixSlice6x4<'a, T, RStride = U1, CStride = U6> = pub type MatrixSlice6x4<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U4, SliceStorage<'a, T, U6, U4, RStride, CStride>>; Matrix<T, U6, U4, ViewStorage<'a, T, U6, U4, RStride, CStride>>;
/// A column-major 6x5 matrix slice. /// A column-major 6x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixView6x5)]
pub type MatrixSlice6x5<'a, T, RStride = U1, CStride = U6> = pub type MatrixSlice6x5<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U5, SliceStorage<'a, T, U6, U5, RStride, CStride>>; Matrix<T, U6, U5, ViewStorage<'a, T, U6, U5, RStride, CStride>>;
/// A column-major matrix slice with 1 row and a number of columns chosen at runtime. /// A column-major matrix slice with 1 row and a number of columns chosen at runtime.
#[deprecated = slice_deprecation_note!(MatrixView1xX)]
pub type MatrixSlice1xX<'a, T, RStride = U1, CStride = U1> = pub type MatrixSlice1xX<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, Dynamic, SliceStorage<'a, T, U1, Dynamic, RStride, CStride>>; Matrix<T, U1, Dyn, ViewStorage<'a, T, U1, Dyn, RStride, CStride>>;
/// A column-major matrix slice with 2 rows and a number of columns chosen at runtime. /// A column-major matrix slice with 2 rows and a number of columns chosen at runtime.
#[deprecated = slice_deprecation_note!(MatrixView2xX)]
pub type MatrixSlice2xX<'a, T, RStride = U1, CStride = U2> = pub type MatrixSlice2xX<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, Dynamic, SliceStorage<'a, T, U2, Dynamic, RStride, CStride>>; Matrix<T, U2, Dyn, ViewStorage<'a, T, U2, Dyn, RStride, CStride>>;
/// A column-major matrix slice with 3 rows and a number of columns chosen at runtime. /// A column-major matrix slice with 3 rows and a number of columns chosen at runtime.
#[deprecated = slice_deprecation_note!(MatrixView3xX)]
pub type MatrixSlice3xX<'a, T, RStride = U1, CStride = U3> = pub type MatrixSlice3xX<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, Dynamic, SliceStorage<'a, T, U3, Dynamic, RStride, CStride>>; Matrix<T, U3, Dyn, ViewStorage<'a, T, U3, Dyn, RStride, CStride>>;
/// A column-major matrix slice with 4 rows and a number of columns chosen at runtime. /// A column-major matrix slice with 4 rows and a number of columns chosen at runtime.
#[deprecated = slice_deprecation_note!(MatrixView4xX)]
pub type MatrixSlice4xX<'a, T, RStride = U1, CStride = U4> = pub type MatrixSlice4xX<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, Dynamic, SliceStorage<'a, T, U4, Dynamic, RStride, CStride>>; Matrix<T, U4, Dyn, ViewStorage<'a, T, U4, Dyn, RStride, CStride>>;
/// A column-major matrix slice with 5 rows and a number of columns chosen at runtime. /// A column-major matrix slice with 5 rows and a number of columns chosen at runtime.
#[deprecated = slice_deprecation_note!(MatrixView5xX)]
pub type MatrixSlice5xX<'a, T, RStride = U1, CStride = U5> = pub type MatrixSlice5xX<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, Dynamic, SliceStorage<'a, T, U5, Dynamic, RStride, CStride>>; Matrix<T, U5, Dyn, ViewStorage<'a, T, U5, Dyn, RStride, CStride>>;
/// A column-major matrix slice with 6 rows and a number of columns chosen at runtime. /// A column-major matrix slice with 6 rows and a number of columns chosen at runtime.
#[deprecated = slice_deprecation_note!(MatrixView6xX)]
pub type MatrixSlice6xX<'a, T, RStride = U1, CStride = U6> = pub type MatrixSlice6xX<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, Dynamic, SliceStorage<'a, T, U6, Dynamic, RStride, CStride>>; Matrix<T, U6, Dyn, ViewStorage<'a, T, U6, Dyn, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 1 column. /// A column-major matrix slice with a number of rows chosen at runtime and 1 column.
pub type MatrixSliceXx1<'a, T, RStride = U1, CStride = Dynamic> = #[deprecated = slice_deprecation_note!(MatrixViewXx1)]
Matrix<T, Dynamic, U1, SliceStorage<'a, T, Dynamic, U1, RStride, CStride>>; pub type MatrixSliceXx1<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U1, ViewStorage<'a, T, Dyn, U1, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 2 columns. /// A column-major matrix slice with a number of rows chosen at runtime and 2 columns.
pub type MatrixSliceXx2<'a, T, RStride = U1, CStride = Dynamic> = #[deprecated = slice_deprecation_note!(MatrixViewXx2)]
Matrix<T, Dynamic, U2, SliceStorage<'a, T, Dynamic, U2, RStride, CStride>>; pub type MatrixSliceXx2<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U2, ViewStorage<'a, T, Dyn, U2, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 3 columns. /// A column-major matrix slice with a number of rows chosen at runtime and 3 columns.
pub type MatrixSliceXx3<'a, T, RStride = U1, CStride = Dynamic> = #[deprecated = slice_deprecation_note!(MatrixViewXx3)]
Matrix<T, Dynamic, U3, SliceStorage<'a, T, Dynamic, U3, RStride, CStride>>; pub type MatrixSliceXx3<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U3, ViewStorage<'a, T, Dyn, U3, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 4 columns. /// A column-major matrix slice with a number of rows chosen at runtime and 4 columns.
pub type MatrixSliceXx4<'a, T, RStride = U1, CStride = Dynamic> = #[deprecated = slice_deprecation_note!(MatrixViewXx4)]
Matrix<T, Dynamic, U4, SliceStorage<'a, T, Dynamic, U4, RStride, CStride>>; pub type MatrixSliceXx4<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U4, ViewStorage<'a, T, Dyn, U4, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 5 columns. /// A column-major matrix slice with a number of rows chosen at runtime and 5 columns.
pub type MatrixSliceXx5<'a, T, RStride = U1, CStride = Dynamic> = #[deprecated = slice_deprecation_note!(MatrixViewXx5)]
Matrix<T, Dynamic, U5, SliceStorage<'a, T, Dynamic, U5, RStride, CStride>>; pub type MatrixSliceXx5<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U5, ViewStorage<'a, T, Dyn, U5, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 6 columns. /// A column-major matrix slice with a number of rows chosen at runtime and 6 columns.
pub type MatrixSliceXx6<'a, T, RStride = U1, CStride = Dynamic> = #[deprecated = slice_deprecation_note!(MatrixViewXx6)]
Matrix<T, Dynamic, U6, SliceStorage<'a, T, Dynamic, U6, RStride, CStride>>; pub type MatrixSliceXx6<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U6, ViewStorage<'a, T, Dyn, U6, RStride, CStride>>;
/// A column vector slice with dimensions known at compile-time. /// A column vector slice with dimensions known at compile-time.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(VectorView)]
pub type VectorSlice<'a, T, D, RStride = U1, CStride = D> = pub type VectorSlice<'a, T, D, RStride = U1, CStride = D> =
Matrix<T, D, U1, SliceStorage<'a, T, D, U1, RStride, CStride>>; Matrix<T, D, U1, ViewStorage<'a, T, D, U1, RStride, CStride>>;
/// A column vector slice with dimensions known at compile-time. /// A column vector slice with dimensions known at compile-time.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(SVectorView)]
pub type SVectorSlice<'a, T, const D: usize> = pub type SVectorSlice<'a, T, const D: usize> =
Matrix<T, Const<D>, Const<1>, SliceStorage<'a, T, Const<D>, Const<1>, Const<1>, Const<D>>>; Matrix<T, Const<D>, Const<1>, ViewStorage<'a, T, Const<D>, Const<1>, Const<1>, Const<D>>>;
/// A column vector slice dynamic numbers of rows and columns. /// A column vector slice dynamic numbers of rows and columns.
pub type DVectorSlice<'a, T, RStride = U1, CStride = Dynamic> = #[deprecated = slice_deprecation_note!(DVectorView)]
Matrix<T, Dynamic, U1, SliceStorage<'a, T, Dynamic, U1, RStride, CStride>>; pub type DVectorSlice<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U1, ViewStorage<'a, T, Dyn, U1, RStride, CStride>>;
/// A 1D column vector slice. /// A 1D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(VectorView1)]
pub type VectorSlice1<'a, T, RStride = U1, CStride = U1> = pub type VectorSlice1<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U1, SliceStorage<'a, T, U1, U1, RStride, CStride>>; Matrix<T, U1, U1, ViewStorage<'a, T, U1, U1, RStride, CStride>>;
/// A 2D column vector slice. /// A 2D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(VectorView2)]
pub type VectorSlice2<'a, T, RStride = U1, CStride = U2> = pub type VectorSlice2<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U1, SliceStorage<'a, T, U2, U1, RStride, CStride>>; Matrix<T, U2, U1, ViewStorage<'a, T, U2, U1, RStride, CStride>>;
/// A 3D column vector slice. /// A 3D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(VectorView3)]
pub type VectorSlice3<'a, T, RStride = U1, CStride = U3> = pub type VectorSlice3<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U1, SliceStorage<'a, T, U3, U1, RStride, CStride>>; Matrix<T, U3, U1, ViewStorage<'a, T, U3, U1, RStride, CStride>>;
/// A 4D column vector slice. /// A 4D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(VectorView4)]
pub type VectorSlice4<'a, T, RStride = U1, CStride = U4> = pub type VectorSlice4<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U1, SliceStorage<'a, T, U4, U1, RStride, CStride>>; Matrix<T, U4, U1, ViewStorage<'a, T, U4, U1, RStride, CStride>>;
/// A 5D column vector slice. /// A 5D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(VectorView5)]
pub type VectorSlice5<'a, T, RStride = U1, CStride = U5> = pub type VectorSlice5<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U1, SliceStorage<'a, T, U5, U1, RStride, CStride>>; Matrix<T, U5, U1, ViewStorage<'a, T, U5, U1, RStride, CStride>>;
/// A 6D column vector slice. /// A 6D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(VectorView6)]
pub type VectorSlice6<'a, T, RStride = U1, CStride = U6> = pub type VectorSlice6<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U1, SliceStorage<'a, T, U6, U1, RStride, CStride>>; Matrix<T, U6, U1, ViewStorage<'a, T, U6, U1, RStride, CStride>>;
/* /*
* *
@ -304,297 +364,358 @@ pub type VectorSlice6<'a, T, RStride = U1, CStride = U6> =
/// A column-major matrix slice with `R` rows and `C` columns. /// A column-major matrix slice with `R` rows and `C` columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = "Use MatrixViewMut instead, which has an identical definition."]
pub type MatrixSliceMutMN<'a, T, R, C, RStride = U1, CStride = R> = pub type MatrixSliceMutMN<'a, T, R, C, RStride = U1, CStride = R> =
Matrix<T, R, C, SliceStorageMut<'a, T, R, C, RStride, CStride>>; Matrix<T, R, C, ViewStorageMut<'a, T, R, C, RStride, CStride>>;
/// A column-major matrix slice with `D` rows and columns. /// A column-major matrix slice with `D` rows and columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = "Use MatrixViewMut instead."]
pub type MatrixSliceMutN<'a, T, D, RStride = U1, CStride = D> = pub type MatrixSliceMutN<'a, T, D, RStride = U1, CStride = D> =
Matrix<T, D, D, SliceStorageMut<'a, T, D, D, RStride, CStride>>; Matrix<T, D, D, ViewStorageMut<'a, T, D, D, RStride, CStride>>;
/// A column-major matrix slice with dimensions known at compile-time. /// A column-major matrix slice with dimensions known at compile-time.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(SMatrixViewMut)]
pub type SMatrixSliceMut<'a, T, const R: usize, const C: usize> = pub type SMatrixSliceMut<'a, T, const R: usize, const C: usize> =
Matrix<T, Const<R>, Const<C>, SliceStorageMut<'a, T, Const<R>, Const<C>, Const<1>, Const<R>>>; Matrix<T, Const<R>, Const<C>, ViewStorageMut<'a, T, Const<R>, Const<C>, Const<1>, Const<R>>>;
/// A column-major matrix slice dynamic numbers of rows and columns. /// A column-major matrix slice dynamic numbers of rows and columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type DMatrixSliceMut<'a, T, RStride = U1, CStride = Dynamic> = #[deprecated = slice_deprecation_note!(DMatrixViewMut)]
Matrix<T, Dynamic, Dynamic, SliceStorageMut<'a, T, Dynamic, Dynamic, RStride, CStride>>; pub type DMatrixSliceMut<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, Dyn, ViewStorageMut<'a, T, Dyn, Dyn, RStride, CStride>>;
/// A column-major 1x1 matrix slice. /// A column-major 1x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut1)]
pub type MatrixSliceMut1<'a, T, RStride = U1, CStride = U1> = pub type MatrixSliceMut1<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U1, SliceStorageMut<'a, T, U1, U1, RStride, CStride>>; Matrix<T, U1, U1, ViewStorageMut<'a, T, U1, U1, RStride, CStride>>;
/// A column-major 2x2 matrix slice. /// A column-major 2x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut2)]
pub type MatrixSliceMut2<'a, T, RStride = U1, CStride = U2> = pub type MatrixSliceMut2<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U2, SliceStorageMut<'a, T, U2, U2, RStride, CStride>>; Matrix<T, U2, U2, ViewStorageMut<'a, T, U2, U2, RStride, CStride>>;
/// A column-major 3x3 matrix slice. /// A column-major 3x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut3)]
pub type MatrixSliceMut3<'a, T, RStride = U1, CStride = U3> = pub type MatrixSliceMut3<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U3, SliceStorageMut<'a, T, U3, U3, RStride, CStride>>; Matrix<T, U3, U3, ViewStorageMut<'a, T, U3, U3, RStride, CStride>>;
/// A column-major 4x4 matrix slice. /// A column-major 4x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut4)]
pub type MatrixSliceMut4<'a, T, RStride = U1, CStride = U4> = pub type MatrixSliceMut4<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U4, SliceStorageMut<'a, T, U4, U4, RStride, CStride>>; Matrix<T, U4, U4, ViewStorageMut<'a, T, U4, U4, RStride, CStride>>;
/// A column-major 5x5 matrix slice. /// A column-major 5x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut5)]
pub type MatrixSliceMut5<'a, T, RStride = U1, CStride = U5> = pub type MatrixSliceMut5<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U5, SliceStorageMut<'a, T, U5, U5, RStride, CStride>>; Matrix<T, U5, U5, ViewStorageMut<'a, T, U5, U5, RStride, CStride>>;
/// A column-major 6x6 matrix slice. /// A column-major 6x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut6)]
pub type MatrixSliceMut6<'a, T, RStride = U1, CStride = U6> = pub type MatrixSliceMut6<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U6, SliceStorageMut<'a, T, U6, U6, RStride, CStride>>; Matrix<T, U6, U6, ViewStorageMut<'a, T, U6, U6, RStride, CStride>>;
/// A column-major 1x2 matrix slice. /// A column-major 1x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut1x2)]
pub type MatrixSliceMut1x2<'a, T, RStride = U1, CStride = U1> = pub type MatrixSliceMut1x2<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U2, SliceStorageMut<'a, T, U1, U2, RStride, CStride>>; Matrix<T, U1, U2, ViewStorageMut<'a, T, U1, U2, RStride, CStride>>;
/// A column-major 1x3 matrix slice. /// A column-major 1x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut1x3)]
pub type MatrixSliceMut1x3<'a, T, RStride = U1, CStride = U1> = pub type MatrixSliceMut1x3<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U3, SliceStorageMut<'a, T, U1, U3, RStride, CStride>>; Matrix<T, U1, U3, ViewStorageMut<'a, T, U1, U3, RStride, CStride>>;
/// A column-major 1x4 matrix slice. /// A column-major 1x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut1x4)]
pub type MatrixSliceMut1x4<'a, T, RStride = U1, CStride = U1> = pub type MatrixSliceMut1x4<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U4, SliceStorageMut<'a, T, U1, U4, RStride, CStride>>; Matrix<T, U1, U4, ViewStorageMut<'a, T, U1, U4, RStride, CStride>>;
/// A column-major 1x5 matrix slice. /// A column-major 1x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut1x5)]
pub type MatrixSliceMut1x5<'a, T, RStride = U1, CStride = U1> = pub type MatrixSliceMut1x5<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U5, SliceStorageMut<'a, T, U1, U5, RStride, CStride>>; Matrix<T, U1, U5, ViewStorageMut<'a, T, U1, U5, RStride, CStride>>;
/// A column-major 1x6 matrix slice. /// A column-major 1x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut1x6)]
pub type MatrixSliceMut1x6<'a, T, RStride = U1, CStride = U1> = pub type MatrixSliceMut1x6<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U6, SliceStorageMut<'a, T, U1, U6, RStride, CStride>>; Matrix<T, U1, U6, ViewStorageMut<'a, T, U1, U6, RStride, CStride>>;
/// A column-major 2x1 matrix slice. /// A column-major 2x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut2x1)]
pub type MatrixSliceMut2x1<'a, T, RStride = U1, CStride = U2> = pub type MatrixSliceMut2x1<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U1, SliceStorageMut<'a, T, U2, U1, RStride, CStride>>; Matrix<T, U2, U1, ViewStorageMut<'a, T, U2, U1, RStride, CStride>>;
/// A column-major 2x3 matrix slice. /// A column-major 2x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut2x3)]
pub type MatrixSliceMut2x3<'a, T, RStride = U1, CStride = U2> = pub type MatrixSliceMut2x3<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U3, SliceStorageMut<'a, T, U2, U3, RStride, CStride>>; Matrix<T, U2, U3, ViewStorageMut<'a, T, U2, U3, RStride, CStride>>;
/// A column-major 2x4 matrix slice. /// A column-major 2x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut2x4)]
pub type MatrixSliceMut2x4<'a, T, RStride = U1, CStride = U2> = pub type MatrixSliceMut2x4<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U4, SliceStorageMut<'a, T, U2, U4, RStride, CStride>>; Matrix<T, U2, U4, ViewStorageMut<'a, T, U2, U4, RStride, CStride>>;
/// A column-major 2x5 matrix slice. /// A column-major 2x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut2x5)]
pub type MatrixSliceMut2x5<'a, T, RStride = U1, CStride = U2> = pub type MatrixSliceMut2x5<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U5, SliceStorageMut<'a, T, U2, U5, RStride, CStride>>; Matrix<T, U2, U5, ViewStorageMut<'a, T, U2, U5, RStride, CStride>>;
/// A column-major 2x6 matrix slice. /// A column-major 2x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut2x6)]
pub type MatrixSliceMut2x6<'a, T, RStride = U1, CStride = U2> = pub type MatrixSliceMut2x6<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U6, SliceStorageMut<'a, T, U2, U6, RStride, CStride>>; Matrix<T, U2, U6, ViewStorageMut<'a, T, U2, U6, RStride, CStride>>;
/// A column-major 3x1 matrix slice. /// A column-major 3x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut3x1)]
pub type MatrixSliceMut3x1<'a, T, RStride = U1, CStride = U3> = pub type MatrixSliceMut3x1<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U1, SliceStorageMut<'a, T, U3, U1, RStride, CStride>>; Matrix<T, U3, U1, ViewStorageMut<'a, T, U3, U1, RStride, CStride>>;
/// A column-major 3x2 matrix slice. /// A column-major 3x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut3x2)]
pub type MatrixSliceMut3x2<'a, T, RStride = U1, CStride = U3> = pub type MatrixSliceMut3x2<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U2, SliceStorageMut<'a, T, U3, U2, RStride, CStride>>; Matrix<T, U3, U2, ViewStorageMut<'a, T, U3, U2, RStride, CStride>>;
/// A column-major 3x4 matrix slice. /// A column-major 3x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut3x4)]
pub type MatrixSliceMut3x4<'a, T, RStride = U1, CStride = U3> = pub type MatrixSliceMut3x4<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U4, SliceStorageMut<'a, T, U3, U4, RStride, CStride>>; Matrix<T, U3, U4, ViewStorageMut<'a, T, U3, U4, RStride, CStride>>;
/// A column-major 3x5 matrix slice. /// A column-major 3x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut3x5)]
pub type MatrixSliceMut3x5<'a, T, RStride = U1, CStride = U3> = pub type MatrixSliceMut3x5<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U5, SliceStorageMut<'a, T, U3, U5, RStride, CStride>>; Matrix<T, U3, U5, ViewStorageMut<'a, T, U3, U5, RStride, CStride>>;
/// A column-major 3x6 matrix slice. /// A column-major 3x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut3x6)]
pub type MatrixSliceMut3x6<'a, T, RStride = U1, CStride = U3> = pub type MatrixSliceMut3x6<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U6, SliceStorageMut<'a, T, U3, U6, RStride, CStride>>; Matrix<T, U3, U6, ViewStorageMut<'a, T, U3, U6, RStride, CStride>>;
/// A column-major 4x1 matrix slice. /// A column-major 4x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut4x1)]
pub type MatrixSliceMut4x1<'a, T, RStride = U1, CStride = U4> = pub type MatrixSliceMut4x1<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U1, SliceStorageMut<'a, T, U4, U1, RStride, CStride>>; Matrix<T, U4, U1, ViewStorageMut<'a, T, U4, U1, RStride, CStride>>;
/// A column-major 4x2 matrix slice. /// A column-major 4x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut4x2)]
pub type MatrixSliceMut4x2<'a, T, RStride = U1, CStride = U4> = pub type MatrixSliceMut4x2<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U2, SliceStorageMut<'a, T, U4, U2, RStride, CStride>>; Matrix<T, U4, U2, ViewStorageMut<'a, T, U4, U2, RStride, CStride>>;
/// A column-major 4x3 matrix slice. /// A column-major 4x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut4x3)]
pub type MatrixSliceMut4x3<'a, T, RStride = U1, CStride = U4> = pub type MatrixSliceMut4x3<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U3, SliceStorageMut<'a, T, U4, U3, RStride, CStride>>; Matrix<T, U4, U3, ViewStorageMut<'a, T, U4, U3, RStride, CStride>>;
/// A column-major 4x5 matrix slice. /// A column-major 4x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut4x5)]
pub type MatrixSliceMut4x5<'a, T, RStride = U1, CStride = U4> = pub type MatrixSliceMut4x5<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U5, SliceStorageMut<'a, T, U4, U5, RStride, CStride>>; Matrix<T, U4, U5, ViewStorageMut<'a, T, U4, U5, RStride, CStride>>;
/// A column-major 4x6 matrix slice. /// A column-major 4x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut4x6)]
pub type MatrixSliceMut4x6<'a, T, RStride = U1, CStride = U4> = pub type MatrixSliceMut4x6<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U6, SliceStorageMut<'a, T, U4, U6, RStride, CStride>>; Matrix<T, U4, U6, ViewStorageMut<'a, T, U4, U6, RStride, CStride>>;
/// A column-major 5x1 matrix slice. /// A column-major 5x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut5x1)]
pub type MatrixSliceMut5x1<'a, T, RStride = U1, CStride = U5> = pub type MatrixSliceMut5x1<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U1, SliceStorageMut<'a, T, U5, U1, RStride, CStride>>; Matrix<T, U5, U1, ViewStorageMut<'a, T, U5, U1, RStride, CStride>>;
/// A column-major 5x2 matrix slice. /// A column-major 5x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut5x2)]
pub type MatrixSliceMut5x2<'a, T, RStride = U1, CStride = U5> = pub type MatrixSliceMut5x2<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U2, SliceStorageMut<'a, T, U5, U2, RStride, CStride>>; Matrix<T, U5, U2, ViewStorageMut<'a, T, U5, U2, RStride, CStride>>;
/// A column-major 5x3 matrix slice. /// A column-major 5x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut5x3)]
pub type MatrixSliceMut5x3<'a, T, RStride = U1, CStride = U5> = pub type MatrixSliceMut5x3<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U3, SliceStorageMut<'a, T, U5, U3, RStride, CStride>>; Matrix<T, U5, U3, ViewStorageMut<'a, T, U5, U3, RStride, CStride>>;
/// A column-major 5x4 matrix slice. /// A column-major 5x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut5x4)]
pub type MatrixSliceMut5x4<'a, T, RStride = U1, CStride = U5> = pub type MatrixSliceMut5x4<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U4, SliceStorageMut<'a, T, U5, U4, RStride, CStride>>; Matrix<T, U5, U4, ViewStorageMut<'a, T, U5, U4, RStride, CStride>>;
/// A column-major 5x6 matrix slice. /// A column-major 5x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut5x6)]
pub type MatrixSliceMut5x6<'a, T, RStride = U1, CStride = U5> = pub type MatrixSliceMut5x6<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U6, SliceStorageMut<'a, T, U5, U6, RStride, CStride>>; Matrix<T, U5, U6, ViewStorageMut<'a, T, U5, U6, RStride, CStride>>;
/// A column-major 6x1 matrix slice. /// A column-major 6x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut6x1)]
pub type MatrixSliceMut6x1<'a, T, RStride = U1, CStride = U6> = pub type MatrixSliceMut6x1<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U1, SliceStorageMut<'a, T, U6, U1, RStride, CStride>>; Matrix<T, U6, U1, ViewStorageMut<'a, T, U6, U1, RStride, CStride>>;
/// A column-major 6x2 matrix slice. /// A column-major 6x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut6x2)]
pub type MatrixSliceMut6x2<'a, T, RStride = U1, CStride = U6> = pub type MatrixSliceMut6x2<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U2, SliceStorageMut<'a, T, U6, U2, RStride, CStride>>; Matrix<T, U6, U2, ViewStorageMut<'a, T, U6, U2, RStride, CStride>>;
/// A column-major 6x3 matrix slice. /// A column-major 6x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut6x3)]
pub type MatrixSliceMut6x3<'a, T, RStride = U1, CStride = U6> = pub type MatrixSliceMut6x3<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U3, SliceStorageMut<'a, T, U6, U3, RStride, CStride>>; Matrix<T, U6, U3, ViewStorageMut<'a, T, U6, U3, RStride, CStride>>;
/// A column-major 6x4 matrix slice. /// A column-major 6x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut6x4)]
pub type MatrixSliceMut6x4<'a, T, RStride = U1, CStride = U6> = pub type MatrixSliceMut6x4<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U4, SliceStorageMut<'a, T, U6, U4, RStride, CStride>>; Matrix<T, U6, U4, ViewStorageMut<'a, T, U6, U4, RStride, CStride>>;
/// A column-major 6x5 matrix slice. /// A column-major 6x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(MatrixViewMut6x5)]
pub type MatrixSliceMut6x5<'a, T, RStride = U1, CStride = U6> = pub type MatrixSliceMut6x5<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U5, SliceStorageMut<'a, T, U6, U5, RStride, CStride>>; Matrix<T, U6, U5, ViewStorageMut<'a, T, U6, U5, RStride, CStride>>;
/// A column-major matrix slice with 1 row and a number of columns chosen at runtime. /// A column-major matrix slice with 1 row and a number of columns chosen at runtime.
#[deprecated = slice_deprecation_note!(MatrixViewMut1xX)]
pub type MatrixSliceMut1xX<'a, T, RStride = U1, CStride = U1> = pub type MatrixSliceMut1xX<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, Dynamic, SliceStorageMut<'a, T, U1, Dynamic, RStride, CStride>>; Matrix<T, U1, Dyn, ViewStorageMut<'a, T, U1, Dyn, RStride, CStride>>;
/// A column-major matrix slice with 2 rows and a number of columns chosen at runtime. /// A column-major matrix slice with 2 rows and a number of columns chosen at runtime.
#[deprecated = slice_deprecation_note!(MatrixViewMut2xX)]
pub type MatrixSliceMut2xX<'a, T, RStride = U1, CStride = U2> = pub type MatrixSliceMut2xX<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, Dynamic, SliceStorageMut<'a, T, U2, Dynamic, RStride, CStride>>; Matrix<T, U2, Dyn, ViewStorageMut<'a, T, U2, Dyn, RStride, CStride>>;
/// A column-major matrix slice with 3 rows and a number of columns chosen at runtime. /// A column-major matrix slice with 3 rows and a number of columns chosen at runtime.
#[deprecated = slice_deprecation_note!(MatrixViewMut3xX)]
pub type MatrixSliceMut3xX<'a, T, RStride = U1, CStride = U3> = pub type MatrixSliceMut3xX<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, Dynamic, SliceStorageMut<'a, T, U3, Dynamic, RStride, CStride>>; Matrix<T, U3, Dyn, ViewStorageMut<'a, T, U3, Dyn, RStride, CStride>>;
/// A column-major matrix slice with 4 rows and a number of columns chosen at runtime. /// A column-major matrix slice with 4 rows and a number of columns chosen at runtime.
#[deprecated = slice_deprecation_note!(MatrixViewMut4xX)]
pub type MatrixSliceMut4xX<'a, T, RStride = U1, CStride = U4> = pub type MatrixSliceMut4xX<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, Dynamic, SliceStorageMut<'a, T, U4, Dynamic, RStride, CStride>>; Matrix<T, U4, Dyn, ViewStorageMut<'a, T, U4, Dyn, RStride, CStride>>;
/// A column-major matrix slice with 5 rows and a number of columns chosen at runtime. /// A column-major matrix slice with 5 rows and a number of columns chosen at runtime.
#[deprecated = slice_deprecation_note!(MatrixViewMut5xX)]
pub type MatrixSliceMut5xX<'a, T, RStride = U1, CStride = U5> = pub type MatrixSliceMut5xX<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, Dynamic, SliceStorageMut<'a, T, U5, Dynamic, RStride, CStride>>; Matrix<T, U5, Dyn, ViewStorageMut<'a, T, U5, Dyn, RStride, CStride>>;
/// A column-major matrix slice with 6 rows and a number of columns chosen at runtime. /// A column-major matrix slice with 6 rows and a number of columns chosen at runtime.
#[deprecated = slice_deprecation_note!(MatrixViewMut6xX)]
pub type MatrixSliceMut6xX<'a, T, RStride = U1, CStride = U6> = pub type MatrixSliceMut6xX<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, Dynamic, SliceStorageMut<'a, T, U6, Dynamic, RStride, CStride>>; Matrix<T, U6, Dyn, ViewStorageMut<'a, T, U6, Dyn, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 1 column. /// A column-major matrix slice with a number of rows chosen at runtime and 1 column.
pub type MatrixSliceMutXx1<'a, T, RStride = U1, CStride = Dynamic> = #[deprecated = slice_deprecation_note!(MatrixViewMutXx1)]
Matrix<T, Dynamic, U1, SliceStorageMut<'a, T, Dynamic, U1, RStride, CStride>>; pub type MatrixSliceMutXx1<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U1, ViewStorageMut<'a, T, Dyn, U1, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 2 columns. /// A column-major matrix slice with a number of rows chosen at runtime and 2 columns.
pub type MatrixSliceMutXx2<'a, T, RStride = U1, CStride = Dynamic> = #[deprecated = slice_deprecation_note!(MatrixViewMutXx2)]
Matrix<T, Dynamic, U2, SliceStorageMut<'a, T, Dynamic, U2, RStride, CStride>>; pub type MatrixSliceMutXx2<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U2, ViewStorageMut<'a, T, Dyn, U2, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 3 columns. /// A column-major matrix slice with a number of rows chosen at runtime and 3 columns.
pub type MatrixSliceMutXx3<'a, T, RStride = U1, CStride = Dynamic> = #[deprecated = slice_deprecation_note!(MatrixViewMutXx3)]
Matrix<T, Dynamic, U3, SliceStorageMut<'a, T, Dynamic, U3, RStride, CStride>>; pub type MatrixSliceMutXx3<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U3, ViewStorageMut<'a, T, Dyn, U3, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 4 columns. /// A column-major matrix slice with a number of rows chosen at runtime and 4 columns.
pub type MatrixSliceMutXx4<'a, T, RStride = U1, CStride = Dynamic> = #[deprecated = slice_deprecation_note!(MatrixViewMutXx4)]
Matrix<T, Dynamic, U4, SliceStorageMut<'a, T, Dynamic, U4, RStride, CStride>>; pub type MatrixSliceMutXx4<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U4, ViewStorageMut<'a, T, Dyn, U4, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 5 columns. /// A column-major matrix slice with a number of rows chosen at runtime and 5 columns.
pub type MatrixSliceMutXx5<'a, T, RStride = U1, CStride = Dynamic> = #[deprecated = slice_deprecation_note!(MatrixViewMutXx5)]
Matrix<T, Dynamic, U5, SliceStorageMut<'a, T, Dynamic, U5, RStride, CStride>>; pub type MatrixSliceMutXx5<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U5, ViewStorageMut<'a, T, Dyn, U5, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 6 columns. /// A column-major matrix slice with a number of rows chosen at runtime and 6 columns.
pub type MatrixSliceMutXx6<'a, T, RStride = U1, CStride = Dynamic> = #[deprecated = slice_deprecation_note!(MatrixViewMutXx6)]
Matrix<T, Dynamic, U6, SliceStorageMut<'a, T, Dynamic, U6, RStride, CStride>>; pub type MatrixSliceMutXx6<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U6, ViewStorageMut<'a, T, Dyn, U6, RStride, CStride>>;
/// A column vector slice with dimensions known at compile-time. /// A column vector slice with dimensions known at compile-time.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(VectorViewMut)]
pub type VectorSliceMut<'a, T, D, RStride = U1, CStride = D> = pub type VectorSliceMut<'a, T, D, RStride = U1, CStride = D> =
Matrix<T, D, U1, SliceStorageMut<'a, T, D, U1, RStride, CStride>>; Matrix<T, D, U1, ViewStorageMut<'a, T, D, U1, RStride, CStride>>;
/// A column vector slice with dimensions known at compile-time. /// A column vector slice with dimensions known at compile-time.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(SVectorViewMut)]
pub type SVectorSliceMut<'a, T, const D: usize> = pub type SVectorSliceMut<'a, T, const D: usize> =
Matrix<T, Const<D>, Const<1>, SliceStorageMut<'a, T, Const<D>, Const<1>, Const<1>, Const<D>>>; Matrix<T, Const<D>, Const<1>, ViewStorageMut<'a, T, Const<D>, Const<1>, Const<1>, Const<D>>>;
/// A column vector slice dynamic numbers of rows and columns. /// A column vector slice dynamic numbers of rows and columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type DVectorSliceMut<'a, T, RStride = U1, CStride = Dynamic> = #[deprecated = slice_deprecation_note!(DVectorViewMut)]
Matrix<T, Dynamic, U1, SliceStorageMut<'a, T, Dynamic, U1, RStride, CStride>>; pub type DVectorSliceMut<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U1, ViewStorageMut<'a, T, Dyn, U1, RStride, CStride>>;
/// A 1D column vector slice. /// A 1D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(VectorViewMut1)]
pub type VectorSliceMut1<'a, T, RStride = U1, CStride = U1> = pub type VectorSliceMut1<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U1, SliceStorageMut<'a, T, U1, U1, RStride, CStride>>; Matrix<T, U1, U1, ViewStorageMut<'a, T, U1, U1, RStride, CStride>>;
/// A 2D column vector slice. /// A 2D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(VectorViewMut2)]
pub type VectorSliceMut2<'a, T, RStride = U1, CStride = U2> = pub type VectorSliceMut2<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U1, SliceStorageMut<'a, T, U2, U1, RStride, CStride>>; Matrix<T, U2, U1, ViewStorageMut<'a, T, U2, U1, RStride, CStride>>;
/// A 3D column vector slice. /// A 3D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(VectorViewMut3)]
pub type VectorSliceMut3<'a, T, RStride = U1, CStride = U3> = pub type VectorSliceMut3<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U1, SliceStorageMut<'a, T, U3, U1, RStride, CStride>>; Matrix<T, U3, U1, ViewStorageMut<'a, T, U3, U1, RStride, CStride>>;
/// A 4D column vector slice. /// A 4D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(VectorViewMut4)]
pub type VectorSliceMut4<'a, T, RStride = U1, CStride = U4> = pub type VectorSliceMut4<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U1, SliceStorageMut<'a, T, U4, U1, RStride, CStride>>; Matrix<T, U4, U1, ViewStorageMut<'a, T, U4, U1, RStride, CStride>>;
/// A 5D column vector slice. /// A 5D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(VectorViewMut5)]
pub type VectorSliceMut5<'a, T, RStride = U1, CStride = U5> = pub type VectorSliceMut5<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U1, SliceStorageMut<'a, T, U5, U1, RStride, CStride>>; Matrix<T, U5, U1, ViewStorageMut<'a, T, U5, U1, RStride, CStride>>;
/// A 6D column vector slice. /// A 6D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated = slice_deprecation_note!(VectorViewMut6)]
pub type VectorSliceMut6<'a, T, RStride = U1, CStride = U6> = pub type VectorSliceMut6<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U1, SliceStorageMut<'a, T, U6, U1, RStride, CStride>>; Matrix<T, U6, U1, ViewStorageMut<'a, T, U6, U1, RStride, CStride>>;

875
src/base/alias_view.rs Normal file
View File

@ -0,0 +1,875 @@
use crate::base::dimension::{Dyn, U1, U2, U3, U4, U5, U6};
use crate::base::matrix_view::{ViewStorage, ViewStorageMut};
use crate::base::{Const, Matrix};
/*
*
*
* Matrix view aliases.
*
*
*/
// NOTE: we can't provide defaults for the strides because it's not supported yet by min_const_generics.
/// An immutable column-major matrix view with dimensions known at compile-time.
///
/// See [`SMatrixViewMut`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type SMatrixView<'a, T, const R: usize, const C: usize> =
Matrix<T, Const<R>, Const<C>, ViewStorage<'a, T, Const<R>, Const<C>, Const<1>, Const<R>>>;
/// An immutable column-major matrix view dynamic numbers of rows and columns.
///
/// See [`DMatrixViewMut`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type DMatrixView<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, Dyn, ViewStorage<'a, T, Dyn, Dyn, RStride, CStride>>;
/// An immutable column-major 1x1 matrix view.
///
/// See [`MatrixViewMut1`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView1<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U1, ViewStorage<'a, T, U1, U1, RStride, CStride>>;
/// An immutable column-major 2x2 matrix view.
///
/// See [`MatrixViewMut2`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView2<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U2, ViewStorage<'a, T, U2, U2, RStride, CStride>>;
/// An immutable column-major 3x3 matrix view.
///
/// See [`MatrixViewMut3`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView3<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U3, ViewStorage<'a, T, U3, U3, RStride, CStride>>;
/// An immutable column-major 4x4 matrix view.
///
/// See [`MatrixViewMut4`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView4<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U4, ViewStorage<'a, T, U4, U4, RStride, CStride>>;
/// An immutable column-major 5x5 matrix view.
///
/// See [`MatrixViewMut5`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView5<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U5, ViewStorage<'a, T, U5, U5, RStride, CStride>>;
/// An immutable column-major 6x6 matrix view.
///
/// See [`MatrixViewMut6`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView6<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U6, ViewStorage<'a, T, U6, U6, RStride, CStride>>;
/// An immutable column-major 1x2 matrix view.
///
/// See [`MatrixViewMut1x2`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView1x2<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U2, ViewStorage<'a, T, U1, U2, RStride, CStride>>;
/// An immutable column-major 1x3 matrix view.
///
/// See [`MatrixViewMut1x3`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView1x3<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U3, ViewStorage<'a, T, U1, U3, RStride, CStride>>;
/// An immutable column-major 1x4 matrix view.
///
/// See [`MatrixViewMut1x4`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView1x4<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U4, ViewStorage<'a, T, U1, U4, RStride, CStride>>;
/// An immutable column-major 1x5 matrix view.
///
/// See [`MatrixViewMut1x5`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView1x5<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U5, ViewStorage<'a, T, U1, U5, RStride, CStride>>;
/// An immutable column-major 1x6 matrix view.
///
/// See [`MatrixViewMut1x6`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView1x6<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U6, ViewStorage<'a, T, U1, U6, RStride, CStride>>;
/// An immutable column-major 2x1 matrix view.
///
/// See [`MatrixViewMut2x1`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView2x1<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U1, ViewStorage<'a, T, U2, U1, RStride, CStride>>;
/// An immutable column-major 2x3 matrix view.
///
/// See [`MatrixViewMut2x3`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView2x3<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U3, ViewStorage<'a, T, U2, U3, RStride, CStride>>;
/// An immutable column-major 2x4 matrix view.
///
/// See [`MatrixViewMut2x4`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView2x4<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U4, ViewStorage<'a, T, U2, U4, RStride, CStride>>;
/// An immutable column-major 2x5 matrix view.
///
/// See [`MatrixViewMut2x5`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView2x5<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U5, ViewStorage<'a, T, U2, U5, RStride, CStride>>;
/// An immutable column-major 2x6 matrix view.
///
/// See [`MatrixViewMut2x6`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView2x6<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U6, ViewStorage<'a, T, U2, U6, RStride, CStride>>;
/// An immutable column-major 3x1 matrix view.
///
/// See [`MatrixViewMut3x1`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView3x1<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U1, ViewStorage<'a, T, U3, U1, RStride, CStride>>;
/// An immutable column-major 3x2 matrix view.
///
/// See [`MatrixViewMut3x2`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView3x2<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U2, ViewStorage<'a, T, U3, U2, RStride, CStride>>;
/// An immutable column-major 3x4 matrix view.
///
/// See [`MatrixViewMut3x4`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView3x4<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U4, ViewStorage<'a, T, U3, U4, RStride, CStride>>;
/// An immutable column-major 3x5 matrix view.
///
/// See [`MatrixViewMut3x5`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView3x5<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U5, ViewStorage<'a, T, U3, U5, RStride, CStride>>;
/// An immutable column-major 3x6 matrix view.
///
/// See [`MatrixViewMut3x6`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView3x6<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U6, ViewStorage<'a, T, U3, U6, RStride, CStride>>;
/// An immutable column-major 4x1 matrix view.
///
/// See [`MatrixViewMut4x1`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView4x1<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U1, ViewStorage<'a, T, U4, U1, RStride, CStride>>;
/// An immutable column-major 4x2 matrix view.
///
/// See [`MatrixViewMut4x2`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView4x2<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U2, ViewStorage<'a, T, U4, U2, RStride, CStride>>;
/// An immutable column-major 4x3 matrix view.
///
/// See [`MatrixViewMut4x3`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView4x3<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U3, ViewStorage<'a, T, U4, U3, RStride, CStride>>;
/// An immutable column-major 4x5 matrix view.
///
/// See [`MatrixViewMut4x5`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView4x5<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U5, ViewStorage<'a, T, U4, U5, RStride, CStride>>;
/// An immutable column-major 4x6 matrix view.
///
/// See [`MatrixViewMut4x6`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView4x6<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U6, ViewStorage<'a, T, U4, U6, RStride, CStride>>;
/// An immutable column-major 5x1 matrix view.
///
/// See [`MatrixViewMut5x1`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView5x1<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U1, ViewStorage<'a, T, U5, U1, RStride, CStride>>;
/// An immutable column-major 5x2 matrix view.
///
/// See [`MatrixViewMut5x2`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView5x2<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U2, ViewStorage<'a, T, U5, U2, RStride, CStride>>;
/// An immutable column-major 5x3 matrix view.
///
/// See [`MatrixViewMut5x3`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView5x3<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U3, ViewStorage<'a, T, U5, U3, RStride, CStride>>;
/// An immutable column-major 5x4 matrix view.
///
/// See [`MatrixViewMut5x4`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView5x4<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U4, ViewStorage<'a, T, U5, U4, RStride, CStride>>;
/// An immutable column-major 5x6 matrix view.
///
/// See [`MatrixViewMut5x6`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView5x6<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U6, ViewStorage<'a, T, U5, U6, RStride, CStride>>;
/// An immutable column-major 6x1 matrix view.
///
/// See [`MatrixViewMut6x1`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView6x1<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U1, ViewStorage<'a, T, U6, U1, RStride, CStride>>;
/// An immutable column-major 6x2 matrix view.
///
/// See [`MatrixViewMut6x2`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView6x2<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U2, ViewStorage<'a, T, U6, U2, RStride, CStride>>;
/// An immutable column-major 6x3 matrix view.
///
/// See [`MatrixViewMut6x3`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView6x3<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U3, ViewStorage<'a, T, U6, U3, RStride, CStride>>;
/// An immutable column-major 6x4 matrix view.
///
/// See [`MatrixViewMut6x4`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView6x4<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U4, ViewStorage<'a, T, U6, U4, RStride, CStride>>;
/// An immutable column-major 6x5 matrix view.
///
/// See [`MatrixViewMut6x5`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView6x5<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U5, ViewStorage<'a, T, U6, U5, RStride, CStride>>;
/// An immutable column-major matrix view with 1 row and a number of columns chosen at runtime.
///
/// See [`MatrixViewMut1xX`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView1xX<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, Dyn, ViewStorage<'a, T, U1, Dyn, RStride, CStride>>;
/// An immutable column-major matrix view with 2 rows and a number of columns chosen at runtime.
///
/// See [`MatrixViewMut2xX`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView2xX<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, Dyn, ViewStorage<'a, T, U2, Dyn, RStride, CStride>>;
/// An immutable column-major matrix view with 3 rows and a number of columns chosen at runtime.
///
/// See [`MatrixViewMut3xX`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView3xX<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, Dyn, ViewStorage<'a, T, U3, Dyn, RStride, CStride>>;
/// An immutable column-major matrix view with 4 rows and a number of columns chosen at runtime.
///
/// See [`MatrixViewMut4xX`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView4xX<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, Dyn, ViewStorage<'a, T, U4, Dyn, RStride, CStride>>;
/// An immutable column-major matrix view with 5 rows and a number of columns chosen at runtime.
///
/// See [`MatrixViewMut5xX`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView5xX<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, Dyn, ViewStorage<'a, T, U5, Dyn, RStride, CStride>>;
/// An immutable column-major matrix view with 6 rows and a number of columns chosen at runtime.
///
/// See [`MatrixViewMut6xX`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixView6xX<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, Dyn, ViewStorage<'a, T, U6, Dyn, RStride, CStride>>;
/// An immutable column-major matrix view with a number of rows chosen at runtime and 1 column.
///
/// See [`MatrixViewMutXx1`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewXx1<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U1, ViewStorage<'a, T, Dyn, U1, RStride, CStride>>;
/// An immutable column-major matrix view with a number of rows chosen at runtime and 2 columns.
///
/// See [`MatrixViewMutXx2`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewXx2<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U2, ViewStorage<'a, T, Dyn, U2, RStride, CStride>>;
/// An immutable column-major matrix view with a number of rows chosen at runtime and 3 columns.
///
/// See [`MatrixViewMutXx3`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewXx3<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U3, ViewStorage<'a, T, Dyn, U3, RStride, CStride>>;
/// An immutable column-major matrix view with a number of rows chosen at runtime and 4 columns.
///
/// See [`MatrixViewMutXx4`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewXx4<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U4, ViewStorage<'a, T, Dyn, U4, RStride, CStride>>;
/// An immutable column-major matrix view with a number of rows chosen at runtime and 5 columns.
///
/// See [`MatrixViewMutXx5`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewXx5<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U5, ViewStorage<'a, T, Dyn, U5, RStride, CStride>>;
/// An immutable column-major matrix view with a number of rows chosen at runtime and 6 columns.
///
/// See [`MatrixViewMutXx6`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewXx6<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U6, ViewStorage<'a, T, Dyn, U6, RStride, CStride>>;
/// An immutable column vector view with dimensions known at compile-time.
///
/// See [`VectorViewMut`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorView<'a, T, D, RStride = U1, CStride = D> =
Matrix<T, D, U1, ViewStorage<'a, T, D, U1, RStride, CStride>>;
/// An immutable column vector view with dimensions known at compile-time.
///
/// See [`SVectorViewMut`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type SVectorView<'a, T, const D: usize> =
Matrix<T, Const<D>, Const<1>, ViewStorage<'a, T, Const<D>, Const<1>, Const<1>, Const<D>>>;
/// An immutable column vector view dynamic numbers of rows and columns.
///
/// See [`DVectorViewMut`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type DVectorView<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U1, ViewStorage<'a, T, Dyn, U1, RStride, CStride>>;
/// An immutable 1D column vector view.
///
/// See [`VectorViewMut1`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorView1<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U1, ViewStorage<'a, T, U1, U1, RStride, CStride>>;
/// An immutable 2D column vector view.
///
/// See [`VectorViewMut2`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorView2<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U1, ViewStorage<'a, T, U2, U1, RStride, CStride>>;
/// An immutable 3D column vector view.
///
/// See [`VectorViewMut3`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorView3<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U1, ViewStorage<'a, T, U3, U1, RStride, CStride>>;
/// An immutable 4D column vector view.
///
/// See [`VectorViewMut4`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorView4<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U1, ViewStorage<'a, T, U4, U1, RStride, CStride>>;
/// An immutable 5D column vector view.
///
/// See [`VectorViewMut5`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorView5<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U1, ViewStorage<'a, T, U5, U1, RStride, CStride>>;
/// An immutable 6D column vector view.
///
/// See [`VectorViewMut6`] for a mutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorView6<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U1, ViewStorage<'a, T, U6, U1, RStride, CStride>>;
/*
*
*
* Same thing, but for mutable views.
*
*
*/
/// A mutable column-major matrix view with dimensions known at compile-time.
///
/// See [`SMatrixView`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type SMatrixViewMut<'a, T, const R: usize, const C: usize> =
Matrix<T, Const<R>, Const<C>, ViewStorageMut<'a, T, Const<R>, Const<C>, Const<1>, Const<R>>>;
/// A mutable column-major matrix view dynamic numbers of rows and columns.
///
/// See [`DMatrixView`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type DMatrixViewMut<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, Dyn, ViewStorageMut<'a, T, Dyn, Dyn, RStride, CStride>>;
/// A mutable column-major 1x1 matrix view.
///
/// See [`MatrixView1`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut1<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U1, ViewStorageMut<'a, T, U1, U1, RStride, CStride>>;
/// A mutable column-major 2x2 matrix view.
///
/// See [`MatrixView2`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut2<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U2, ViewStorageMut<'a, T, U2, U2, RStride, CStride>>;
/// A mutable column-major 3x3 matrix view.
///
/// See [`MatrixView3`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut3<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U3, ViewStorageMut<'a, T, U3, U3, RStride, CStride>>;
/// A mutable column-major 4x4 matrix view.
///
/// See [`MatrixView4`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut4<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U4, ViewStorageMut<'a, T, U4, U4, RStride, CStride>>;
/// A mutable column-major 5x5 matrix view.
///
/// See [`MatrixView5`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut5<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U5, ViewStorageMut<'a, T, U5, U5, RStride, CStride>>;
/// A mutable column-major 6x6 matrix view.
///
/// See [`MatrixView6`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut6<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U6, ViewStorageMut<'a, T, U6, U6, RStride, CStride>>;
/// A mutable column-major 1x2 matrix view.
///
/// See [`MatrixView1x2`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut1x2<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U2, ViewStorageMut<'a, T, U1, U2, RStride, CStride>>;
/// A mutable column-major 1x3 matrix view.
///
/// See [`MatrixView1x3`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut1x3<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U3, ViewStorageMut<'a, T, U1, U3, RStride, CStride>>;
/// A mutable column-major 1x4 matrix view.
///
/// See [`MatrixView1x4`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut1x4<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U4, ViewStorageMut<'a, T, U1, U4, RStride, CStride>>;
/// A mutable column-major 1x5 matrix view.
///
/// See [`MatrixView1x5`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut1x5<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U5, ViewStorageMut<'a, T, U1, U5, RStride, CStride>>;
/// A mutable column-major 1x6 matrix view.
///
/// See [`MatrixView1x6`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut1x6<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U6, ViewStorageMut<'a, T, U1, U6, RStride, CStride>>;
/// A mutable column-major 2x1 matrix view.
///
/// See [`MatrixView2x1`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut2x1<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U1, ViewStorageMut<'a, T, U2, U1, RStride, CStride>>;
/// A mutable column-major 2x3 matrix view.
///
/// See [`MatrixView2x3`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut2x3<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U3, ViewStorageMut<'a, T, U2, U3, RStride, CStride>>;
/// A mutable column-major 2x4 matrix view.
///
/// See [`MatrixView2x4`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut2x4<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U4, ViewStorageMut<'a, T, U2, U4, RStride, CStride>>;
/// A mutable column-major 2x5 matrix view.
///
/// See [`MatrixView2x5`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut2x5<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U5, ViewStorageMut<'a, T, U2, U5, RStride, CStride>>;
/// A mutable column-major 2x6 matrix view.
///
/// See [`MatrixView2x6`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut2x6<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U6, ViewStorageMut<'a, T, U2, U6, RStride, CStride>>;
/// A mutable column-major 3x1 matrix view.
///
/// See [`MatrixView3x1`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut3x1<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U1, ViewStorageMut<'a, T, U3, U1, RStride, CStride>>;
/// A mutable column-major 3x2 matrix view.
///
/// See [`MatrixView3x2`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut3x2<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U2, ViewStorageMut<'a, T, U3, U2, RStride, CStride>>;
/// A mutable column-major 3x4 matrix view.
///
/// See [`MatrixView3x4`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut3x4<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U4, ViewStorageMut<'a, T, U3, U4, RStride, CStride>>;
/// A mutable column-major 3x5 matrix view.
///
/// See [`MatrixView3x5`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut3x5<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U5, ViewStorageMut<'a, T, U3, U5, RStride, CStride>>;
/// A mutable column-major 3x6 matrix view.
///
/// See [`MatrixView3x6`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut3x6<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U6, ViewStorageMut<'a, T, U3, U6, RStride, CStride>>;
/// A mutable column-major 4x1 matrix view.
///
/// See [`MatrixView4x1`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut4x1<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U1, ViewStorageMut<'a, T, U4, U1, RStride, CStride>>;
/// A mutable column-major 4x2 matrix view.
///
/// See [`MatrixView4x2`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut4x2<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U2, ViewStorageMut<'a, T, U4, U2, RStride, CStride>>;
/// A mutable column-major 4x3 matrix view.
///
/// See [`MatrixView4x3`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut4x3<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U3, ViewStorageMut<'a, T, U4, U3, RStride, CStride>>;
/// A mutable column-major 4x5 matrix view.
///
/// See [`MatrixView4x5`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut4x5<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U5, ViewStorageMut<'a, T, U4, U5, RStride, CStride>>;
/// A mutable column-major 4x6 matrix view.
///
/// See [`MatrixView4x6`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut4x6<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U6, ViewStorageMut<'a, T, U4, U6, RStride, CStride>>;
/// A mutable column-major 5x1 matrix view.
///
/// See [`MatrixView5x1`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut5x1<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U1, ViewStorageMut<'a, T, U5, U1, RStride, CStride>>;
/// A mutable column-major 5x2 matrix view.
///
/// See [`MatrixView5x2`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut5x2<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U2, ViewStorageMut<'a, T, U5, U2, RStride, CStride>>;
/// A mutable column-major 5x3 matrix view.
///
/// See [`MatrixView5x3`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut5x3<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U3, ViewStorageMut<'a, T, U5, U3, RStride, CStride>>;
/// A mutable column-major 5x4 matrix view.
///
/// See [`MatrixView5x4`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut5x4<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U4, ViewStorageMut<'a, T, U5, U4, RStride, CStride>>;
/// A mutable column-major 5x6 matrix view.
///
/// See [`MatrixView5x6`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut5x6<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U6, ViewStorageMut<'a, T, U5, U6, RStride, CStride>>;
/// A mutable column-major 6x1 matrix view.
///
/// See [`MatrixView6x1`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut6x1<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U1, ViewStorageMut<'a, T, U6, U1, RStride, CStride>>;
/// A mutable column-major 6x2 matrix view.
///
/// See [`MatrixView6x2`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut6x2<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U2, ViewStorageMut<'a, T, U6, U2, RStride, CStride>>;
/// A mutable column-major 6x3 matrix view.
///
/// See [`MatrixView6x3`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut6x3<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U3, ViewStorageMut<'a, T, U6, U3, RStride, CStride>>;
/// A mutable column-major 6x4 matrix view.
///
/// See [`MatrixView6x4`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut6x4<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U4, ViewStorageMut<'a, T, U6, U4, RStride, CStride>>;
/// A mutable column-major 6x5 matrix view.
///
/// See [`MatrixView6x5`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut6x5<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U5, ViewStorageMut<'a, T, U6, U5, RStride, CStride>>;
/// A mutable column-major matrix view with 1 row and a number of columns chosen at runtime.
///
/// See [`MatrixView1xX`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut1xX<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, Dyn, ViewStorageMut<'a, T, U1, Dyn, RStride, CStride>>;
/// A mutable column-major matrix view with 2 rows and a number of columns chosen at runtime.
///
/// See [`MatrixView2xX`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut2xX<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, Dyn, ViewStorageMut<'a, T, U2, Dyn, RStride, CStride>>;
/// A mutable column-major matrix view with 3 rows and a number of columns chosen at runtime.
///
/// See [`MatrixView3xX`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut3xX<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, Dyn, ViewStorageMut<'a, T, U3, Dyn, RStride, CStride>>;
/// A mutable column-major matrix view with 4 rows and a number of columns chosen at runtime.
///
/// See [`MatrixView4xX`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut4xX<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, Dyn, ViewStorageMut<'a, T, U4, Dyn, RStride, CStride>>;
/// A mutable column-major matrix view with 5 rows and a number of columns chosen at runtime.
///
/// See [`MatrixView5xX`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut5xX<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, Dyn, ViewStorageMut<'a, T, U5, Dyn, RStride, CStride>>;
/// A mutable column-major matrix view with 6 rows and a number of columns chosen at runtime.
///
/// See [`MatrixView6xX`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMut6xX<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, Dyn, ViewStorageMut<'a, T, U6, Dyn, RStride, CStride>>;
/// A mutable column-major matrix view with a number of rows chosen at runtime and 1 column.
///
/// See [`MatrixViewXx1`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMutXx1<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U1, ViewStorageMut<'a, T, Dyn, U1, RStride, CStride>>;
/// A mutable column-major matrix view with a number of rows chosen at runtime and 2 columns.
///
/// See [`MatrixViewXx2`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMutXx2<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U2, ViewStorageMut<'a, T, Dyn, U2, RStride, CStride>>;
/// A mutable column-major matrix view with a number of rows chosen at runtime and 3 columns.
///
/// See [`MatrixViewXx3`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMutXx3<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U3, ViewStorageMut<'a, T, Dyn, U3, RStride, CStride>>;
/// A mutable column-major matrix view with a number of rows chosen at runtime and 4 columns.
///
/// See [`MatrixViewXx4`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMutXx4<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U4, ViewStorageMut<'a, T, Dyn, U4, RStride, CStride>>;
/// A mutable column-major matrix view with a number of rows chosen at runtime and 5 columns.
///
/// See [`MatrixViewXx5`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMutXx5<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U5, ViewStorageMut<'a, T, Dyn, U5, RStride, CStride>>;
/// A mutable column-major matrix view with a number of rows chosen at runtime and 6 columns.
///
/// See [`MatrixViewXx6`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixViewMutXx6<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U6, ViewStorageMut<'a, T, Dyn, U6, RStride, CStride>>;
/// A mutable column vector view with dimensions known at compile-time.
///
/// See [`VectorView`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorViewMut<'a, T, D, RStride = U1, CStride = D> =
Matrix<T, D, U1, ViewStorageMut<'a, T, D, U1, RStride, CStride>>;
/// A mutable column vector view with dimensions known at compile-time.
///
/// See [`SVectorView`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type SVectorViewMut<'a, T, const D: usize> =
Matrix<T, Const<D>, Const<1>, ViewStorageMut<'a, T, Const<D>, Const<1>, Const<1>, Const<D>>>;
/// A mutable column vector view dynamic numbers of rows and columns.
///
/// See [`DVectorView`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type DVectorViewMut<'a, T, RStride = U1, CStride = Dyn> =
Matrix<T, Dyn, U1, ViewStorageMut<'a, T, Dyn, U1, RStride, CStride>>;
/// A mutable 1D column vector view.
///
/// See [`VectorView1`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorViewMut1<'a, T, RStride = U1, CStride = U1> =
Matrix<T, U1, U1, ViewStorageMut<'a, T, U1, U1, RStride, CStride>>;
/// A mutable 2D column vector view.
///
/// See [`VectorView2`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorViewMut2<'a, T, RStride = U1, CStride = U2> =
Matrix<T, U2, U1, ViewStorageMut<'a, T, U2, U1, RStride, CStride>>;
/// A mutable 3D column vector view.
///
/// See [`VectorView3`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorViewMut3<'a, T, RStride = U1, CStride = U3> =
Matrix<T, U3, U1, ViewStorageMut<'a, T, U3, U1, RStride, CStride>>;
/// A mutable 4D column vector view.
///
/// See [`VectorView4`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorViewMut4<'a, T, RStride = U1, CStride = U4> =
Matrix<T, U4, U1, ViewStorageMut<'a, T, U4, U1, RStride, CStride>>;
/// A mutable 5D column vector view.
///
/// See [`VectorView5`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorViewMut5<'a, T, RStride = U1, CStride = U5> =
Matrix<T, U5, U1, ViewStorageMut<'a, T, U5, U1, RStride, CStride>>;
/// A mutable 6D column vector view.
///
/// See [`VectorView6`] for an immutable version of this type.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorViewMut6<'a, T, RStride = U1, CStride = U6> =
Matrix<T, U6, U1, ViewStorageMut<'a, T, U6, U1, RStride, CStride>>;

View File

@ -15,14 +15,14 @@ use std::mem::MaybeUninit;
/// ///
/// An allocator is said to be: /// An allocator is said to be:
/// static: if `R` and `C` both implement `DimName`. /// static: if `R` and `C` both implement `DimName`.
/// dynamic: if either one (or both) of `R` or `C` is equal to `Dynamic`. /// dynamic: if either one (or both) of `R` or `C` is equal to `Dyn`.
/// ///
/// Every allocator must be both static and dynamic. Though not all implementations may share the /// Every allocator must be both static and dynamic. Though not all implementations may share the
/// same `Buffer` type. /// same `Buffer` type.
pub trait Allocator<T, R: Dim, C: Dim = U1>: Any + Sized { pub trait Allocator<T, R: Dim, C: Dim = U1>: Any + Sized {
/// The type of buffer this allocator can instanciate. /// The type of buffer this allocator can instantiate.
type Buffer: StorageMut<T, R, C> + IsContiguous + Clone + Debug; type Buffer: StorageMut<T, R, C> + IsContiguous + Clone + Debug;
/// The type of buffer with uninitialized components this allocator can instanciate. /// The type of buffer with uninitialized components this allocator can instantiate.
type BufferUninit: RawStorageMut<MaybeUninit<T>, R, C> + IsContiguous; type BufferUninit: RawStorageMut<MaybeUninit<T>, R, C> + IsContiguous;
/// Allocates a buffer with the given number of rows and columns without initializing its content. /// Allocates a buffer with the given number of rows and columns without initializing its content.
@ -41,6 +41,41 @@ pub trait Allocator<T, R: Dim, C: Dim = U1>: Any + Sized {
ncols: C, ncols: C,
iter: I, iter: I,
) -> Self::Buffer; ) -> Self::Buffer;
#[inline]
/// Allocates a buffer initialized with the content of the given row-major order iterator.
fn allocate_from_row_iterator<I: IntoIterator<Item = T>>(
nrows: R,
ncols: C,
iter: I,
) -> Self::Buffer {
let mut res = Self::allocate_uninit(nrows, ncols);
let mut count = 0;
unsafe {
// OK because the allocated buffer is guaranteed to be contiguous.
let res_ptr = res.as_mut_slice_unchecked();
for (k, e) in iter
.into_iter()
.take(ncols.value() * nrows.value())
.enumerate()
{
let i = k / ncols.value();
let j = k % ncols.value();
// result[(i, j)] = e;
*res_ptr.get_unchecked_mut(i + j * nrows.value()) = MaybeUninit::new(e);
count += 1;
}
assert!(
count == nrows.value() * ncols.value(),
"Matrix init. from row iterator: iterator not long enough."
);
<Self as Allocator<T, R, C>>::assume_init(res)
}
}
} }
/// A matrix reallocator. Changes the size of the memory buffer that initially contains (`RFrom` × /// A matrix reallocator. Changes the size of the memory buffer that initially contains (`RFrom` ×

View File

@ -5,12 +5,15 @@ use std::ops::Mul;
#[cfg(feature = "serde-serialize-no-std")] #[cfg(feature = "serde-serialize-no-std")]
use serde::de::{Error, SeqAccess, Visitor}; use serde::de::{Error, SeqAccess, Visitor};
#[cfg(feature = "serde-serialize-no-std")] #[cfg(feature = "serde-serialize-no-std")]
use serde::ser::SerializeSeq; use serde::ser::SerializeTuple;
#[cfg(feature = "serde-serialize-no-std")] #[cfg(feature = "serde-serialize-no-std")]
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "serde-serialize-no-std")] #[cfg(feature = "serde-serialize-no-std")]
use std::marker::PhantomData; use std::marker::PhantomData;
#[cfg(feature = "rkyv-serialize")]
use rkyv::bytecheck;
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::default_allocator::DefaultAllocator; use crate::base::default_allocator::DefaultAllocator;
use crate::base::dimension::{Const, ToTypenum}; use crate::base::dimension::{Const, ToTypenum};
@ -27,7 +30,18 @@ use std::mem;
/// A array-based statically sized matrix data storage. /// A array-based statically sized matrix data storage.
#[repr(transparent)] #[repr(transparent)]
#[derive(Copy, Clone, PartialEq, Eq, Hash)] #[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] #[cfg_attr(
feature = "rkyv-serialize-no-std",
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize),
archive(
as = "ArrayStorage<T::Archived, R, C>",
bound(archive = "
T: rkyv::Archive,
[[T; R]; C]: rkyv::Archive<Archived = [[T::Archived; R]; C]>
")
)
)]
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
pub struct ArrayStorage<T, const R: usize, const C: usize>(pub [[T; R]; C]); pub struct ArrayStorage<T, const R: usize, const C: usize>(pub [[T; R]; C]);
impl<T, const R: usize, const C: usize> ArrayStorage<T, R, C> { impl<T, const R: usize, const C: usize> ArrayStorage<T, R, C> {
@ -177,7 +191,7 @@ where
where where
S: Serializer, S: Serializer,
{ {
let mut serializer = serializer.serialize_seq(Some(R * C))?; let mut serializer = serializer.serialize_tuple(R * C)?;
for e in self.as_slice().iter() { for e in self.as_slice().iter() {
serializer.serialize_element(e)?; serializer.serialize_element(e)?;
@ -196,7 +210,7 @@ where
where where
D: Deserializer<'a>, D: Deserializer<'a>,
{ {
deserializer.deserialize_seq(ArrayStorageVisitor::new()) deserializer.deserialize_tuple(R * C, ArrayStorageVisitor::new())
} }
} }
@ -273,45 +287,3 @@ unsafe impl<T: Scalar + Copy + bytemuck::Pod, const R: usize, const C: usize> by
for ArrayStorage<T, R, C> for ArrayStorage<T, R, C>
{ {
} }
#[cfg(feature = "rkyv-serialize-no-std")]
mod rkyv_impl {
use super::ArrayStorage;
use rkyv::{offset_of, project_struct, Archive, Deserialize, Fallible, Serialize};
impl<T: Archive, const R: usize, const C: usize> Archive for ArrayStorage<T, R, C> {
type Archived = ArrayStorage<T::Archived, R, C>;
type Resolver = <[[T; R]; C] as Archive>::Resolver;
fn resolve(
&self,
pos: usize,
resolver: Self::Resolver,
out: &mut core::mem::MaybeUninit<Self::Archived>,
) {
self.0.resolve(
pos + offset_of!(Self::Archived, 0),
resolver,
project_struct!(out: Self::Archived => 0),
);
}
}
impl<T: Serialize<S>, S: Fallible + ?Sized, const R: usize, const C: usize> Serialize<S>
for ArrayStorage<T, R, C>
{
fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
self.0.serialize(serializer)
}
}
impl<T: Archive, D: Fallible + ?Sized, const R: usize, const C: usize>
Deserialize<ArrayStorage<T, R, C>, D> for ArrayStorage<T::Archived, R, C>
where
T::Archived: Deserialize<T, D>,
{
fn deserialize(&self, deserializer: &mut D) -> Result<ArrayStorage<T, R, C>, D::Error> {
Ok(ArrayStorage(self.0.deserialize(deserializer)?))
}
}
}

View File

@ -7,11 +7,11 @@ use crate::base::blas_uninit::{axcpy_uninit, gemm_uninit, gemv_uninit};
use crate::base::constraint::{ use crate::base::constraint::{
AreMultipliable, DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint, AreMultipliable, DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint,
}; };
use crate::base::dimension::{Const, Dim, Dynamic, U1, U2, U3, U4}; use crate::base::dimension::{Const, Dim, Dyn, U1, U2, U3, U4};
use crate::base::storage::{Storage, StorageMut}; use crate::base::storage::{Storage, StorageMut};
use crate::base::uninit::Init; use crate::base::uninit::Init;
use crate::base::{ use crate::base::{
DVectorSlice, DefaultAllocator, Matrix, Scalar, SquareMatrix, Vector, VectorSlice, DVectorView, DefaultAllocator, Matrix, Scalar, SquareMatrix, Vector, VectorView,
}; };
/// # Dot/scalar product /// # Dot/scalar product
@ -363,8 +363,8 @@ where
x: &Vector<T, D3, SC>, x: &Vector<T, D3, SC>,
beta: T, beta: T,
dot: impl Fn( dot: impl Fn(
&DVectorSlice<'_, T, SB::RStride, SB::CStride>, &DVectorView<'_, T, SB::RStride, SB::CStride>,
&DVectorSlice<'_, T, SC::RStride, SC::CStride>, &DVectorView<'_, T, SC::RStride, SC::CStride>,
) -> T, ) -> T,
) where ) where
T: One, T: One,
@ -393,7 +393,7 @@ where
let col2 = a.column(0); let col2 = a.column(0);
let val = unsafe { x.vget_unchecked(0).clone() }; let val = unsafe { x.vget_unchecked(0).clone() };
self.axpy(alpha.clone() * val, &col2, beta); self.axpy(alpha.clone() * val, &col2, beta);
self[0] += alpha.clone() * dot(&a.slice_range(1.., 0), &x.rows_range(1..)); self[0] += alpha.clone() * dot(&a.view_range(1.., 0), &x.rows_range(1..));
for j in 1..dim2 { for j in 1..dim2 {
let col2 = a.column(j); let col2 = a.column(j);
@ -506,7 +506,7 @@ where
a: &Matrix<T, R2, C2, SB>, a: &Matrix<T, R2, C2, SB>,
x: &Vector<T, D3, SC>, x: &Vector<T, D3, SC>,
beta: T, beta: T,
dot: impl Fn(&VectorSlice<'_, T, R2, SB::RStride, SB::CStride>, &Vector<T, D3, SC>) -> T, dot: impl Fn(&VectorView<'_, T, R2, SB::RStride, SB::CStride>, &Vector<T, D3, SC>) -> T,
) where ) where
T: One, T: One,
SB: Storage<T, R2, C2>, SB: Storage<T, R2, C2>,
@ -890,9 +890,9 @@ where
for j in 0..dim1 { for j in 0..dim1 {
let val = unsafe { conjugate(y.vget_unchecked(j).clone()) }; let val = unsafe { conjugate(y.vget_unchecked(j).clone()) };
let subdim = Dynamic::new(dim1 - j); let subdim = Dyn(dim1 - j);
// TODO: avoid bound checks. // TODO: avoid bound checks.
self.generic_slice_mut((j, j), (subdim, Const::<1>)).axpy( self.generic_view_mut((j, j), (subdim, Const::<1>)).axpy(
alpha.clone() * val, alpha.clone() * val,
&x.rows_range(j..), &x.rows_range(j..),
beta.clone(), beta.clone(),

View File

@ -13,16 +13,17 @@ use matrixmultiply;
use num::{One, Zero}; use num::{One, Zero};
use simba::scalar::{ClosedAdd, ClosedMul}; use simba::scalar::{ClosedAdd, ClosedMul};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::mem; use std::{any::TypeId, mem};
use crate::base::constraint::{ use crate::base::constraint::{
AreMultipliable, DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint, AreMultipliable, DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint,
}; };
use crate::base::dimension::{Dim, Dynamic, U1}; #[cfg(feature = "std")]
use crate::base::dimension::Dyn;
use crate::base::dimension::{Dim, U1};
use crate::base::storage::{RawStorage, RawStorageMut}; use crate::base::storage::{RawStorage, RawStorageMut};
use crate::base::uninit::InitStatus; use crate::base::uninit::InitStatus;
use crate::base::{Matrix, Scalar, Vector}; use crate::base::{Matrix, Scalar, Vector};
use std::any::TypeId;
// # Safety // # Safety
// The content of `y` must only contain values for which // The content of `y` must only contain values for which
@ -209,16 +210,16 @@ pub unsafe fn gemm_uninit<
#[cfg(feature = "std")] #[cfg(feature = "std")]
{ {
// We assume large matrices will be Dynamic but small matrices static. // We assume large matrices will be Dyn but small matrices static.
// We could use matrixmultiply for large statically-sized matrices but the performance // We could use matrixmultiply for large statically-sized matrices but the performance
// threshold to activate it would be different from SMALL_DIM because our code optimizes // threshold to activate it would be different from SMALL_DIM because our code optimizes
// better for statically-sized matrices. // better for statically-sized matrices.
if R1::is::<Dynamic>() if R1::is::<Dyn>()
|| C1::is::<Dynamic>() || C1::is::<Dyn>()
|| R2::is::<Dynamic>() || R2::is::<Dyn>()
|| C2::is::<Dynamic>() || C2::is::<Dyn>()
|| R3::is::<Dynamic>() || R3::is::<Dyn>()
|| C3::is::<Dynamic>() || C3::is::<Dyn>()
{ {
// matrixmultiply can be used only if the std feature is available. // matrixmultiply can be used only if the std feature is available.
let nrows1 = y.nrows(); let nrows1 = y.nrows();

View File

@ -59,7 +59,7 @@ where
SB: Storage<T, DimNameDiff<D, U1>>, SB: Storage<T, DimNameDiff<D, U1>>,
{ {
let mut res = Self::identity(); let mut res = Self::identity();
res.generic_slice_mut( res.generic_view_mut(
(0, D::dim() - 1), (0, D::dim() - 1),
(DimNameDiff::<D, U1>::name(), Const::<1>), (DimNameDiff::<D, U1>::name(), Const::<1>),
) )
@ -382,19 +382,19 @@ impl<T: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<T, D
DefaultAllocator: Allocator<T, DimNameDiff<D, U1>>, DefaultAllocator: Allocator<T, DimNameDiff<D, U1>>,
{ {
let scale = self let scale = self
.generic_slice( .generic_view(
(D::dim() - 1, 0), (D::dim() - 1, 0),
(Const::<1>, DimNameDiff::<D, U1>::name()), (Const::<1>, DimNameDiff::<D, U1>::name()),
) )
.tr_dot(shift); .tr_dot(shift);
let post_translation = self.generic_slice( let post_translation = self.generic_view(
(0, 0), (0, 0),
(DimNameDiff::<D, U1>::name(), DimNameDiff::<D, U1>::name()), (DimNameDiff::<D, U1>::name(), DimNameDiff::<D, U1>::name()),
) * shift; ) * shift;
self[(D::dim() - 1, D::dim() - 1)] += scale; self[(D::dim() - 1, D::dim() - 1)] += scale;
let mut translation = self.generic_slice_mut( let mut translation = self.generic_view_mut(
(0, D::dim() - 1), (0, D::dim() - 1),
(DimNameDiff::<D, U1>::name(), Const::<1>), (DimNameDiff::<D, U1>::name(), Const::<1>),
); );
@ -415,11 +415,11 @@ where
&self, &self,
v: &OVector<T, DimNameDiff<D, U1>>, v: &OVector<T, DimNameDiff<D, U1>>,
) -> OVector<T, DimNameDiff<D, U1>> { ) -> OVector<T, DimNameDiff<D, U1>> {
let transform = self.generic_slice( let transform = self.generic_view(
(0, 0), (0, 0),
(DimNameDiff::<D, U1>::name(), DimNameDiff::<D, U1>::name()), (DimNameDiff::<D, U1>::name(), DimNameDiff::<D, U1>::name()),
); );
let normalizer = self.generic_slice( let normalizer = self.generic_view(
(D::dim() - 1, 0), (D::dim() - 1, 0),
(Const::<1>, DimNameDiff::<D, U1>::name()), (Const::<1>, DimNameDiff::<D, U1>::name()),
); );
@ -437,9 +437,9 @@ impl<T: RealField, S: Storage<T, Const<3>, Const<3>>> SquareMatrix<T, Const<3>,
/// Transforms the given point, assuming the matrix `self` uses homogeneous coordinates. /// Transforms the given point, assuming the matrix `self` uses homogeneous coordinates.
#[inline] #[inline]
pub fn transform_point(&self, pt: &Point<T, 2>) -> Point<T, 2> { pub fn transform_point(&self, pt: &Point<T, 2>) -> Point<T, 2> {
let transform = self.fixed_slice::<2, 2>(0, 0); let transform = self.fixed_view::<2, 2>(0, 0);
let translation = self.fixed_slice::<2, 1>(0, 2); let translation = self.fixed_view::<2, 1>(0, 2);
let normalizer = self.fixed_slice::<1, 2>(2, 0); let normalizer = self.fixed_view::<1, 2>(2, 0);
let n = normalizer.tr_dot(&pt.coords) + unsafe { self.get_unchecked((2, 2)).clone() }; let n = normalizer.tr_dot(&pt.coords) + unsafe { self.get_unchecked((2, 2)).clone() };
if !n.is_zero() { if !n.is_zero() {
@ -454,9 +454,9 @@ impl<T: RealField, S: Storage<T, Const<4>, Const<4>>> SquareMatrix<T, Const<4>,
/// Transforms the given point, assuming the matrix `self` uses homogeneous coordinates. /// Transforms the given point, assuming the matrix `self` uses homogeneous coordinates.
#[inline] #[inline]
pub fn transform_point(&self, pt: &Point<T, 3>) -> Point<T, 3> { pub fn transform_point(&self, pt: &Point<T, 3>) -> Point<T, 3> {
let transform = self.fixed_slice::<3, 3>(0, 0); let transform = self.fixed_view::<3, 3>(0, 0);
let translation = self.fixed_slice::<3, 1>(0, 3); let translation = self.fixed_view::<3, 1>(0, 3);
let normalizer = self.fixed_slice::<1, 3>(3, 0); let normalizer = self.fixed_view::<1, 3>(3, 0);
let n = normalizer.tr_dot(&pt.coords) + unsafe { self.get_unchecked((3, 3)).clone() }; let n = normalizer.tr_dot(&pt.coords) + unsafe { self.get_unchecked((3, 3)).clone() };
if !n.is_zero() { if !n.is_zero() {

View File

@ -1,12 +1,12 @@
//! Compatibility constraints between matrix shapes, e.g., for addition or multiplication. //! Compatibility constraints between matrix shapes, e.g., for addition or multiplication.
use crate::base::dimension::{Dim, DimName, Dynamic}; use crate::base::dimension::{Dim, DimName, Dyn};
/// A type used in `where` clauses for enforcing constraints. /// A type used in `where` clauses for enforcing constraints.
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct ShapeConstraint; pub struct ShapeConstraint;
/// Constraints `C1` and `R2` to be equivalent. /// Constrains `C1` and `R2` to be equivalent.
pub trait AreMultipliable<R1: Dim, C1: Dim, R2: Dim, C2: Dim>: DimEq<C1, R2> {} pub trait AreMultipliable<R1: Dim, C1: Dim, R2: Dim, C2: Dim>: DimEq<C1, R2> {}
impl<R1: Dim, C1: Dim, R2: Dim, C2: Dim> AreMultipliable<R1, C1, R2, C2> for ShapeConstraint where impl<R1: Dim, C1: Dim, R2: Dim, C2: Dim> AreMultipliable<R1, C1, R2, C2> for ShapeConstraint where
@ -14,7 +14,7 @@ impl<R1: Dim, C1: Dim, R2: Dim, C2: Dim> AreMultipliable<R1, C1, R2, C2> for Sha
{ {
} }
/// Constraints `D1` and `D2` to be equivalent. /// Constrains `D1` and `D2` to be equivalent.
pub trait DimEq<D1: Dim, D2: Dim> { pub trait DimEq<D1: Dim, D2: Dim> {
/// This is either equal to `D1` or `D2`, always choosing the one (if any) which is a type-level /// This is either equal to `D1` or `D2`, always choosing the one (if any) which is a type-level
/// constant. /// constant.
@ -25,17 +25,17 @@ impl<D: Dim> DimEq<D, D> for ShapeConstraint {
type Representative = D; type Representative = D;
} }
impl<D: DimName> DimEq<D, Dynamic> for ShapeConstraint { impl<D: DimName> DimEq<D, Dyn> for ShapeConstraint {
type Representative = D; type Representative = D;
} }
impl<D: DimName> DimEq<Dynamic, D> for ShapeConstraint { impl<D: DimName> DimEq<Dyn, D> for ShapeConstraint {
type Representative = D; type Representative = D;
} }
macro_rules! equality_trait_decl( macro_rules! equality_trait_decl(
($($doc: expr, $Trait: ident),* $(,)*) => {$( ($($doc: expr, $Trait: ident),* $(,)*) => {$(
// XXX: we can't do something like `DimEq<D1> for D2` because we would require a blancket impl… // XXX: we can't do something like `DimEq<D1> for D2` because we would require a blanket impl…
#[doc = $doc] #[doc = $doc]
pub trait $Trait<D1: Dim, D2: Dim>: DimEq<D1, D2> + DimEq<D2, D1> { pub trait $Trait<D1: Dim, D2: Dim>: DimEq<D1, D2> + DimEq<D2, D1> {
/// This is either equal to `D1` or `D2`, always choosing the one (if any) which is a type-level /// This is either equal to `D1` or `D2`, always choosing the one (if any) which is a type-level
@ -47,28 +47,28 @@ macro_rules! equality_trait_decl(
type Representative = D; type Representative = D;
} }
impl<D: DimName> $Trait<D, Dynamic> for ShapeConstraint { impl<D: DimName> $Trait<D, Dyn> for ShapeConstraint {
type Representative = D; type Representative = D;
} }
impl<D: DimName> $Trait<Dynamic, D> for ShapeConstraint { impl<D: DimName> $Trait<Dyn, D> for ShapeConstraint {
type Representative = D; type Representative = D;
} }
)*} )*}
); );
equality_trait_decl!( equality_trait_decl!(
"Constraints `D1` and `D2` to be equivalent. \ "Constrains `D1` and `D2` to be equivalent. \
They are both assumed to be the number of \ They are both assumed to be the number of \
rows of a matrix.", rows of a matrix.",
SameNumberOfRows, SameNumberOfRows,
"Constraints `D1` and `D2` to be equivalent. \ "Constrains `D1` and `D2` to be equivalent. \
They are both assumed to be the number of \ They are both assumed to be the number of \
columns of a matrix.", columns of a matrix.",
SameNumberOfColumns SameNumberOfColumns
); );
/// Constraints D1 and D2 to be equivalent, where they both designate dimensions of algebraic /// Constrains D1 and D2 to be equivalent, where they both designate dimensions of algebraic
/// entities (e.g. square matrices). /// entities (e.g. square matrices).
pub trait SameDimension<D1: Dim, D2: Dim>: pub trait SameDimension<D1: Dim, D2: Dim>:
SameNumberOfRows<D1, D2> + SameNumberOfColumns<D1, D2> SameNumberOfRows<D1, D2> + SameNumberOfColumns<D1, D2>
@ -82,10 +82,10 @@ impl<D: Dim> SameDimension<D, D> for ShapeConstraint {
type Representative = D; type Representative = D;
} }
impl<D: DimName> SameDimension<D, Dynamic> for ShapeConstraint { impl<D: DimName> SameDimension<D, Dyn> for ShapeConstraint {
type Representative = D; type Representative = D;
} }
impl<D: DimName> SameDimension<Dynamic, D> for ShapeConstraint { impl<D: DimName> SameDimension<Dyn, D> for ShapeConstraint {
type Representative = D; type Representative = D;
} }

View File

@ -19,7 +19,7 @@ use typenum::{self, Cmp, Greater};
use simba::scalar::{ClosedAdd, ClosedMul}; use simba::scalar::{ClosedAdd, ClosedMul};
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{Dim, DimName, Dynamic, ToTypenum}; use crate::base::dimension::{Dim, DimName, Dyn, ToTypenum};
use crate::base::storage::RawStorage; use crate::base::storage::RawStorage;
use crate::base::{ use crate::base::{
ArrayStorage, Const, DefaultAllocator, Matrix, OMatrix, OVector, Scalar, Unit, Vector, ArrayStorage, Const, DefaultAllocator, Matrix, OMatrix, OVector, Scalar, Unit, Vector,
@ -86,6 +86,17 @@ where
Self::from_data(DefaultAllocator::allocate_from_iterator(nrows, ncols, iter)) Self::from_data(DefaultAllocator::allocate_from_iterator(nrows, ncols, iter))
} }
/// Creates a matrix with all its elements filled by an row-major order iterator.
#[inline]
pub fn from_row_iterator_generic<I>(nrows: R, ncols: C, iter: I) -> Self
where
I: IntoIterator<Item = T>,
{
Self::from_data(DefaultAllocator::allocate_from_row_iterator(
nrows, ncols, iter,
))
}
/// Creates a matrix with its elements filled with the components provided by a slice in /// Creates a matrix with its elements filled with the components provided by a slice in
/// row-major order. /// row-major order.
/// ///
@ -215,7 +226,7 @@ where
SB: RawStorage<T, Const<1>, C>, SB: RawStorage<T, Const<1>, C>,
{ {
assert!(!rows.is_empty(), "At least one row must be given."); assert!(!rows.is_empty(), "At least one row must be given.");
let nrows = R::try_to_usize().unwrap_or_else(|| rows.len()); let nrows = R::try_to_usize().unwrap_or(rows.len());
let ncols = rows[0].len(); let ncols = rows[0].len();
assert!( assert!(
rows.len() == nrows, rows.len() == nrows,
@ -257,7 +268,7 @@ where
SB: RawStorage<T, R>, SB: RawStorage<T, R>,
{ {
assert!(!columns.is_empty(), "At least one column must be given."); assert!(!columns.is_empty(), "At least one column must be given.");
let ncols = C::try_to_usize().unwrap_or_else(|| columns.len()); let ncols = C::try_to_usize().unwrap_or(columns.len());
let nrows = columns[0].len(); let nrows = columns[0].len();
assert!( assert!(
columns.len() == ncols, columns.len() == ncols,
@ -306,12 +317,12 @@ where
/// ///
/// # Example /// # Example
/// ``` /// ```
/// # use nalgebra::{Dynamic, DMatrix, Matrix, Const}; /// # use nalgebra::{Dyn, DMatrix, Matrix, Const};
/// ///
/// let vec = vec![0, 1, 2, 3, 4, 5]; /// let vec = vec![0, 1, 2, 3, 4, 5];
/// let vec_ptr = vec.as_ptr(); /// let vec_ptr = vec.as_ptr();
/// ///
/// let matrix = Matrix::from_vec_generic(Dynamic::new(vec.len()), Const::<1>, vec); /// let matrix = Matrix::from_vec_generic(Dyn(vec.len()), Const::<1>, vec);
/// let matrix_storage_ptr = matrix.data.as_vec().as_ptr(); /// let matrix_storage_ptr = matrix.data.as_vec().as_ptr();
/// ///
/// // `matrix` is backed by exactly the same `Vec` as it was constructed from. /// // `matrix` is backed by exactly the same `Vec` as it was constructed from.
@ -479,6 +490,36 @@ macro_rules! impl_constructors(
Self::from_iterator_generic($($gargs, )* iter) Self::from_iterator_generic($($gargs, )* iter)
} }
/// Creates a matrix or vector with all its elements filled by a row-major iterator.
///
/// The output matrix is filled row-by-row.
///
/// ## Example
/// ```
/// # use nalgebra::{Matrix2x3, Vector3, DVector, DMatrix};
/// # use std::iter;
///
/// let v = Vector3::from_row_iterator((0..3).into_iter());
/// // The additional argument represents the vector dimension.
/// let dv = DVector::from_row_iterator(3, (0..3).into_iter());
/// let m = Matrix2x3::from_row_iterator((0..6).into_iter());
/// // The two additional arguments represent the matrix dimensions.
/// let dm = DMatrix::from_row_iterator(2, 3, (0..6).into_iter());
///
/// // For Vectors from_row_iterator is identical to from_iterator
/// assert!(v.x == 0 && v.y == 1 && v.z == 2);
/// assert!(dv[0] == 0 && dv[1] == 1 && dv[2] == 2);
/// assert!(m.m11 == 0 && m.m12 == 1 && m.m13 == 2 &&
/// m.m21 == 3 && m.m22 == 4 && m.m23 == 5);
/// assert!(dm[(0, 0)] == 0 && dm[(0, 1)] == 1 && dm[(0, 2)] == 2 &&
/// dm[(1, 0)] == 3 && dm[(1, 1)] == 4 && dm[(1, 2)] == 5);
/// ```
#[inline]
pub fn from_row_iterator<I>($($args: usize,)* iter: I) -> Self
where I: IntoIterator<Item = T> {
Self::from_row_iterator_generic($($gargs, )* iter)
}
/// Creates a matrix or vector filled with the results of a function applied to each of its /// Creates a matrix or vector filled with the results of a function applied to each of its
/// component coordinates. /// component coordinates.
/// ///
@ -615,35 +656,35 @@ where
} }
/// # Constructors of matrices with a dynamic number of columns /// # Constructors of matrices with a dynamic number of columns
impl<T: Scalar, R: DimName> OMatrix<T, R, Dynamic> impl<T: Scalar, R: DimName> OMatrix<T, R, Dyn>
where where
DefaultAllocator: Allocator<T, R, Dynamic>, DefaultAllocator: Allocator<T, R, Dyn>,
{ {
impl_constructors!(R, Dynamic; impl_constructors!(R, Dyn;
=> R: DimName; => R: DimName;
R::name(), Dynamic::new(ncols); R::name(), Dyn(ncols);
ncols); ncols);
} }
/// # Constructors of dynamic vectors and matrices with a dynamic number of rows /// # Constructors of dynamic vectors and matrices with a dynamic number of rows
impl<T: Scalar, C: DimName> OMatrix<T, Dynamic, C> impl<T: Scalar, C: DimName> OMatrix<T, Dyn, C>
where where
DefaultAllocator: Allocator<T, Dynamic, C>, DefaultAllocator: Allocator<T, Dyn, C>,
{ {
impl_constructors!(Dynamic, C; impl_constructors!(Dyn, C;
=> C: DimName; => C: DimName;
Dynamic::new(nrows), C::name(); Dyn(nrows), C::name();
nrows); nrows);
} }
/// # Constructors of fully dynamic matrices /// # Constructors of fully dynamic matrices
impl<T: Scalar> OMatrix<T, Dynamic, Dynamic> impl<T: Scalar> OMatrix<T, Dyn, Dyn>
where where
DefaultAllocator: Allocator<T, Dynamic, Dynamic>, DefaultAllocator: Allocator<T, Dyn, Dyn>,
{ {
impl_constructors!(Dynamic, Dynamic; impl_constructors!(Dyn, Dyn;
; ;
Dynamic::new(nrows), Dynamic::new(ncols); Dyn(nrows), Dyn(ncols);
nrows, ncols); nrows, ncols);
} }
@ -749,19 +790,19 @@ impl_constructors_from_data!(data; R, C; // Arguments for Matri
R::name(), C::name(); // Arguments for `_generic` constructors. R::name(), C::name(); // Arguments for `_generic` constructors.
); // Arguments for non-generic constructors. ); // Arguments for non-generic constructors.
impl_constructors_from_data!(data; R, Dynamic; impl_constructors_from_data!(data; R, Dyn;
=> R: DimName; => R: DimName;
R::name(), Dynamic::new(data.len() / R::dim()); R::name(), Dyn(data.len() / R::dim());
); );
impl_constructors_from_data!(data; Dynamic, C; impl_constructors_from_data!(data; Dyn, C;
=> C: DimName; => C: DimName;
Dynamic::new(data.len() / C::dim()), C::name(); Dyn(data.len() / C::dim()), C::name();
); );
impl_constructors_from_data!(data; Dynamic, Dynamic; impl_constructors_from_data!(data; Dyn, Dyn;
; ;
Dynamic::new(nrows), Dynamic::new(ncols); Dyn(nrows), Dyn(ncols);
nrows, ncols); nrows, ncols);
/* /*

View File

@ -1,18 +1,18 @@
use crate::base::dimension::{Const, Dim, DimName, Dynamic}; use crate::base::dimension::{Const, Dim, DimName, Dyn};
use crate::base::matrix_slice::{SliceStorage, SliceStorageMut}; use crate::base::matrix_view::{ViewStorage, ViewStorageMut};
use crate::base::{MatrixSlice, MatrixSliceMutMN, Scalar}; use crate::base::{MatrixView, MatrixViewMut, Scalar};
use num_rational::Ratio; use num_rational::Ratio;
/// # Creating matrix slices from `&[T]` /// # Creating matrix views from `&[T]`
impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
MatrixSlice<'a, T, R, C, RStride, CStride> MatrixView<'a, T, R, C, RStride, CStride>
{ {
/// Creates, without bound-checking, a matrix slice from an array and with dimensions and strides specified by generic types instances. /// Creates, without bounds checking, a matrix view from an array and with dimensions and strides specified by generic types instances.
/// ///
/// # Safety /// # Safety
/// This method is unsafe because the input data array is not checked to contain enough elements. /// This method is unsafe because the input data array is not checked to contain enough elements.
/// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`. /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dyn()`.
#[inline] #[inline]
pub unsafe fn from_slice_with_strides_generic_unchecked( pub unsafe fn from_slice_with_strides_generic_unchecked(
data: &'a [T], data: &'a [T],
@ -22,7 +22,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
rstride: RStride, rstride: RStride,
cstride: CStride, cstride: CStride,
) -> Self { ) -> Self {
let data = SliceStorage::from_raw_parts( let data = ViewStorage::from_raw_parts(
data.as_ptr().add(start), data.as_ptr().add(start),
(nrows, ncols), (nrows, ncols),
(rstride, cstride), (rstride, cstride),
@ -30,10 +30,10 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
Self::from_data(data) Self::from_data(data)
} }
/// Creates a matrix slice from an array and with dimensions and strides specified by generic types instances. /// Creates a matrix view from an array and with dimensions and strides specified by generic types instances.
/// ///
/// Panics if the input data array dose not contain enough elements. /// Panics if the input data array dose not contain enough elements.
/// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`. /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dyn()`.
#[inline] #[inline]
pub fn from_slice_with_strides_generic( pub fn from_slice_with_strides_generic(
data: &'a [T], data: &'a [T],
@ -48,7 +48,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
assert!( assert!(
data.len() + cstride.value() + rstride.value() data.len() + cstride.value() + rstride.value()
>= ncols.value() * cstride.value() + nrows.value() * rstride.value() + 1, >= ncols.value() * cstride.value() + nrows.value() * rstride.value() + 1,
"Matrix slice: input data buffer to small." "Matrix view: input data buffer too small."
); );
unsafe { unsafe {
@ -57,12 +57,12 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
} }
} }
impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSlice<'a, T, R, C> { impl<'a, T: Scalar, R: Dim, C: Dim> MatrixView<'a, T, R, C> {
/// Creates, without bound-checking, a matrix slice from an array and with dimensions specified by generic types instances. /// Creates, without bound-checking, a matrix view from an array and with dimensions specified by generic types instances.
/// ///
/// # Safety /// # Safety
/// This method is unsafe because the input data array is not checked to contain enough elements. /// This method is unsafe because the input data array is not checked to contain enough elements.
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`. /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dyn()`.
#[inline] #[inline]
pub unsafe fn from_slice_generic_unchecked( pub unsafe fn from_slice_generic_unchecked(
data: &'a [T], data: &'a [T],
@ -75,10 +75,10 @@ impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSlice<'a, T, R, C> {
) )
} }
/// Creates a matrix slice from an array and with dimensions and strides specified by generic types instances. /// Creates a matrix view from an array and with dimensions and strides specified by generic types instances.
/// ///
/// Panics if the input data array dose not contain enough elements. /// Panics if the input data array dose not contain enough elements.
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`. /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dyn()`.
#[inline] #[inline]
pub fn from_slice_generic(data: &'a [T], nrows: R, ncols: C) -> Self { pub fn from_slice_generic(data: &'a [T], nrows: R, ncols: C) -> Self {
Self::from_slice_with_strides_generic(data, nrows, ncols, Const::<1>, nrows) Self::from_slice_with_strides_generic(data, nrows, ncols, Const::<1>, nrows)
@ -87,8 +87,8 @@ impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSlice<'a, T, R, C> {
macro_rules! impl_constructors( macro_rules! impl_constructors(
($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => { ($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixSlice<'a, T, $($Dims),*> { impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixView<'a, T, $($Dims),*> {
/// Creates a new matrix slice from the given data array. /// Creates a new matrix view from the given data array.
/// ///
/// Panics if `data` does not contain enough elements. /// Panics if `data` does not contain enough elements.
#[inline] #[inline]
@ -96,26 +96,33 @@ macro_rules! impl_constructors(
Self::from_slice_generic(data, $($gargs),*) Self::from_slice_generic(data, $($gargs),*)
} }
/// Creates, without bound checking, a new matrix slice from the given data array. /// Creates, without bound checking, a new matrix view from the given data array.
/// # Safety
/// `data[start..start+rstride * cstride]` must be within bounds.
#[inline] #[inline]
pub unsafe fn from_slice_unchecked(data: &'a [T], start: usize, $($args: usize),*) -> Self { pub unsafe fn from_slice_unchecked(data: &'a [T], start: usize, $($args: usize),*) -> Self {
Self::from_slice_generic_unchecked(data, start, $($gargs),*) Self::from_slice_generic_unchecked(data, start, $($gargs),*)
} }
} }
impl<'a, T: Scalar, $($DimIdent: $DimBound, )*> MatrixSlice<'a, T, $($Dims,)* Dynamic, Dynamic> { impl<'a, T: Scalar, $($DimIdent: $DimBound, )*> MatrixView<'a, T, $($Dims,)* Dyn, Dyn> {
/// Creates a new matrix slice with the specified strides from the given data array. /// Creates a new matrix view with the specified strides from the given data array.
/// ///
/// Panics if `data` does not contain enough elements. /// Panics if `data` does not contain enough elements.
#[inline] #[inline]
pub fn from_slice_with_strides(data: &'a [T], $($args: usize,)* rstride: usize, cstride: usize) -> Self { pub fn from_slice_with_strides(data: &'a [T], $($args: usize,)* rstride: usize, cstride: usize) -> Self {
Self::from_slice_with_strides_generic(data, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride)) Self::from_slice_with_strides_generic(data, $($gargs,)* Dyn(rstride), Dyn(cstride))
} }
/// Creates, without bound checking, a new matrix slice with the specified strides from the given data array. /// Creates, without bound checking, a new matrix view with the specified strides from the given data array.
///
/// # Safety
///
/// `start`, `rstride`, and `cstride`, with the given matrix size will not index
/// outside of `data`.
#[inline] #[inline]
pub unsafe fn from_slice_with_strides_unchecked(data: &'a [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self { pub unsafe fn from_slice_with_strides_unchecked(data: &'a [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
Self::from_slice_with_strides_generic_unchecked(data, start, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride)) Self::from_slice_with_strides_generic_unchecked(data, start, $($gargs,)* Dyn(rstride), Dyn(cstride))
} }
} }
} }
@ -127,30 +134,30 @@ impl_constructors!(R, C; // Arguments for Matrix<T, ...,
R::name(), C::name(); // Arguments for `_generic` constructors. R::name(), C::name(); // Arguments for `_generic` constructors.
); // Arguments for non-generic constructors. ); // Arguments for non-generic constructors.
impl_constructors!(R, Dynamic; impl_constructors!(R, Dyn;
=> R: DimName; => R: DimName;
R::name(), Dynamic::new(ncols); R::name(), Dyn(ncols);
ncols); ncols);
impl_constructors!(Dynamic, C; impl_constructors!(Dyn, C;
=> C: DimName; => C: DimName;
Dynamic::new(nrows), C::name(); Dyn(nrows), C::name();
nrows); nrows);
impl_constructors!(Dynamic, Dynamic; impl_constructors!(Dyn, Dyn;
; ;
Dynamic::new(nrows), Dynamic::new(ncols); Dyn(nrows), Dyn(ncols);
nrows, ncols); nrows, ncols);
/// # Creating mutable matrix slices from `&mut [T]` /// # Creating mutable matrix views from `&mut [T]`
impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
MatrixSliceMutMN<'a, T, R, C, RStride, CStride> MatrixViewMut<'a, T, R, C, RStride, CStride>
{ {
/// Creates, without bound-checking, a mutable matrix slice from an array and with dimensions and strides specified by generic types instances. /// Creates, without bound-checking, a mutable matrix view from an array and with dimensions and strides specified by generic types instances.
/// ///
/// # Safety /// # Safety
/// This method is unsafe because the input data array is not checked to contain enough elements. /// This method is unsafe because the input data array is not checked to contain enough elements.
/// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`. /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dyn()`.
#[inline] #[inline]
pub unsafe fn from_slice_with_strides_generic_unchecked( pub unsafe fn from_slice_with_strides_generic_unchecked(
data: &'a mut [T], data: &'a mut [T],
@ -160,7 +167,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
rstride: RStride, rstride: RStride,
cstride: CStride, cstride: CStride,
) -> Self { ) -> Self {
let data = SliceStorageMut::from_raw_parts( let data = ViewStorageMut::from_raw_parts(
data.as_mut_ptr().add(start), data.as_mut_ptr().add(start),
(nrows, ncols), (nrows, ncols),
(rstride, cstride), (rstride, cstride),
@ -168,10 +175,10 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
Self::from_data(data) Self::from_data(data)
} }
/// Creates a mutable matrix slice from an array and with dimensions and strides specified by generic types instances. /// Creates a mutable matrix view from an array and with dimensions and strides specified by generic types instances.
/// ///
/// Panics if the input data array dose not contain enough elements. /// Panics if the input data array dose not contain enough elements.
/// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`. /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dyn()`.
#[inline] #[inline]
pub fn from_slice_with_strides_generic( pub fn from_slice_with_strides_generic(
data: &'a mut [T], data: &'a mut [T],
@ -186,7 +193,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
assert!( assert!(
data.len() + cstride.value() + rstride.value() data.len() + cstride.value() + rstride.value()
>= ncols.value() * cstride.value() + nrows.value() * rstride.value() + 1, >= ncols.value() * cstride.value() + nrows.value() * rstride.value() + 1,
"Matrix slice: input data buffer to small." "Matrix view: input data buffer too small."
); );
assert!( assert!(
@ -208,7 +215,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
} }
} }
}, },
"Matrix slice: dimensions and strides result in aliased indices." "Matrix view: dimensions and strides result in aliased indices."
); );
unsafe { unsafe {
@ -217,12 +224,12 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
} }
} }
impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSliceMutMN<'a, T, R, C> { impl<'a, T: Scalar, R: Dim, C: Dim> MatrixViewMut<'a, T, R, C> {
/// Creates, without bound-checking, a mutable matrix slice from an array and with dimensions specified by generic types instances. /// Creates, without bound-checking, a mutable matrix view from an array and with dimensions specified by generic types instances.
/// ///
/// # Safety /// # Safety
/// This method is unsafe because the input data array is not checked to contain enough elements. /// This method is unsafe because the input data array is not checked to contain enough elements.
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`. /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dyn()`.
#[inline] #[inline]
pub unsafe fn from_slice_generic_unchecked( pub unsafe fn from_slice_generic_unchecked(
data: &'a mut [T], data: &'a mut [T],
@ -235,10 +242,10 @@ impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSliceMutMN<'a, T, R, C> {
) )
} }
/// Creates a mutable matrix slice from an array and with dimensions and strides specified by generic types instances. /// Creates a mutable matrix view from an array and with dimensions and strides specified by generic types instances.
/// ///
/// Panics if the input data array dose not contain enough elements. /// Panics if the input data array dose not contain enough elements.
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`. /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dyn()`.
#[inline] #[inline]
pub fn from_slice_generic(data: &'a mut [T], nrows: R, ncols: C) -> Self { pub fn from_slice_generic(data: &'a mut [T], nrows: R, ncols: C) -> Self {
Self::from_slice_with_strides_generic(data, nrows, ncols, Const::<1>, nrows) Self::from_slice_with_strides_generic(data, nrows, ncols, Const::<1>, nrows)
@ -247,8 +254,8 @@ impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSliceMutMN<'a, T, R, C> {
macro_rules! impl_constructors_mut( macro_rules! impl_constructors_mut(
($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => { ($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixSliceMutMN<'a, T, $($Dims),*> { impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixViewMut<'a, T, $($Dims),*> {
/// Creates a new mutable matrix slice from the given data array. /// Creates a new mutable matrix view from the given data array.
/// ///
/// Panics if `data` does not contain enough elements. /// Panics if `data` does not contain enough elements.
#[inline] #[inline]
@ -256,28 +263,34 @@ macro_rules! impl_constructors_mut(
Self::from_slice_generic(data, $($gargs),*) Self::from_slice_generic(data, $($gargs),*)
} }
/// Creates, without bound checking, a new mutable matrix slice from the given data array. /// Creates, without bound checking, a new mutable matrix view from the given data array.
///
/// # Safety
///
/// `data[start..start+(R * C)]` must be within bounds.
#[inline] #[inline]
pub unsafe fn from_slice_unchecked(data: &'a mut [T], start: usize, $($args: usize),*) -> Self { pub unsafe fn from_slice_unchecked(data: &'a mut [T], start: usize, $($args: usize),*) -> Self {
Self::from_slice_generic_unchecked(data, start, $($gargs),*) Self::from_slice_generic_unchecked(data, start, $($gargs),*)
} }
} }
impl<'a, T: Scalar, $($DimIdent: $DimBound, )*> MatrixSliceMutMN<'a, T, $($Dims,)* Dynamic, Dynamic> { impl<'a, T: Scalar, $($DimIdent: $DimBound, )*> MatrixViewMut<'a, T, $($Dims,)* Dyn, Dyn> {
/// Creates a new mutable matrix slice with the specified strides from the given data array. /// Creates a new mutable matrix view with the specified strides from the given data array.
/// ///
/// Panics if `data` does not contain enough elements. /// Panics if `data` does not contain enough elements.
#[inline] #[inline]
pub fn from_slice_with_strides_mut(data: &'a mut [T], $($args: usize,)* rstride: usize, cstride: usize) -> Self { pub fn from_slice_with_strides_mut(data: &'a mut [T], $($args: usize,)* rstride: usize, cstride: usize) -> Self {
Self::from_slice_with_strides_generic( Self::from_slice_with_strides_generic(
data, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride)) data, $($gargs,)* Dyn(rstride), Dyn(cstride))
} }
/// Creates, without bound checking, a new mutable matrix slice with the specified strides from the given data array. /// Creates, without bound checking, a new mutable matrix view with the specified strides from the given data array.
/// # Safety
/// `data[start..start+rstride * cstride]` must be within bounds.
#[inline] #[inline]
pub unsafe fn from_slice_with_strides_unchecked(data: &'a mut [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self { pub unsafe fn from_slice_with_strides_unchecked(data: &'a mut [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
Self::from_slice_with_strides_generic_unchecked( Self::from_slice_with_strides_generic_unchecked(
data, start, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride)) data, start, $($gargs,)* Dyn(rstride), Dyn(cstride))
} }
} }
} }
@ -289,17 +302,17 @@ impl_constructors_mut!(R, C; // Arguments for Matrix<T,
R::name(), C::name(); // Arguments for `_generic` constructors. R::name(), C::name(); // Arguments for `_generic` constructors.
); // Arguments for non-generic constructors. ); // Arguments for non-generic constructors.
impl_constructors_mut!(R, Dynamic; impl_constructors_mut!(R, Dyn;
=> R: DimName; => R: DimName;
R::name(), Dynamic::new(ncols); R::name(), Dyn(ncols);
ncols); ncols);
impl_constructors_mut!(Dynamic, C; impl_constructors_mut!(Dyn, C;
=> C: DimName; => C: DimName;
Dynamic::new(nrows), C::name(); Dyn(nrows), C::name();
nrows); nrows);
impl_constructors_mut!(Dynamic, Dynamic; impl_constructors_mut!(Dyn, Dyn;
; ;
Dynamic::new(nrows), Dynamic::new(ncols); Dyn(nrows), Dyn(ncols);
nrows, ncols); nrows, ncols);

View File

@ -8,22 +8,22 @@ use simba::simd::{PrimitiveSimdValue, SimdValue};
use crate::base::allocator::{Allocator, SameShapeAllocator}; use crate::base::allocator::{Allocator, SameShapeAllocator};
use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
#[cfg(any(feature = "std", feature = "alloc"))]
use crate::base::dimension::Dynamic;
use crate::base::dimension::{ use crate::base::dimension::{
Const, Dim, DimName, U1, U10, U11, U12, U13, U14, U15, U16, U2, U3, U4, U5, U6, U7, U8, U9, Const, Dim, U1, U10, U11, U12, U13, U14, U15, U16, U2, U3, U4, U5, U6, U7, U8, U9,
}; };
#[cfg(any(feature = "std", feature = "alloc"))]
use crate::base::dimension::{DimName, Dyn};
use crate::base::iter::{MatrixIter, MatrixIterMut}; use crate::base::iter::{MatrixIter, MatrixIterMut};
use crate::base::storage::{IsContiguous, RawStorage, RawStorageMut}; use crate::base::storage::{IsContiguous, RawStorage, RawStorageMut};
use crate::base::{ use crate::base::{
ArrayStorage, DVectorSlice, DVectorSliceMut, DefaultAllocator, Matrix, MatrixSlice, ArrayStorage, DVectorView, DVectorViewMut, DefaultAllocator, Matrix, MatrixView, MatrixViewMut,
MatrixSliceMut, OMatrix, Scalar, OMatrix, Scalar,
}; };
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
use crate::base::{DVector, RowDVector, VecStorage}; use crate::base::{DVector, RowDVector, VecStorage};
use crate::base::{SliceStorage, SliceStorageMut}; use crate::base::{ViewStorage, ViewStorageMut};
use crate::constraint::DimEq; use crate::constraint::DimEq;
use crate::{IsNotStaticOne, RowSVector, SMatrix, SVector, VectorSlice, VectorSliceMut}; use crate::{IsNotStaticOne, RowSVector, SMatrix, SVector, VectorView, VectorViewMut};
use std::mem::MaybeUninit; use std::mem::MaybeUninit;
// TODO: too bad this won't work for slice conversions. // TODO: too bad this won't work for slice conversions.
@ -98,6 +98,18 @@ impl<'a, T: Scalar, R: Dim, C: Dim, S: RawStorage<T, R, C>> IntoIterator
} }
} }
impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> IntoIterator
for Matrix<T, R, C, ViewStorage<'a, T, R, C, RStride, CStride>>
{
type Item = &'a T;
type IntoIter = MatrixIter<'a, T, R, C, ViewStorage<'a, T, R, C, RStride, CStride>>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
MatrixIter::new_owned(self.data)
}
}
impl<'a, T: Scalar, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> IntoIterator impl<'a, T: Scalar, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> IntoIterator
for &'a mut Matrix<T, R, C, S> for &'a mut Matrix<T, R, C, S>
{ {
@ -110,6 +122,18 @@ impl<'a, T: Scalar, R: Dim, C: Dim, S: RawStorageMut<T, R, C>> IntoIterator
} }
} }
impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> IntoIterator
for Matrix<T, R, C, ViewStorageMut<'a, T, R, C, RStride, CStride>>
{
type Item = &'a mut T;
type IntoIter = MatrixIterMut<'a, T, R, C, ViewStorageMut<'a, T, R, C, RStride, CStride>>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
MatrixIterMut::new_owned_mut(self.data)
}
}
impl<T: Scalar, const D: usize> From<[T; D]> for SVector<T, D> { impl<T: Scalar, const D: usize> From<[T; D]> for SVector<T, D> {
#[inline] #[inline]
fn from(arr: [T; D]) -> Self { fn from(arr: [T; D]) -> Self {
@ -126,19 +150,19 @@ impl<T: Scalar, const D: usize> From<SVector<T, D>> for [T; D] {
} }
impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const D: usize> impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const D: usize>
From<VectorSlice<'a, T, Const<D>, RStride, CStride>> for [T; D] From<VectorView<'a, T, Const<D>, RStride, CStride>> for [T; D]
{ {
#[inline] #[inline]
fn from(vec: VectorSlice<'a, T, Const<D>, RStride, CStride>) -> Self { fn from(vec: VectorView<'a, T, Const<D>, RStride, CStride>) -> Self {
vec.into_owned().into() vec.into_owned().into()
} }
} }
impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const D: usize> impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const D: usize>
From<VectorSliceMut<'a, T, Const<D>, RStride, CStride>> for [T; D] From<VectorViewMut<'a, T, Const<D>, RStride, CStride>> for [T; D]
{ {
#[inline] #[inline]
fn from(vec: VectorSliceMut<'a, T, Const<D>, RStride, CStride>) -> Self { fn from(vec: VectorViewMut<'a, T, Const<D>, RStride, CStride>) -> Self {
vec.into_owned().into() vec.into_owned().into()
} }
} }
@ -221,19 +245,19 @@ impl<T: Scalar, const R: usize, const C: usize> From<SMatrix<T, R, C>> for [[T;
} }
impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const R: usize, const C: usize> impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const R: usize, const C: usize>
From<MatrixSlice<'a, T, Const<R>, Const<C>, RStride, CStride>> for [[T; R]; C] From<MatrixView<'a, T, Const<R>, Const<C>, RStride, CStride>> for [[T; R]; C]
{ {
#[inline] #[inline]
fn from(mat: MatrixSlice<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self { fn from(mat: MatrixView<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
mat.into_owned().into() mat.into_owned().into()
} }
} }
impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const R: usize, const C: usize> impl<'a, T: Scalar, RStride: Dim, CStride: Dim, const R: usize, const C: usize>
From<MatrixSliceMut<'a, T, Const<R>, Const<C>, RStride, CStride>> for [[T; R]; C] From<MatrixViewMut<'a, T, Const<R>, Const<C>, RStride, CStride>> for [[T; R]; C]
{ {
#[inline] #[inline]
fn from(mat: MatrixSliceMut<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self { fn from(mat: MatrixViewMut<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
mat.into_owned().into() mat.into_owned().into()
} }
} }
@ -289,192 +313,183 @@ impl_from_into_asref_borrow_2D!(
); );
impl<'a, T, RStride, CStride, const R: usize, const C: usize> impl<'a, T, RStride, CStride, const R: usize, const C: usize>
From<MatrixSlice<'a, T, Const<R>, Const<C>, RStride, CStride>> From<MatrixView<'a, T, Const<R>, Const<C>, RStride, CStride>>
for Matrix<T, Const<R>, Const<C>, ArrayStorage<T, R, C>> for Matrix<T, Const<R>, Const<C>, ArrayStorage<T, R, C>>
where where
T: Scalar, T: Scalar,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
{ {
fn from(matrix_slice: MatrixSlice<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self { fn from(matrix_view: MatrixView<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
matrix_slice.into_owned() matrix_view.into_owned()
} }
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, T, C, RStride, CStride> From<MatrixSlice<'a, T, Dynamic, C, RStride, CStride>> impl<'a, T, C, RStride, CStride> From<MatrixView<'a, T, Dyn, C, RStride, CStride>>
for Matrix<T, Dynamic, C, VecStorage<T, Dynamic, C>> for Matrix<T, Dyn, C, VecStorage<T, Dyn, C>>
where where
T: Scalar, T: Scalar,
C: Dim, C: Dim,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
{ {
fn from(matrix_slice: MatrixSlice<'a, T, Dynamic, C, RStride, CStride>) -> Self { fn from(matrix_view: MatrixView<'a, T, Dyn, C, RStride, CStride>) -> Self {
matrix_slice.into_owned() matrix_view.into_owned()
} }
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, T, R, RStride, CStride> From<MatrixSlice<'a, T, R, Dynamic, RStride, CStride>> impl<'a, T, R, RStride, CStride> From<MatrixView<'a, T, R, Dyn, RStride, CStride>>
for Matrix<T, R, Dynamic, VecStorage<T, R, Dynamic>> for Matrix<T, R, Dyn, VecStorage<T, R, Dyn>>
where where
T: Scalar, T: Scalar,
R: DimName, R: DimName,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
{ {
fn from(matrix_slice: MatrixSlice<'a, T, R, Dynamic, RStride, CStride>) -> Self { fn from(matrix_view: MatrixView<'a, T, R, Dyn, RStride, CStride>) -> Self {
matrix_slice.into_owned() matrix_view.into_owned()
} }
} }
impl<'a, T, RStride, CStride, const R: usize, const C: usize> impl<'a, T, RStride, CStride, const R: usize, const C: usize>
From<MatrixSliceMut<'a, T, Const<R>, Const<C>, RStride, CStride>> From<MatrixViewMut<'a, T, Const<R>, Const<C>, RStride, CStride>>
for Matrix<T, Const<R>, Const<C>, ArrayStorage<T, R, C>> for Matrix<T, Const<R>, Const<C>, ArrayStorage<T, R, C>>
where where
T: Scalar, T: Scalar,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
{ {
fn from(matrix_slice: MatrixSliceMut<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self { fn from(matrix_view: MatrixViewMut<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
matrix_slice.into_owned() matrix_view.into_owned()
} }
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, T, C, RStride, CStride> From<MatrixSliceMut<'a, T, Dynamic, C, RStride, CStride>> impl<'a, T, C, RStride, CStride> From<MatrixViewMut<'a, T, Dyn, C, RStride, CStride>>
for Matrix<T, Dynamic, C, VecStorage<T, Dynamic, C>> for Matrix<T, Dyn, C, VecStorage<T, Dyn, C>>
where where
T: Scalar, T: Scalar,
C: Dim, C: Dim,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
{ {
fn from(matrix_slice: MatrixSliceMut<'a, T, Dynamic, C, RStride, CStride>) -> Self { fn from(matrix_view: MatrixViewMut<'a, T, Dyn, C, RStride, CStride>) -> Self {
matrix_slice.into_owned() matrix_view.into_owned()
} }
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, T, R, RStride, CStride> From<MatrixSliceMut<'a, T, R, Dynamic, RStride, CStride>> impl<'a, T, R, RStride, CStride> From<MatrixViewMut<'a, T, R, Dyn, RStride, CStride>>
for Matrix<T, R, Dynamic, VecStorage<T, R, Dynamic>> for Matrix<T, R, Dyn, VecStorage<T, R, Dyn>>
where where
T: Scalar, T: Scalar,
R: DimName, R: DimName,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
{ {
fn from(matrix_slice: MatrixSliceMut<'a, T, R, Dynamic, RStride, CStride>) -> Self { fn from(matrix_view: MatrixViewMut<'a, T, R, Dyn, RStride, CStride>) -> Self {
matrix_slice.into_owned() matrix_view.into_owned()
} }
} }
impl<'a, T, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a Matrix<T, R, C, S>> impl<'a, T, R, C, RView, CView, RStride, CStride, S> From<&'a Matrix<T, R, C, S>>
for MatrixSlice<'a, T, RSlice, CSlice, RStride, CStride> for MatrixView<'a, T, RView, CView, RStride, CStride>
where where
T: Scalar,
R: Dim, R: Dim,
C: Dim, C: Dim,
RSlice: Dim, RView: Dim,
CSlice: Dim, CView: Dim,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
S: RawStorage<T, R, C>, S: RawStorage<T, R, C>,
ShapeConstraint: DimEq<R, RSlice> ShapeConstraint:
+ DimEq<C, CSlice> DimEq<R, RView> + DimEq<C, CView> + DimEq<RStride, S::RStride> + DimEq<CStride, S::CStride>,
+ DimEq<RStride, S::RStride>
+ DimEq<CStride, S::CStride>,
{ {
fn from(m: &'a Matrix<T, R, C, S>) -> Self { fn from(m: &'a Matrix<T, R, C, S>) -> Self {
let (row, col) = m.shape_generic(); let (row, col) = m.shape_generic();
let row_slice = RSlice::from_usize(row.value()); let rows_result = RView::from_usize(row.value());
let col_slice = CSlice::from_usize(col.value()); let cols_result = CView::from_usize(col.value());
let (rstride, cstride) = m.strides(); let (rstride, cstride) = m.strides();
let rstride_slice = RStride::from_usize(rstride); let rstride_result = RStride::from_usize(rstride);
let cstride_slice = CStride::from_usize(cstride); let cstride_result = CStride::from_usize(cstride);
unsafe { unsafe {
let data = SliceStorage::from_raw_parts( let data = ViewStorage::from_raw_parts(
m.data.ptr(), m.data.ptr(),
(row_slice, col_slice), (rows_result, cols_result),
(rstride_slice, cstride_slice), (rstride_result, cstride_result),
); );
Matrix::from_data_statically_unchecked(data) Matrix::from_data_statically_unchecked(data)
} }
} }
} }
impl<'a, T, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix<T, R, C, S>> impl<'a, T, R, C, RView, CView, RStride, CStride, S> From<&'a mut Matrix<T, R, C, S>>
for MatrixSlice<'a, T, RSlice, CSlice, RStride, CStride> for MatrixView<'a, T, RView, CView, RStride, CStride>
where where
T: Scalar,
R: Dim, R: Dim,
C: Dim, C: Dim,
RSlice: Dim, RView: Dim,
CSlice: Dim, CView: Dim,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
S: RawStorage<T, R, C>, S: RawStorage<T, R, C>,
ShapeConstraint: DimEq<R, RSlice> ShapeConstraint:
+ DimEq<C, CSlice> DimEq<R, RView> + DimEq<C, CView> + DimEq<RStride, S::RStride> + DimEq<CStride, S::CStride>,
+ DimEq<RStride, S::RStride>
+ DimEq<CStride, S::CStride>,
{ {
fn from(m: &'a mut Matrix<T, R, C, S>) -> Self { fn from(m: &'a mut Matrix<T, R, C, S>) -> Self {
let (row, col) = m.shape_generic(); let (row, col) = m.shape_generic();
let row_slice = RSlice::from_usize(row.value()); let rows_result = RView::from_usize(row.value());
let col_slice = CSlice::from_usize(col.value()); let cols_result = CView::from_usize(col.value());
let (rstride, cstride) = m.strides(); let (rstride, cstride) = m.strides();
let rstride_slice = RStride::from_usize(rstride); let rstride_result = RStride::from_usize(rstride);
let cstride_slice = CStride::from_usize(cstride); let cstride_result = CStride::from_usize(cstride);
unsafe { unsafe {
let data = SliceStorage::from_raw_parts( let data = ViewStorage::from_raw_parts(
m.data.ptr(), m.data.ptr(),
(row_slice, col_slice), (rows_result, cols_result),
(rstride_slice, cstride_slice), (rstride_result, cstride_result),
); );
Matrix::from_data_statically_unchecked(data) Matrix::from_data_statically_unchecked(data)
} }
} }
} }
impl<'a, T, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix<T, R, C, S>> impl<'a, T, R, C, RView, CView, RStride, CStride, S> From<&'a mut Matrix<T, R, C, S>>
for MatrixSliceMut<'a, T, RSlice, CSlice, RStride, CStride> for MatrixViewMut<'a, T, RView, CView, RStride, CStride>
where where
T: Scalar,
R: Dim, R: Dim,
C: Dim, C: Dim,
RSlice: Dim, RView: Dim,
CSlice: Dim, CView: Dim,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
S: RawStorageMut<T, R, C>, S: RawStorageMut<T, R, C>,
ShapeConstraint: DimEq<R, RSlice> ShapeConstraint:
+ DimEq<C, CSlice> DimEq<R, RView> + DimEq<C, CView> + DimEq<RStride, S::RStride> + DimEq<CStride, S::CStride>,
+ DimEq<RStride, S::RStride>
+ DimEq<CStride, S::CStride>,
{ {
fn from(m: &'a mut Matrix<T, R, C, S>) -> Self { fn from(m: &'a mut Matrix<T, R, C, S>) -> Self {
let (row, col) = m.shape_generic(); let (row, col) = m.shape_generic();
let row_slice = RSlice::from_usize(row.value()); let rows_result = RView::from_usize(row.value());
let col_slice = CSlice::from_usize(col.value()); let cols_result = CView::from_usize(col.value());
let (rstride, cstride) = m.strides(); let (rstride, cstride) = m.strides();
let rstride_slice = RStride::from_usize(rstride); let rstride_result = RStride::from_usize(rstride);
let cstride_slice = CStride::from_usize(cstride); let cstride_result = CStride::from_usize(cstride);
unsafe { unsafe {
let data = SliceStorageMut::from_raw_parts( let data = ViewStorageMut::from_raw_parts(
m.data.ptr_mut(), m.data.ptr_mut(),
(row_slice, col_slice), (rows_result, cols_result),
(rstride_slice, cstride_slice), (rstride_result, cstride_result),
); );
Matrix::from_data_statically_unchecked(data) Matrix::from_data_statically_unchecked(data)
} }
@ -482,7 +497,7 @@ where
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, T: Scalar> From<Vec<T>> for DVector<T> { impl<T: Scalar> From<Vec<T>> for DVector<T> {
#[inline] #[inline]
fn from(vec: Vec<T>) -> Self { fn from(vec: Vec<T>) -> Self {
Self::from_vec(vec) Self::from_vec(vec)
@ -490,7 +505,7 @@ impl<'a, T: Scalar> From<Vec<T>> for DVector<T> {
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, T: Scalar> From<Vec<T>> for RowDVector<T> { impl<T: Scalar> From<Vec<T>> for RowDVector<T> {
#[inline] #[inline]
fn from(vec: Vec<T>) -> Self { fn from(vec: Vec<T>) -> Self {
Self::from_vec(vec) Self::from_vec(vec)
@ -515,28 +530,28 @@ impl<'a, T: Scalar + Copy, R: Dim, C: Dim, S: RawStorageMut<T, R, C> + IsContigu
} }
} }
impl<'a, T: Scalar + Copy> From<&'a [T]> for DVectorSlice<'a, T> { impl<'a, T: Scalar + Copy> From<&'a [T]> for DVectorView<'a, T> {
#[inline] #[inline]
fn from(slice: &'a [T]) -> Self { fn from(slice: &'a [T]) -> Self {
Self::from_slice(slice, slice.len()) Self::from_slice(slice, slice.len())
} }
} }
impl<'a, T: Scalar> From<DVectorSlice<'a, T>> for &'a [T] { impl<'a, T: Scalar> From<DVectorView<'a, T>> for &'a [T] {
fn from(vec: DVectorSlice<'a, T>) -> &'a [T] { fn from(vec: DVectorView<'a, T>) -> &'a [T] {
vec.data.into_slice() vec.data.into_slice()
} }
} }
impl<'a, T: Scalar + Copy> From<&'a mut [T]> for DVectorSliceMut<'a, T> { impl<'a, T: Scalar + Copy> From<&'a mut [T]> for DVectorViewMut<'a, T> {
#[inline] #[inline]
fn from(slice: &'a mut [T]) -> Self { fn from(slice: &'a mut [T]) -> Self {
Self::from_slice(slice, slice.len()) Self::from_slice(slice, slice.len())
} }
} }
impl<'a, T: Scalar> From<DVectorSliceMut<'a, T>> for &'a mut [T] { impl<'a, T: Scalar> From<DVectorViewMut<'a, T>> for &'a mut [T] {
fn from(vec: DVectorSliceMut<'a, T>) -> &'a mut [T] { fn from(vec: DVectorViewMut<'a, T>) -> &'a mut [T] {
vec.data.into_slice_mut() vec.data.into_slice_mut()
} }
} }

View File

@ -12,21 +12,23 @@ use alloc::vec::Vec;
use super::Const; use super::Const;
use crate::base::allocator::{Allocator, Reallocator}; use crate::base::allocator::{Allocator, Reallocator};
use crate::base::array_storage::ArrayStorage; use crate::base::array_storage::ArrayStorage;
use crate::base::dimension::Dim;
#[cfg(any(feature = "alloc", feature = "std"))] #[cfg(any(feature = "alloc", feature = "std"))]
use crate::base::dimension::Dynamic; use crate::base::dimension::{DimName, Dyn};
use crate::base::dimension::{Dim, DimName};
use crate::base::storage::{RawStorage, RawStorageMut}; use crate::base::storage::{RawStorage, RawStorageMut};
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
use crate::base::vec_storage::VecStorage; use crate::base::vec_storage::VecStorage;
use crate::base::Scalar; use crate::base::Scalar;
use std::mem::{ManuallyDrop, MaybeUninit}; #[cfg(any(feature = "std", feature = "alloc"))]
use std::mem::ManuallyDrop;
use std::mem::MaybeUninit;
/* /*
* *
* Allocator. * Allocator.
* *
*/ */
/// An allocator based on `GenericArray` and `VecStorage` for statically-sized and dynamically-sized /// An allocator based on [`ArrayStorage`] and [`VecStorage`] for statically-sized and dynamically-sized
/// matrices respectively. /// matrices respectively.
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct DefaultAllocator; pub struct DefaultAllocator;
@ -82,15 +84,15 @@ impl<T: Scalar, const R: usize, const C: usize> Allocator<T, Const<R>, Const<C>>
} }
} }
// Dynamic - Static // Dyn - Static
// Dynamic - Dynamic // Dyn - Dyn
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<T: Scalar, C: Dim> Allocator<T, Dynamic, C> for DefaultAllocator { impl<T: Scalar, C: Dim> Allocator<T, Dyn, C> for DefaultAllocator {
type Buffer = VecStorage<T, Dynamic, C>; type Buffer = VecStorage<T, Dyn, C>;
type BufferUninit = VecStorage<MaybeUninit<T>, Dynamic, C>; type BufferUninit = VecStorage<MaybeUninit<T>, Dyn, C>;
#[inline] #[inline]
fn allocate_uninit(nrows: Dynamic, ncols: C) -> VecStorage<MaybeUninit<T>, Dynamic, C> { fn allocate_uninit(nrows: Dyn, ncols: C) -> VecStorage<MaybeUninit<T>, Dyn, C> {
let mut data = Vec::new(); let mut data = Vec::new();
let length = nrows.value() * ncols.value(); let length = nrows.value() * ncols.value();
data.reserve_exact(length); data.reserve_exact(length);
@ -99,9 +101,7 @@ impl<T: Scalar, C: Dim> Allocator<T, Dynamic, C> for DefaultAllocator {
} }
#[inline] #[inline]
unsafe fn assume_init( unsafe fn assume_init(uninit: VecStorage<MaybeUninit<T>, Dyn, C>) -> VecStorage<T, Dyn, C> {
uninit: VecStorage<MaybeUninit<T>, Dynamic, C>,
) -> VecStorage<T, Dynamic, C> {
// Avoids a double-drop. // Avoids a double-drop.
let (nrows, ncols) = uninit.shape(); let (nrows, ncols) = uninit.shape();
let vec: Vec<_> = uninit.into(); let vec: Vec<_> = uninit.into();
@ -117,7 +117,7 @@ impl<T: Scalar, C: Dim> Allocator<T, Dynamic, C> for DefaultAllocator {
#[inline] #[inline]
fn allocate_from_iterator<I: IntoIterator<Item = T>>( fn allocate_from_iterator<I: IntoIterator<Item = T>>(
nrows: Dynamic, nrows: Dyn,
ncols: C, ncols: C,
iter: I, iter: I,
) -> Self::Buffer { ) -> Self::Buffer {
@ -130,14 +130,14 @@ impl<T: Scalar, C: Dim> Allocator<T, Dynamic, C> for DefaultAllocator {
} }
} }
// Static - Dynamic // Static - Dyn
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<T: Scalar, R: DimName> Allocator<T, R, Dynamic> for DefaultAllocator { impl<T: Scalar, R: DimName> Allocator<T, R, Dyn> for DefaultAllocator {
type Buffer = VecStorage<T, R, Dynamic>; type Buffer = VecStorage<T, R, Dyn>;
type BufferUninit = VecStorage<MaybeUninit<T>, R, Dynamic>; type BufferUninit = VecStorage<MaybeUninit<T>, R, Dyn>;
#[inline] #[inline]
fn allocate_uninit(nrows: R, ncols: Dynamic) -> VecStorage<MaybeUninit<T>, R, Dynamic> { fn allocate_uninit(nrows: R, ncols: Dyn) -> VecStorage<MaybeUninit<T>, R, Dyn> {
let mut data = Vec::new(); let mut data = Vec::new();
let length = nrows.value() * ncols.value(); let length = nrows.value() * ncols.value();
data.reserve_exact(length); data.reserve_exact(length);
@ -147,9 +147,7 @@ impl<T: Scalar, R: DimName> Allocator<T, R, Dynamic> for DefaultAllocator {
} }
#[inline] #[inline]
unsafe fn assume_init( unsafe fn assume_init(uninit: VecStorage<MaybeUninit<T>, R, Dyn>) -> VecStorage<T, R, Dyn> {
uninit: VecStorage<MaybeUninit<T>, R, Dynamic>,
) -> VecStorage<T, R, Dynamic> {
// Avoids a double-drop. // Avoids a double-drop.
let (nrows, ncols) = uninit.shape(); let (nrows, ncols) = uninit.shape();
let vec: Vec<_> = uninit.into(); let vec: Vec<_> = uninit.into();
@ -166,7 +164,7 @@ impl<T: Scalar, R: DimName> Allocator<T, R, Dynamic> for DefaultAllocator {
#[inline] #[inline]
fn allocate_from_iterator<I: IntoIterator<Item = T>>( fn allocate_from_iterator<I: IntoIterator<Item = T>>(
nrows: R, nrows: R,
ncols: Dynamic, ncols: Dyn,
iter: I, iter: I,
) -> Self::Buffer { ) -> Self::Buffer {
let it = iter.into_iter(); let it = iter.into_iter();
@ -215,20 +213,20 @@ where
} }
} }
// Static × Static -> Dynamic × Any // Static × Static -> Dyn × Any
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<T: Scalar, CTo, const RFROM: usize, const CFROM: usize> impl<T: Scalar, CTo, const RFROM: usize, const CFROM: usize>
Reallocator<T, Const<RFROM>, Const<CFROM>, Dynamic, CTo> for DefaultAllocator Reallocator<T, Const<RFROM>, Const<CFROM>, Dyn, CTo> for DefaultAllocator
where where
CTo: Dim, CTo: Dim,
{ {
#[inline] #[inline]
unsafe fn reallocate_copy( unsafe fn reallocate_copy(
rto: Dynamic, rto: Dyn,
cto: CTo, cto: CTo,
buf: ArrayStorage<T, RFROM, CFROM>, buf: ArrayStorage<T, RFROM, CFROM>,
) -> VecStorage<MaybeUninit<T>, Dynamic, CTo> { ) -> VecStorage<MaybeUninit<T>, Dyn, CTo> {
let mut res = <Self as Allocator<T, Dynamic, CTo>>::allocate_uninit(rto, cto); let mut res = <Self as Allocator<T, Dyn, CTo>>::allocate_uninit(rto, cto);
let (rfrom, cfrom) = buf.shape(); let (rfrom, cfrom) = buf.shape();
@ -246,20 +244,20 @@ where
} }
} }
// Static × Static -> Static × Dynamic // Static × Static -> Static × Dyn
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<T: Scalar, RTo, const RFROM: usize, const CFROM: usize> impl<T: Scalar, RTo, const RFROM: usize, const CFROM: usize>
Reallocator<T, Const<RFROM>, Const<CFROM>, RTo, Dynamic> for DefaultAllocator Reallocator<T, Const<RFROM>, Const<CFROM>, RTo, Dyn> for DefaultAllocator
where where
RTo: DimName, RTo: DimName,
{ {
#[inline] #[inline]
unsafe fn reallocate_copy( unsafe fn reallocate_copy(
rto: RTo, rto: RTo,
cto: Dynamic, cto: Dyn,
buf: ArrayStorage<T, RFROM, CFROM>, buf: ArrayStorage<T, RFROM, CFROM>,
) -> VecStorage<MaybeUninit<T>, RTo, Dynamic> { ) -> VecStorage<MaybeUninit<T>, RTo, Dyn> {
let mut res = <Self as Allocator<T, RTo, Dynamic>>::allocate_uninit(rto, cto); let mut res = <Self as Allocator<T, RTo, Dyn>>::allocate_uninit(rto, cto);
let (rfrom, cfrom) = buf.shape(); let (rfrom, cfrom) = buf.shape();
@ -279,60 +277,58 @@ where
// All conversion from a dynamic buffer to a dynamic buffer. // All conversion from a dynamic buffer to a dynamic buffer.
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<T: Scalar, CFrom: Dim, CTo: Dim> Reallocator<T, Dynamic, CFrom, Dynamic, CTo> impl<T: Scalar, CFrom: Dim, CTo: Dim> Reallocator<T, Dyn, CFrom, Dyn, CTo> for DefaultAllocator {
for DefaultAllocator
{
#[inline] #[inline]
unsafe fn reallocate_copy( unsafe fn reallocate_copy(
rto: Dynamic, rto: Dyn,
cto: CTo, cto: CTo,
buf: VecStorage<T, Dynamic, CFrom>, buf: VecStorage<T, Dyn, CFrom>,
) -> VecStorage<MaybeUninit<T>, Dynamic, CTo> { ) -> VecStorage<MaybeUninit<T>, Dyn, CTo> {
let new_buf = buf.resize(rto.value() * cto.value()); let new_buf = buf.resize(rto.value() * cto.value());
VecStorage::new(rto, cto, new_buf) VecStorage::new(rto, cto, new_buf)
} }
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<T: Scalar, CFrom: Dim, RTo: DimName> Reallocator<T, Dynamic, CFrom, RTo, Dynamic> impl<T: Scalar, CFrom: Dim, RTo: DimName> Reallocator<T, Dyn, CFrom, RTo, Dyn>
for DefaultAllocator for DefaultAllocator
{ {
#[inline] #[inline]
unsafe fn reallocate_copy( unsafe fn reallocate_copy(
rto: RTo, rto: RTo,
cto: Dynamic, cto: Dyn,
buf: VecStorage<T, Dynamic, CFrom>, buf: VecStorage<T, Dyn, CFrom>,
) -> VecStorage<MaybeUninit<T>, RTo, Dynamic> { ) -> VecStorage<MaybeUninit<T>, RTo, Dyn> {
let new_buf = buf.resize(rto.value() * cto.value()); let new_buf = buf.resize(rto.value() * cto.value());
VecStorage::new(rto, cto, new_buf) VecStorage::new(rto, cto, new_buf)
} }
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<T: Scalar, RFrom: DimName, CTo: Dim> Reallocator<T, RFrom, Dynamic, Dynamic, CTo> impl<T: Scalar, RFrom: DimName, CTo: Dim> Reallocator<T, RFrom, Dyn, Dyn, CTo>
for DefaultAllocator for DefaultAllocator
{ {
#[inline] #[inline]
unsafe fn reallocate_copy( unsafe fn reallocate_copy(
rto: Dynamic, rto: Dyn,
cto: CTo, cto: CTo,
buf: VecStorage<T, RFrom, Dynamic>, buf: VecStorage<T, RFrom, Dyn>,
) -> VecStorage<MaybeUninit<T>, Dynamic, CTo> { ) -> VecStorage<MaybeUninit<T>, Dyn, CTo> {
let new_buf = buf.resize(rto.value() * cto.value()); let new_buf = buf.resize(rto.value() * cto.value());
VecStorage::new(rto, cto, new_buf) VecStorage::new(rto, cto, new_buf)
} }
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<T: Scalar, RFrom: DimName, RTo: DimName> Reallocator<T, RFrom, Dynamic, RTo, Dynamic> impl<T: Scalar, RFrom: DimName, RTo: DimName> Reallocator<T, RFrom, Dyn, RTo, Dyn>
for DefaultAllocator for DefaultAllocator
{ {
#[inline] #[inline]
unsafe fn reallocate_copy( unsafe fn reallocate_copy(
rto: RTo, rto: RTo,
cto: Dynamic, cto: Dyn,
buf: VecStorage<T, RFrom, Dynamic>, buf: VecStorage<T, RFrom, Dyn>,
) -> VecStorage<MaybeUninit<T>, RTo, Dynamic> { ) -> VecStorage<MaybeUninit<T>, RTo, Dyn> {
let new_buf = buf.resize(rto.value() * cto.value()); let new_buf = buf.resize(rto.value() * cto.value());
VecStorage::new(rto, cto, new_buf) VecStorage::new(rto, cto, new_buf)
} }

View File

@ -8,54 +8,69 @@ use std::fmt::Debug;
use std::ops::{Add, Div, Mul, Sub}; use std::ops::{Add, Div, Mul, Sub};
use typenum::{self, Diff, Max, Maximum, Min, Minimum, Prod, Quot, Sum, Unsigned}; use typenum::{self, Diff, Max, Maximum, Min, Minimum, Prod, Quot, Sum, Unsigned};
#[cfg(feature = "rkyv-serialize")]
use rkyv::bytecheck;
#[cfg(feature = "serde-serialize-no-std")] #[cfg(feature = "serde-serialize-no-std")]
use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
/// Dim of dynamically-sized algebraic entities. /// Dim of dynamically-sized algebraic entities.
#[derive(Clone, Copy, Eq, PartialEq, Debug)] #[derive(Clone, Copy, Eq, PartialEq, Debug)]
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] #[cfg_attr(
pub struct Dynamic { feature = "rkyv-serialize-no-std",
value: usize, derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
} )]
#[cfg_attr(
feature = "rkyv-serialize",
archive_attr(derive(bytecheck::CheckBytes))
)]
pub struct Dyn(pub usize);
impl Dynamic { #[deprecated(note = "use Dyn instead.")]
pub type Dynamic = Dyn;
impl Dyn {
/// A dynamic size equal to `value`. /// A dynamic size equal to `value`.
#[inline] #[inline]
#[deprecated(note = "use Dyn(value) instead.")]
pub const fn new(value: usize) -> Self { pub const fn new(value: usize) -> Self {
Self { value } Self(value)
} }
} }
#[cfg(feature = "serde-serialize-no-std")] #[cfg(feature = "serde-serialize-no-std")]
impl Serialize for Dynamic { impl Serialize for Dyn {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
S: Serializer, S: Serializer,
{ {
self.value.serialize(serializer) self.0.serialize(serializer)
} }
} }
#[cfg(feature = "serde-serialize-no-std")] #[cfg(feature = "serde-serialize-no-std")]
impl<'de> Deserialize<'de> for Dynamic { impl<'de> Deserialize<'de> for Dyn {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
usize::deserialize(deserializer).map(|x| Dynamic { value: x }) usize::deserialize(deserializer).map(|x| Dyn(x))
} }
} }
/// Trait implemented by `Dynamic`. /// Trait implemented by `Dyn`.
pub trait IsDynamic {} pub trait IsDynamic {}
/// Trait implemented by `Dynamic` and type-level integers different from `U1`. /// Trait implemented by `Dyn` and type-level integers different from `U1`.
pub trait IsNotStaticOne {} pub trait IsNotStaticOne {}
impl IsDynamic for Dynamic {} impl IsDynamic for Dyn {}
impl IsNotStaticOne for Dynamic {} impl IsNotStaticOne for Dyn {}
/// Trait implemented by any type that can be used as a dimension. This includes type-level /// Trait implemented by any type that can be used as a dimension. This includes type-level
/// integers and `Dynamic` (for dimensions not known at compile-time). /// integers and `Dyn` (for dimensions not known at compile-time).
///
/// # Safety
///
/// Hoists integers to the type level, including binary operations.
pub unsafe trait Dim: Any + Debug + Copy + PartialEq + Send + Sync { pub unsafe trait Dim: Any + Debug + Copy + PartialEq + Send + Sync {
#[inline(always)] #[inline(always)]
fn is<D: Dim>() -> bool { fn is<D: Dim>() -> bool {
@ -63,7 +78,7 @@ pub unsafe trait Dim: Any + Debug + Copy + PartialEq + Send + Sync {
} }
/// Gets the compile-time value of `Self`. Returns `None` if it is not known, i.e., if `Self = /// Gets the compile-time value of `Self`. Returns `None` if it is not known, i.e., if `Self =
/// Dynamic`. /// Dyn`.
fn try_to_usize() -> Option<usize>; fn try_to_usize() -> Option<usize>;
/// Gets the run-time value of `self`. For type-level integers, this is the same as /// Gets the run-time value of `self`. For type-level integers, this is the same as
@ -75,7 +90,7 @@ pub unsafe trait Dim: Any + Debug + Copy + PartialEq + Send + Sync {
fn from_usize(dim: usize) -> Self; fn from_usize(dim: usize) -> Self;
} }
unsafe impl Dim for Dynamic { unsafe impl Dim for Dyn {
#[inline] #[inline]
fn try_to_usize() -> Option<usize> { fn try_to_usize() -> Option<usize> {
None None
@ -83,30 +98,30 @@ unsafe impl Dim for Dynamic {
#[inline] #[inline]
fn from_usize(dim: usize) -> Self { fn from_usize(dim: usize) -> Self {
Self::new(dim) Self(dim)
} }
#[inline] #[inline]
fn value(&self) -> usize { fn value(&self) -> usize {
self.value self.0
} }
} }
impl Add<usize> for Dynamic { impl Add<usize> for Dyn {
type Output = Dynamic; type Output = Dyn;
#[inline] #[inline]
fn add(self, rhs: usize) -> Self { fn add(self, rhs: usize) -> Self {
Self::new(self.value + rhs) Self(self.0 + rhs)
} }
} }
impl Sub<usize> for Dynamic { impl Sub<usize> for Dyn {
type Output = Dynamic; type Output = Dyn;
#[inline] #[inline]
fn sub(self, rhs: usize) -> Self { fn sub(self, rhs: usize) -> Self {
Self::new(self.value - rhs) Self(self.0 - rhs)
} }
} }
@ -144,22 +159,22 @@ macro_rules! dim_ops(
} }
} }
impl<D: Dim> $DimOp<D> for Dynamic { impl<D: Dim> $DimOp<D> for Dyn {
type Output = Dynamic; type Output = Dyn;
#[inline] #[inline]
fn $op(self, other: D) -> Dynamic { fn $op(self, other: D) -> Dyn {
Dynamic::new($op_path(self.value, other.value())) Dyn($op_path(self.value(), other.value()))
} }
} }
// TODO: use Const<T> instead of D: DimName? // TODO: use Const<T> instead of D: DimName?
impl<D: DimName> $DimOp<Dynamic> for D { impl<D: DimName> $DimOp<Dyn> for D {
type Output = Dynamic; type Output = Dyn;
#[inline] #[inline]
fn $op(self, other: Dynamic) -> Dynamic { fn $op(self, other: Dyn) -> Dyn {
Dynamic::new($op_path(self.value(), other.value)) Dyn($op_path(self.value(), other.value()))
} }
} }
@ -198,7 +213,12 @@ dim_ops!(
); );
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] #[cfg_attr(
feature = "rkyv-serialize-no-std",
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize),
archive(as = "Self")
)]
#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
pub struct Const<const R: usize>; pub struct Const<const R: usize>;
/// Trait implemented exclusively by type-level integers. /// Trait implemented exclusively by type-level integers.
@ -233,37 +253,6 @@ impl<'de, const D: usize> Deserialize<'de> for Const<D> {
} }
} }
#[cfg(feature = "rkyv-serialize-no-std")]
mod rkyv_impl {
use super::Const;
use rkyv::{Archive, Deserialize, Fallible, Serialize};
impl<const R: usize> Archive for Const<R> {
type Archived = Self;
type Resolver = ();
fn resolve(
&self,
_: usize,
_: Self::Resolver,
_: &mut core::mem::MaybeUninit<Self::Archived>,
) {
}
}
impl<S: Fallible + ?Sized, const R: usize> Serialize<S> for Const<R> {
fn serialize(&self, _: &mut S) -> Result<Self::Resolver, S::Error> {
Ok(())
}
}
impl<D: Fallible + ?Sized, const R: usize> Deserialize<Self, D> for Const<R> {
fn deserialize(&self, _: &mut D) -> Result<Self, D::Error> {
Ok(Const)
}
}
}
pub trait ToConst { pub trait ToConst {
type Const: DimName; type Const: DimName;
} }
@ -273,14 +262,17 @@ pub trait ToTypenum {
} }
unsafe impl<const T: usize> Dim for Const<T> { unsafe impl<const T: usize> Dim for Const<T> {
#[inline]
fn try_to_usize() -> Option<usize> { fn try_to_usize() -> Option<usize> {
Some(T) Some(T)
} }
#[inline]
fn value(&self) -> usize { fn value(&self) -> usize {
T T
} }
#[inline]
fn from_usize(dim: usize) -> Self { fn from_usize(dim: usize) -> Self {
assert_eq!(dim, T); assert_eq!(dim, T);
Self Self
@ -324,6 +316,11 @@ macro_rules! from_to_typenum (
} }
impl IsNotStaticOne for $D { } impl IsNotStaticOne for $D { }
/// The constant dimension
#[doc = stringify!($VAL)]
/// .
pub const $D: $D = Const::<$VAL>;
)*} )*}
); );
@ -337,3 +334,7 @@ from_to_typenum!(
U111, 111; U112, 112; U113, 113; U114, 114; U115, 115; U116, 116; U117, 117; U118, 118; U119, 119; U120, 120; U121, 121; U122, 122; U123, 123; U124, 124; U125, 125; U126, 126; U111, 111; U112, 112; U113, 113; U114, 114; U115, 115; U116, 116; U117, 117; U118, 118; U119, 119; U120, 120; U121, 121; U122, 122; U123, 123; U124, 124; U125, 125; U126, 126;
U127, 127 U127, 127
); );
/// The constant dimension 1.
// Note: We add U1 separately since it's not covered by the from_to_typenum! macro.
pub const U1: U1 = Const::<1>;

Some files were not shown because too many files have changed in this diff Show More