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:
runs-on: ubuntu-latest
steps:
# Needed because the --all-features build which enables cuda support.
- uses: Jimver/cuda-toolkit@v0.2.4
- uses: actions/checkout@v2
- run: cargo build --all-features;
- run: cargo build -p nalgebra-glm --all-features;
@ -61,7 +59,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- 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:
runs-on: ubuntu-latest
steps:
@ -120,20 +118,9 @@ jobs:
run: xargo build --verbose --no-default-features -p nalgebra-glm --target=x86_64-unknown-linux-gnu;
- name: build thumbv7em-none-eabihf nalgebra-glm
run: xargo build --verbose --no-default-features -p nalgebra-glm --target=thumbv7em-none-eabihf;
build-cuda:
docs:
runs-on: ubuntu-latest
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
- run: rustup target add nvptx64-nvidia-cuda
- run: cargo build --no-default-features --features cuda
- run: cargo build --no-default-features --features cuda --target=nvptx64-nvidia-cuda
env:
CUDA_ARCH: "350"
- uses: actions/checkout@v2
- name: Generate documentation
run: cargo doc

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[package]
name = "nalgebra"
version = "0.30.1"
version = "0.32.3"
authors = [ "Sébastien Crozet <developer@crozet.re>" ]
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"
categories = [ "science", "mathematics", "wasm", "no-std" ]
keywords = [ "linear", "algebra", "matrix", "vector", "math" ]
license = "BSD-3-Clause"
license = "Apache-2.0"
edition = "2018"
exclude = ["/ci/*", "/.travis.yml", "/Makefile"]
@ -23,7 +23,7 @@ path = "src/lib.rs"
[features]
default = [ "std", "macros" ]
std = [ "matrixmultiply", "simba/std" ]
std = [ "matrixmultiply", "num-traits/std", "num-complex/std", "num-rational/std", "approx/std", "simba/std" ]
sparse = [ ]
debug = [ "approx/num-complex", "rand" ]
alloc = [ ]
@ -32,12 +32,11 @@ compare = [ "matrixcompare-core" ]
libm = [ "simba/libm" ]
libm-force = [ "simba/libm_force" ]
macros = [ "nalgebra-macros" ]
cuda = [ "cust_core", "simba/cuda" ]
# Conversion
convert-mint = [ "mint" ]
convert-bytemuck = [ "bytemuck" ]
convert-glam013 = [ "glam013" ]
convert-glam014 = [ "glam014" ]
convert-glam015 = [ "glam015" ]
convert-glam016 = [ "glam016" ]
@ -45,6 +44,11 @@ convert-glam017 = [ "glam017" ]
convert-glam018 = [ "glam018" ]
convert-glam019 = [ "glam019" ]
convert-glam020 = [ "glam020" ]
convert-glam021 = [ "glam021" ]
convert-glam022 = [ "glam022" ]
convert-glam023 = [ "glam023" ]
convert-glam024 = [ "glam024" ]
convert-glam025 = [ "glam025" ]
# Serialization
## To use serde in a #[no-std] environment, enable the
@ -53,8 +57,8 @@ convert-glam020 = [ "glam020" ]
## `serde-serialize`.
serde-serialize-no-std = [ "serde", "num-complex/serde" ]
serde-serialize = [ "serde-serialize-no-std", "serde/std" ]
rkyv-serialize-no-std = [ "rkyv" ]
rkyv-serialize = [ "rkyv-serialize-no-std", "rkyv/std" ]
rkyv-serialize-no-std = [ "rkyv/size_32" ]
rkyv-serialize = [ "rkyv-serialize-no-std", "rkyv/std", "rkyv/validation" ]
# Randomness
## 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" ]
proptest-support = [ "proptest" ]
slow-tests = []
rkyv-safe-deser = [ "rkyv-serialize", "rkyv/validation" ]
[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"
rand-package = { package = "rand", version = "0.8", optional = true, default-features = false }
num-traits = { version = "0.2", default-features = false }
num-complex = { version = "0.4", default-features = false }
num-rational = { version = "0.4", 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 }
rand_distr = { version = "0.4", default-features = false, optional = true }
matrixmultiply = { version = "0.3", 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 }
quickcheck = { version = "1", optional = true }
pest = { version = "2", optional = true }
@ -88,7 +93,6 @@ pest_derive = { version = "2", optional = true }
bytemuck = { version = "1.5", optional = true }
matrixcompare-core = { version = "0.1", optional = true }
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 }
glam015 = { package = "glam", version = "0.15", 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 }
glam019 = { package = "glam", version = "0.19", 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]
serde_json = "1.0"
rand_xorshift = "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
matrixcompare = "0.3.0"
@ -131,6 +140,7 @@ required-features = ["rand"]
lto = true
[package.metadata.docs.rs]
# Enable certain features when building docs for docs.rs
features = [ "proptest-support", "compare", "macros", "rand" ]
# Enable all the features when building the docs on docs.rs
all-features = true
# define the configuration attribute `docsrs`
rustdoc-args = ["--cfg", "docsrs"]

View File

@ -29,19 +29,3 @@
</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| {
bh.iter(|| {
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
})
});
@ -142,7 +142,7 @@ fn iter(bench: &mut criterion::Criterion) {
bench.bench_function("iter", move |bh| {
bh.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| {
bh.iter(|| {
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)]
extern crate nalgebra as na;

View File

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

View File

@ -28,7 +28,7 @@ where
}
/// 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>
where
T: RealField,

View File

@ -2,7 +2,7 @@
extern crate nalgebra as na;
use na::{DMatrix, Dynamic, Matrix2x3, Matrix3x2, Const};
use na::{DMatrix, Dyn, Matrix2x3, Matrix3x2, Const};
fn main() {
// 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);
// 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]
name = "nalgebra-glm"
version = "0.16.0"
version = "0.18.0"
authors = ["sebcrozet <developer@crozet.re>"]
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"
categories = [ "science", "mathematics", "wasm", "no standard library" ]
keywords = [ "linear", "algebra", "matrix", "vector", "math" ]
license = "BSD-3-Clause"
license = "Apache-2.0"
edition = "2018"
[badges]
@ -21,12 +21,10 @@ default = [ "std" ]
std = [ "nalgebra/std", "simba/std" ]
arbitrary = [ "nalgebra/arbitrary" ]
serde-serialize = [ "nalgebra/serde-serialize-no-std" ]
cuda = [ "nalgebra/cuda" ]
# Conversion
convert-mint = [ "nalgebra/mint" ]
convert-bytemuck = [ "nalgebra/bytemuck" ]
convert-glam013 = [ "nalgebra/glam013" ]
convert-glam014 = [ "nalgebra/glam014" ]
convert-glam015 = [ "nalgebra/glam015" ]
convert-glam016 = [ "nalgebra/glam016" ]
@ -36,5 +34,5 @@ convert-glam018 = [ "nalgebra/glam018" ]
[dependencies]
num-traits = { version = "0.2", default-features = false }
approx = { version = "0.5", default-features = false }
simba = { version = "0.7", default-features = false }
nalgebra = { path = "..", version = "0.30", default-features = false }
simba = { version = "0.8", 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.
///
/// 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
/// also work on a vector.
///
/// # See also:
///
/// * [`TMat2`](type.TMat2.html)
/// * [`TMat2x2`](type.TMat2x2.html)
/// * [`TMat2x3`](type.TMat2x3.html)
/// * [`TMat2x4`](type.TMat2x4.html)
/// * [`TMat3`](type.TMat3.html)
/// * [`TMat3x2`](type.TMat3x2.html)
/// * [`TMat3x3`](type.TMat3x3.html)
/// * [`TMat3x4`](type.TMat3x4.html)
/// * [`TMat4`](type.TMat4.html)
/// * [`TMat4x2`](type.TMat4x2.html)
/// * [`TMat4x3`](type.TMat4x3.html)
/// * [`TMat4x4`](type.TMat4x4.html)
/// * [`TVec`](type.TVec.html)
/// * [`TMat2`]
/// * [`TMat2x2`]
/// * [`TMat2x3`]
/// * [`TMat2x4`]
/// * [`TMat3`]
/// * [`TMat3x2`]
/// * [`TMat3x3`]
/// * [`TMat3x4`]
/// * [`TMat4`]
/// * [`TMat4x2`]
/// * [`TMat4x3`]
/// * [`TMat4x4`]
/// * [`TVec`]
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).
///
/// 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:
///
/// * [`TMat`](type.TMat.html)
/// * [`TVec1`](type.TVec1.html)
/// * [`TVec2`](type.TVec2.html)
/// * [`TVec3`](type.TVec3.html)
/// * [`TVec4`](type.TVec4.html)
/// * [`TMat`]
/// * [`TVec1`]
/// * [`TVec2`]
/// * [`TVec3`]
/// * [`TVec4`]
pub type TVec<T, const R: usize> = SVector<T, R>;
/// A quaternion with components of type `T`.
pub type Qua<T> = Quaternion<T>;
@ -47,28 +47,28 @@ pub type Qua<T> = Quaternion<T>;
///
/// ## Constructors:
///
/// * [`make_vec1`](fn.make_vec1.html)
/// * [`vec1`](fn.vec1.html)
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec4_to_vec1`](fn.vec4_to_vec1.html)
/// * [`make_vec1()`](crate::make_vec1)
/// * [`vec1()`](crate::vec1)
/// * [`vec2_to_vec1()`](crate::vec2_to_vec1)
/// * [`vec3_to_vec1()`](crate::vec3_to_vec1)
/// * [`vec4_to_vec1()`](crate::vec4_to_vec1)
///
/// ## Related types:
///
/// * [`BVec1`](type.BVec1.html)
/// * [`DVec1`](type.DVec1.html)
/// * [`IVec1`](type.IVec1.html)
/// * [`I16Vec1`](type.I16Vec1.html)
/// * [`I32Vec1`](type.I32Vec1.html)
/// * [`I64Vec1`](type.I64Vec1.html)
/// * [`I8Vec1`](type.I8Vec1.html)
/// * [`TVec`](type.TVec.html)
/// * [`UVec1`](type.UVec1.html)
/// * [`U16Vec1`](type.U16Vec1.html)
/// * [`U32Vec1`](type.U32Vec1.html)
/// * [`U64Vec1`](type.U64Vec1.html)
/// * [`U8Vec1`](type.U8Vec1.html)
/// * [`Vec1`](type.Vec1.html)
/// * [`BVec1`]
/// * [`DVec1`]
/// * [`IVec1`]
/// * [`I16Vec1`]
/// * [`I32Vec1`]
/// * [`I64Vec1`]
/// * [`I8Vec1`]
/// * [`TVec`]
/// * [`UVec1`]
/// * [`U16Vec1`]
/// * [`U32Vec1`]
/// * [`U64Vec1`]
/// * [`U8Vec1`]
/// * [`Vec1`]
pub type TVec1<T> = TVec<T, 1>;
/// A 2D vector with components of type `T`.
///
@ -76,29 +76,28 @@ pub type TVec1<T> = TVec<T, 1>;
///
/// ## Constructors:
///
/// * [`make_vec2`](fn.make_vec2.html)
/// * [`vec2`](fn.vec2.html)
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
/// * [`make_vec2()`](crate::make_vec2)
/// * [`vec2()`](crate::vec2)
/// * [`vec1_to_vec2()`](crate::vec1_to_vec2)
/// * [`vec3_to_vec2()`](crate::vec3_to_vec2)
/// * [`vec4_to_vec2()`](crate::vec4_to_vec2)
///
/// ## Related types:
///
/// * [`vec2`](fn.vec2.html)
/// * [`BVec2`](type.BVec2.html)
/// * [`DVec2`](type.DVec2.html)
/// * [`IVec2`](type.IVec2.html)
/// * [`I16Vec2`](type.I16Vec2.html)
/// * [`I32Vec2`](type.I32Vec2.html)
/// * [`I64Vec2`](type.I64Vec2.html)
/// * [`I8Vec2`](type.I8Vec2.html)
/// * [`TVec`](type.TVec.html)
/// * [`UVec2`](type.UVec2.html)
/// * [`U16Vec2`](type.U16Vec2.html)
/// * [`U32Vec2`](type.U32Vec2.html)
/// * [`U64Vec2`](type.U64Vec2.html)
/// * [`U8Vec2`](type.U8Vec2.html)
/// * [`Vec2`](type.Vec2.html)
/// * [`BVec2`]
/// * [`DVec2`]
/// * [`IVec2`]
/// * [`I16Vec2`]
/// * [`I32Vec2`]
/// * [`I64Vec2`]
/// * [`I8Vec2`]
/// * [`TVec`]
/// * [`UVec2`]
/// * [`U16Vec2`]
/// * [`U32Vec2`]
/// * [`U64Vec2`]
/// * [`U8Vec2`]
/// * [`Vec2`]
pub type TVec2<T> = TVec<T, 2>;
/// A 3D vector with components of type `T`.
///
@ -106,29 +105,28 @@ pub type TVec2<T> = TVec<T, 2>;
///
/// ## Constructors:
///
/// * [`make_vec3`](fn.make_vec3.html)
/// * [`vec3`](fn.vec3.html)
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
/// * [`make_vec3()`](crate::make_vec3)
/// * [`vec3()`](crate::vec3)
/// * [`vec1_to_vec3()`](crate::vec1_to_vec3)
/// * [`vec2_to_vec3()`](crate::vec2_to_vec3)
/// * [`vec4_to_vec3()`](crate::vec4_to_vec3)
///
/// ## Related types:
///
/// * [`vec3`](fn.vec3.html)
/// * [`BVec3`](type.BVec3.html)
/// * [`DVec3`](type.DVec3.html)
/// * [`IVec3`](type.IVec3.html)
/// * [`I16Vec3`](type.I16Vec3.html)
/// * [`I32Vec3`](type.I32Vec3.html)
/// * [`I64Vec3`](type.I64Vec3.html)
/// * [`I8Vec3`](type.I8Vec3.html)
/// * [`TVec`](type.TVec.html)
/// * [`UVec3`](type.UVec3.html)
/// * [`U16Vec3`](type.U16Vec3.html)
/// * [`U32Vec3`](type.U32Vec3.html)
/// * [`U64Vec3`](type.U64Vec3.html)
/// * [`U8Vec3`](type.U8Vec3.html)
/// * [`Vec3`](type.Vec3.html)
/// * [`BVec3`]
/// * [`DVec3`]
/// * [`IVec3`]
/// * [`I16Vec3`]
/// * [`I32Vec3`]
/// * [`I64Vec3`]
/// * [`I8Vec3`]
/// * [`TVec`]
/// * [`UVec3`]
/// * [`U16Vec3`]
/// * [`U32Vec3`]
/// * [`U64Vec3`]
/// * [`U8Vec3`]
/// * [`Vec3`]
pub type TVec3<T> = TVec<T, 3>;
/// A 4D vector with components of type `T`.
///
@ -136,28 +134,27 @@ pub type TVec3<T> = TVec<T, 3>;
///
/// ## Constructors:
///
/// * [`make_vec4`](fn.make_vec4.html)
/// * [`vec4`](fn.vec4.html)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
/// * [`make_vec4()`](crate::make_vec4)
/// * [`vec4()`](crate::vec4)
/// * [`vec1_to_vec4()`](crate::vec1_to_vec4)
/// * [`vec2_to_vec4()`](crate::vec2_to_vec4)
/// * [`vec3_to_vec4()`](crate::vec3_to_vec4)
///
/// ## Related types:
///
/// * [`vec4`](fn.vec4.html)
/// * [`BVec4`](type.BVec4.html)
/// * [`DVec4`](type.DVec4.html)
/// * [`IVec4`](type.IVec4.html)
/// * [`I16Vec4`](type.I16Vec4.html)
/// * [`I32Vec4`](type.I32Vec4.html)
/// * [`I64Vec4`](type.I64Vec4.html)
/// * [`I8Vec4`](type.I8Vec4.html)
/// * [`UVec4`](type.UVec4.html)
/// * [`U16Vec4`](type.U16Vec4.html)
/// * [`U32Vec4`](type.U32Vec4.html)
/// * [`U64Vec4`](type.U64Vec4.html)
/// * [`U8Vec4`](type.U8Vec4.html)
/// * [`Vec4`](type.Vec4.html)
/// * [`BVec4`]
/// * [`DVec4`]
/// * [`IVec4`]
/// * [`I16Vec4`]
/// * [`I32Vec4`]
/// * [`I64Vec4`]
/// * [`I8Vec4`]
/// * [`UVec4`]
/// * [`U16Vec4`]
/// * [`U32Vec4`]
/// * [`U64Vec4`]
/// * [`U8Vec4`]
/// * [`Vec4`]
pub type TVec4<T> = TVec<T, 4>;
/// A 1D vector with boolean components.
pub type BVec1 = TVec1<bool>;

View File

@ -1,5 +1,4 @@
use core::mem;
use na;
use crate::aliases::{TMat, TVec};
use crate::traits::Number;
@ -20,7 +19,7 @@ use crate::RealNumber;
///
/// # 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> {
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:
///
/// * [`ceil`](fn.ceil.html)
/// * [`floor`](fn.floor.html)
/// * [`fract`](fn.fract.html)
/// * [`round`](fn.round.html)
/// * [`trunc`](fn.trunc.html)
/// * [`ceil()`]
/// * [`floor()`]
/// * [`fract()`]
/// * [`round()`]
/// * [`trunc()`]
pub fn ceil<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
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:
///
/// * [`clamp`](fn.clamp.html)
/// * [`clamp_vec`](fn.clamp_vec.html)
/// * [`clamp()`]
/// * [`clamp_vec()`]
pub fn clamp_scalar<T: Number>(x: T, min_val: T, max_val: T) -> T {
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:
///
/// * [`clamp_scalar`](fn.clamp_scalar.html)
/// * [`clamp_vec`](fn.clamp_vec.html)
/// * [`clamp_scalar()`]
/// * [`clamp_vec()`]
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))
}
@ -120,8 +119,8 @@ pub fn clamp<T: Number, const D: usize>(x: &TVec<T, D>, min_val: T, max_val: T)
///
/// # See also:
///
/// * [`clamp_scalar`](fn.clamp_scalar.html)
/// * [`clamp`](fn.clamp.html)
/// * [`clamp_scalar()`]
/// * [`clamp()`]
pub fn clamp_vec<T: Number, const D: usize>(
x: &TVec<T, D>,
min_val: &TVec<T, D>,
@ -136,13 +135,13 @@ pub fn clamp_vec<T: Number, const D: usize>(
///
/// # See also:
///
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
/// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar()`]
pub fn float_bits_to_int(v: f32) -> i32 {
unsafe { mem::transmute(v) }
}
@ -153,13 +152,13 @@ pub fn float_bits_to_int(v: f32) -> i32 {
///
/// # See also:
///
/// * [`float_bits_to_int`](fn.float_bits_to_int.html)
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
/// * [`float_bits_to_int()`]
/// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar()`]
pub fn float_bits_to_int_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<i32, D> {
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:
///
/// * [`float_bits_to_int`](fn.float_bits_to_int.html)
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
/// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar()`]
pub fn float_bits_to_uint(v: f32) -> u32 {
unsafe { mem::transmute(v) }
}
@ -187,13 +186,13 @@ pub fn float_bits_to_uint(v: f32) -> u32 {
///
/// # See also:
///
/// * [`float_bits_to_int`](fn.float_bits_to_int.html)
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
/// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint()`]
/// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar()`]
pub fn float_bits_to_uint_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<u32, D> {
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:
///
/// * [`ceil`](fn.ceil.html)
/// * [`fract`](fn.fract.html)
/// * [`round`](fn.round.html)
/// * [`trunc`](fn.trunc.html)
/// * [`ceil()`]
/// * [`fract()`]
/// * [`round()`]
/// * [`trunc()`]
pub fn floor<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
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:
///
/// * [`ceil`](fn.ceil.html)
/// * [`floor`](fn.floor.html)
/// * [`round`](fn.round.html)
/// * [`trunc`](fn.trunc.html)
/// * [`ceil()`]
/// * [`floor()`]
/// * [`round()`]
/// * [`trunc()`]
pub fn fract<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
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:
///
/// * [`float_bits_to_int`](fn.float_bits_to_int.html)
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
/// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar()`]
pub fn int_bits_to_float(v: i32) -> f32 {
f32::from_bits(v as u32)
}
@ -275,13 +274,13 @@ pub fn int_bits_to_float(v: i32) -> f32 {
///
/// # See also:
///
/// * [`float_bits_to_int`](fn.float_bits_to_int.html)
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
/// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float()`]
/// * [`uint_bits_to_float()`]
/// * [`uint_bits_to_float_scalar()`]
pub fn int_bits_to_float_vec<const D: usize>(v: &TVec<i32, D>) -> TVec<f32, D> {
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:
///
/// * [`mix`](fn.mix.html)
/// * [`mix_vec`](fn.mix_vec.html)
/// * [`mix()`]
/// * [`mix_vec()`]
pub fn mix_scalar<T: Number>(x: T, y: T, a: T) -> T {
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:
///
/// * [`mix_scalar`](fn.mix_scalar.html)
/// * [`mix_vec`](fn.mix_vec.html)
/// * [`mix_scalar()`]
/// * [`mix_vec()`]
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
}
@ -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:
///
/// * [`mix_scalar`](fn.mix_scalar.html)
/// * [`mix`](fn.mix.html)
/// * [`mix_scalar()`]
/// * [`mix()`]
pub fn mix_vec<T: Number, const D: usize>(
x: &TVec<T, D>,
y: &TVec<T, D>,
a: &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.
@ -383,8 +382,8 @@ pub fn mix_vec<T: Number, const D: usize>(
///
/// # See also:
///
/// * [`lerp`](fn.lerp.html)
/// * [`lerp_vec`](fn.lerp_vec.html)
/// * [`lerp()`]
/// * [`lerp_vec()`]
pub fn lerp_scalar<T: Number>(x: T, y: T, a: T) -> T {
mix_scalar(x, y, a)
}
@ -405,8 +404,8 @@ pub fn lerp_scalar<T: Number>(x: T, y: T, a: T) -> T {
///
/// # See also:
///
/// * [`lerp_scalar`](fn.lerp_scalar.html)
/// * [`lerp_vec`](fn.lerp_vec.html)
/// * [`lerp_scalar()`]
/// * [`lerp_vec()`]
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)
}
@ -429,8 +428,8 @@ pub fn lerp<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) ->
///
/// # See also:
///
/// * [`lerp_scalar`](fn.lerp_scalar.html)
/// * [`lerp`](fn.lerp.html)
/// * [`lerp_scalar()`]
/// * [`lerp()`]
pub fn lerp_vec<T: Number, const D: usize>(
x: &TVec<T, D>,
y: &TVec<T, D>,
@ -445,7 +444,7 @@ pub fn lerp_vec<T: Number, const D: usize>(
///
/// # 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> {
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:
///
/// * [`modf_vec`](fn.modf_vec.html)
/// * [`modf_vec()`]
pub fn modf<T: Number>(x: T, i: T) -> T {
x % i
}
@ -473,10 +472,10 @@ pub fn modf<T: Number>(x: T, i: T) -> T {
///
/// # See also:
///
/// * [`ceil`](fn.ceil.html)
/// * [`floor`](fn.floor.html)
/// * [`fract`](fn.fract.html)
/// * [`trunc`](fn.trunc.html)
/// * [`ceil()`]
/// * [`floor()`]
/// * [`fract()`]
/// * [`trunc()`]
pub fn round<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
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:
///
/// * [`abs`](fn.abs.html)
/// * [`abs()`]
///
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() })
@ -545,10 +544,10 @@ pub fn step_vec<T: Number, const D: usize>(edge: &TVec<T, D>, x: &TVec<T, D>) ->
///
/// # See also:
///
/// * [`ceil`](fn.ceil.html)
/// * [`floor`](fn.floor.html)
/// * [`fract`](fn.fract.html)
/// * [`round`](fn.round.html)
/// * [`ceil()`]
/// * [`floor()`]
/// * [`fract()`]
/// * [`round()`]
pub fn trunc<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
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:
///
/// * [`float_bits_to_int`](fn.float_bits_to_int.html)
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float()`]
pub fn uint_bits_to_float_scalar(v: u32) -> f32 {
f32::from_bits(v)
}
@ -576,13 +575,13 @@ pub fn uint_bits_to_float_scalar(v: u32) -> f32 {
///
/// # See also:
///
/// * [`float_bits_to_int`](fn.float_bits_to_int.html)
/// * [`float_bits_to_int_vec`](fn.float_bits_to_int_vec.html)
/// * [`float_bits_to_uint`](fn.float_bits_to_uint.html)
/// * [`float_bits_to_uint_vec`](fn.float_bits_to_uint_vec.html)
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
/// * [`float_bits_to_int()`]
/// * [`float_bits_to_int_vec()`]
/// * [`float_bits_to_uint()`]
/// * [`float_bits_to_uint_vec()`]
/// * [`int_bits_to_float()`]
/// * [`int_bits_to_float_vec()`]
/// * [`uint_bits_to_float_scalar()`]
pub fn uint_bits_to_float<const D: usize>(v: &TVec<u32, D>) -> TVec<f32, D> {
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]
#[allow(clippy::too_many_arguments)]
pub fn mat3<T: Scalar>(m11: T, m12: T, m13: T,
m21: T, m22: T, m23: 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.
#[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat3x3<T: Scalar>(m11: T, m12: T, m13: T,
m21: T, m22: T, m23: 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.
#[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat3x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
m21: T, m22: T, m23: T, m24: 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.
#[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat4x3<T: Scalar>(m11: T, m12: T, m13: T,
m21: T, m22: T, m23: 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.
#[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat4x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
m21: T, m22: T, m23: T, m24: 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.
#[rustfmt::skip]
#[allow(clippy::too_many_arguments)]
pub fn mat4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
m21: T, m22: T, m23: T, m24: T,
m31: T, m32: T, m33: T, m34: T,

View File

@ -5,7 +5,7 @@ use crate::RealNumber;
///
/// # See also:
///
/// * [`exp2`](fn.exp2.html)
/// * [`exp2()`]
pub fn exp<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
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:
///
/// * [`exp`](fn.exp.html)
/// * [`exp()`]
pub fn exp2<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
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:
///
/// * [`sqrt`](fn.sqrt.html)
/// * [`sqrt()`]
pub fn inversesqrt<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
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:
///
/// * [`log2`](fn.log2.html)
/// * [`log2()`]
pub fn log<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
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:
///
/// * [`log`](fn.log.html)
/// * [`log()`]
pub fn log2<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
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:
///
/// * [`exp`](fn.exp.html)
/// * [`exp2`](fn.exp2.html)
/// * [`inversesqrt`](fn.inversesqrt.html)
/// * [`pow`](fn.pow.html)
/// * [`exp()`]
/// * [`exp2()`]
/// * [`inversesqrt()`]
/// * [`pow`]
pub fn sqrt<T: RealNumber, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
v.map(|x| x.sqrt())
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,9 +5,9 @@ use crate::traits::Number;
///
/// # See also:
///
/// * [`equal_eps_vec`](fn.equal_eps_vec.html)
/// * [`not_equal_eps`](fn.not_equal_eps.html)
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
/// * [`equal_eps_vec()`]
/// * [`not_equal_eps()`]
/// * [`not_equal_eps_vec()`]
pub fn equal_eps<T: Number, const D: usize>(
x: &TVec<T, D>,
y: &TVec<T, D>,
@ -20,9 +20,9 @@ pub fn equal_eps<T: Number, const D: usize>(
///
/// # See also:
///
/// * [`equal_eps`](fn.equal_eps.html)
/// * [`not_equal_eps`](fn.not_equal_eps.html)
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
/// * [`equal_eps()`]
/// * [`not_equal_eps()`]
/// * [`not_equal_eps_vec()`]
pub fn equal_eps_vec<T: Number, const D: usize>(
x: &TVec<T, D>,
y: &TVec<T, D>,
@ -35,9 +35,9 @@ pub fn equal_eps_vec<T: Number, const D: usize>(
///
/// # See also:
///
/// * [`equal_eps`](fn.equal_eps.html)
/// * [`equal_eps_vec`](fn.equal_eps_vec.html)
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
/// * [`equal_eps()`]
/// * [`equal_eps_vec()`]
/// * [`not_equal_eps_vec()`]
pub fn not_equal_eps<T: Number, const D: usize>(
x: &TVec<T, D>,
y: &TVec<T, D>,
@ -50,9 +50,9 @@ pub fn not_equal_eps<T: Number, const D: usize>(
///
/// # See also:
///
/// * [`equal_eps`](fn.equal_eps.html)
/// * [`equal_eps_vec`](fn.equal_eps_vec.html)
/// * [`not_equal_eps`](fn.not_equal_eps.html)
/// * [`equal_eps()`]
/// * [`equal_eps_vec()`]
/// * [`not_equal_eps()`]
pub fn not_equal_eps_vec<T: Number, const D: usize>(
x: &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:
///
/// * [`distance2`](fn.distance2.html)
/// * [`distance2()`](crate::distance2)
pub fn distance<T: RealNumber, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T {
(p1 - p0).norm()
}
@ -37,13 +37,13 @@ pub fn faceforward<T: Number, const D: usize>(
/// The magnitude of a vector.
///
/// A synonym for [`magnitude`](fn.magnitude.html).
/// A synonym for [`magnitude()`].
///
/// # See also:
///
/// * [`length2`](fn.length2.html)
/// * [`magnitude`](fn.magnitude.html)
/// * [`magnitude2`](fn.magnitude2.html)
/// * [`length2()`](crate::length2)
/// * [`magnitude()`]
/// * [`magnitude2()`](crate::magnitude2)
pub fn length<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
x.norm()
}
@ -54,8 +54,8 @@ pub fn length<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
///
/// # See also:
///
/// * [`length`](fn.length.html)
/// * [`magnitude2`](fn.magnitude2.html)
/// * [`length()`]
/// * [`magnitude2()`](crate::magnitude2)
/// * [`nalgebra::norm`](../nalgebra/fn.norm.html)
pub fn magnitude<T: RealNumber, const D: usize>(x: &TVec<T, D>) -> T {
x.norm()

View File

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

View File

@ -7,24 +7,24 @@ use na::DefaultAllocator;
use crate::traits::{Alloc, Number, Dimension};
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>
where DefaultAllocator: Alloc<T, D> {
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 {
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>
where DefaultAllocator: Alloc<T, D> {
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 {
abs_diff_ne!(x, y, epsilon = epsilon)
}

View File

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

View File

@ -128,9 +128,9 @@ pub fn make_quat<T: RealNumber>(ptr: &[T]) -> Qua<T> {
///
/// # See also:
///
/// * [`make_vec2`](fn.make_vec2.html)
/// * [`make_vec3`](fn.make_vec3.html)
/// * [`make_vec4`](fn.make_vec4.html)
/// * [`make_vec2()`]
/// * [`make_vec3()`]
/// * [`make_vec4()`]
pub fn make_vec1<T: Scalar>(v: &TVec1<T>) -> TVec1<T> {
v.clone()
}
@ -139,12 +139,11 @@ pub fn make_vec1<T: Scalar>(v: &TVec1<T>) -> TVec1<T> {
///
/// # See also:
///
/// * [`vec1_to_vec1`](fn.vec1_to_vec1.html)
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec4_to_vec1`](fn.vec4_to_vec1.html)
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
/// * [`vec3_to_vec1()`]
/// * [`vec4_to_vec1()`]
/// * [`vec1_to_vec2()`]
/// * [`vec1_to_vec3()`]
/// * [`vec1_to_vec4()`]
pub fn vec2_to_vec1<T: Scalar>(v: &TVec2<T>) -> TVec1<T> {
TVec1::new(v.x.clone())
}
@ -153,12 +152,11 @@ pub fn vec2_to_vec1<T: Scalar>(v: &TVec2<T>) -> TVec1<T> {
///
/// # See also:
///
/// * [`vec1_to_vec1`](fn.vec1_to_vec1.html)
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec4_to_vec1`](fn.vec4_to_vec1.html)
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
/// * [`vec2_to_vec1()`]
/// * [`vec4_to_vec1()`]
/// * [`vec1_to_vec2()`]
/// * [`vec1_to_vec3()`]
/// * [`vec1_to_vec4()`]
pub fn vec3_to_vec1<T: Scalar>(v: &TVec3<T>) -> TVec1<T> {
TVec1::new(v.x.clone())
}
@ -167,12 +165,11 @@ pub fn vec3_to_vec1<T: Scalar>(v: &TVec3<T>) -> TVec1<T> {
///
/// # See also:
///
/// * [`vec1_to_vec1`](fn.vec1_to_vec1.html)
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
/// * [`vec2_to_vec1()`]
/// * [`vec3_to_vec1()`]
/// * [`vec1_to_vec2()`]
/// * [`vec1_to_vec3()`]
/// * [`vec1_to_vec4()`]
pub fn vec4_to_vec1<T: Scalar>(v: &TVec4<T>) -> TVec1<T> {
TVec1::new(v.x.clone())
}
@ -183,12 +180,12 @@ pub fn vec4_to_vec1<T: Scalar>(v: &TVec4<T>) -> TVec1<T> {
///
/// # See also:
///
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
/// * [`vec3_to_vec2()`]
/// * [`vec4_to_vec2()`]
/// * [`vec2_to_vec1()`]
/// * [`vec2_to_vec2()`]
/// * [`vec2_to_vec3()`]
/// * [`vec2_to_vec4()`]
pub fn vec1_to_vec2<T: Number>(v: &TVec1<T>) -> TVec2<T> {
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:
///
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
/// * [`vec1_to_vec2()`]
/// * [`vec3_to_vec2()`]
/// * [`vec4_to_vec2()`]
/// * [`vec2_to_vec1()`]
/// * [`vec2_to_vec2()`]
/// * [`vec2_to_vec3()`]
/// * [`vec2_to_vec4()`]
pub fn vec2_to_vec2<T: Scalar>(v: &TVec2<T>) -> TVec2<T> {
v.clone()
}
@ -212,12 +209,12 @@ pub fn vec2_to_vec2<T: Scalar>(v: &TVec2<T>) -> TVec2<T> {
///
/// # See also:
///
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
/// * [`vec1_to_vec2()`]
/// * [`vec4_to_vec2()`]
/// * [`vec2_to_vec1()`]
/// * [`vec2_to_vec2()`]
/// * [`vec2_to_vec3()`]
/// * [`vec2_to_vec4()`]
pub fn vec3_to_vec2<T: Scalar>(v: &TVec3<T>) -> TVec2<T> {
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:
///
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec3_to_vec2`](fn.vec4_to_vec2.html)
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
/// * [`vec1_to_vec2()`]
/// * [`vec3_to_vec2()`]
/// * [`vec2_to_vec1()`]
/// * [`vec2_to_vec2()`]
/// * [`vec2_to_vec3()`]
/// * [`vec2_to_vec4()`]
pub fn vec4_to_vec2<T: Scalar>(v: &TVec4<T>) -> TVec2<T> {
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:
///
/// * [`make_vec1`](fn.make_vec1.html)
/// * [`make_vec3`](fn.make_vec3.html)
/// * [`make_vec4`](fn.make_vec4.html)
/// * [`make_vec1()`]
/// * [`make_vec3()`]
/// * [`make_vec4()`]
pub fn make_vec2<T: Scalar>(ptr: &[T]) -> TVec2<T> {
TVec2::from_column_slice(ptr)
}
@ -253,11 +250,11 @@ pub fn make_vec2<T: Scalar>(ptr: &[T]) -> TVec2<T> {
///
/// # See also:
///
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec3_to_vec3`](fn.vec3_to_vec3.html)
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
/// * [`vec2_to_vec3()`]
/// * [`vec3_to_vec3()`]
/// * [`vec4_to_vec3()`]
/// * [`vec1_to_vec2()`]
/// * [`vec1_to_vec4()`]
pub fn vec1_to_vec3<T: Number>(v: &TVec1<T>) -> TVec3<T> {
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:
///
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec3_to_vec3`](fn.vec3_to_vec3.html)
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
/// * [`vec1_to_vec3()`]
/// * [`vec3_to_vec3()`]
/// * [`vec4_to_vec3()`]
/// * [`vec3_to_vec1()`]
/// * [`vec3_to_vec2()`]
/// * [`vec3_to_vec4()`]
pub fn vec2_to_vec3<T: Number>(v: &TVec2<T>) -> TVec3<T> {
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:
///
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
/// * [`vec1_to_vec3()`]
/// * [`vec2_to_vec3()`]
/// * [`vec4_to_vec3()`]
/// * [`vec3_to_vec1()`]
/// * [`vec3_to_vec2()`]
/// * [`vec3_to_vec4()`]
pub fn vec3_to_vec3<T: Scalar>(v: &TVec3<T>) -> TVec3<T> {
v.clone()
}
@ -296,12 +293,12 @@ pub fn vec3_to_vec3<T: Scalar>(v: &TVec3<T>) -> TVec3<T> {
///
/// # See also:
///
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec3_to_vec3`](fn.vec3_to_vec3.html)
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
/// * [`vec1_to_vec3()`]
/// * [`vec2_to_vec3()`]
/// * [`vec3_to_vec3()`]
/// * [`vec3_to_vec1()`]
/// * [`vec3_to_vec2()`]
/// * [`vec3_to_vec4()`]
pub fn vec4_to_vec3<T: Scalar>(v: &TVec4<T>) -> TVec3<T> {
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:
///
/// * [`make_vec1`](fn.make_vec1.html)
/// * [`make_vec2`](fn.make_vec2.html)
/// * [`make_vec4`](fn.make_vec4.html)
/// * [`make_vec1()`]
/// * [`make_vec2()`]
/// * [`make_vec4()`]
pub fn make_vec3<T: Scalar>(ptr: &[T]) -> TVec3<T> {
TVec3::from_column_slice(ptr)
}
@ -323,12 +320,12 @@ pub fn make_vec3<T: Scalar>(ptr: &[T]) -> TVec3<T> {
///
/// # See also:
///
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
/// * [`vec4_to_vec4`](fn.vec4_to_vec4.html)
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
/// * [`vec2_to_vec4()`]
/// * [`vec3_to_vec4()`]
/// * [`vec4_to_vec4()`]
/// * [`vec1_to_vec2()`]
/// * [`vec1_to_vec3()`]
/// * [`vec1_to_vec4()`]
pub fn vec1_to_vec4<T: Number>(v: &TVec1<T>) -> TVec4<T> {
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:
///
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
/// * [`vec4_to_vec4`](fn.vec4_to_vec4.html)
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec1_to_vec4()`]
/// * [`vec3_to_vec4()`]
/// * [`vec4_to_vec4()`]
/// * [`vec2_to_vec1()`]
/// * [`vec2_to_vec2()`]
/// * [`vec2_to_vec3()`]
pub fn vec2_to_vec4<T: Number>(v: &TVec2<T>) -> TVec4<T> {
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:
///
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
/// * [`vec4_to_vec4`](fn.vec4_to_vec4.html)
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec3_to_vec3`](fn.vec3_to_vec3.html)
/// * [`vec1_to_vec4()`]
/// * [`vec2_to_vec4()`]
/// * [`vec4_to_vec4()`]
/// * [`vec3_to_vec1()`]
/// * [`vec3_to_vec2()`]
/// * [`vec3_to_vec3()`]
pub fn vec3_to_vec4<T: Number>(v: &TVec3<T>) -> TVec4<T> {
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:
///
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
/// * [`vec4_to_vec1`](fn.vec4_to_vec1.html)
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
/// * [`vec1_to_vec4()`]
/// * [`vec2_to_vec4()`]
/// * [`vec3_to_vec4()`]
/// * [`vec4_to_vec1()`]
/// * [`vec4_to_vec2()`]
/// * [`vec4_to_vec3()`]
pub fn vec4_to_vec4<T: Scalar>(v: &TVec4<T>) -> TVec4<T> {
v.clone()
}
@ -383,9 +380,9 @@ pub fn vec4_to_vec4<T: Scalar>(v: &TVec4<T>) -> TVec4<T> {
///
/// # See also:
///
/// * [`make_vec1`](fn.make_vec1.html)
/// * [`make_vec2`](fn.make_vec2.html)
/// * [`make_vec3`](fn.make_vec3.html)
/// * [`make_vec1()`]
/// * [`make_vec2()`]
/// * [`make_vec3()`]
pub fn make_vec4<T: Scalar>(ptr: &[T]) -> TVec4<T> {
TVec4::from_column_slice(ptr)
}

View File

@ -16,9 +16,9 @@ use crate::traits::Number;
///
/// # See also:
///
/// * [`comp_max`](fn.comp_max.html)
/// * [`comp_min`](fn.comp_min.html)
/// * [`comp_mul`](fn.comp_mul.html)
/// * [`comp_max()`]
/// * [`comp_min()`]
/// * [`comp_mul()`]
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)
}
@ -38,13 +38,13 @@ pub fn comp_add<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) ->
///
/// # See also:
///
/// * [`comp_add`](fn.comp_add.html)
/// * [`comp_max`](fn.comp_max.html)
/// * [`comp_min`](fn.comp_min.html)
/// * [`max`](fn.max.html)
/// * [`max2`](fn.max2.html)
/// * [`max3`](fn.max3.html)
/// * [`max4`](fn.max4.html)
/// * [`comp_add()`]
/// * [`comp_max()`]
/// * [`comp_min()`]
/// * [`max()`](crate::max)
/// * [`max2()`](crate::max2)
/// * [`max3()`](crate::max3)
/// * [`max4()`](crate::max4)
pub fn comp_max<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
m.iter()
.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:
///
/// * [`comp_add`](fn.comp_add.html)
/// * [`comp_max`](fn.comp_max.html)
/// * [`comp_mul`](fn.comp_mul.html)
/// * [`min`](fn.min.html)
/// * [`min2`](fn.min2.html)
/// * [`min3`](fn.min3.html)
/// * [`min4`](fn.min4.html)
/// * [`comp_add()`]
/// * [`comp_max()`]
/// * [`comp_mul()`]
/// * [`min()`](crate::min)
/// * [`min2()`](crate::min2)
/// * [`min3()`](crate::min3)
/// * [`min4()`](crate::min4)
pub fn comp_min<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
m.iter()
.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:
///
/// * [`comp_add`](fn.comp_add.html)
/// * [`comp_max`](fn.comp_max.html)
/// * [`comp_min`](fn.comp_min.html)
/// * [`comp_add()`]
/// * [`comp_max()`]
/// * [`comp_min()`]
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)
}

View File

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

View File

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

View File

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

View File

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

View File

@ -4,11 +4,11 @@ use crate::aliases::TVec;
/// 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:
///
/// * [`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 {
// XXX: improve those.
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:
///
/// * [`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 {
// XXX: improve those.
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()
}
/// 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> {
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.
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)
}

View File

@ -7,11 +7,11 @@ use crate::traits::{Number, RealNumber};
///
/// # See also:
///
/// * [`scaling`](fn.scaling.html)
/// * [`translation`](fn.translation.html)
/// * [`rotation2d`](fn.rotation2d.html)
/// * [`scaling2d`](fn.scaling2d.html)
/// * [`translation2d`](fn.translation2d.html)
/// * [`scaling()`]
/// * [`translation()`]
/// * [`rotation2d()`]
/// * [`scaling2d()`]
/// * [`translation2d()`]
pub fn rotation<T: RealNumber>(angle: T, v: &TVec3<T>) -> TMat4<T> {
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:
///
/// * [`rotation`](fn.rotation.html)
/// * [`translation`](fn.translation.html)
/// * [`rotation2d`](fn.rotation2d.html)
/// * [`scaling2d`](fn.scaling2d.html)
/// * [`translation2d`](fn.translation2d.html)
/// * [`rotation()`]
/// * [`translation()`]
/// * [`rotation2d()`]
/// * [`scaling2d()`]
/// * [`translation2d()`]
pub fn scaling<T: Number>(v: &TVec3<T>) -> TMat4<T> {
TMat4::new_nonuniform_scaling(v)
}
@ -33,11 +33,11 @@ pub fn scaling<T: Number>(v: &TVec3<T>) -> TMat4<T> {
///
/// # See also:
///
/// * [`rotation`](fn.rotation.html)
/// * [`scaling`](fn.scaling.html)
/// * [`rotation2d`](fn.rotation2d.html)
/// * [`scaling2d`](fn.scaling2d.html)
/// * [`translation2d`](fn.translation2d.html)
/// * [`rotation()`]
/// * [`scaling()`]
/// * [`rotation2d()`]
/// * [`scaling2d()`]
/// * [`translation2d()`]
pub fn translation<T: Number>(v: &TVec3<T>) -> TMat4<T> {
TMat4::new_translation(v)
}
@ -46,11 +46,11 @@ pub fn translation<T: Number>(v: &TVec3<T>) -> TMat4<T> {
///
/// # See also:
///
/// * [`rotation`](fn.rotation.html)
/// * [`scaling`](fn.scaling.html)
/// * [`translation`](fn.translation.html)
/// * [`scaling2d`](fn.scaling2d.html)
/// * [`translation2d`](fn.translation2d.html)
/// * [`rotation()`]
/// * [`scaling()`]
/// * [`translation()`]
/// * [`scaling2d()`]
/// * [`translation2d()`]
pub fn rotation2d<T: RealNumber>(angle: T) -> TMat3<T> {
Rotation2::new(angle).to_homogeneous()
}
@ -59,11 +59,11 @@ pub fn rotation2d<T: RealNumber>(angle: T) -> TMat3<T> {
///
/// # See also:
///
/// * [`rotation`](fn.rotation.html)
/// * [`scaling`](fn.scaling.html)
/// * [`translation`](fn.translation.html)
/// * [`rotation2d`](fn.rotation2d.html)
/// * [`translation2d`](fn.translation2d.html)
/// * [`rotation()`]
/// * [`scaling()`]
/// * [`translation()`]
/// * [`rotation2d()`]
/// * [`translation2d()`]
pub fn scaling2d<T: Number>(v: &TVec2<T>) -> TMat3<T> {
TMat3::new_nonuniform_scaling(v)
}
@ -72,11 +72,11 @@ pub fn scaling2d<T: Number>(v: &TVec2<T>) -> TMat3<T> {
///
/// # See also:
///
/// * [`rotation`](fn.rotation.html)
/// * [`scaling`](fn.scaling.html)
/// * [`translation`](fn.translation.html)
/// * [`rotation2d`](fn.rotation2d.html)
/// * [`scaling2d`](fn.scaling2d.html)
/// * [`rotation()`]
/// * [`scaling()`]
/// * [`translation()`]
/// * [`rotation2d()`]
/// * [`scaling2d()`]
pub fn translation2d<T: Number>(v: &TVec2<T>) -> TMat3<T> {
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 part = res.fixed_slice_mut::<2, 2>(0, 0);
let mut part = res.fixed_view_mut::<2, 2>(0, 0);
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 part = res.fixed_slice_mut::<3, 3>(0, 0);
let mut part = res.fixed_view_mut::<3, 3>(0, 0);
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 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();
}
@ -43,7 +43,7 @@ pub fn reflect<T: RealNumber>(m: &TMat4<T>, normal: &TVec3<T>) -> TMat4<T> {
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();
}

View File

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

View File

@ -7,7 +7,7 @@ use crate::traits::Number;
///
/// # 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 {
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:
///
/// * [`are_collinear`](fn.are_collinear.html)
/// * [`are_collinear()`]
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)
}
@ -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).
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).

View File

@ -38,7 +38,7 @@
* All function names use `snake_case`, 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.
* 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
functions are available.
* 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.
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 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).
* Every function related to quaternions start with the `quat_` prefix, e.g., [`glm::quat_dot(q1, q2)`](fn.quat_dot.html).
* 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()`](crate::rotate_vec2).
* 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).
### Vector and matrix construction
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 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.
* 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.
### Swizzling
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
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`.
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.
* 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:
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`.

View File

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

View File

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

View File

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

View File

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

View File

@ -7,13 +7,12 @@ 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 na::{allocator::Allocator, DefaultAllocator, Matrix, OMatrix, OVector, Scalar};
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",
@ -36,8 +35,10 @@ pub struct Eigen<T: Scalar, D: Dim>
where
DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
{
/// The eigenvalues of the decomposed matrix.
pub eigenvalues: OVector<T, D>,
/// The real parts of eigenvalues of the decomposed matrix.
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.
pub eigenvectors: Option<OMatrix<T, D, D>>,
/// The left eigenvectors of the decomposed matrix.
@ -69,8 +70,8 @@ where
"Unable to compute the eigenvalue decomposition of a non-square matrix."
);
let ljob = if left_eigenvectors { b'V' } else { b'T' };
let rjob = if eigenvectors { b'V' } else { b'T' };
let ljob = if left_eigenvectors { b'V' } else { b'N' };
let rjob = if eigenvectors { b'V' } else { b'N' };
let (nrows, ncols) = m.shape_generic();
let n = nrows.value();
@ -104,213 +105,231 @@ where
lapack_check!(info);
let mut work = vec![T::zero(); lwork as usize];
let mut vl = if left_eigenvectors {
Some(Matrix::zeros_generic(nrows, ncols))
} else {
None
};
let mut vr = if eigenvectors {
Some(Matrix::zeros_generic(nrows, ncols))
} else {
None
};
match (left_eigenvectors, eigenvectors) {
(true, true) => {
// 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
}
/// The complex eigenvalues of the given matrix.
///
/// Panics if the eigenvalue computation does not converge.
pub fn complex_eigenvalues(mut m: OMatrix<T, D, D>) -> OVector<Complex<T>, D>
where
DefaultAllocator: Allocator<Complex<T>, D>,
{
assert!(
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];
let vl_ref = vl
.as_mut()
.map(|m| m.as_mut_slice())
.unwrap_or(&mut placeholder1);
let vr_ref = vr
.as_mut()
.map(|m| m.as_mut_slice())
.unwrap_or(&mut placeholder2);
T::xgeev(
b'T',
b'T',
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,
vl_ref,
if left_eigenvectors { n as i32 } else { 1 },
vr_ref,
if eigenvectors { n as i32 } else { 1 },
&mut work,
lwork,
&mut info,
);
lapack_panic!(info);
lapack_check!(info);
let mut res = Matrix::zeros_generic(nrows, Const::<1>);
Some(Self {
eigenvalues_re: wr,
eigenvalues_im: wi,
left_eigenvectors: vl,
eigenvectors: vr,
})
}
for i in 0..res.len() {
res[i] = Complex::new(wr[i].clone(), wi[i].clone());
}
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.
#[inline]
#[must_use]
pub fn determinant(&self) -> T {
let mut det = T::one();
for e in self.eigenvalues.iter() {
det *= e.clone();
pub fn determinant(&self) -> Complex<T> {
let mut det: Complex<T> = na::one();
for (re, im) in self.eigenvalues_re.iter().zip(self.eigenvalues_im.iter()) {
det *= Complex::new(re.clone(), im.clone());
}
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 eigen;
mod generalized_eigenvalues;
mod hessenberg;
mod lu;
mod qr;
mod qz;
mod schur;
mod svd;
mod symmetric_eigen;
@ -94,9 +96,11 @@ use num_complex::Complex;
pub use self::cholesky::{Cholesky, CholeskyScalar};
pub use self::eigen::Eigen;
pub use self::generalized_eigenvalues::GeneralizedEigen;
pub use self::hessenberg::Hessenberg;
pub use self::lu::{LUScalar, LU};
pub use self::qr::QR;
pub use self::qz::QZ;
pub use self::schur::Schur;
pub use self::svd::SVD;
pub use self::symmetric_eigen::SymmetricEigen;

View File

@ -126,7 +126,7 @@ where
let mut q = self
.qr
.generic_slice((0, 0), (nrows, min_nrows_ncols))
.generic_view((0, 0), (nrows, min_nrows_ncols))
.into_owned();
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 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));
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 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);
for i in 0 .. min_nrows_ncols.value() {

View File

@ -58,8 +58,8 @@ proptest! {
let sol1 = chol.solve(&b1).unwrap();
let sol2 = chol.solve(&b2).unwrap();
prop_assert!(relative_eq!(m * sol1, b1, epsilon = 1.0e-7));
prop_assert!(relative_eq!(m * sol2, b2, 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-4));
}
}
@ -84,7 +84,7 @@ proptest! {
let id1 = &m * &m1;
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_sol2 = lup.solve_transpose(&b2).unwrap();
prop_assert!(relative_eq!(&m * sol1, b1, epsilon = 1.0e-7));
prop_assert!(relative_eq!(&m * sol2, b2, epsilon = 1.0e-7));
prop_assert!(relative_eq!(m.transpose() * tr_sol1, b1, epsilon = 1.0e-7));
prop_assert!(relative_eq!(m.transpose() * tr_sol2, b2, 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-5));
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-5));
}
#[test]
@ -68,10 +68,10 @@ proptest! {
let tr_sol1 = lup.solve_transpose(&b1).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 * sol2, b2, epsilon = 1.0e-7));
prop_assert!(relative_eq!(m.transpose() * tr_sol1, b1, epsilon = 1.0e-7));
prop_assert!(relative_eq!(m.transpose() * tr_sol2, b2, 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-5));
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-5));
}
#[test]

View File

@ -1,6 +1,9 @@
mod cholesky;
mod complex_eigen;
mod generalized_eigenvalues;
mod lu;
mod qr;
mod qz;
mod real_eigensystem;
mod schur;
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);
if let Some(eig) = Eigen::new(m.clone(), true, true) {
let eigvals = DMatrix::from_diagonal(&eig.eigenvalues);
let transformed_eigvectors = &m * eig.eigenvectors.as_ref().unwrap();
let scaled_eigvectors = eig.eigenvectors.as_ref().unwrap() * &eigvals;
// 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 scaled_eigvectors = eig.eigenvectors.as_ref().unwrap() * &eigvals;
let transformed_left_eigvectors = m.transpose() * eig.left_eigenvectors.as_ref().unwrap();
let scaled_left_eigvectors = eig.left_eigenvectors.as_ref().unwrap() * &eigvals;
let transformed_left_eigvectors = m.transpose() * eig.left_eigenvectors.as_ref().unwrap();
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_left_eigvectors, scaled_left_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-5));
}
}
}
#[test]
fn eigensystem_static(m in matrix4()) {
if let Some(eig) = Eigen::new(m, true, true) {
let eigvals = Matrix4::from_diagonal(&eig.eigenvalues);
let transformed_eigvectors = m * eig.eigenvectors.unwrap();
let scaled_eigvectors = eig.eigenvectors.unwrap() * eigvals;
// 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 scaled_eigvectors = eig.eigenvectors.unwrap() * eigvals;
let transformed_left_eigvectors = m.transpose() * eig.left_eigenvectors.unwrap();
let scaled_left_eigvectors = eig.left_eigenvectors.unwrap() * eigvals;
let transformed_left_eigvectors = m.transpose() * eig.left_eigenvectors.unwrap();
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_left_eigvectors, scaled_left_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-5));
}
}
}
}

View File

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

View File

@ -1,6 +1,6 @@
[package]
name = "nalgebra-macros"
version = "0.1.0"
version = "0.2.1"
authors = [ "Andreas Longva", "Sébastien Crozet <developer@crozet.re>" ]
edition = "2018"
description = "Procedural macros for nalgebra"
@ -21,5 +21,5 @@ quote = "1.0"
proc-macro2 = "1.0"
[dev-dependencies]
nalgebra = { version = "0.30.0", path = ".." }
nalgebra = { version = "0.32.0", path = ".." }
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! {
nalgebra::DMatrix::<_>
::from_vec_storage(nalgebra::VecStorage::new(
nalgebra::Dynamic::new(#row_dim),
nalgebra::Dynamic::new(#col_dim),
nalgebra::Dyn(#row_dim),
nalgebra::Dyn(#col_dim),
vec!#array_tokens))
};
@ -223,7 +223,7 @@ impl Parse for Vector {
elements: Vec::new(),
})
} else {
let elements = MatrixRowSyntax::parse_separated_nonempty(input)?
let elements = MatrixRowSyntax::parse_terminated(input)?
.into_iter()
.collect();
Ok(Self { elements })
@ -285,7 +285,7 @@ pub fn dvector(stream: TokenStream) -> TokenStream {
let output = quote! {
nalgebra::DVector::<_>
::from_vec_storage(nalgebra::VecStorage::new(
nalgebra::Dynamic::new(#len),
nalgebra::Dyn(#len),
nalgebra::Const::<1>,
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]));
}
#[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
#[rustfmt::skip]
#[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]));
}
#[test]
fn vector_trailing_comma() {
vector![1, 2,];
point![1, 2,];
dvector![1, 2,];
}
#[test]
fn matrix_trybuild_tests() {
let t = trybuild::TestCases::new();

View File

@ -1,6 +1,6 @@
[package]
name = "nalgebra-sparse"
version = "0.6.0"
version = "0.9.0"
authors = [ "Andreas Longva", "Sébastien Crozet <developer@crozet.re>" ]
edition = "2018"
description = "Sparse matrix computation based on nalgebra."
@ -24,7 +24,7 @@ io = [ "pest", "pest_derive" ]
slow-tests = []
[dependencies]
nalgebra = { version="0.30", path = "../" }
nalgebra = { version="0.32", path = "../" }
num-traits = { version = "0.2", default-features = false }
proptest = { version = "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]
itertools = "0.10"
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"
[package.metadata.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),
&idx_workspace[..count],
&values_workspace[..count],
&Add::add,
Add::add,
);
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).
// TODO: Consider giving the iterator a concrete type instead of impl trait...?
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))
}
/// 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.
///
/// 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);
}
/// 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.
#[inline]
#[must_use]

View File

@ -1,4 +1,3 @@
use std::mem::replace;
use std::ops::Range;
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> {
#[inline]
pub fn identity(n: usize) -> Self {
@ -360,7 +368,7 @@ where
if let Some(minor_indices) = lane {
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);
self.remaining_values = remaining;
self.current_lane_idx += 1;
@ -494,7 +502,7 @@ where
assert_eq!(source_minor_indices.len(), 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];
for minor_idx in source_minor_indices {
minor_counts[*minor_idx] += 1;
@ -569,7 +577,7 @@ where
} else if sort {
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(
SparseFormatErrorKind::InvalidStructure,
"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(
SparseFormatErrorKind::IndexOutOfBounds,
"A major offset is out of bounds.",
),
)?;
)
})?;
// We test for in-bounds, uniqueness and monotonicity at the same time
// to ensure that we only visit each minor index once
@ -653,9 +661,9 @@ where
if !monotonic && sort {
let range_size = range_end - range_start;
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.extend_from_slice(&minor_idx_in_lane);
minor_idx_buffer.extend_from_slice(minor_idx_in_lane);
apply_permutation(
&mut minor_indices[range_start..range_end],
&minor_idx_buffer,

View File

@ -24,6 +24,7 @@ use std::slice::{Iter, IterMut};
/// # Usage
///
/// ```
/// use nalgebra_sparse::coo::CooMatrix;
/// use nalgebra_sparse::csc::CscMatrix;
/// use nalgebra::{DMatrix, Matrix3x4};
/// 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
/// // way to construct a CSC matrix is to first incrementally construct a COO matrix,
/// // 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);
///
/// // 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 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(
num_rows: 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
/// 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(
num_rows: 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.
///
/// 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>,
}
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> {
/// 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> {
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> {
lane_iter: CsLaneIterMut<'a, T>,
}

View File

@ -25,6 +25,7 @@ use std::slice::{Iter, IterMut};
/// # Usage
///
/// ```
/// use nalgebra_sparse::coo::CooMatrix;
/// use nalgebra_sparse::csr::CsrMatrix;
/// use nalgebra::{DMatrix, Matrix3x4};
/// 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
/// // way to construct a CSR matrix is to first incrementally construct a COO matrix,
/// // 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);
///
/// // 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 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(
num_rows: 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
/// 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(
num_rows: 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.
///
/// 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>,
}
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> {
/// 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> {
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> {
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::pattern::SparsityPattern;
use core::{iter, mem};
use nalgebra::{DMatrix, DMatrixSlice, DMatrixSliceMut, RealField};
use nalgebra::{DMatrix, DMatrixView, DMatrixViewMut, RealField};
use std::fmt::{Display, Formatter};
/// A symbolic sparse Cholesky factorization of a CSC matrix.
@ -264,7 +264,7 @@ impl<T: RealField> CscCholesky<T> {
///
/// Panics if `B` is not square.
#[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 mut output = b.clone_owned();
self.solve_mut(&mut output);
@ -278,7 +278,7 @@ impl<T: RealField> CscCholesky<T> {
/// # Panics
///
/// 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,\
then the triangular solve should never fail";
// Solve LY = B

View File

@ -1,9 +1,9 @@
//! 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.
use crate::coo::CooMatrix;
use crate::SparseFormatError;
use crate::SparseFormatErrorKind;
use crate::{CooMatrix, CscMatrix, CsrMatrix};
use nalgebra::Complex;
use pest::iterators::Pairs;
use pest::Parser;
@ -12,7 +12,8 @@ use std::convert::Infallible;
use std::convert::TryFrom;
use std::fmt;
use std::fmt::Formatter;
use std::fs;
use std::fs::{self, File};
use std::io::{BufWriter, Write};
use std::num::ParseIntError;
use std::num::TryFromIntError;
use std::path::Path;
@ -267,7 +268,7 @@ impl fmt::Display for MatrixMarketError {
write!(f, "InvalidHeader,")?;
}
MatrixMarketErrorKind::EntryMismatch => {
write!(f, "EntryNumUnmatched,")?;
write!(f, "EntryMismatch,")?;
}
MatrixMarketErrorKind::TypeMismatch => {
write!(f, "TypeMismatch,")?;
@ -288,7 +289,7 @@ impl fmt::Display for MatrixMarketError {
write!(f, "NotLowerTriangle,")?;
}
MatrixMarketErrorKind::NonSquare => {
write!(f, "NotSquareMatrix,")?;
write!(f, "NonSquare,")?;
}
}
write!(f, " message: {}", self.message)
@ -506,6 +507,21 @@ mod internal {
fn negative(self) -> Result<Self, MatrixMarketError>;
/// When matrix is a Hermitian matrix, it will convert itself to its conjugate.
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> {
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> {
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> {
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"),
))
}
#[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!(());
/// 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)]
#[grammar = "io/matrix_market.pest"]
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 |
//! | ------------------------------------------------|------------|------------|
//! | [Matrix market](#matrix-market-format) | Yes | No |
//! | [Matrix market](#matrix-market-format) | Yes | Yes |
//!
//! [Matrix market]: https://math.nist.gov/MatrixMarket/formats.html
//!
@ -19,10 +19,12 @@
//! which also uses the Matrix Market file format.
//!
//! 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
//! a matrix stored in the matrix market format with the function [load_coo_from_matrix_market_str].
//!
//! Export is currently not implemented, but [planned](https://github.com/dimforge/nalgebra/issues/1037).
//! [CooMatrix](crate::CooMatrix) through the function [load_coo_from_matrix_market_file],
//! 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
//! 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)
//! on the Matrix Market website and the
@ -32,7 +34,8 @@
//! > "*The Matrix Market Exchange Formats: Initial Design.*" (1996).
pub use self::matrix_market::{
load_coo_from_matrix_market_file, load_coo_from_matrix_market_str, MatrixMarketError,
MatrixMarketErrorKind, MatrixMarketScalar,
load_coo_from_matrix_market_file, load_coo_from_matrix_market_str, save_to_matrix_market,
save_to_matrix_market_file, save_to_matrix_market_str, MatrixMarketError,
MatrixMarketErrorKind, MatrixMarketExport, MatrixMarketScalar,
};
mod matrix_market;

View File

@ -143,8 +143,6 @@
)]
pub extern crate nalgebra as na;
#[cfg(feature = "io")]
extern crate pest;
#[macro_use]
#[cfg(feature = "io")]
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]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum SparseFormatErrorKind {

View File

@ -3,14 +3,14 @@ use crate::csr::CsrMatrix;
use crate::ops::serial::{
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 nalgebra::allocator::Allocator;
use nalgebra::base::storage::RawStorage;
use nalgebra::constraint::{DimEq, ShapeConstraint};
use nalgebra::{
ClosedAdd, ClosedDiv, ClosedMul, ClosedSub, DefaultAllocator, Dim, Dynamic, Matrix, OMatrix,
ClosedAdd, ClosedDiv, ClosedMul, ClosedSub, DefaultAllocator, Dim, Dyn, Matrix, OMatrix,
Scalar, U1,
};
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)
.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
});
@ -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
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
/// 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
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 nrows = Dynamic::new(lhs.nrows());
let mut result = OMatrix::<T, Dynamic, C>::zeros_generic(nrows, ncols);
let nrows = Dyn(lhs.nrows());
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));
result
});
@ -302,21 +302,21 @@ macro_rules! impl_spmm_cs_dense {
R: Dim,
C: Dim,
S: RawStorage<T, R, C>,
DefaultAllocator: Allocator<T, Dynamic, C>,
DefaultAllocator: Allocator<T, Dyn, C>,
// TODO: Is it possible to simplify these bounds?
ShapeConstraint:
// Bounds so that we can turn OMatrix<T, Dynamic, C> into a DMatrixSliceMut
DimEq<U1, <<DefaultAllocator as Allocator<T, Dynamic, C>>::Buffer as RawStorage<T, Dynamic, C>>::RStride>
+ DimEq<C, Dynamic>
+ DimEq<Dynamic, <<DefaultAllocator as Allocator<T, Dynamic, C>>::Buffer as RawStorage<T, Dynamic, C>>::CStride>
// Bounds so that we can turn OMatrix<T, Dyn, C> into a DMatrixSliceMut
DimEq<U1, <<DefaultAllocator as Allocator<T, Dyn, C>>::Buffer as RawStorage<T, Dyn, C>>::RStride>
+ DimEq<C, Dyn>
+ 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
+ DimEq<U1, S::RStride>
+ DimEq<R, Dynamic>
+ DimEq<Dynamic, S::CStride>
+ DimEq<R, Dyn>
+ DimEq<Dyn, S::CStride>
{
// 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)
type Output = OMatrix<T, Dynamic, C>;
type Output = OMatrix<T, Dyn, C>;
fn mul(self, rhs: $dense_matrix_type) -> Self::Output {
let $lhs = self;

View File

@ -149,8 +149,8 @@ impl<T> Op<T> {
#[must_use]
pub fn as_ref(&self) -> Op<&T> {
match self {
Op::NoOp(obj) => Op::NoOp(&obj),
Op::Transpose(obj) => Op::Transpose(&obj),
Op::NoOp(obj) => Op::NoOp(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::Op;
use crate::SparseEntryMut;
use nalgebra::{ClosedAdd, ClosedMul, DMatrixSlice, DMatrixSliceMut, Scalar};
use nalgebra::{ClosedAdd, ClosedMul, DMatrixView, DMatrixViewMut, Scalar};
use num_traits::{One, Zero};
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)).
///
/// 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>(
beta: T,
c: &mut CsMatrix<T>,
@ -131,10 +176,10 @@ where
/// the transposed operation must be specified for the CSC matrix.
pub fn spmm_cs_dense<T>(
beta: T,
mut c: DMatrixSliceMut<'_, T>,
mut c: DMatrixViewMut<'_, T>,
alpha: T,
a: Op<&CsMatrix<T>>,
b: Op<DMatrixSlice<'_, T>>,
b: Op<DMatrixView<'_, T>>,
) where
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{

View File

@ -1,8 +1,10 @@
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::Op;
use nalgebra::{ClosedAdd, ClosedMul, DMatrixSlice, DMatrixSliceMut, RealField, Scalar};
use nalgebra::{ClosedAdd, ClosedMul, DMatrixView, DMatrixViewMut, RealField, Scalar};
use num_traits::{One, Zero};
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.
pub fn spmm_csc_dense<'a, T>(
beta: T,
c: impl Into<DMatrixSliceMut<'a, T>>,
c: impl Into<DMatrixViewMut<'a, T>>,
alpha: T,
a: Op<&CscMatrix<T>>,
b: Op<impl Into<DMatrixSlice<'a, T>>>,
b: Op<impl Into<DMatrixView<'a, T>>>,
) where
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{
@ -27,10 +29,10 @@ pub fn spmm_csc_dense<'a, T>(
fn spmm_csc_dense_<T>(
beta: T,
c: DMatrixSliceMut<'_, T>,
c: DMatrixViewMut<'_, T>,
alpha: T,
a: Op<&CscMatrix<T>>,
b: Op<DMatrixSlice<'_, T>>,
b: Op<DMatrixView<'_, T>>,
) where
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{
@ -83,35 +85,81 @@ where
{
assert_compatible_spmm_dims!(c, a, b);
use Op::{NoOp, Transpose};
use Op::NoOp;
match (&a, &b) {
(NoOp(ref a), NoOp(ref b)) => {
(NoOp(a), NoOp(b)) => {
// Note: We have to reverse the order for CSC matrices
spmm_cs_prealloc(beta, &mut c.cs, alpha, &b.cs, &a.cs)
}
_ => {
// Currently we handle transposition by explicitly precomputing transposed matrices
// and calling the operation again without transposition
let a_ref: &CscMatrix<T> = a.inner_ref();
let b_ref: &CscMatrix<T> = b.inner_ref();
let (a, b) = {
use Cow::*;
match (&a, &b) {
(NoOp(_), NoOp(_)) => unreachable!(),
(Transpose(ref a), NoOp(_)) => (Owned(a.transpose()), Borrowed(b_ref)),
(NoOp(_), Transpose(ref b)) => (Borrowed(a_ref), Owned(b.transpose())),
(Transpose(ref a), Transpose(ref b)) => {
(Owned(a.transpose()), Owned(b.transpose()))
}
}
};
spmm_csc_prealloc(beta, c, alpha, NoOp(a.as_ref()), NoOp(b.as_ref()))
}
_ => 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
// and calling the operation again without transposition
let a_ref: &CscMatrix<T> = a.inner_ref();
let b_ref: &CscMatrix<T> = b.inner_ref();
let (a, b) = {
use Cow::*;
match (&a, &b) {
(NoOp(_), NoOp(_)) => unreachable!(),
(Transpose(a), NoOp(_)) => (Owned(a.transpose()), Borrowed(b_ref)),
(NoOp(_), Transpose(b)) => (Borrowed(a_ref), Owned(b.transpose())),
(Transpose(a), Transpose(b)) => (Owned(a.transpose()), Owned(b.transpose())),
}
};
spmm_kernel(beta, c, alpha, NoOp(a.as_ref()), NoOp(b.as_ref()))
}
/// Solve the lower triangular system `op(L) X = B`.
///
/// Only the lower triangular part of L is read, and the result is stored in B.
@ -125,7 +173,7 @@ where
/// Panics if `L` is not square, or if `L` and `B` are not dimensionally compatible.
pub fn spsolve_csc_lower_triangular<'a, T: RealField>(
l: Op<&CscMatrix<T>>,
b: impl Into<DMatrixSliceMut<'a, T>>,
b: impl Into<DMatrixViewMut<'a, T>>,
) -> Result<(), OperationError> {
let b = b.into();
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>(
l: &CscMatrix<T>,
b: DMatrixSliceMut<'_, T>,
b: DMatrixViewMut<'_, T>,
) -> Result<(), OperationError> {
let mut x = b;
@ -205,7 +253,7 @@ fn spsolve_encountered_zero_diagonal() -> Result<(), OperationError> {
fn spsolve_csc_lower_triangular_transpose<T: RealField>(
l: &CscMatrix<T>,
b: DMatrixSliceMut<'_, T>,
b: DMatrixViewMut<'_, T>,
) -> Result<(), OperationError> {
let mut x = b;

View File

@ -1,18 +1,20 @@
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::Op;
use nalgebra::{ClosedAdd, ClosedMul, DMatrixSlice, DMatrixSliceMut, Scalar};
use nalgebra::{ClosedAdd, ClosedMul, DMatrixView, DMatrixViewMut, Scalar};
use num_traits::{One, Zero};
use std::borrow::Cow;
/// Sparse-dense matrix-matrix multiplication `C <- beta * C + alpha * op(A) * op(B)`.
pub fn spmm_csr_dense<'a, T>(
beta: T,
c: impl Into<DMatrixSliceMut<'a, T>>,
c: impl Into<DMatrixViewMut<'a, T>>,
alpha: T,
a: Op<&CsrMatrix<T>>,
b: Op<impl Into<DMatrixSlice<'a, T>>>,
b: Op<impl Into<DMatrixView<'a, T>>>,
) where
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{
@ -22,10 +24,10 @@ pub fn spmm_csr_dense<'a, T>(
fn spmm_csr_dense_<T>(
beta: T,
c: DMatrixSliceMut<'_, T>,
c: DMatrixViewMut<'_, T>,
alpha: T,
a: Op<&CsrMatrix<T>>,
b: Op<DMatrixSlice<'_, T>>,
b: Op<DMatrixView<'_, T>>,
) where
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
{
@ -77,30 +79,71 @@ where
{
assert_compatible_spmm_dims!(c, a, b);
use Op::{NoOp, Transpose};
use Op::NoOp;
match (&a, &b) {
(NoOp(ref a), NoOp(ref b)) => spmm_cs_prealloc(beta, &mut c.cs, alpha, &a.cs, &b.cs),
_ => {
// Currently we handle transposition by explicitly precomputing transposed matrices
// 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 b_ref: &CsrMatrix<T> = b.inner_ref();
let (a, b) = {
use Cow::*;
match (&a, &b) {
(NoOp(_), NoOp(_)) => unreachable!(),
(Transpose(ref a), NoOp(_)) => (Owned(a.transpose()), Borrowed(b_ref)),
(NoOp(_), Transpose(ref b)) => (Borrowed(a_ref), Owned(b.transpose())),
(Transpose(ref a), Transpose(ref b)) => {
(Owned(a.transpose()), Owned(b.transpose()))
}
}
};
spmm_csr_prealloc(beta, c, alpha, NoOp(a.as_ref()), NoOp(b.as_ref()))
}
(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
// and calling the operation again without transposition
let a_ref: &CsrMatrix<T> = a.inner_ref();
let b_ref: &CsrMatrix<T> = b.inner_ref();
let (a, b) = {
use Cow::*;
match (&a, &b) {
(NoOp(_), NoOp(_)) => unreachable!(),
(Transpose(a), NoOp(_)) => (Owned(a.transpose()), Borrowed(b_ref)),
(NoOp(_), Transpose(b)) => (Borrowed(a_ref), Owned(b.transpose())),
(Transpose(a), Transpose(b)) => (Owned(a.transpose()), Owned(b.transpose())),
}
};
spmm_kernel(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 {
iter::from_fn(move || {
if let (Some(a_item), Some(b_item)) = (sorted_a.first(), sorted_b.first()) {
let item = if a_item < b_item {
sorted_a = &sorted_a[1..];
a_item
} else if b_item < a_item {
sorted_b = &sorted_b[1..];
b_item
} else {
// Both lists contain the same element, advance both slices to avoid
// duplicate entries in the result
sorted_a = &sorted_a[1..];
sorted_b = &sorted_b[1..];
a_item
let item = match a_item.cmp(b_item) {
std::cmp::Ordering::Less => {
sorted_a = &sorted_a[1..];
a_item
}
std::cmp::Ordering::Greater => {
sorted_b = &sorted_b[1..];
b_item
}
std::cmp::Ordering::Equal => {
// Both lists contain the same element, advance both slices to avoid
// duplicate entries in the result
sorted_a = &sorted_a[1..];
sorted_b = &sorted_b[1..];
a_item
}
};
Some(*item)
} else if let Some(a_item) = sorted_a.first() {

View File

@ -80,7 +80,7 @@ impl SparsityPattern {
#[inline]
#[must_use]
pub fn major_dim(&self) -> usize {
assert!(self.major_offsets.len() > 0);
assert!(!self.major_offsets.is_empty());
self.major_offsets.len() - 1
}
@ -162,7 +162,7 @@ impl SparsityPattern {
// We test for in-bounds, uniqueness and monotonicity at the same time
// to ensure that we only visit each minor index once
let mut iter = minor_indices.iter();
let mut prev = None;
let mut prev: Option<usize> = None;
while let Some(next) = iter.next().copied() {
if next >= minor_dim {
@ -170,10 +170,10 @@ impl SparsityPattern {
}
if let Some(prev) = prev {
if prev > next {
return Err(NonmonotonicMinorIndices);
} else if prev == next {
return Err(DuplicateEntry);
match prev.cmp(&next) {
std::cmp::Ordering::Greater => return Err(NonmonotonicMinorIndices),
std::cmp::Ordering::Equal => return Err(DuplicateEntry),
std::cmp::Ordering::Less => {}
}
}
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
/// 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(
major_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.
#[non_exhaustive]
#[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]
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]
fn coo_try_from_triplets_panics_on_mismatched_vectors() {
// 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]
fn coo_push_out_of_bounds_entries() {
{
@ -291,8 +373,8 @@ fn coo_push_matrix_valid_entries() {
// Works with sliced
{
let source = nalgebra::SMatrix::<i32, 2, 2>::new(6, 7, 8, 9);
let sliced = source.fixed_slice::<2, 1>(0, 0);
coo.push_matrix(1, 0, &sliced);
let view = source.fixed_view::<2, 1>(0, 0);
coo.push_matrix(1, 0, &view);
assert_eq!(
coo.triplet_iter().collect::<Vec<_>>(),

View File

@ -12,6 +12,18 @@ use crate::common::csc_strategy;
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]
fn csc_matrix_valid_data() {
// 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;
#[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]
fn csr_matrix_valid_data() {
// Construct matrix from valid data and check that selected methods return results

View File

@ -1,12 +1,21 @@
use matrixcompare::assert_matrix_eq;
use nalgebra::dmatrix;
use nalgebra::matrix;
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 proptest::prelude::*;
use tempfile::tempdir;
type C64 = Complex<f64>;
type C32 = Complex<f32>;
#[test]
#[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
let shapes = vec![ (0, 0), (1, 0), (0, 1) ];
let strings: Vec<String> = shapes
@ -24,7 +33,7 @@ fn test_matrixmarket_sparse_real_general_empty() {
#[test]
#[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
let shapes = vec![ (0, 0), (1, 0), (0, 1) ];
let strings: Vec<String> = shapes
@ -42,7 +51,7 @@ fn test_matrixmarket_dense_real_general_empty() {
#[test]
#[rustfmt::skip]
fn test_matrixmarket_sparse_real_general() {
fn test_matrixmarket_load_sparse_real_general() {
let file_str = r#"
%%MatrixMarket matrix CoOrdinate real general
% This is also an example of free-format features.
@ -89,7 +98,7 @@ fn test_matrixmarket_sparse_real_general() {
5 5 1.200e+01
"#;
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;
0.0, 10.5, 0.0, 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]
#[rustfmt::skip]
fn test_matrixmarket_sparse_int_symmetric() {
fn test_matrixmarket_load_sparse_int_symmetric() {
let file_str = r#"
%%MatrixMarket matrix coordinate integer symmetric
%
@ -117,7 +126,7 @@ fn test_matrixmarket_sparse_int_symmetric() {
5 5 55
"#;
let sparse_mat = load_coo_from_matrix_market_str::<i128>(file_str).unwrap();
let expected = dmatrix![
let expected = matrix![
11, 0, 0, 0, -15;
0, 22, 23, 24, 0;
0, 23, 33, 0, 35;
@ -129,7 +138,7 @@ fn test_matrixmarket_sparse_int_symmetric() {
#[test]
#[rustfmt::skip]
fn test_matrixmarket_sparse_complex_hermitian() {
fn test_matrixmarket_load_sparse_complex_hermitian() {
let file_str = r#"
%%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 expected = dmatrix![
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};
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};
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};
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};
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};
let expected = matrix![
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};
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};
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};
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};
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);
}
#[test]
#[rustfmt::skip]
fn test_matrixmarket_sparse_real_skew() {
fn test_matrixmarket_load_sparse_real_skew() {
let file_str = r#"
%%MatrixMarket matrix coordinate real skew-symmetric
%
@ -167,7 +176,7 @@ fn test_matrixmarket_sparse_real_skew() {
5 3 -35.0
"#;
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, 23.0, 24.0, 0.0;
0.0, -23.0, 0.0, 0.0, 35.0;
@ -179,7 +188,7 @@ fn test_matrixmarket_sparse_real_skew() {
#[test]
#[rustfmt::skip]
fn test_matrixmarket_sparse_pattern_general() {
fn test_matrixmarket_load_sparse_pattern_general() {
let file_str = r#"
%%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 nrows = pattern_matrix.nrows();
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 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;
0, 0, 1, 1, 0;
0, 1, 0, 0, 1;
@ -213,7 +222,7 @@ fn test_matrixmarket_sparse_pattern_general() {
#[test]
#[rustfmt::skip]
fn test_matrixmarket_dense_real_general() {
fn test_matrixmarket_load_dense_real_general() {
let file_str = r#"
%%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 expected = dmatrix![
let expected = matrix![
1.0, 5.0, 9.0;
2.0, 6.0, 10.0;
3.0, 7.0, 11.0;
@ -244,7 +253,7 @@ fn test_matrixmarket_dense_real_general() {
#[test]
#[rustfmt::skip]
fn test_matrixmarket_dense_real_symmetric() {
fn test_matrixmarket_load_dense_real_symmetric() {
let file_str = r#"
%%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 expected = dmatrix![
let expected = matrix![
1.0, 2.0, 3.0, 4.0;
2.0, 5.0, 6.0, 7.0;
3.0, 6.0, 8.0, 9.0;
@ -273,7 +282,7 @@ fn test_matrixmarket_dense_real_symmetric() {
#[test]
#[rustfmt::skip]
fn test_matrixmarket_dense_complex_hermitian() {
fn test_matrixmarket_load_dense_complex_hermitian() {
let file_str = r#"
%%MatrixMarket matrix array complex hermitian
%
@ -290,19 +299,19 @@ fn test_matrixmarket_dense_complex_hermitian() {
10.0 0.0
"#;
let sparse_mat = load_coo_from_matrix_market_str::<Complex<f64>>(file_str).unwrap();
let expected = dmatrix![
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};
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};
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};
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};
let sparse_mat = load_coo_from_matrix_market_str::<C64>(file_str).unwrap();
let expected = matrix![
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};
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};
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};
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);
}
#[test]
#[rustfmt::skip]
fn test_matrixmarket_dense_int_skew() {
fn test_matrixmarket_load_dense_int_skew() {
let file_str = r#"
%%MatrixMarket matrix array integer skew-symmetric
%
@ -315,7 +324,7 @@ fn test_matrixmarket_dense_int_skew() {
6
"#;
let sparse_mat = load_coo_from_matrix_market_str::<i32>(file_str).unwrap();
let expected = dmatrix![
let expected = matrix![
0,-1,-2,-3;
1, 0,-4,-5;
2, 4, 0,-6;
@ -326,7 +335,7 @@ fn test_matrixmarket_dense_int_skew() {
#[test]
#[rustfmt::skip]
fn test_matrixmarket_dense_complex_general() {
fn test_matrixmarket_load_dense_complex_general() {
let file_str = r#"
%%MatrixMarket matrix array complex general
%
@ -336,10 +345,124 @@ fn test_matrixmarket_dense_complex_general() {
1 0
1 0
"#;
let sparse_mat = load_coo_from_matrix_market_str::<Complex<f32>>(file_str).unwrap();
let expected = dmatrix![
Complex::<f32>{re:1.0,im:0.0},Complex::<f32>{re:1.0,im:0.0};
Complex::<f32>{re:1.0,im:0.0},Complex::<f32>{re:1.0,im:0.0};
let sparse_mat = load_coo_from_matrix_market_str::<C32>(file_str).unwrap();
let expected = matrix![
C32{re:1.0,im:0.0},C32{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);
}
#[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::ops::serial::{
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::pattern::SparsityPattern;
use nalgebra_sparse::proptest::{csc, csr, sparsity_pattern};
use nalgebra::proptest::{matrix, vector};
use nalgebra::{DMatrix, DMatrixSlice, DMatrixSliceMut, Scalar};
use nalgebra::{DMatrix, DMatrixView, DMatrixViewMut, Scalar};
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
fn dense_gemm<'a>(
beta: i32,
c: impl Into<DMatrixSliceMut<'a, i32>>,
c: impl Into<DMatrixViewMut<'a, i32>>,
alpha: i32,
a: Op<impl Into<DMatrixSlice<'a, i32>>>,
b: Op<impl Into<DMatrixSlice<'a, i32>>>,
a: Op<impl Into<DMatrixView<'a, i32>>>,
b: Op<impl Into<DMatrixView<'a, i32>>>,
) {
let mut c = c.into();
let a = a.convert();
@ -543,6 +544,29 @@ proptest! {
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]
fn spmm_csr_prealloc_test(SpmmCsrArgs { c, beta, alpha, a, b }
in spmm_csr_prealloc_args_strategy()
@ -705,6 +729,29 @@ proptest! {
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]
fn spmm_csc_prealloc_panics_on_dim_mismatch(
(alpha, beta, c, a, b)

View File

@ -1,5 +1,19 @@
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]
fn sparsity_pattern_valid_data() {
// Construct pattern from valid data and check that selected methods return results

View File

@ -1,5 +1,5 @@
#[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::storage::Owned;
#[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.**
#[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.
///
/// **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"))]
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.
///
/// **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"))]
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.
///
/// **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"))]
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.
///
/// **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"))]
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.
///
/// **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"))]
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.
///
/// **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"))]
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.**
#[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix1xX<T> = Matrix<T, U1, Dynamic, VecStorage<T, U1, Dynamic>>;
/// A heap-allocated, row-major, matrix with 2 rows and a dynamic number of columns.
pub type Matrix1xX<T> = Matrix<T, U1, Dyn, VecStorage<T, U1, Dyn>>;
/// 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.**
#[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix2xX<T> = Matrix<T, U2, Dynamic, VecStorage<T, U2, Dynamic>>;
/// A heap-allocated, row-major, matrix with 3 rows and a dynamic number of columns.
pub type Matrix2xX<T> = Matrix<T, U2, Dyn, VecStorage<T, U2, Dyn>>;
/// 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.**
#[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix3xX<T> = Matrix<T, U3, Dynamic, VecStorage<T, U3, Dynamic>>;
/// A heap-allocated, row-major, matrix with 4 rows and a dynamic number of columns.
pub type Matrix3xX<T> = Matrix<T, U3, Dyn, VecStorage<T, U3, Dyn>>;
/// 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.**
#[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix4xX<T> = Matrix<T, U4, Dynamic, VecStorage<T, U4, Dynamic>>;
/// A heap-allocated, row-major, matrix with 5 rows and a dynamic number of columns.
pub type Matrix4xX<T> = Matrix<T, U4, Dyn, VecStorage<T, U4, Dyn>>;
/// 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.**
#[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix5xX<T> = Matrix<T, U5, Dynamic, VecStorage<T, U5, Dynamic>>;
/// A heap-allocated, row-major, matrix with 6 rows and a dynamic number of columns.
pub type Matrix5xX<T> = Matrix<T, U5, Dyn, VecStorage<T, U5, Dyn>>;
/// 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.**
#[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.
///
@ -276,7 +276,7 @@ pub type Matrix6x5<T> = Matrix<T, U6, U5, ArrayStorage<T, 6, 5>>;
*/
/// A dynamically sized column vector.
#[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.
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.
#[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.
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::matrix_slice::{SliceStorage, SliceStorageMut};
use crate::base::dimension::{Dyn, U1, U2, U3, U4, U5, U6};
use crate::base::matrix_view::{ViewStorage, ViewStorageMut};
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.
///
/// **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> =
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.
///
/// **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> =
Matrix<T, Dynamic, Dynamic, SliceStorage<'a, T, Dynamic, Dynamic, RStride, CStride>>;
#[deprecated = slice_deprecation_note!(DMatrixView)]
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
#[deprecated = slice_deprecation_note!(MatrixView1xX)]
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.
#[deprecated = slice_deprecation_note!(MatrixView2xX)]
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.
#[deprecated = slice_deprecation_note!(MatrixView3xX)]
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.
#[deprecated = slice_deprecation_note!(MatrixView4xX)]
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.
#[deprecated = slice_deprecation_note!(MatrixView5xX)]
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.
#[deprecated = slice_deprecation_note!(MatrixView6xX)]
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.
pub type MatrixSliceXx1<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<T, Dynamic, U1, SliceStorage<'a, T, Dynamic, U1, RStride, CStride>>;
#[deprecated = slice_deprecation_note!(MatrixViewXx1)]
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.
pub type MatrixSliceXx2<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<T, Dynamic, U2, SliceStorage<'a, T, Dynamic, U2, RStride, CStride>>;
#[deprecated = slice_deprecation_note!(MatrixViewXx2)]
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.
pub type MatrixSliceXx3<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<T, Dynamic, U3, SliceStorage<'a, T, Dynamic, U3, RStride, CStride>>;
#[deprecated = slice_deprecation_note!(MatrixViewXx3)]
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.
pub type MatrixSliceXx4<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<T, Dynamic, U4, SliceStorage<'a, T, Dynamic, U4, RStride, CStride>>;
#[deprecated = slice_deprecation_note!(MatrixViewXx4)]
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.
pub type MatrixSliceXx5<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<T, Dynamic, U5, SliceStorage<'a, T, Dynamic, U5, RStride, CStride>>;
#[deprecated = slice_deprecation_note!(MatrixViewXx5)]
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.
pub type MatrixSliceXx6<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<T, Dynamic, U6, SliceStorage<'a, T, Dynamic, U6, RStride, CStride>>;
#[deprecated = slice_deprecation_note!(MatrixViewXx6)]
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.
///
/// **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> =
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.
///
/// **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> =
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.
pub type DVectorSlice<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<T, Dynamic, U1, SliceStorage<'a, T, Dynamic, U1, RStride, CStride>>;
#[deprecated = slice_deprecation_note!(DVectorView)]
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
Matrix<T, Dynamic, Dynamic, SliceStorageMut<'a, T, Dynamic, Dynamic, RStride, CStride>>;
#[deprecated = slice_deprecation_note!(DMatrixViewMut)]
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
#[deprecated = slice_deprecation_note!(MatrixViewMut1xX)]
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.
#[deprecated = slice_deprecation_note!(MatrixViewMut2xX)]
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.
#[deprecated = slice_deprecation_note!(MatrixViewMut3xX)]
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.
#[deprecated = slice_deprecation_note!(MatrixViewMut4xX)]
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.
#[deprecated = slice_deprecation_note!(MatrixViewMut5xX)]
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.
#[deprecated = slice_deprecation_note!(MatrixViewMut6xX)]
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.
pub type MatrixSliceMutXx1<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<T, Dynamic, U1, SliceStorageMut<'a, T, Dynamic, U1, RStride, CStride>>;
#[deprecated = slice_deprecation_note!(MatrixViewMutXx1)]
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.
pub type MatrixSliceMutXx2<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<T, Dynamic, U2, SliceStorageMut<'a, T, Dynamic, U2, RStride, CStride>>;
#[deprecated = slice_deprecation_note!(MatrixViewMutXx2)]
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.
pub type MatrixSliceMutXx3<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<T, Dynamic, U3, SliceStorageMut<'a, T, Dynamic, U3, RStride, CStride>>;
#[deprecated = slice_deprecation_note!(MatrixViewMutXx3)]
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.
pub type MatrixSliceMutXx4<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<T, Dynamic, U4, SliceStorageMut<'a, T, Dynamic, U4, RStride, CStride>>;
#[deprecated = slice_deprecation_note!(MatrixViewMutXx4)]
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.
pub type MatrixSliceMutXx5<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<T, Dynamic, U5, SliceStorageMut<'a, T, Dynamic, U5, RStride, CStride>>;
#[deprecated = slice_deprecation_note!(MatrixViewMutXx5)]
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.
pub type MatrixSliceMutXx6<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<T, Dynamic, U6, SliceStorageMut<'a, T, Dynamic, U6, RStride, CStride>>;
#[deprecated = slice_deprecation_note!(MatrixViewMutXx6)]
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
Matrix<T, Dynamic, U1, SliceStorageMut<'a, T, Dynamic, U1, RStride, CStride>>;
#[deprecated = slice_deprecation_note!(DVectorViewMut)]
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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.
///
/// **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> =
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:
/// 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
/// same `Buffer` type.
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;
/// 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;
/// 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,
iter: I,
) -> 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` ×

View File

@ -5,12 +5,15 @@ use std::ops::Mul;
#[cfg(feature = "serde-serialize-no-std")]
use serde::de::{Error, SeqAccess, Visitor};
#[cfg(feature = "serde-serialize-no-std")]
use serde::ser::SerializeSeq;
use serde::ser::SerializeTuple;
#[cfg(feature = "serde-serialize-no-std")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "serde-serialize-no-std")]
use std::marker::PhantomData;
#[cfg(feature = "rkyv-serialize")]
use rkyv::bytecheck;
use crate::base::allocator::Allocator;
use crate::base::default_allocator::DefaultAllocator;
use crate::base::dimension::{Const, ToTypenum};
@ -27,7 +30,18 @@ use std::mem;
/// A array-based statically sized matrix data storage.
#[repr(transparent)]
#[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]);
impl<T, const R: usize, const C: usize> ArrayStorage<T, R, C> {
@ -177,7 +191,7 @@ where
where
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() {
serializer.serialize_element(e)?;
@ -196,7 +210,7 @@ where
where
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>
{
}
#[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::{
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::uninit::Init;
use crate::base::{
DVectorSlice, DefaultAllocator, Matrix, Scalar, SquareMatrix, Vector, VectorSlice,
DVectorView, DefaultAllocator, Matrix, Scalar, SquareMatrix, Vector, VectorView,
};
/// # Dot/scalar product
@ -363,8 +363,8 @@ where
x: &Vector<T, D3, SC>,
beta: T,
dot: impl Fn(
&DVectorSlice<'_, T, SB::RStride, SB::CStride>,
&DVectorSlice<'_, T, SC::RStride, SC::CStride>,
&DVectorView<'_, T, SB::RStride, SB::CStride>,
&DVectorView<'_, T, SC::RStride, SC::CStride>,
) -> T,
) where
T: One,
@ -393,7 +393,7 @@ where
let col2 = a.column(0);
let val = unsafe { x.vget_unchecked(0).clone() };
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 {
let col2 = a.column(j);
@ -506,7 +506,7 @@ where
a: &Matrix<T, R2, C2, SB>,
x: &Vector<T, D3, SC>,
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
T: One,
SB: Storage<T, R2, C2>,
@ -890,9 +890,9 @@ where
for j in 0..dim1 {
let val = unsafe { conjugate(y.vget_unchecked(j).clone()) };
let subdim = Dynamic::new(dim1 - j);
let subdim = Dyn(dim1 - j);
// 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,
&x.rows_range(j..),
beta.clone(),

View File

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

View File

@ -59,7 +59,7 @@ where
SB: Storage<T, DimNameDiff<D, U1>>,
{
let mut res = Self::identity();
res.generic_slice_mut(
res.generic_view_mut(
(0, D::dim() - 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>>,
{
let scale = self
.generic_slice(
.generic_view(
(D::dim() - 1, 0),
(Const::<1>, DimNameDiff::<D, U1>::name()),
)
.tr_dot(shift);
let post_translation = self.generic_slice(
let post_translation = self.generic_view(
(0, 0),
(DimNameDiff::<D, U1>::name(), DimNameDiff::<D, U1>::name()),
) * shift;
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),
(DimNameDiff::<D, U1>::name(), Const::<1>),
);
@ -415,11 +415,11 @@ where
&self,
v: &OVector<T, DimNameDiff<D, U1>>,
) -> OVector<T, DimNameDiff<D, U1>> {
let transform = self.generic_slice(
let transform = self.generic_view(
(0, 0),
(DimNameDiff::<D, U1>::name(), DimNameDiff::<D, U1>::name()),
);
let normalizer = self.generic_slice(
let normalizer = self.generic_view(
(D::dim() - 1, 0),
(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.
#[inline]
pub fn transform_point(&self, pt: &Point<T, 2>) -> Point<T, 2> {
let transform = self.fixed_slice::<2, 2>(0, 0);
let translation = self.fixed_slice::<2, 1>(0, 2);
let normalizer = self.fixed_slice::<1, 2>(2, 0);
let transform = self.fixed_view::<2, 2>(0, 0);
let translation = self.fixed_view::<2, 1>(0, 2);
let normalizer = self.fixed_view::<1, 2>(2, 0);
let n = normalizer.tr_dot(&pt.coords) + unsafe { self.get_unchecked((2, 2)).clone() };
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.
#[inline]
pub fn transform_point(&self, pt: &Point<T, 3>) -> Point<T, 3> {
let transform = self.fixed_slice::<3, 3>(0, 0);
let translation = self.fixed_slice::<3, 1>(0, 3);
let normalizer = self.fixed_slice::<1, 3>(3, 0);
let transform = self.fixed_view::<3, 3>(0, 0);
let translation = self.fixed_view::<3, 1>(0, 3);
let normalizer = self.fixed_view::<1, 3>(3, 0);
let n = normalizer.tr_dot(&pt.coords) + unsafe { self.get_unchecked((3, 3)).clone() };
if !n.is_zero() {

View File

@ -1,12 +1,12 @@
//! 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.
#[derive(Copy, Clone, Debug)]
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> {}
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> {
/// This is either equal to `D1` or `D2`, always choosing the one (if any) which is a type-level
/// constant.
@ -25,17 +25,17 @@ impl<D: Dim> DimEq<D, D> for ShapeConstraint {
type Representative = D;
}
impl<D: DimName> DimEq<D, Dynamic> for ShapeConstraint {
impl<D: DimName> DimEq<D, Dyn> for ShapeConstraint {
type Representative = D;
}
impl<D: DimName> DimEq<Dynamic, D> for ShapeConstraint {
impl<D: DimName> DimEq<Dyn, D> for ShapeConstraint {
type Representative = D;
}
macro_rules! equality_trait_decl(
($($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]
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
@ -47,28 +47,28 @@ macro_rules! equality_trait_decl(
type Representative = D;
}
impl<D: DimName> $Trait<D, Dynamic> for ShapeConstraint {
impl<D: DimName> $Trait<D, Dyn> for ShapeConstraint {
type Representative = D;
}
impl<D: DimName> $Trait<Dynamic, D> for ShapeConstraint {
impl<D: DimName> $Trait<Dyn, D> for ShapeConstraint {
type Representative = D;
}
)*}
);
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 \
rows of a matrix.",
SameNumberOfRows,
"Constraints `D1` and `D2` to be equivalent. \
"Constrains `D1` and `D2` to be equivalent. \
They are both assumed to be the number of \
columns of a matrix.",
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).
pub trait SameDimension<D1: Dim, D2: Dim>:
SameNumberOfRows<D1, D2> + SameNumberOfColumns<D1, D2>
@ -82,10 +82,10 @@ impl<D: Dim> SameDimension<D, D> for ShapeConstraint {
type Representative = D;
}
impl<D: DimName> SameDimension<D, Dynamic> for ShapeConstraint {
impl<D: DimName> SameDimension<D, Dyn> for ShapeConstraint {
type Representative = D;
}
impl<D: DimName> SameDimension<Dynamic, D> for ShapeConstraint {
impl<D: DimName> SameDimension<Dyn, D> for ShapeConstraint {
type Representative = D;
}

View File

@ -19,7 +19,7 @@ use typenum::{self, Cmp, Greater};
use simba::scalar::{ClosedAdd, ClosedMul};
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::{
ArrayStorage, Const, DefaultAllocator, Matrix, OMatrix, OVector, Scalar, Unit, Vector,
@ -86,6 +86,17 @@ where
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
/// row-major order.
///
@ -215,7 +226,7 @@ where
SB: RawStorage<T, Const<1>, C>,
{
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();
assert!(
rows.len() == nrows,
@ -257,7 +268,7 @@ where
SB: RawStorage<T, R>,
{
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();
assert!(
columns.len() == ncols,
@ -306,12 +317,12 @@ where
///
/// # Example
/// ```
/// # use nalgebra::{Dynamic, DMatrix, Matrix, Const};
/// # use nalgebra::{Dyn, DMatrix, Matrix, Const};
///
/// let vec = vec![0, 1, 2, 3, 4, 5];
/// 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();
///
/// // `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)
}
/// 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
/// component coordinates.
///
@ -615,35 +656,35 @@ where
}
/// # 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
DefaultAllocator: Allocator<T, R, Dynamic>,
DefaultAllocator: Allocator<T, R, Dyn>,
{
impl_constructors!(R, Dynamic;
impl_constructors!(R, Dyn;
=> R: DimName;
R::name(), Dynamic::new(ncols);
R::name(), Dyn(ncols);
ncols);
}
/// # 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
DefaultAllocator: Allocator<T, Dynamic, C>,
DefaultAllocator: Allocator<T, Dyn, C>,
{
impl_constructors!(Dynamic, C;
impl_constructors!(Dyn, C;
=> C: DimName;
Dynamic::new(nrows), C::name();
Dyn(nrows), C::name();
nrows);
}
/// # Constructors of fully dynamic matrices
impl<T: Scalar> OMatrix<T, Dynamic, Dynamic>
impl<T: Scalar> OMatrix<T, Dyn, Dyn>
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);
}
@ -749,19 +790,19 @@ impl_constructors_from_data!(data; R, C; // Arguments for Matri
R::name(), C::name(); // Arguments for `_generic` constructors.
); // Arguments for non-generic constructors.
impl_constructors_from_data!(data; R, Dynamic;
impl_constructors_from_data!(data; R, Dyn;
=> 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;
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);
/*

View File

@ -1,18 +1,18 @@
use crate::base::dimension::{Const, Dim, DimName, Dynamic};
use crate::base::matrix_slice::{SliceStorage, SliceStorageMut};
use crate::base::{MatrixSlice, MatrixSliceMutMN, Scalar};
use crate::base::dimension::{Const, Dim, DimName, Dyn};
use crate::base::matrix_view::{ViewStorage, ViewStorageMut};
use crate::base::{MatrixView, MatrixViewMut, Scalar};
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>
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
/// 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]
pub unsafe fn from_slice_with_strides_generic_unchecked(
data: &'a [T],
@ -22,7 +22,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
rstride: RStride,
cstride: CStride,
) -> Self {
let data = SliceStorage::from_raw_parts(
let data = ViewStorage::from_raw_parts(
data.as_ptr().add(start),
(nrows, ncols),
(rstride, cstride),
@ -30,10 +30,10 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
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.
/// 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]
pub fn from_slice_with_strides_generic(
data: &'a [T],
@ -48,7 +48,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
assert!(
data.len() + cstride.value() + rstride.value()
>= ncols.value() * cstride.value() + nrows.value() * rstride.value() + 1,
"Matrix slice: input data buffer to small."
"Matrix view: input data buffer too small."
);
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> {
/// Creates, without bound-checking, a matrix slice from an array and with dimensions specified by generic types instances.
impl<'a, T: Scalar, R: Dim, C: Dim> MatrixView<'a, T, R, C> {
/// Creates, without bound-checking, a matrix view from an array and with dimensions specified by generic types instances.
///
/// # Safety
/// 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]
pub unsafe fn from_slice_generic_unchecked(
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.
/// 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]
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)
@ -87,8 +87,8 @@ impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSlice<'a, T, R, C> {
macro_rules! impl_constructors(
($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixSlice<'a, T, $($Dims),*> {
/// Creates a new matrix slice from the given data array.
impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixView<'a, T, $($Dims),*> {
/// Creates a new matrix view from the given data array.
///
/// Panics if `data` does not contain enough elements.
#[inline]
@ -96,26 +96,33 @@ macro_rules! impl_constructors(
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]
pub unsafe fn from_slice_unchecked(data: &'a [T], start: usize, $($args: usize),*) -> Self {
Self::from_slice_generic_unchecked(data, start, $($gargs),*)
}
}
impl<'a, T: Scalar, $($DimIdent: $DimBound, )*> MatrixSlice<'a, T, $($Dims,)* Dynamic, Dynamic> {
/// Creates a new matrix slice with the specified strides from the given data array.
impl<'a, T: Scalar, $($DimIdent: $DimBound, )*> MatrixView<'a, T, $($Dims,)* Dyn, Dyn> {
/// Creates a new matrix view with the specified strides from the given data array.
///
/// Panics if `data` does not contain enough elements.
#[inline]
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]
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.
); // Arguments for non-generic constructors.
impl_constructors!(R, Dynamic;
impl_constructors!(R, Dyn;
=> R: DimName;
R::name(), Dynamic::new(ncols);
R::name(), Dyn(ncols);
ncols);
impl_constructors!(Dynamic, C;
impl_constructors!(Dyn, C;
=> C: DimName;
Dynamic::new(nrows), C::name();
Dyn(nrows), C::name();
nrows);
impl_constructors!(Dynamic, Dynamic;
impl_constructors!(Dyn, Dyn;
;
Dynamic::new(nrows), Dynamic::new(ncols);
Dyn(nrows), Dyn(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>
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
/// 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]
pub unsafe fn from_slice_with_strides_generic_unchecked(
data: &'a mut [T],
@ -160,7 +167,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
rstride: RStride,
cstride: CStride,
) -> Self {
let data = SliceStorageMut::from_raw_parts(
let data = ViewStorageMut::from_raw_parts(
data.as_mut_ptr().add(start),
(nrows, ncols),
(rstride, cstride),
@ -168,10 +175,10 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
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.
/// 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]
pub fn from_slice_with_strides_generic(
data: &'a mut [T],
@ -186,7 +193,7 @@ impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
assert!(
data.len() + cstride.value() + rstride.value()
>= ncols.value() * cstride.value() + nrows.value() * rstride.value() + 1,
"Matrix slice: input data buffer to small."
"Matrix view: input data buffer too small."
);
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 {
@ -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> {
/// Creates, without bound-checking, a mutable matrix slice from an array and with dimensions specified by generic types instances.
impl<'a, T: Scalar, R: Dim, C: Dim> MatrixViewMut<'a, T, R, C> {
/// Creates, without bound-checking, a mutable matrix view from an array and with dimensions specified by generic types instances.
///
/// # Safety
/// 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]
pub unsafe fn from_slice_generic_unchecked(
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.
/// 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]
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)
@ -247,8 +254,8 @@ impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSliceMutMN<'a, T, R, C> {
macro_rules! impl_constructors_mut(
($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixSliceMutMN<'a, T, $($Dims),*> {
/// Creates a new mutable matrix slice from the given data array.
impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixViewMut<'a, T, $($Dims),*> {
/// Creates a new mutable matrix view from the given data array.
///
/// Panics if `data` does not contain enough elements.
#[inline]
@ -256,28 +263,34 @@ macro_rules! impl_constructors_mut(
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]
pub unsafe fn from_slice_unchecked(data: &'a mut [T], start: usize, $($args: usize),*) -> Self {
Self::from_slice_generic_unchecked(data, start, $($gargs),*)
}
}
impl<'a, T: Scalar, $($DimIdent: $DimBound, )*> MatrixSliceMutMN<'a, T, $($Dims,)* Dynamic, Dynamic> {
/// Creates a new mutable matrix slice with the specified strides from the given data array.
impl<'a, T: Scalar, $($DimIdent: $DimBound, )*> MatrixViewMut<'a, T, $($Dims,)* Dyn, Dyn> {
/// Creates a new mutable matrix view with the specified strides from the given data array.
///
/// Panics if `data` does not contain enough elements.
#[inline]
pub fn from_slice_with_strides_mut(data: &'a mut [T], $($args: usize,)* rstride: usize, cstride: usize) -> Self {
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]
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(
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.
); // Arguments for non-generic constructors.
impl_constructors_mut!(R, Dynamic;
impl_constructors_mut!(R, Dyn;
=> R: DimName;
R::name(), Dynamic::new(ncols);
R::name(), Dyn(ncols);
ncols);
impl_constructors_mut!(Dynamic, C;
impl_constructors_mut!(Dyn, C;
=> C: DimName;
Dynamic::new(nrows), C::name();
Dyn(nrows), C::name();
nrows);
impl_constructors_mut!(Dynamic, Dynamic;
impl_constructors_mut!(Dyn, Dyn;
;
Dynamic::new(nrows), Dynamic::new(ncols);
Dyn(nrows), Dyn(ncols);
nrows, ncols);

View File

@ -8,22 +8,22 @@ use simba::simd::{PrimitiveSimdValue, SimdValue};
use crate::base::allocator::{Allocator, SameShapeAllocator};
use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
#[cfg(any(feature = "std", feature = "alloc"))]
use crate::base::dimension::Dynamic;
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::storage::{IsContiguous, RawStorage, RawStorageMut};
use crate::base::{
ArrayStorage, DVectorSlice, DVectorSliceMut, DefaultAllocator, Matrix, MatrixSlice,
MatrixSliceMut, OMatrix, Scalar,
ArrayStorage, DVectorView, DVectorViewMut, DefaultAllocator, Matrix, MatrixView, MatrixViewMut,
OMatrix, Scalar,
};
#[cfg(any(feature = "std", feature = "alloc"))]
use crate::base::{DVector, RowDVector, VecStorage};
use crate::base::{SliceStorage, SliceStorageMut};
use crate::base::{ViewStorage, ViewStorageMut};
use crate::constraint::DimEq;
use crate::{IsNotStaticOne, RowSVector, SMatrix, SVector, VectorSlice, VectorSliceMut};
use crate::{IsNotStaticOne, RowSVector, SMatrix, SVector, VectorView, VectorViewMut};
use std::mem::MaybeUninit;
// 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
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> {
#[inline]
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>
From<VectorSlice<'a, T, Const<D>, RStride, CStride>> for [T; D]
From<VectorView<'a, T, Const<D>, RStride, CStride>> for [T; D]
{
#[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()
}
}
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]
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()
}
}
@ -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>
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]
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()
}
}
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]
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()
}
}
@ -289,192 +313,183 @@ impl_from_into_asref_borrow_2D!(
);
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>>
where
T: Scalar,
RStride: Dim,
CStride: Dim,
{
fn from(matrix_slice: MatrixSlice<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
matrix_slice.into_owned()
fn from(matrix_view: MatrixView<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
matrix_view.into_owned()
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, T, C, RStride, CStride> From<MatrixSlice<'a, T, Dynamic, C, RStride, CStride>>
for Matrix<T, Dynamic, C, VecStorage<T, Dynamic, C>>
impl<'a, T, C, RStride, CStride> From<MatrixView<'a, T, Dyn, C, RStride, CStride>>
for Matrix<T, Dyn, C, VecStorage<T, Dyn, C>>
where
T: Scalar,
C: Dim,
RStride: Dim,
CStride: Dim,
{
fn from(matrix_slice: MatrixSlice<'a, T, Dynamic, C, RStride, CStride>) -> Self {
matrix_slice.into_owned()
fn from(matrix_view: MatrixView<'a, T, Dyn, C, RStride, CStride>) -> Self {
matrix_view.into_owned()
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, T, R, RStride, CStride> From<MatrixSlice<'a, T, R, Dynamic, RStride, CStride>>
for Matrix<T, R, Dynamic, VecStorage<T, R, Dynamic>>
impl<'a, T, R, RStride, CStride> From<MatrixView<'a, T, R, Dyn, RStride, CStride>>
for Matrix<T, R, Dyn, VecStorage<T, R, Dyn>>
where
T: Scalar,
R: DimName,
RStride: Dim,
CStride: Dim,
{
fn from(matrix_slice: MatrixSlice<'a, T, R, Dynamic, RStride, CStride>) -> Self {
matrix_slice.into_owned()
fn from(matrix_view: MatrixView<'a, T, R, Dyn, RStride, CStride>) -> Self {
matrix_view.into_owned()
}
}
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>>
where
T: Scalar,
RStride: Dim,
CStride: Dim,
{
fn from(matrix_slice: MatrixSliceMut<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
matrix_slice.into_owned()
fn from(matrix_view: MatrixViewMut<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
matrix_view.into_owned()
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, T, C, RStride, CStride> From<MatrixSliceMut<'a, T, Dynamic, C, RStride, CStride>>
for Matrix<T, Dynamic, C, VecStorage<T, Dynamic, C>>
impl<'a, T, C, RStride, CStride> From<MatrixViewMut<'a, T, Dyn, C, RStride, CStride>>
for Matrix<T, Dyn, C, VecStorage<T, Dyn, C>>
where
T: Scalar,
C: Dim,
RStride: Dim,
CStride: Dim,
{
fn from(matrix_slice: MatrixSliceMut<'a, T, Dynamic, C, RStride, CStride>) -> Self {
matrix_slice.into_owned()
fn from(matrix_view: MatrixViewMut<'a, T, Dyn, C, RStride, CStride>) -> Self {
matrix_view.into_owned()
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, T, R, RStride, CStride> From<MatrixSliceMut<'a, T, R, Dynamic, RStride, CStride>>
for Matrix<T, R, Dynamic, VecStorage<T, R, Dynamic>>
impl<'a, T, R, RStride, CStride> From<MatrixViewMut<'a, T, R, Dyn, RStride, CStride>>
for Matrix<T, R, Dyn, VecStorage<T, R, Dyn>>
where
T: Scalar,
R: DimName,
RStride: Dim,
CStride: Dim,
{
fn from(matrix_slice: MatrixSliceMut<'a, T, R, Dynamic, RStride, CStride>) -> Self {
matrix_slice.into_owned()
fn from(matrix_view: MatrixViewMut<'a, T, R, Dyn, RStride, CStride>) -> Self {
matrix_view.into_owned()
}
}
impl<'a, T, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a Matrix<T, R, C, S>>
for MatrixSlice<'a, T, RSlice, CSlice, RStride, CStride>
impl<'a, T, R, C, RView, CView, RStride, CStride, S> From<&'a Matrix<T, R, C, S>>
for MatrixView<'a, T, RView, CView, RStride, CStride>
where
T: Scalar,
R: Dim,
C: Dim,
RSlice: Dim,
CSlice: Dim,
RView: Dim,
CView: Dim,
RStride: Dim,
CStride: Dim,
S: RawStorage<T, R, C>,
ShapeConstraint: DimEq<R, RSlice>
+ DimEq<C, CSlice>
+ DimEq<RStride, S::RStride>
+ DimEq<CStride, S::CStride>,
ShapeConstraint:
DimEq<R, RView> + DimEq<C, CView> + DimEq<RStride, S::RStride> + DimEq<CStride, S::CStride>,
{
fn from(m: &'a Matrix<T, R, C, S>) -> Self {
let (row, col) = m.shape_generic();
let row_slice = RSlice::from_usize(row.value());
let col_slice = CSlice::from_usize(col.value());
let rows_result = RView::from_usize(row.value());
let cols_result = CView::from_usize(col.value());
let (rstride, cstride) = m.strides();
let rstride_slice = RStride::from_usize(rstride);
let cstride_slice = CStride::from_usize(cstride);
let rstride_result = RStride::from_usize(rstride);
let cstride_result = CStride::from_usize(cstride);
unsafe {
let data = SliceStorage::from_raw_parts(
let data = ViewStorage::from_raw_parts(
m.data.ptr(),
(row_slice, col_slice),
(rstride_slice, cstride_slice),
(rows_result, cols_result),
(rstride_result, cstride_result),
);
Matrix::from_data_statically_unchecked(data)
}
}
}
impl<'a, T, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix<T, R, C, S>>
for MatrixSlice<'a, T, RSlice, CSlice, RStride, CStride>
impl<'a, T, R, C, RView, CView, RStride, CStride, S> From<&'a mut Matrix<T, R, C, S>>
for MatrixView<'a, T, RView, CView, RStride, CStride>
where
T: Scalar,
R: Dim,
C: Dim,
RSlice: Dim,
CSlice: Dim,
RView: Dim,
CView: Dim,
RStride: Dim,
CStride: Dim,
S: RawStorage<T, R, C>,
ShapeConstraint: DimEq<R, RSlice>
+ DimEq<C, CSlice>
+ DimEq<RStride, S::RStride>
+ DimEq<CStride, S::CStride>,
ShapeConstraint:
DimEq<R, RView> + DimEq<C, CView> + DimEq<RStride, S::RStride> + DimEq<CStride, S::CStride>,
{
fn from(m: &'a mut Matrix<T, R, C, S>) -> Self {
let (row, col) = m.shape_generic();
let row_slice = RSlice::from_usize(row.value());
let col_slice = CSlice::from_usize(col.value());
let rows_result = RView::from_usize(row.value());
let cols_result = CView::from_usize(col.value());
let (rstride, cstride) = m.strides();
let rstride_slice = RStride::from_usize(rstride);
let cstride_slice = CStride::from_usize(cstride);
let rstride_result = RStride::from_usize(rstride);
let cstride_result = CStride::from_usize(cstride);
unsafe {
let data = SliceStorage::from_raw_parts(
let data = ViewStorage::from_raw_parts(
m.data.ptr(),
(row_slice, col_slice),
(rstride_slice, cstride_slice),
(rows_result, cols_result),
(rstride_result, cstride_result),
);
Matrix::from_data_statically_unchecked(data)
}
}
}
impl<'a, T, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix<T, R, C, S>>
for MatrixSliceMut<'a, T, RSlice, CSlice, RStride, CStride>
impl<'a, T, R, C, RView, CView, RStride, CStride, S> From<&'a mut Matrix<T, R, C, S>>
for MatrixViewMut<'a, T, RView, CView, RStride, CStride>
where
T: Scalar,
R: Dim,
C: Dim,
RSlice: Dim,
CSlice: Dim,
RView: Dim,
CView: Dim,
RStride: Dim,
CStride: Dim,
S: RawStorageMut<T, R, C>,
ShapeConstraint: DimEq<R, RSlice>
+ DimEq<C, CSlice>
+ DimEq<RStride, S::RStride>
+ DimEq<CStride, S::CStride>,
ShapeConstraint:
DimEq<R, RView> + DimEq<C, CView> + DimEq<RStride, S::RStride> + DimEq<CStride, S::CStride>,
{
fn from(m: &'a mut Matrix<T, R, C, S>) -> Self {
let (row, col) = m.shape_generic();
let row_slice = RSlice::from_usize(row.value());
let col_slice = CSlice::from_usize(col.value());
let rows_result = RView::from_usize(row.value());
let cols_result = CView::from_usize(col.value());
let (rstride, cstride) = m.strides();
let rstride_slice = RStride::from_usize(rstride);
let cstride_slice = CStride::from_usize(cstride);
let rstride_result = RStride::from_usize(rstride);
let cstride_result = CStride::from_usize(cstride);
unsafe {
let data = SliceStorageMut::from_raw_parts(
let data = ViewStorageMut::from_raw_parts(
m.data.ptr_mut(),
(row_slice, col_slice),
(rstride_slice, cstride_slice),
(rows_result, cols_result),
(rstride_result, cstride_result),
);
Matrix::from_data_statically_unchecked(data)
}
@ -482,7 +497,7 @@ where
}
#[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]
fn from(vec: Vec<T>) -> Self {
Self::from_vec(vec)
@ -490,7 +505,7 @@ impl<'a, T: Scalar> From<Vec<T>> for DVector<T> {
}
#[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]
fn from(vec: Vec<T>) -> Self {
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]
fn from(slice: &'a [T]) -> Self {
Self::from_slice(slice, slice.len())
}
}
impl<'a, T: Scalar> From<DVectorSlice<'a, T>> for &'a [T] {
fn from(vec: DVectorSlice<'a, T>) -> &'a [T] {
impl<'a, T: Scalar> From<DVectorView<'a, T>> for &'a [T] {
fn from(vec: DVectorView<'a, T>) -> &'a [T] {
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]
fn from(slice: &'a mut [T]) -> Self {
Self::from_slice(slice, slice.len())
}
}
impl<'a, T: Scalar> From<DVectorSliceMut<'a, T>> for &'a mut [T] {
fn from(vec: DVectorSliceMut<'a, T>) -> &'a mut [T] {
impl<'a, T: Scalar> From<DVectorViewMut<'a, T>> for &'a mut [T] {
fn from(vec: DVectorViewMut<'a, T>) -> &'a mut [T] {
vec.data.into_slice_mut()
}
}

View File

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

View File

@ -8,54 +8,69 @@ use std::fmt::Debug;
use std::ops::{Add, Div, Mul, Sub};
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")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
/// Dim of dynamically-sized algebraic entities.
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
pub struct Dynamic {
value: usize,
}
#[cfg_attr(
feature = "rkyv-serialize-no-std",
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`.
#[inline]
#[deprecated(note = "use Dyn(value) instead.")]
pub const fn new(value: usize) -> Self {
Self { value }
Self(value)
}
}
#[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>
where
S: Serializer,
{
self.value.serialize(serializer)
self.0.serialize(serializer)
}
}
#[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>
where
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 {}
/// 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 {}
impl IsDynamic for Dynamic {}
impl IsNotStaticOne for Dynamic {}
impl IsDynamic for Dyn {}
impl IsNotStaticOne for Dyn {}
/// 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 {
#[inline(always)]
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 =
/// Dynamic`.
/// Dyn`.
fn try_to_usize() -> Option<usize>;
/// 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;
}
unsafe impl Dim for Dynamic {
unsafe impl Dim for Dyn {
#[inline]
fn try_to_usize() -> Option<usize> {
None
@ -83,30 +98,30 @@ unsafe impl Dim for Dynamic {
#[inline]
fn from_usize(dim: usize) -> Self {
Self::new(dim)
Self(dim)
}
#[inline]
fn value(&self) -> usize {
self.value
self.0
}
}
impl Add<usize> for Dynamic {
type Output = Dynamic;
impl Add<usize> for Dyn {
type Output = Dyn;
#[inline]
fn add(self, rhs: usize) -> Self {
Self::new(self.value + rhs)
Self(self.0 + rhs)
}
}
impl Sub<usize> for Dynamic {
type Output = Dynamic;
impl Sub<usize> for Dyn {
type Output = Dyn;
#[inline]
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 {
type Output = Dynamic;
impl<D: Dim> $DimOp<D> for Dyn {
type Output = Dyn;
#[inline]
fn $op(self, other: D) -> Dynamic {
Dynamic::new($op_path(self.value, other.value()))
fn $op(self, other: D) -> Dyn {
Dyn($op_path(self.value(), other.value()))
}
}
// TODO: use Const<T> instead of D: DimName?
impl<D: DimName> $DimOp<Dynamic> for D {
type Output = Dynamic;
impl<D: DimName> $DimOp<Dyn> for D {
type Output = Dyn;
#[inline]
fn $op(self, other: Dynamic) -> Dynamic {
Dynamic::new($op_path(self.value(), other.value))
fn $op(self, other: Dyn) -> Dyn {
Dyn($op_path(self.value(), other.value()))
}
}
@ -198,7 +213,12 @@ dim_ops!(
);
#[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>;
/// 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 {
type Const: DimName;
}
@ -273,14 +262,17 @@ pub trait ToTypenum {
}
unsafe impl<const T: usize> Dim for Const<T> {
#[inline]
fn try_to_usize() -> Option<usize> {
Some(T)
}
#[inline]
fn value(&self) -> usize {
T
}
#[inline]
fn from_usize(dim: usize) -> Self {
assert_eq!(dim, T);
Self
@ -324,6 +316,11 @@ macro_rules! from_to_typenum (
}
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;
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