commit
156f292917
|
@ -34,6 +34,8 @@ jobs:
|
||||||
run: cargo build --no-default-features;
|
run: cargo build --no-default-features;
|
||||||
- name: Build (default features)
|
- name: Build (default features)
|
||||||
run: cargo build;
|
run: cargo build;
|
||||||
|
- name: Build --features serde-serialize
|
||||||
|
run: cargo build --features serde-serialize
|
||||||
- name: Build --all-features
|
- name: Build --all-features
|
||||||
run: cargo build --all-features;
|
run: cargo build --all-features;
|
||||||
- name: Build nalgebra-glm
|
- name: Build nalgebra-glm
|
||||||
|
@ -55,7 +57,7 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: test nalgebra-glm
|
- name: test nalgebra-glm
|
||||||
run: cargo test -p nalgebra-glm --features arbitrary,rand,serde-serialize,abomonation-serialize,sparse,debug,io,compare,libm,proptest-support,slow-tests;
|
run: cargo test -p nalgebra-glm --features arbitrary,serde-serialize,abomonation-serialize;
|
||||||
test-nalgebra-sparse:
|
test-nalgebra-sparse:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
44
CHANGELOG.md
44
CHANGELOG.md
|
@ -4,6 +4,50 @@ documented here.
|
||||||
|
|
||||||
This project adheres to [Semantic Versioning](https://semver.org/).
|
This project adheres to [Semantic Versioning](https://semver.org/).
|
||||||
|
|
||||||
|
## [0.26.0]
|
||||||
|
This releases integrates `min-const-generics` to nalgebra. See
|
||||||
|
[our blog post](https://dimforge.com/blog/2021/04/12/nalgebra-const-generics)
|
||||||
|
for details about this release.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Add type aliases for unit vector, e.g., `UnitVector3`.
|
||||||
|
- Add a `pow` and `pow_mut` function to square matrices.
|
||||||
|
- Add `Cholesky::determinant` to compute the determinant of a matrix decomposed
|
||||||
|
with Cholesky.
|
||||||
|
- Add the `serde-serialize-no-std` feature to enable serialization of static matrices/vectors
|
||||||
|
with serde, but without requiring `std`.
|
||||||
|
|
||||||
|
|
||||||
|
### Modified
|
||||||
|
- The `serde` crate isn't enabled by default now. Enable the `serde-serialize` or the
|
||||||
|
`serde-serialize-no-std` features instead.
|
||||||
|
- The `Const<const D: usize>` type has been introduced to represent dimensions known
|
||||||
|
at compile-time. This replaces the type-level integers from `typenum` as well as
|
||||||
|
the `U1, U2, ..., U127` types from `nalgebra`. These `U1, U2, ..., U127` are now
|
||||||
|
just aliases for `Const<D>`, e.g., `type U2 = Const<2>`.
|
||||||
|
- The `ArrayStorage` now uses a standard array `[[T; R]; C]` instead of a `GenericArray`.
|
||||||
|
- Many trait bounds were changed to accommodate const-generics. Most of these changes
|
||||||
|
should be transparent wrt. non-generic code.
|
||||||
|
- The `MatrixMN` alias has been deprecated. Use `OMatrix` or `SMatrix` instead.
|
||||||
|
- The `MatrixN<T, D>` alias has been deprecated. Use `OMatrix<T, D, D>` or `SMatrix` instead.
|
||||||
|
- The `VectorN<T, D>` alias has been deprecated. Use `OVector` or `SVector` instead.
|
||||||
|
- The `Point`, `Translation`, `Isometry`, `Similarity`, and `Transformation` types now take an
|
||||||
|
integer for their dimension (instead of a type-level integer).
|
||||||
|
- The type parameter order of `Isometry`, `Similarity`, `Transformation` changed to put
|
||||||
|
the integer dimensions in the last position (this is required by the compiler).
|
||||||
|
- The `::new` constructors of translations, points, matrices, and vectors of dimensions `<= 6`
|
||||||
|
are now `const fn`, making them usable to define constant globals. The `Quaternion::new`
|
||||||
|
constructor is also a `const fn` now.
|
||||||
|
|
||||||
|
## [0.25.4]
|
||||||
|
### Fixed
|
||||||
|
- Fix a compilation error when only the `serde-serialize` feature is enabled.
|
||||||
|
|
||||||
|
## [0.25.3]
|
||||||
|
### Added
|
||||||
|
- The `Vector::simd_cap_magnitude` method to cap the magnitude of the a vector with
|
||||||
|
SIMD components.
|
||||||
|
|
||||||
## [0.25.2]
|
## [0.25.2]
|
||||||
### Added
|
### Added
|
||||||
- A `convert-glam` cargo feature to enable implementations of `From` traits to convert
|
- A `convert-glam` cargo feature to enable implementations of `From` traits to convert
|
||||||
|
|
25
Cargo.toml
25
Cargo.toml
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "nalgebra"
|
name = "nalgebra"
|
||||||
version = "0.25.2"
|
version = "0.26.0"
|
||||||
authors = [ "Sébastien Crozet <developer@crozet.re>" ]
|
authors = [ "Sébastien Crozet <developer@crozet.re>" ]
|
||||||
|
|
||||||
description = "General-purpose linear algebra library with transformations and statically-sized or dynamically-sized matrices."
|
description = "General-purpose linear algebra library with transformations and statically-sized or dynamically-sized matrices."
|
||||||
|
@ -36,14 +36,21 @@ no_unsound_assume_init = [ ]
|
||||||
# Conversion
|
# Conversion
|
||||||
convert-mint = [ "mint" ]
|
convert-mint = [ "mint" ]
|
||||||
convert-glam = [ "glam" ]
|
convert-glam = [ "glam" ]
|
||||||
convert-glam-unchecked = [ "convert-glam" ] # Unable edgy conversions like Mat4 -> Isometry3
|
convert-glam-unchecked = [ "convert-glam" ] # Enable edgy conversions like Mat4 -> Isometry3
|
||||||
convert-bytemuck = [ "bytemuck" ]
|
convert-bytemuck = [ "bytemuck" ]
|
||||||
|
|
||||||
# Serialization
|
# Serialization
|
||||||
serde-serialize = [ "serde", "num-complex/serde" ]
|
## To use serde in a #[no-std] environment, enable the
|
||||||
|
## `serde-serialize-no-std` feature instead of `serde-serialize`.
|
||||||
|
## Serialization of dynamically-sized matrices/vectors require
|
||||||
|
## `serde-serialize`.
|
||||||
|
serde-serialize-no-std = [ "serde", "num-complex/serde" ]
|
||||||
|
serde-serialize = [ "serde-serialize-no-std", "serde/std" ]
|
||||||
abomonation-serialize = [ "abomonation" ]
|
abomonation-serialize = [ "abomonation" ]
|
||||||
|
|
||||||
# Randomness
|
# Randomness
|
||||||
|
## To use rand in a #[no-std] environment, enable the
|
||||||
|
## `rand-no-std` feature instead of `rand`.
|
||||||
rand-no-std = [ "rand-package" ]
|
rand-no-std = [ "rand-package" ]
|
||||||
rand = [ "rand-no-std", "rand-package/std", "rand-package/std_rng", "rand_distr" ]
|
rand = [ "rand-no-std", "rand-package/std", "rand-package/std_rng", "rand_distr" ]
|
||||||
|
|
||||||
|
@ -54,7 +61,6 @@ slow-tests = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
typenum = "1.12"
|
typenum = "1.12"
|
||||||
generic-array = "0.14"
|
|
||||||
rand-package = { package = "rand", version = "0.8", optional = true, default-features = false }
|
rand-package = { package = "rand", version = "0.8", optional = true, default-features = false }
|
||||||
num-traits = { version = "0.2", default-features = false }
|
num-traits = { version = "0.2", default-features = false }
|
||||||
num-complex = { version = "0.3", default-features = false }
|
num-complex = { version = "0.3", default-features = false }
|
||||||
|
@ -79,11 +85,7 @@ proptest = { version = "1", optional = true, default-features = false, features
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
rand_xorshift = "0.3"
|
rand_xorshift = "0.3"
|
||||||
rand_isaac = "0.3"
|
rand_isaac = "0.3"
|
||||||
### Uncomment this line before running benchmarks.
|
criterion = "0.2.10"
|
||||||
### We can't just let this uncommented because that would break
|
|
||||||
### compilation for #[no-std] because of the terrible Cargo bug
|
|
||||||
### https://github.com/rust-lang/cargo/issues/4866
|
|
||||||
#criterion = "0.2.10"
|
|
||||||
|
|
||||||
# For matrix comparison macro
|
# For matrix comparison macro
|
||||||
matrixcompare = "0.2.0"
|
matrixcompare = "0.2.0"
|
||||||
|
@ -91,6 +93,11 @@ itertools = "0.10"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [ "nalgebra-lapack", "nalgebra-glm", "nalgebra-sparse" ]
|
members = [ "nalgebra-lapack", "nalgebra-glm", "nalgebra-sparse" ]
|
||||||
|
resolver = "2"
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "matrixcompare"
|
||||||
|
required-features = ["compare"]
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "nalgebra_bench"
|
name = "nalgebra_bench"
|
||||||
|
|
|
@ -30,10 +30,10 @@
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
|
||||||
## Gold sponsors
|
## Platinum sponsors
|
||||||
Rapier is supported by:
|
Rapier is supported by:
|
||||||
<p>
|
<p>
|
||||||
<a href="https://embark-studios.com">
|
<a href="https://embark-studios.com">
|
||||||
<img src="https://www.embark.dev/img/logo_black.png" width="301px">
|
<img src="https://www.embark.dev/img/logo_black.png" width="401px">
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -60,7 +60,7 @@ macro_rules! bench_unop_na(
|
||||||
i = (i + 1) & (LEN - 1);
|
i = (i + 1) & (LEN - 1);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
test::black_box(na::$unop(elems.get_unchecked(i)))
|
std::hint::black_box(na::$unop(elems.get_unchecked(i)))
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ macro_rules! bench_unop(
|
||||||
i = (i + 1) & (LEN - 1);
|
i = (i + 1) & (LEN - 1);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
test::black_box(elems.get_unchecked_mut(i).$unop())
|
std::hint::black_box(elems.get_unchecked_mut(i).$unop())
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ macro_rules! bench_construction(
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let res = $constructor($(*$args.get_unchecked(i),)*);
|
let res = $constructor($(*$args.get_unchecked(i),)*);
|
||||||
test::black_box(res)
|
std::hint::black_box(res)
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use na::{DMatrix, DVector, Matrix2, Matrix3, Matrix4, MatrixN, Vector2, Vector3, Vector4, U10};
|
use na::{DMatrix, DVector, Matrix2, Matrix3, Matrix4, OMatrix, Vector2, Vector3, Vector4, U10};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use rand_isaac::IsaacRng;
|
use rand_isaac::IsaacRng;
|
||||||
use std::ops::{Add, Div, Mul, Sub};
|
use std::ops::{Add, Div, Mul, Sub};
|
||||||
|
@ -116,8 +116,8 @@ fn mat10_mul_mat10(bench: &mut criterion::Criterion) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mat10_mul_mat10_static(bench: &mut criterion::Criterion) {
|
fn mat10_mul_mat10_static(bench: &mut criterion::Criterion) {
|
||||||
let a = MatrixN::<f64, U10>::new_random();
|
let a = OMatrix::<f64, U10, U10>::new_random();
|
||||||
let b = MatrixN::<f64, U10>::new_random();
|
let b = OMatrix::<f64, U10, U10>::new_random();
|
||||||
|
|
||||||
bench.bench_function("mat10_mul_mat10_static", move |bh| bh.iter(|| &a * &b));
|
bench.bench_function("mat10_mul_mat10_static", move |bh| bh.iter(|| &a * &b));
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ fn mat_mul_mat(bench: &mut criterion::Criterion) {
|
||||||
|
|
||||||
bench.bench_function("mat_mul_mat", move |bh| {
|
bench.bench_function("mat_mul_mat", move |bh| {
|
||||||
bh.iter(|| {
|
bh.iter(|| {
|
||||||
test::black_box(a.mul_to(&b, &mut ab));
|
std::hint::black_box(a.mul_to(&b, &mut ab));
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use na::{DVector, Vector2, Vector3, Vector4, VectorN};
|
use na::{DVector, SVector, Vector2, Vector3, Vector4};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use rand_isaac::IsaacRng;
|
use rand_isaac::IsaacRng;
|
||||||
use std::ops::{Add, Div, Mul, Sub};
|
use std::ops::{Add, Div, Mul, Sub};
|
||||||
use typenum::U10000;
|
|
||||||
|
|
||||||
#[path = "../common/macros.rs"]
|
#[path = "../common/macros.rs"]
|
||||||
mod macros;
|
mod macros;
|
||||||
|
@ -45,8 +44,8 @@ bench_unop!(vec2_normalize, Vector2<f32>, normalize);
|
||||||
bench_unop!(vec3_normalize, Vector3<f32>, normalize);
|
bench_unop!(vec3_normalize, Vector3<f32>, normalize);
|
||||||
bench_unop!(vec4_normalize, Vector4<f32>, normalize);
|
bench_unop!(vec4_normalize, Vector4<f32>, normalize);
|
||||||
|
|
||||||
bench_binop_ref!(vec10000_dot_f64, VectorN<f64, U10000>, VectorN<f64, U10000>, dot);
|
bench_binop_ref!(vec10000_dot_f64, SVector<f64, 10000>, SVector<f64, 10000>, dot);
|
||||||
bench_binop_ref!(vec10000_dot_f32, VectorN<f32, U10000>, VectorN<f32, U10000>, dot);
|
bench_binop_ref!(vec10000_dot_f32, SVector<f32, 10000>, SVector<f32, 10000>, dot);
|
||||||
|
|
||||||
fn vec10000_axpy_f64(bh: &mut criterion::Criterion) {
|
fn vec10000_axpy_f64(bh: &mut criterion::Criterion) {
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
|
@ -82,8 +81,8 @@ fn vec10000_axpy_f64_slice(bh: &mut criterion::Criterion) {
|
||||||
|
|
||||||
bh.bench_function("vec10000_axpy_f64_slice", move |bh| {
|
bh.bench_function("vec10000_axpy_f64_slice", move |bh| {
|
||||||
bh.iter(|| {
|
bh.iter(|| {
|
||||||
let mut a = a.fixed_rows_mut::<U10000>(0);
|
let mut a = a.fixed_rows_mut::<10000>(0);
|
||||||
let b = b.fixed_rows::<U10000>(0);
|
let b = b.fixed_rows::<10000>(0);
|
||||||
|
|
||||||
a.axpy(n, &b, 1.0)
|
a.axpy(n, &b, 1.0)
|
||||||
})
|
})
|
||||||
|
@ -93,11 +92,11 @@ fn vec10000_axpy_f64_slice(bh: &mut criterion::Criterion) {
|
||||||
fn vec10000_axpy_f64_static(bh: &mut criterion::Criterion) {
|
fn vec10000_axpy_f64_static(bh: &mut criterion::Criterion) {
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
let mut rng = IsaacRng::seed_from_u64(0);
|
let mut rng = IsaacRng::seed_from_u64(0);
|
||||||
let mut a = VectorN::<f64, U10000>::new_random();
|
let mut a = SVector::<f64, 10000>::new_random();
|
||||||
let b = VectorN::<f64, U10000>::new_random();
|
let b = SVector::<f64, 10000>::new_random();
|
||||||
let n = rng.gen::<f64>();
|
let n = rng.gen::<f64>();
|
||||||
|
|
||||||
// NOTE: for some reasons, it is much faster if the arument are boxed (Box::new(VectorN...)).
|
// NOTE: for some reasons, it is much faster if the arument are boxed (Box::new(OVector...)).
|
||||||
bh.bench_function("vec10000_axpy_f64_static", move |bh| {
|
bh.bench_function("vec10000_axpy_f64_static", move |bh| {
|
||||||
bh.iter(|| a.axpy(n, &b, 1.0))
|
bh.iter(|| a.axpy(n, &b, 1.0))
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,10 +2,7 @@
|
||||||
#![allow(unused_macros)]
|
#![allow(unused_macros)]
|
||||||
|
|
||||||
extern crate nalgebra as na;
|
extern crate nalgebra as na;
|
||||||
extern crate rand;
|
extern crate rand_package as rand;
|
||||||
extern crate rand_isaac;
|
|
||||||
extern crate test;
|
|
||||||
extern crate typenum;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate criterion;
|
extern crate criterion;
|
||||||
|
|
|
@ -7,35 +7,35 @@ mod macros;
|
||||||
fn bidiagonalize_100x100(bh: &mut criterion::Criterion) {
|
fn bidiagonalize_100x100(bh: &mut criterion::Criterion) {
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
bh.bench_function("bidiagonalize_100x100", move |bh| {
|
bh.bench_function("bidiagonalize_100x100", move |bh| {
|
||||||
bh.iter(|| test::black_box(Bidiagonal::new(m.clone())))
|
bh.iter(|| std::hint::black_box(Bidiagonal::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bidiagonalize_100x500(bh: &mut criterion::Criterion) {
|
fn bidiagonalize_100x500(bh: &mut criterion::Criterion) {
|
||||||
let m = DMatrix::<f64>::new_random(100, 500);
|
let m = DMatrix::<f64>::new_random(100, 500);
|
||||||
bh.bench_function("bidiagonalize_100x500", move |bh| {
|
bh.bench_function("bidiagonalize_100x500", move |bh| {
|
||||||
bh.iter(|| test::black_box(Bidiagonal::new(m.clone())))
|
bh.iter(|| std::hint::black_box(Bidiagonal::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bidiagonalize_4x4(bh: &mut criterion::Criterion) {
|
fn bidiagonalize_4x4(bh: &mut criterion::Criterion) {
|
||||||
let m = Matrix4::<f64>::new_random();
|
let m = Matrix4::<f64>::new_random();
|
||||||
bh.bench_function("bidiagonalize_4x4", move |bh| {
|
bh.bench_function("bidiagonalize_4x4", move |bh| {
|
||||||
bh.iter(|| test::black_box(Bidiagonal::new(m.clone())))
|
bh.iter(|| std::hint::black_box(Bidiagonal::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bidiagonalize_500x100(bh: &mut criterion::Criterion) {
|
fn bidiagonalize_500x100(bh: &mut criterion::Criterion) {
|
||||||
let m = DMatrix::<f64>::new_random(500, 100);
|
let m = DMatrix::<f64>::new_random(500, 100);
|
||||||
bh.bench_function("bidiagonalize_500x100", move |bh| {
|
bh.bench_function("bidiagonalize_500x100", move |bh| {
|
||||||
bh.iter(|| test::black_box(Bidiagonal::new(m.clone())))
|
bh.iter(|| std::hint::black_box(Bidiagonal::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bidiagonalize_500x500(bh: &mut criterion::Criterion) {
|
fn bidiagonalize_500x500(bh: &mut criterion::Criterion) {
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
bh.bench_function("bidiagonalize_500x500", move |bh| {
|
bh.bench_function("bidiagonalize_500x500", move |bh| {
|
||||||
bh.iter(|| test::black_box(Bidiagonal::new(m.clone())))
|
bh.iter(|| std::hint::black_box(Bidiagonal::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ fn cholesky_100x100(bh: &mut criterion::Criterion) {
|
||||||
let m = &m * m.transpose();
|
let m = &m * m.transpose();
|
||||||
|
|
||||||
bh.bench_function("cholesky_100x100", move |bh| {
|
bh.bench_function("cholesky_100x100", move |bh| {
|
||||||
bh.iter(|| test::black_box(Cholesky::new(m.clone())))
|
bh.iter(|| std::hint::black_box(Cholesky::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ fn cholesky_500x500(bh: &mut criterion::Criterion) {
|
||||||
let m = &m * m.transpose();
|
let m = &m * m.transpose();
|
||||||
|
|
||||||
bh.bench_function("cholesky_500x500", move |bh| {
|
bh.bench_function("cholesky_500x500", move |bh| {
|
||||||
bh.iter(|| test::black_box(Cholesky::new(m.clone())))
|
bh.iter(|| std::hint::black_box(Cholesky::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,21 +4,21 @@ use na::{DMatrix, DVector, FullPivLU};
|
||||||
fn full_piv_lu_decompose_10x10(bh: &mut criterion::Criterion) {
|
fn full_piv_lu_decompose_10x10(bh: &mut criterion::Criterion) {
|
||||||
let m = DMatrix::<f64>::new_random(10, 10);
|
let m = DMatrix::<f64>::new_random(10, 10);
|
||||||
bh.bench_function("full_piv_lu_decompose_10x10", move |bh| {
|
bh.bench_function("full_piv_lu_decompose_10x10", move |bh| {
|
||||||
bh.iter(|| test::black_box(FullPivLU::new(m.clone())))
|
bh.iter(|| std::hint::black_box(FullPivLU::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn full_piv_lu_decompose_100x100(bh: &mut criterion::Criterion) {
|
fn full_piv_lu_decompose_100x100(bh: &mut criterion::Criterion) {
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
bh.bench_function("full_piv_lu_decompose_100x100", move |bh| {
|
bh.bench_function("full_piv_lu_decompose_100x100", move |bh| {
|
||||||
bh.iter(|| test::black_box(FullPivLU::new(m.clone())))
|
bh.iter(|| std::hint::black_box(FullPivLU::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn full_piv_lu_decompose_500x500(bh: &mut criterion::Criterion) {
|
fn full_piv_lu_decompose_500x500(bh: &mut criterion::Criterion) {
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
bh.bench_function("full_piv_lu_decompose_500x500", move |bh| {
|
bh.bench_function("full_piv_lu_decompose_500x500", move |bh| {
|
||||||
bh.iter(|| test::black_box(FullPivLU::new(m.clone())))
|
bh.iter(|| std::hint::black_box(FullPivLU::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ fn full_piv_lu_inverse_10x10(bh: &mut criterion::Criterion) {
|
||||||
let lu = FullPivLU::new(m.clone());
|
let lu = FullPivLU::new(m.clone());
|
||||||
|
|
||||||
bh.bench_function("full_piv_lu_inverse_10x10", move |bh| {
|
bh.bench_function("full_piv_lu_inverse_10x10", move |bh| {
|
||||||
bh.iter(|| test::black_box(lu.try_inverse()))
|
bh.iter(|| std::hint::black_box(lu.try_inverse()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ fn full_piv_lu_inverse_100x100(bh: &mut criterion::Criterion) {
|
||||||
let lu = FullPivLU::new(m.clone());
|
let lu = FullPivLU::new(m.clone());
|
||||||
|
|
||||||
bh.bench_function("full_piv_lu_inverse_100x100", move |bh| {
|
bh.bench_function("full_piv_lu_inverse_100x100", move |bh| {
|
||||||
bh.iter(|| test::black_box(lu.try_inverse()))
|
bh.iter(|| std::hint::black_box(lu.try_inverse()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ fn full_piv_lu_inverse_500x500(bh: &mut criterion::Criterion) {
|
||||||
let lu = FullPivLU::new(m.clone());
|
let lu = FullPivLU::new(m.clone());
|
||||||
|
|
||||||
bh.bench_function("full_piv_lu_inverse_500x500", move |bh| {
|
bh.bench_function("full_piv_lu_inverse_500x500", move |bh| {
|
||||||
bh.iter(|| test::black_box(lu.try_inverse()))
|
bh.iter(|| std::hint::black_box(lu.try_inverse()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ fn full_piv_lu_determinant_10x10(bh: &mut criterion::Criterion) {
|
||||||
let lu = FullPivLU::new(m.clone());
|
let lu = FullPivLU::new(m.clone());
|
||||||
|
|
||||||
bh.bench_function("full_piv_lu_determinant_10x10", move |bh| {
|
bh.bench_function("full_piv_lu_determinant_10x10", move |bh| {
|
||||||
bh.iter(|| test::black_box(lu.determinant()))
|
bh.iter(|| std::hint::black_box(lu.determinant()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ fn full_piv_lu_determinant_100x100(bh: &mut criterion::Criterion) {
|
||||||
let lu = FullPivLU::new(m.clone());
|
let lu = FullPivLU::new(m.clone());
|
||||||
|
|
||||||
bh.bench_function("full_piv_lu_determinant_100x100", move |bh| {
|
bh.bench_function("full_piv_lu_determinant_100x100", move |bh| {
|
||||||
bh.iter(|| test::black_box(lu.determinant()))
|
bh.iter(|| std::hint::black_box(lu.determinant()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ fn full_piv_lu_determinant_500x500(bh: &mut criterion::Criterion) {
|
||||||
let lu = FullPivLU::new(m.clone());
|
let lu = FullPivLU::new(m.clone());
|
||||||
|
|
||||||
bh.bench_function("full_piv_lu_determinant_500x500", move |bh| {
|
bh.bench_function("full_piv_lu_determinant_500x500", move |bh| {
|
||||||
bh.iter(|| test::black_box(lu.determinant()))
|
bh.iter(|| std::hint::black_box(lu.determinant()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,28 +7,28 @@ mod macros;
|
||||||
fn hessenberg_decompose_4x4(bh: &mut criterion::Criterion) {
|
fn hessenberg_decompose_4x4(bh: &mut criterion::Criterion) {
|
||||||
let m = Matrix4::<f64>::new_random();
|
let m = Matrix4::<f64>::new_random();
|
||||||
bh.bench_function("hessenberg_decompose_4x4", move |bh| {
|
bh.bench_function("hessenberg_decompose_4x4", move |bh| {
|
||||||
bh.iter(|| test::black_box(Hessenberg::new(m.clone())))
|
bh.iter(|| std::hint::black_box(Hessenberg::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hessenberg_decompose_100x100(bh: &mut criterion::Criterion) {
|
fn hessenberg_decompose_100x100(bh: &mut criterion::Criterion) {
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
bh.bench_function("hessenberg_decompose_100x100", move |bh| {
|
bh.bench_function("hessenberg_decompose_100x100", move |bh| {
|
||||||
bh.iter(|| test::black_box(Hessenberg::new(m.clone())))
|
bh.iter(|| std::hint::black_box(Hessenberg::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hessenberg_decompose_200x200(bh: &mut criterion::Criterion) {
|
fn hessenberg_decompose_200x200(bh: &mut criterion::Criterion) {
|
||||||
let m = DMatrix::<f64>::new_random(200, 200);
|
let m = DMatrix::<f64>::new_random(200, 200);
|
||||||
bh.bench_function("hessenberg_decompose_200x200", move |bh| {
|
bh.bench_function("hessenberg_decompose_200x200", move |bh| {
|
||||||
bh.iter(|| test::black_box(Hessenberg::new(m.clone())))
|
bh.iter(|| std::hint::black_box(Hessenberg::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hessenberg_decompose_500x500(bh: &mut criterion::Criterion) {
|
fn hessenberg_decompose_500x500(bh: &mut criterion::Criterion) {
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
bh.bench_function("hessenberg_decompose_500x500", move |bh| {
|
bh.bench_function("hessenberg_decompose_500x500", move |bh| {
|
||||||
bh.iter(|| test::black_box(Hessenberg::new(m.clone())))
|
bh.iter(|| std::hint::black_box(Hessenberg::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,21 +4,21 @@ use na::{DMatrix, DVector, LU};
|
||||||
fn lu_decompose_10x10(bh: &mut criterion::Criterion) {
|
fn lu_decompose_10x10(bh: &mut criterion::Criterion) {
|
||||||
let m = DMatrix::<f64>::new_random(10, 10);
|
let m = DMatrix::<f64>::new_random(10, 10);
|
||||||
bh.bench_function("lu_decompose_10x10", move |bh| {
|
bh.bench_function("lu_decompose_10x10", move |bh| {
|
||||||
bh.iter(|| test::black_box(LU::new(m.clone())))
|
bh.iter(|| std::hint::black_box(LU::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lu_decompose_100x100(bh: &mut criterion::Criterion) {
|
fn lu_decompose_100x100(bh: &mut criterion::Criterion) {
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
bh.bench_function("lu_decompose_100x100", move |bh| {
|
bh.bench_function("lu_decompose_100x100", move |bh| {
|
||||||
bh.iter(|| test::black_box(LU::new(m.clone())))
|
bh.iter(|| std::hint::black_box(LU::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lu_decompose_500x500(bh: &mut criterion::Criterion) {
|
fn lu_decompose_500x500(bh: &mut criterion::Criterion) {
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
bh.bench_function("lu_decompose_500x500", move |bh| {
|
bh.bench_function("lu_decompose_500x500", move |bh| {
|
||||||
bh.iter(|| test::black_box(LU::new(m.clone())))
|
bh.iter(|| std::hint::black_box(LU::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ fn lu_inverse_10x10(bh: &mut criterion::Criterion) {
|
||||||
let lu = LU::new(m.clone());
|
let lu = LU::new(m.clone());
|
||||||
|
|
||||||
bh.bench_function("lu_inverse_10x10", move |bh| {
|
bh.bench_function("lu_inverse_10x10", move |bh| {
|
||||||
bh.iter(|| test::black_box(lu.try_inverse()))
|
bh.iter(|| std::hint::black_box(lu.try_inverse()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ fn lu_inverse_100x100(bh: &mut criterion::Criterion) {
|
||||||
let lu = LU::new(m.clone());
|
let lu = LU::new(m.clone());
|
||||||
|
|
||||||
bh.bench_function("lu_inverse_100x100", move |bh| {
|
bh.bench_function("lu_inverse_100x100", move |bh| {
|
||||||
bh.iter(|| test::black_box(lu.try_inverse()))
|
bh.iter(|| std::hint::black_box(lu.try_inverse()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ fn lu_inverse_500x500(bh: &mut criterion::Criterion) {
|
||||||
let lu = LU::new(m.clone());
|
let lu = LU::new(m.clone());
|
||||||
|
|
||||||
bh.bench_function("lu_inverse_500x500", move |bh| {
|
bh.bench_function("lu_inverse_500x500", move |bh| {
|
||||||
bh.iter(|| test::black_box(lu.try_inverse()))
|
bh.iter(|| std::hint::black_box(lu.try_inverse()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ fn lu_determinant_10x10(bh: &mut criterion::Criterion) {
|
||||||
let lu = LU::new(m.clone());
|
let lu = LU::new(m.clone());
|
||||||
|
|
||||||
bh.bench_function("lu_determinant_10x10", move |bh| {
|
bh.bench_function("lu_determinant_10x10", move |bh| {
|
||||||
bh.iter(|| test::black_box(lu.determinant()))
|
bh.iter(|| std::hint::black_box(lu.determinant()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ fn lu_determinant_100x100(bh: &mut criterion::Criterion) {
|
||||||
let lu = LU::new(m.clone());
|
let lu = LU::new(m.clone());
|
||||||
|
|
||||||
bh.bench_function("lu_determinant_100x100", move |bh| {
|
bh.bench_function("lu_determinant_100x100", move |bh| {
|
||||||
bh.iter(|| test::black_box(lu.determinant()))
|
bh.iter(|| std::hint::black_box(lu.determinant()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +107,9 @@ fn lu_determinant_500x500(bh: &mut criterion::Criterion) {
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
let lu = LU::new(m.clone());
|
let lu = LU::new(m.clone());
|
||||||
|
|
||||||
bh.bench_function("", move |bh| bh.iter(|| test::black_box(lu.determinant())));
|
bh.bench_function("", move |bh| {
|
||||||
|
bh.iter(|| std::hint::black_box(lu.determinant()))
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
criterion_group!(
|
criterion_group!(
|
||||||
|
|
|
@ -7,35 +7,35 @@ mod macros;
|
||||||
fn qr_decompose_100x100(bh: &mut criterion::Criterion) {
|
fn qr_decompose_100x100(bh: &mut criterion::Criterion) {
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
bh.bench_function("qr_decompose_100x100", move |bh| {
|
bh.bench_function("qr_decompose_100x100", move |bh| {
|
||||||
bh.iter(|| test::black_box(QR::new(m.clone())))
|
bh.iter(|| std::hint::black_box(QR::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn qr_decompose_100x500(bh: &mut criterion::Criterion) {
|
fn qr_decompose_100x500(bh: &mut criterion::Criterion) {
|
||||||
let m = DMatrix::<f64>::new_random(100, 500);
|
let m = DMatrix::<f64>::new_random(100, 500);
|
||||||
bh.bench_function("qr_decompose_100x500", move |bh| {
|
bh.bench_function("qr_decompose_100x500", move |bh| {
|
||||||
bh.iter(|| test::black_box(QR::new(m.clone())))
|
bh.iter(|| std::hint::black_box(QR::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn qr_decompose_4x4(bh: &mut criterion::Criterion) {
|
fn qr_decompose_4x4(bh: &mut criterion::Criterion) {
|
||||||
let m = Matrix4::<f64>::new_random();
|
let m = Matrix4::<f64>::new_random();
|
||||||
bh.bench_function("qr_decompose_4x4", move |bh| {
|
bh.bench_function("qr_decompose_4x4", move |bh| {
|
||||||
bh.iter(|| test::black_box(QR::new(m.clone())))
|
bh.iter(|| std::hint::black_box(QR::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn qr_decompose_500x100(bh: &mut criterion::Criterion) {
|
fn qr_decompose_500x100(bh: &mut criterion::Criterion) {
|
||||||
let m = DMatrix::<f64>::new_random(500, 100);
|
let m = DMatrix::<f64>::new_random(500, 100);
|
||||||
bh.bench_function("qr_decompose_500x100", move |bh| {
|
bh.bench_function("qr_decompose_500x100", move |bh| {
|
||||||
bh.iter(|| test::black_box(QR::new(m.clone())))
|
bh.iter(|| std::hint::black_box(QR::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn qr_decompose_500x500(bh: &mut criterion::Criterion) {
|
fn qr_decompose_500x500(bh: &mut criterion::Criterion) {
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
bh.bench_function("qr_decompose_500x500", move |bh| {
|
bh.bench_function("qr_decompose_500x500", move |bh| {
|
||||||
bh.iter(|| test::black_box(QR::new(m.clone())))
|
bh.iter(|| std::hint::black_box(QR::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ fn qr_inverse_10x10(bh: &mut criterion::Criterion) {
|
||||||
let qr = QR::new(m.clone());
|
let qr = QR::new(m.clone());
|
||||||
|
|
||||||
bh.bench_function("qr_inverse_10x10", move |bh| {
|
bh.bench_function("qr_inverse_10x10", move |bh| {
|
||||||
bh.iter(|| test::black_box(qr.try_inverse()))
|
bh.iter(|| std::hint::black_box(qr.try_inverse()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ fn qr_inverse_100x100(bh: &mut criterion::Criterion) {
|
||||||
let qr = QR::new(m.clone());
|
let qr = QR::new(m.clone());
|
||||||
|
|
||||||
bh.bench_function("qr_inverse_100x100", move |bh| {
|
bh.bench_function("qr_inverse_100x100", move |bh| {
|
||||||
bh.iter(|| test::black_box(qr.try_inverse()))
|
bh.iter(|| std::hint::black_box(qr.try_inverse()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ fn qr_inverse_500x500(bh: &mut criterion::Criterion) {
|
||||||
let qr = QR::new(m.clone());
|
let qr = QR::new(m.clone());
|
||||||
|
|
||||||
bh.bench_function("qr_inverse_500x500", move |bh| {
|
bh.bench_function("qr_inverse_500x500", move |bh| {
|
||||||
bh.iter(|| test::black_box(qr.try_inverse()))
|
bh.iter(|| std::hint::black_box(qr.try_inverse()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,56 +3,56 @@ use na::{Matrix4, Schur};
|
||||||
fn schur_decompose_4x4(bh: &mut criterion::Criterion) {
|
fn schur_decompose_4x4(bh: &mut criterion::Criterion) {
|
||||||
let m = Matrix4::<f64>::new_random();
|
let m = Matrix4::<f64>::new_random();
|
||||||
bh.bench_function("schur_decompose_4x4", move |bh| {
|
bh.bench_function("schur_decompose_4x4", move |bh| {
|
||||||
bh.iter(|| test::black_box(Schur::new(m.clone())))
|
bh.iter(|| std::hint::black_box(Schur::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn schur_decompose_10x10(bh: &mut criterion::Criterion) {
|
fn schur_decompose_10x10(bh: &mut criterion::Criterion) {
|
||||||
let m = crate::reproductible_dmatrix(10, 10);
|
let m = crate::reproductible_dmatrix(10, 10);
|
||||||
bh.bench_function("schur_decompose_10x10", move |bh| {
|
bh.bench_function("schur_decompose_10x10", move |bh| {
|
||||||
bh.iter(|| test::black_box(Schur::new(m.clone())))
|
bh.iter(|| std::hint::black_box(Schur::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn schur_decompose_100x100(bh: &mut criterion::Criterion) {
|
fn schur_decompose_100x100(bh: &mut criterion::Criterion) {
|
||||||
let m = crate::reproductible_dmatrix(100, 100);
|
let m = crate::reproductible_dmatrix(100, 100);
|
||||||
bh.bench_function("schur_decompose_100x100", move |bh| {
|
bh.bench_function("schur_decompose_100x100", move |bh| {
|
||||||
bh.iter(|| test::black_box(Schur::new(m.clone())))
|
bh.iter(|| std::hint::black_box(Schur::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn schur_decompose_200x200(bh: &mut criterion::Criterion) {
|
fn schur_decompose_200x200(bh: &mut criterion::Criterion) {
|
||||||
let m = crate::reproductible_dmatrix(200, 200);
|
let m = crate::reproductible_dmatrix(200, 200);
|
||||||
bh.bench_function("schur_decompose_200x200", move |bh| {
|
bh.bench_function("schur_decompose_200x200", move |bh| {
|
||||||
bh.iter(|| test::black_box(Schur::new(m.clone())))
|
bh.iter(|| std::hint::black_box(Schur::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eigenvalues_4x4(bh: &mut criterion::Criterion) {
|
fn eigenvalues_4x4(bh: &mut criterion::Criterion) {
|
||||||
let m = Matrix4::<f64>::new_random();
|
let m = Matrix4::<f64>::new_random();
|
||||||
bh.bench_function("eigenvalues_4x4", move |bh| {
|
bh.bench_function("eigenvalues_4x4", move |bh| {
|
||||||
bh.iter(|| test::black_box(m.complex_eigenvalues()))
|
bh.iter(|| std::hint::black_box(m.complex_eigenvalues()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eigenvalues_10x10(bh: &mut criterion::Criterion) {
|
fn eigenvalues_10x10(bh: &mut criterion::Criterion) {
|
||||||
let m = crate::reproductible_dmatrix(10, 10);
|
let m = crate::reproductible_dmatrix(10, 10);
|
||||||
bh.bench_function("eigenvalues_10x10", move |bh| {
|
bh.bench_function("eigenvalues_10x10", move |bh| {
|
||||||
bh.iter(|| test::black_box(m.complex_eigenvalues()))
|
bh.iter(|| std::hint::black_box(m.complex_eigenvalues()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eigenvalues_100x100(bh: &mut criterion::Criterion) {
|
fn eigenvalues_100x100(bh: &mut criterion::Criterion) {
|
||||||
let m = crate::reproductible_dmatrix(100, 100);
|
let m = crate::reproductible_dmatrix(100, 100);
|
||||||
bh.bench_function("eigenvalues_100x100", move |bh| {
|
bh.bench_function("eigenvalues_100x100", move |bh| {
|
||||||
bh.iter(|| test::black_box(m.complex_eigenvalues()))
|
bh.iter(|| std::hint::black_box(m.complex_eigenvalues()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eigenvalues_200x200(bh: &mut criterion::Criterion) {
|
fn eigenvalues_200x200(bh: &mut criterion::Criterion) {
|
||||||
let m = crate::reproductible_dmatrix(200, 200);
|
let m = crate::reproductible_dmatrix(200, 200);
|
||||||
bh.bench_function("eigenvalues_200x200", move |bh| {
|
bh.bench_function("eigenvalues_200x200", move |bh| {
|
||||||
bh.iter(|| test::black_box(m.complex_eigenvalues()))
|
bh.iter(|| std::hint::black_box(m.complex_eigenvalues()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,112 +3,112 @@ use na::{Matrix4, SVD};
|
||||||
fn svd_decompose_4x4(bh: &mut criterion::Criterion) {
|
fn svd_decompose_4x4(bh: &mut criterion::Criterion) {
|
||||||
let m = Matrix4::<f64>::new_random();
|
let m = Matrix4::<f64>::new_random();
|
||||||
bh.bench_function("svd_decompose_4x4", move |bh| {
|
bh.bench_function("svd_decompose_4x4", move |bh| {
|
||||||
bh.iter(|| test::black_box(SVD::new(m.clone(), true, true)))
|
bh.iter(|| std::hint::black_box(SVD::new(m.clone(), true, true)))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn svd_decompose_10x10(bh: &mut criterion::Criterion) {
|
fn svd_decompose_10x10(bh: &mut criterion::Criterion) {
|
||||||
let m = crate::reproductible_dmatrix(10, 10);
|
let m = crate::reproductible_dmatrix(10, 10);
|
||||||
bh.bench_function("svd_decompose_10x10", move |bh| {
|
bh.bench_function("svd_decompose_10x10", move |bh| {
|
||||||
bh.iter(|| test::black_box(SVD::new(m.clone(), true, true)))
|
bh.iter(|| std::hint::black_box(SVD::new(m.clone(), true, true)))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn svd_decompose_100x100(bh: &mut criterion::Criterion) {
|
fn svd_decompose_100x100(bh: &mut criterion::Criterion) {
|
||||||
let m = crate::reproductible_dmatrix(100, 100);
|
let m = crate::reproductible_dmatrix(100, 100);
|
||||||
bh.bench_function("svd_decompose_100x100", move |bh| {
|
bh.bench_function("svd_decompose_100x100", move |bh| {
|
||||||
bh.iter(|| test::black_box(SVD::new(m.clone(), true, true)))
|
bh.iter(|| std::hint::black_box(SVD::new(m.clone(), true, true)))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn svd_decompose_200x200(bh: &mut criterion::Criterion) {
|
fn svd_decompose_200x200(bh: &mut criterion::Criterion) {
|
||||||
let m = crate::reproductible_dmatrix(200, 200);
|
let m = crate::reproductible_dmatrix(200, 200);
|
||||||
bh.bench_function("svd_decompose_200x200", move |bh| {
|
bh.bench_function("svd_decompose_200x200", move |bh| {
|
||||||
bh.iter(|| test::black_box(SVD::new(m.clone(), true, true)))
|
bh.iter(|| std::hint::black_box(SVD::new(m.clone(), true, true)))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rank_4x4(bh: &mut criterion::Criterion) {
|
fn rank_4x4(bh: &mut criterion::Criterion) {
|
||||||
let m = Matrix4::<f64>::new_random();
|
let m = Matrix4::<f64>::new_random();
|
||||||
bh.bench_function("rank_4x4", move |bh| {
|
bh.bench_function("rank_4x4", move |bh| {
|
||||||
bh.iter(|| test::black_box(m.rank(1.0e-10)))
|
bh.iter(|| std::hint::black_box(m.rank(1.0e-10)))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rank_10x10(bh: &mut criterion::Criterion) {
|
fn rank_10x10(bh: &mut criterion::Criterion) {
|
||||||
let m = crate::reproductible_dmatrix(10, 10);
|
let m = crate::reproductible_dmatrix(10, 10);
|
||||||
bh.bench_function("rank_10x10", move |bh| {
|
bh.bench_function("rank_10x10", move |bh| {
|
||||||
bh.iter(|| test::black_box(m.rank(1.0e-10)))
|
bh.iter(|| std::hint::black_box(m.rank(1.0e-10)))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rank_100x100(bh: &mut criterion::Criterion) {
|
fn rank_100x100(bh: &mut criterion::Criterion) {
|
||||||
let m = crate::reproductible_dmatrix(100, 100);
|
let m = crate::reproductible_dmatrix(100, 100);
|
||||||
bh.bench_function("rank_100x100", move |bh| {
|
bh.bench_function("rank_100x100", move |bh| {
|
||||||
bh.iter(|| test::black_box(m.rank(1.0e-10)))
|
bh.iter(|| std::hint::black_box(m.rank(1.0e-10)))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rank_200x200(bh: &mut criterion::Criterion) {
|
fn rank_200x200(bh: &mut criterion::Criterion) {
|
||||||
let m = crate::reproductible_dmatrix(200, 200);
|
let m = crate::reproductible_dmatrix(200, 200);
|
||||||
bh.bench_function("rank_200x200", move |bh| {
|
bh.bench_function("rank_200x200", move |bh| {
|
||||||
bh.iter(|| test::black_box(m.rank(1.0e-10)))
|
bh.iter(|| std::hint::black_box(m.rank(1.0e-10)))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn singular_values_4x4(bh: &mut criterion::Criterion) {
|
fn singular_values_4x4(bh: &mut criterion::Criterion) {
|
||||||
let m = Matrix4::<f64>::new_random();
|
let m = Matrix4::<f64>::new_random();
|
||||||
bh.bench_function("singular_values_4x4", move |bh| {
|
bh.bench_function("singular_values_4x4", move |bh| {
|
||||||
bh.iter(|| test::black_box(m.singular_values()))
|
bh.iter(|| std::hint::black_box(m.singular_values()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn singular_values_10x10(bh: &mut criterion::Criterion) {
|
fn singular_values_10x10(bh: &mut criterion::Criterion) {
|
||||||
let m = crate::reproductible_dmatrix(10, 10);
|
let m = crate::reproductible_dmatrix(10, 10);
|
||||||
bh.bench_function("singular_values_10x10", move |bh| {
|
bh.bench_function("singular_values_10x10", move |bh| {
|
||||||
bh.iter(|| test::black_box(m.singular_values()))
|
bh.iter(|| std::hint::black_box(m.singular_values()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn singular_values_100x100(bh: &mut criterion::Criterion) {
|
fn singular_values_100x100(bh: &mut criterion::Criterion) {
|
||||||
let m = crate::reproductible_dmatrix(100, 100);
|
let m = crate::reproductible_dmatrix(100, 100);
|
||||||
bh.bench_function("singular_values_100x100", move |bh| {
|
bh.bench_function("singular_values_100x100", move |bh| {
|
||||||
bh.iter(|| test::black_box(m.singular_values()))
|
bh.iter(|| std::hint::black_box(m.singular_values()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn singular_values_200x200(bh: &mut criterion::Criterion) {
|
fn singular_values_200x200(bh: &mut criterion::Criterion) {
|
||||||
let m = crate::reproductible_dmatrix(200, 200);
|
let m = crate::reproductible_dmatrix(200, 200);
|
||||||
bh.bench_function("singular_values_200x200", move |bh| {
|
bh.bench_function("singular_values_200x200", move |bh| {
|
||||||
bh.iter(|| test::black_box(m.singular_values()))
|
bh.iter(|| std::hint::black_box(m.singular_values()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pseudo_inverse_4x4(bh: &mut criterion::Criterion) {
|
fn pseudo_inverse_4x4(bh: &mut criterion::Criterion) {
|
||||||
let m = Matrix4::<f64>::new_random();
|
let m = Matrix4::<f64>::new_random();
|
||||||
bh.bench_function("pseudo_inverse_4x4", move |bh| {
|
bh.bench_function("pseudo_inverse_4x4", move |bh| {
|
||||||
bh.iter(|| test::black_box(m.clone().pseudo_inverse(1.0e-10)))
|
bh.iter(|| std::hint::black_box(m.clone().pseudo_inverse(1.0e-10)))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pseudo_inverse_10x10(bh: &mut criterion::Criterion) {
|
fn pseudo_inverse_10x10(bh: &mut criterion::Criterion) {
|
||||||
let m = crate::reproductible_dmatrix(10, 10);
|
let m = crate::reproductible_dmatrix(10, 10);
|
||||||
bh.bench_function("pseudo_inverse_10x10", move |bh| {
|
bh.bench_function("pseudo_inverse_10x10", move |bh| {
|
||||||
bh.iter(|| test::black_box(m.clone().pseudo_inverse(1.0e-10)))
|
bh.iter(|| std::hint::black_box(m.clone().pseudo_inverse(1.0e-10)))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pseudo_inverse_100x100(bh: &mut criterion::Criterion) {
|
fn pseudo_inverse_100x100(bh: &mut criterion::Criterion) {
|
||||||
let m = crate::reproductible_dmatrix(100, 100);
|
let m = crate::reproductible_dmatrix(100, 100);
|
||||||
bh.bench_function("pseudo_inverse_100x100", move |bh| {
|
bh.bench_function("pseudo_inverse_100x100", move |bh| {
|
||||||
bh.iter(|| test::black_box(m.clone().pseudo_inverse(1.0e-10)))
|
bh.iter(|| std::hint::black_box(m.clone().pseudo_inverse(1.0e-10)))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pseudo_inverse_200x200(bh: &mut criterion::Criterion) {
|
fn pseudo_inverse_200x200(bh: &mut criterion::Criterion) {
|
||||||
let m = crate::reproductible_dmatrix(200, 200);
|
let m = crate::reproductible_dmatrix(200, 200);
|
||||||
bh.bench_function("pseudo_inverse_200x200", move |bh| {
|
bh.bench_function("pseudo_inverse_200x200", move |bh| {
|
||||||
bh.iter(|| test::black_box(m.clone().pseudo_inverse(1.0e-10)))
|
bh.iter(|| std::hint::black_box(m.clone().pseudo_inverse(1.0e-10)))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,28 +3,28 @@ use na::{Matrix4, SymmetricEigen};
|
||||||
fn symmetric_eigen_decompose_4x4(bh: &mut criterion::Criterion) {
|
fn symmetric_eigen_decompose_4x4(bh: &mut criterion::Criterion) {
|
||||||
let m = Matrix4::<f64>::new_random();
|
let m = Matrix4::<f64>::new_random();
|
||||||
bh.bench_function("symmetric_eigen_decompose_4x4", move |bh| {
|
bh.bench_function("symmetric_eigen_decompose_4x4", move |bh| {
|
||||||
bh.iter(|| test::black_box(SymmetricEigen::new(m.clone())))
|
bh.iter(|| std::hint::black_box(SymmetricEigen::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn symmetric_eigen_decompose_10x10(bh: &mut criterion::Criterion) {
|
fn symmetric_eigen_decompose_10x10(bh: &mut criterion::Criterion) {
|
||||||
let m = crate::reproductible_dmatrix(10, 10);
|
let m = crate::reproductible_dmatrix(10, 10);
|
||||||
bh.bench_function("symmetric_eigen_decompose_10x10", move |bh| {
|
bh.bench_function("symmetric_eigen_decompose_10x10", move |bh| {
|
||||||
bh.iter(|| test::black_box(SymmetricEigen::new(m.clone())))
|
bh.iter(|| std::hint::black_box(SymmetricEigen::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn symmetric_eigen_decompose_100x100(bh: &mut criterion::Criterion) {
|
fn symmetric_eigen_decompose_100x100(bh: &mut criterion::Criterion) {
|
||||||
let m = crate::reproductible_dmatrix(100, 100);
|
let m = crate::reproductible_dmatrix(100, 100);
|
||||||
bh.bench_function("symmetric_eigen_decompose_100x100", move |bh| {
|
bh.bench_function("symmetric_eigen_decompose_100x100", move |bh| {
|
||||||
bh.iter(|| test::black_box(SymmetricEigen::new(m.clone())))
|
bh.iter(|| std::hint::black_box(SymmetricEigen::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn symmetric_eigen_decompose_200x200(bh: &mut criterion::Criterion) {
|
fn symmetric_eigen_decompose_200x200(bh: &mut criterion::Criterion) {
|
||||||
let m = crate::reproductible_dmatrix(200, 200);
|
let m = crate::reproductible_dmatrix(200, 200);
|
||||||
bh.bench_function("symmetric_eigen_decompose_200x200", move |bh| {
|
bh.bench_function("symmetric_eigen_decompose_200x200", move |bh| {
|
||||||
bh.iter(|| test::black_box(SymmetricEigen::new(m.clone())))
|
bh.iter(|| std::hint::black_box(SymmetricEigen::new(m.clone())))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ version = "0.0.0"
|
||||||
authors = [ "You" ]
|
authors = [ "You" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nalgebra = "0.21.0"
|
nalgebra = "0.26.0"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "example"
|
name = "example"
|
||||||
|
|
|
@ -2,26 +2,26 @@ extern crate nalgebra as na;
|
||||||
|
|
||||||
use na::allocator::Allocator;
|
use na::allocator::Allocator;
|
||||||
use na::dimension::Dim;
|
use na::dimension::Dim;
|
||||||
use na::{DefaultAllocator, RealField, Unit, Vector2, Vector3, VectorN};
|
use na::{DefaultAllocator, OVector, RealField, Unit, Vector2, Vector3};
|
||||||
|
|
||||||
/// Reflects a vector wrt. the hyperplane with normal `plane_normal`.
|
/// Reflects a vector wrt. the hyperplane with normal `plane_normal`.
|
||||||
fn reflect_wrt_hyperplane_with_dimensional_genericity<N: RealField, D: Dim>(
|
fn reflect_wrt_hyperplane_with_dimensional_genericity<T: RealField, D: Dim>(
|
||||||
plane_normal: &Unit<VectorN<N, D>>,
|
plane_normal: &Unit<OVector<T, D>>,
|
||||||
vector: &VectorN<N, D>,
|
vector: &OVector<T, D>,
|
||||||
) -> VectorN<N, D>
|
) -> OVector<T, D>
|
||||||
where
|
where
|
||||||
N: RealField,
|
T: RealField,
|
||||||
D: Dim,
|
D: Dim,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
DefaultAllocator: Allocator<T, D>,
|
||||||
{
|
{
|
||||||
let n = plane_normal.as_ref(); // Get the underlying V.
|
let n = plane_normal.as_ref(); // Get the underlying V.
|
||||||
vector - n * (n.dot(vector) * na::convert(2.0))
|
vector - n * (n.dot(vector) * na::convert(2.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reflects a 2D vector wrt. the 2D line with normal `plane_normal`.
|
/// Reflects a 2D vector wrt. the 2D line with normal `plane_normal`.
|
||||||
fn reflect_wrt_hyperplane2<N>(plane_normal: &Unit<Vector2<N>>, vector: &Vector2<N>) -> Vector2<N>
|
fn reflect_wrt_hyperplane2<T>(plane_normal: &Unit<Vector2<T>>, vector: &Vector2<T>) -> Vector2<T>
|
||||||
where
|
where
|
||||||
N: RealField,
|
T: RealField,
|
||||||
{
|
{
|
||||||
let n = plane_normal.as_ref(); // Get the underlying Vector2
|
let n = plane_normal.as_ref(); // Get the underlying Vector2
|
||||||
vector - n * (n.dot(vector) * na::convert(2.0))
|
vector - n * (n.dot(vector) * na::convert(2.0))
|
||||||
|
@ -29,9 +29,9 @@ where
|
||||||
|
|
||||||
/// Reflects a 3D vector wrt. the 3D plane with normal `plane_normal`.
|
/// Reflects a 3D vector wrt. the 3D plane with normal `plane_normal`.
|
||||||
/// /!\ This is an exact replicate of `reflect_wrt_hyperplane2, but for 3D.
|
/// /!\ This is an exact replicate of `reflect_wrt_hyperplane2, but for 3D.
|
||||||
fn reflect_wrt_hyperplane3<N>(plane_normal: &Unit<Vector3<N>>, vector: &Vector3<N>) -> Vector3<N>
|
fn reflect_wrt_hyperplane3<T>(plane_normal: &Unit<Vector3<T>>, vector: &Vector3<T>) -> Vector3<T>
|
||||||
where
|
where
|
||||||
N: RealField,
|
T: RealField,
|
||||||
{
|
{
|
||||||
let n = plane_normal.as_ref(); // Get the underlying Vector3
|
let n = plane_normal.as_ref(); // Get the underlying Vector3
|
||||||
vector - n * (n.dot(vector) * na::convert(2.0))
|
vector - n * (n.dot(vector) * na::convert(2.0))
|
||||||
|
|
|
@ -2,20 +2,20 @@ extern crate nalgebra as na;
|
||||||
|
|
||||||
use matrixcompare::comparators::{AbsoluteElementwiseComparator, ExactElementwiseComparator};
|
use matrixcompare::comparators::{AbsoluteElementwiseComparator, ExactElementwiseComparator};
|
||||||
use matrixcompare::compare_matrices;
|
use matrixcompare::compare_matrices;
|
||||||
use na::{MatrixMN, U3, U4};
|
use na::{OMatrix, U3, U4};
|
||||||
|
|
||||||
fn compare_integers_fail() {
|
fn compare_integers_fail() {
|
||||||
println!("Comparing two integer matrices.");
|
println!("Comparing two integer matrices.");
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
let a = MatrixMN::<_, U3, U4>::from_row_slice(&[
|
let a = OMatrix::<_, U3, U4>::from_row_slice(&[
|
||||||
0, 1, 2, 3,
|
0, 1, 2, 3,
|
||||||
4, 5, 6, 7,
|
4, 5, 6, 7,
|
||||||
8, 9, -2, 11
|
8, 9, -2, 11
|
||||||
]);
|
]);
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
let b = MatrixMN::<_, U3, U4>::from_row_slice(&[
|
let b = OMatrix::<_, U3, U4>::from_row_slice(&[
|
||||||
0, 1, 2, 3,
|
0, 1, 2, 3,
|
||||||
4, 5, 6, 7,
|
4, 5, 6, 7,
|
||||||
8, 9, 10, 11
|
8, 9, 10, 11
|
||||||
|
@ -29,14 +29,14 @@ fn compare_integers_fail() {
|
||||||
fn compare_different_size() {
|
fn compare_different_size() {
|
||||||
println!("Comparing matrices of different size.");
|
println!("Comparing matrices of different size.");
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
let a = MatrixMN::<_, U3, U3>::from_row_slice(&[
|
let a = OMatrix::<_, U3, U3>::from_row_slice(&[
|
||||||
0, 1, 2,
|
0, 1, 2,
|
||||||
4, 5, 6,
|
4, 5, 6,
|
||||||
8, 9, 10,
|
8, 9, 10,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
let b = MatrixMN::<_, U3, U4>::from_row_slice(&[
|
let b = OMatrix::<_, U3, U4>::from_row_slice(&[
|
||||||
0, 1, 2, 3,
|
0, 1, 2, 3,
|
||||||
4, 5, 6, 7,
|
4, 5, 6, 7,
|
||||||
8, 9, 10, 11
|
8, 9, 10, 11
|
||||||
|
@ -51,14 +51,14 @@ fn compare_f64_abs_tol_fail() {
|
||||||
println!("Comparing two f64 matrices.");
|
println!("Comparing two f64 matrices.");
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
let a = MatrixMN::<f64, U3, U3>::from_row_slice(&[
|
let a = OMatrix::<f64, U3, U3>::from_row_slice(&[
|
||||||
0.0, 1.0, 2.0 + 1e-10,
|
0.0, 1.0, 2.0 + 1e-10,
|
||||||
4.0, 5.0, 6.0,
|
4.0, 5.0, 6.0,
|
||||||
8.0, 9.0, 10.0,
|
8.0, 9.0, 10.0,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
let b = MatrixMN::<_, U3, U3>::from_row_slice(&[
|
let b = OMatrix::<_, U3, U3>::from_row_slice(&[
|
||||||
0.0, 1.0, 2.0,
|
0.0, 1.0, 2.0,
|
||||||
4.0, 5.0, 6.0,
|
4.0, 5.0, 6.0,
|
||||||
8.0, 9.0, 10.0
|
8.0, 9.0, 10.0
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
extern crate nalgebra as na;
|
extern crate nalgebra as na;
|
||||||
|
|
||||||
use na::{DMatrix, Dynamic, Matrix2x3, Matrix3x2, U2, U3};
|
use na::{DMatrix, Dynamic, Matrix2x3, Matrix3x2, Const};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Matrices can be reshaped in-place without moving or copying values.
|
// Matrices can be reshaped in-place without moving or copying values.
|
||||||
|
@ -16,7 +16,7 @@ fn main() {
|
||||||
1.2, 2.3
|
1.2, 2.3
|
||||||
);
|
);
|
||||||
|
|
||||||
let m3 = m1.reshape_generic(U3, U2);
|
let m3 = m1.reshape_generic(Const::<3>, Const::<2>);
|
||||||
assert_eq!(m3, m2);
|
assert_eq!(m3, m2);
|
||||||
|
|
||||||
// Note that, for statically sized matrices, invalid reshapes will not compile:
|
// Note that, for statically sized matrices, invalid reshapes will not compile:
|
||||||
|
|
|
@ -3,15 +3,15 @@ extern crate nalgebra as na;
|
||||||
use na::{Scalar, Vector3};
|
use na::{Scalar, Vector3};
|
||||||
use simba::scalar::RealField;
|
use simba::scalar::RealField;
|
||||||
|
|
||||||
fn print_vector<N: Scalar>(m: &Vector3<N>) {
|
fn print_vector<T: Scalar>(m: &Vector3<T>) {
|
||||||
println!("{:?}", m)
|
println!("{:?}", m)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_norm<N: RealField>(v: &Vector3<N>) {
|
fn print_norm<T: RealField>(v: &Vector3<T>) {
|
||||||
// NOTE: alternatively, nalgebra already defines `v.norm()`.
|
// NOTE: alternatively, nalgebra already defines `v.norm()`.
|
||||||
let norm = v.dot(v).sqrt();
|
let norm = v.dot(v).sqrt();
|
||||||
|
|
||||||
// The RealField bound implies that N is Display so we can
|
// The RealField bound implies that T is Display so we can
|
||||||
// use "{}" instead of "{:?}" for the format string.
|
// use "{}" instead of "{:?}" for the format string.
|
||||||
println!("{}", norm)
|
println!("{}", norm)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "nalgebra-glm"
|
name = "nalgebra-glm"
|
||||||
version = "0.11.0"
|
version = "0.12.0"
|
||||||
authors = ["sebcrozet <developer@crozet.re>"]
|
authors = ["sebcrozet <developer@crozet.re>"]
|
||||||
|
|
||||||
description = "A computer-graphics oriented API for nalgebra, inspired by the C++ GLM library."
|
description = "A computer-graphics oriented API for nalgebra, inspired by the C++ GLM library."
|
||||||
|
@ -20,11 +20,11 @@ maintenance = { status = "actively-developed" }
|
||||||
default = [ "std" ]
|
default = [ "std" ]
|
||||||
std = [ "nalgebra/std", "simba/std" ]
|
std = [ "nalgebra/std", "simba/std" ]
|
||||||
arbitrary = [ "nalgebra/arbitrary" ]
|
arbitrary = [ "nalgebra/arbitrary" ]
|
||||||
serde-serialize = [ "nalgebra/serde-serialize" ]
|
serde-serialize = [ "nalgebra/serde-serialize-no-std" ]
|
||||||
abomonation-serialize = [ "nalgebra/abomonation-serialize" ]
|
abomonation-serialize = [ "nalgebra/abomonation-serialize" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
num-traits = { version = "0.2", default-features = false }
|
num-traits = { version = "0.2", default-features = false }
|
||||||
approx = { version = "0.4", default-features = false }
|
approx = { version = "0.4", default-features = false }
|
||||||
simba = { version = "0.4", default-features = false }
|
simba = { version = "0.4", default-features = false }
|
||||||
nalgebra = { path = "..", version = "0.25", default-features = false }
|
nalgebra = { path = "..", version = "0.26", default-features = false }
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use na::{
|
use na::{
|
||||||
Matrix2, Matrix2x3, Matrix2x4, Matrix3, Matrix3x2, Matrix3x4, Matrix4, Matrix4x2, Matrix4x3,
|
Matrix2, Matrix2x3, Matrix2x4, Matrix3, Matrix3x2, Matrix3x4, Matrix4, Matrix4x2, Matrix4x3,
|
||||||
MatrixMN, Quaternion, VectorN, U1, U2, U3, U4,
|
Quaternion, SMatrix, SVector,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A matrix with components of type `N`. It has `R` rows, and `C` columns.
|
/// A matrix with components of type `T`. It has `R` rows, and `C` columns.
|
||||||
///
|
///
|
||||||
/// In this library, vectors, represented as [`TVec`](type.TVec.html) and
|
/// In this library, vectors, represented as [`TVec`](type.TVec.html) and
|
||||||
/// friends, are also matrices. Operations that operate on a matrix will
|
/// friends, are also matrices. Operations that operate on a matrix will
|
||||||
|
@ -24,8 +24,8 @@ use na::{
|
||||||
/// * [`TMat4x3`](type.TMat4x3.html)
|
/// * [`TMat4x3`](type.TMat4x3.html)
|
||||||
/// * [`TMat4x4`](type.TMat4x4.html)
|
/// * [`TMat4x4`](type.TMat4x4.html)
|
||||||
/// * [`TVec`](type.TVec.html)
|
/// * [`TVec`](type.TVec.html)
|
||||||
pub type TMat<N, R, C> = MatrixMN<N, R, C>;
|
pub type TMat<T, const R: usize, const C: usize> = SMatrix<T, R, C>;
|
||||||
/// A column vector with components of type `N`. It has `D` rows (and one column).
|
/// A column vector with components of type `T`. It has `D` rows (and one column).
|
||||||
///
|
///
|
||||||
/// In this library, vectors are represented as a single column matrix, so
|
/// In this library, vectors are represented as a single column matrix, so
|
||||||
/// operations on [`TMat`](type.TMat.html) are also valid on vectors.
|
/// operations on [`TMat`](type.TMat.html) are also valid on vectors.
|
||||||
|
@ -37,11 +37,11 @@ pub type TMat<N, R, C> = MatrixMN<N, R, C>;
|
||||||
/// * [`TVec2`](type.TVec2.html)
|
/// * [`TVec2`](type.TVec2.html)
|
||||||
/// * [`TVec3`](type.TVec3.html)
|
/// * [`TVec3`](type.TVec3.html)
|
||||||
/// * [`TVec4`](type.TVec4.html)
|
/// * [`TVec4`](type.TVec4.html)
|
||||||
pub type TVec<N, R> = VectorN<N, R>;
|
pub type TVec<T, const R: usize> = SVector<T, R>;
|
||||||
/// A quaternion with components of type `N`.
|
/// A quaternion with components of type `T`.
|
||||||
pub type Qua<N> = Quaternion<N>;
|
pub type Qua<T> = Quaternion<T>;
|
||||||
|
|
||||||
/// A 1D vector with components of type `N`.
|
/// A 1D vector with components of type `T`.
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
|
@ -69,8 +69,8 @@ pub type Qua<N> = Quaternion<N>;
|
||||||
/// * [`U64Vec1`](type.U64Vec1.html)
|
/// * [`U64Vec1`](type.U64Vec1.html)
|
||||||
/// * [`U8Vec1`](type.U8Vec1.html)
|
/// * [`U8Vec1`](type.U8Vec1.html)
|
||||||
/// * [`Vec1`](type.Vec1.html)
|
/// * [`Vec1`](type.Vec1.html)
|
||||||
pub type TVec1<N> = TVec<N, U1>;
|
pub type TVec1<T> = TVec<T, 1>;
|
||||||
/// A 2D vector with components of type `N`.
|
/// A 2D vector with components of type `T`.
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
|
@ -99,8 +99,8 @@ pub type TVec1<N> = TVec<N, U1>;
|
||||||
/// * [`U64Vec2`](type.U64Vec2.html)
|
/// * [`U64Vec2`](type.U64Vec2.html)
|
||||||
/// * [`U8Vec2`](type.U8Vec2.html)
|
/// * [`U8Vec2`](type.U8Vec2.html)
|
||||||
/// * [`Vec2`](type.Vec2.html)
|
/// * [`Vec2`](type.Vec2.html)
|
||||||
pub type TVec2<N> = TVec<N, U2>;
|
pub type TVec2<T> = TVec<T, 2>;
|
||||||
/// A 3D vector with components of type `N`.
|
/// A 3D vector with components of type `T`.
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
|
@ -129,8 +129,8 @@ pub type TVec2<N> = TVec<N, U2>;
|
||||||
/// * [`U64Vec3`](type.U64Vec3.html)
|
/// * [`U64Vec3`](type.U64Vec3.html)
|
||||||
/// * [`U8Vec3`](type.U8Vec3.html)
|
/// * [`U8Vec3`](type.U8Vec3.html)
|
||||||
/// * [`Vec3`](type.Vec3.html)
|
/// * [`Vec3`](type.Vec3.html)
|
||||||
pub type TVec3<N> = TVec<N, U3>;
|
pub type TVec3<T> = TVec<T, 3>;
|
||||||
/// A 4D vector with components of type `N`.
|
/// A 4D vector with components of type `T`.
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
|
@ -158,7 +158,7 @@ pub type TVec3<N> = TVec<N, U3>;
|
||||||
/// * [`U64Vec4`](type.U64Vec4.html)
|
/// * [`U64Vec4`](type.U64Vec4.html)
|
||||||
/// * [`U8Vec4`](type.U8Vec4.html)
|
/// * [`U8Vec4`](type.U8Vec4.html)
|
||||||
/// * [`Vec4`](type.Vec4.html)
|
/// * [`Vec4`](type.Vec4.html)
|
||||||
pub type TVec4<N> = TVec<N, U4>;
|
pub type TVec4<T> = TVec<T, 4>;
|
||||||
/// A 1D vector with boolean components.
|
/// A 1D vector with boolean components.
|
||||||
pub type BVec1 = TVec1<bool>;
|
pub type BVec1 = TVec1<bool>;
|
||||||
/// A 2D vector with boolean components.
|
/// A 2D vector with boolean components.
|
||||||
|
@ -268,31 +268,31 @@ pub type I8Vec3 = TVec3<i8>;
|
||||||
/// A 4D vector with `i8` components.
|
/// A 4D vector with `i8` components.
|
||||||
pub type I8Vec4 = TVec4<i8>;
|
pub type I8Vec4 = TVec4<i8>;
|
||||||
|
|
||||||
/// A 2x2 matrix with components of type `N`.
|
/// A 2x2 matrix with components of type `T`.
|
||||||
pub type TMat2<N> = Matrix2<N>;
|
pub type TMat2<T> = Matrix2<T>;
|
||||||
/// A 2x2 matrix with components of type `N`.
|
/// A 2x2 matrix with components of type `T`.
|
||||||
pub type TMat2x2<N> = Matrix2<N>;
|
pub type TMat2x2<T> = Matrix2<T>;
|
||||||
/// A 2x3 matrix with components of type `N`.
|
/// A 2x3 matrix with components of type `T`.
|
||||||
pub type TMat2x3<N> = Matrix2x3<N>;
|
pub type TMat2x3<T> = Matrix2x3<T>;
|
||||||
/// A 2x4 matrix with components of type `N`.
|
/// A 2x4 matrix with components of type `T`.
|
||||||
pub type TMat2x4<N> = Matrix2x4<N>;
|
pub type TMat2x4<T> = Matrix2x4<T>;
|
||||||
/// A 3x3 matrix with components of type `N`.
|
/// A 3x3 matrix with components of type `T`.
|
||||||
pub type TMat3<N> = Matrix3<N>;
|
pub type TMat3<T> = Matrix3<T>;
|
||||||
/// A 3x2 matrix with components of type `N`.
|
/// A 3x2 matrix with components of type `T`.
|
||||||
pub type TMat3x2<N> = Matrix3x2<N>;
|
pub type TMat3x2<T> = Matrix3x2<T>;
|
||||||
/// A 3x3 matrix with components of type `N`.
|
/// A 3x3 matrix with components of type `T`.
|
||||||
pub type TMat3x3<N> = Matrix3<N>;
|
pub type TMat3x3<T> = Matrix3<T>;
|
||||||
/// A 3x4 matrix with components of type `N`.
|
/// A 3x4 matrix with components of type `T`.
|
||||||
pub type TMat3x4<N> = Matrix3x4<N>;
|
pub type TMat3x4<T> = Matrix3x4<T>;
|
||||||
/// A 4x4 matrix with components of type `N`.
|
/// A 4x4 matrix with components of type `T`.
|
||||||
pub type TMat4<N> = Matrix4<N>;
|
pub type TMat4<T> = Matrix4<T>;
|
||||||
/// A 4x2 matrix with components of type `N`.
|
/// A 4x2 matrix with components of type `T`.
|
||||||
pub type TMat4x2<N> = Matrix4x2<N>;
|
pub type TMat4x2<T> = Matrix4x2<T>;
|
||||||
/// A 4x3 matrix with components of type `N`.
|
/// A 4x3 matrix with components of type `T`.
|
||||||
pub type TMat4x3<N> = Matrix4x3<N>;
|
pub type TMat4x3<T> = Matrix4x3<T>;
|
||||||
/// A 4x4 matrix with components of type `N`.
|
/// A 4x4 matrix with components of type `T`.
|
||||||
pub type TMat4x4<N> = Matrix4<N>;
|
pub type TMat4x4<T> = Matrix4<T>;
|
||||||
/// A 2x2 matrix with components of type `N`.
|
/// A 2x2 matrix with components of type `T`.
|
||||||
pub type DMat2 = Matrix2<f64>;
|
pub type DMat2 = Matrix2<f64>;
|
||||||
/// A 2x2 matrix with `f64` components.
|
/// A 2x2 matrix with `f64` components.
|
||||||
pub type DMat2x2 = Matrix2<f64>;
|
pub type DMat2x2 = Matrix2<f64>;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use core::mem;
|
use core::mem;
|
||||||
use na::{self, DefaultAllocator, RealField};
|
use na::{self, RealField};
|
||||||
use num::FromPrimitive;
|
use num::FromPrimitive;
|
||||||
|
|
||||||
use crate::aliases::{TMat, TVec};
|
use crate::aliases::{TMat, TVec};
|
||||||
use crate::traits::{Alloc, Dimension, Number};
|
use crate::traits::Number;
|
||||||
|
|
||||||
/// For each matrix or vector component `x` if `x >= 0`; otherwise, it returns `-x`.
|
/// For each matrix or vector component `x` if `x >= 0`; otherwise, it returns `-x`.
|
||||||
///
|
///
|
||||||
|
@ -21,10 +21,7 @@ use crate::traits::{Alloc, Dimension, Number};
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`sign`](fn.sign.html)
|
/// * [`sign`](fn.sign.html)
|
||||||
pub fn abs<N: Number, R: Dimension, C: Dimension>(x: &TMat<N, R, C>) -> TMat<N, R, C>
|
pub fn abs<T: Number, const R: usize, const C: usize>(x: &TMat<T, R, C>) -> TMat<T, R, C> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, R, C>,
|
|
||||||
{
|
|
||||||
x.abs()
|
x.abs()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,10 +42,7 @@ where
|
||||||
/// * [`fract`](fn.fract.html)
|
/// * [`fract`](fn.fract.html)
|
||||||
/// * [`round`](fn.round.html)
|
/// * [`round`](fn.round.html)
|
||||||
/// * [`trunc`](fn.trunc.html)
|
/// * [`trunc`](fn.trunc.html)
|
||||||
pub fn ceil<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn ceil<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.map(|x| x.ceil())
|
x.map(|x| x.ceil())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +67,7 @@ where
|
||||||
///
|
///
|
||||||
/// * [`clamp`](fn.clamp.html)
|
/// * [`clamp`](fn.clamp.html)
|
||||||
/// * [`clamp_vec`](fn.clamp_vec.html)
|
/// * [`clamp_vec`](fn.clamp_vec.html)
|
||||||
pub fn clamp_scalar<N: Number>(x: N, min_val: N, max_val: N) -> N {
|
pub fn clamp_scalar<T: Number>(x: T, min_val: T, max_val: T) -> T {
|
||||||
na::clamp(x, min_val, max_val)
|
na::clamp(x, min_val, max_val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,10 +91,7 @@ pub fn clamp_scalar<N: Number>(x: N, min_val: N, max_val: N) -> N {
|
||||||
///
|
///
|
||||||
/// * [`clamp_scalar`](fn.clamp_scalar.html)
|
/// * [`clamp_scalar`](fn.clamp_scalar.html)
|
||||||
/// * [`clamp_vec`](fn.clamp_vec.html)
|
/// * [`clamp_vec`](fn.clamp_vec.html)
|
||||||
pub fn clamp<N: Number, D: Dimension>(x: &TVec<N, D>, min_val: N, max_val: N) -> TVec<N, D>
|
pub fn clamp<T: Number, const D: usize>(x: &TVec<T, D>, min_val: T, max_val: T) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.map(|x| na::clamp(x, min_val, max_val))
|
x.map(|x| na::clamp(x, min_val, max_val))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,14 +122,11 @@ where
|
||||||
///
|
///
|
||||||
/// * [`clamp_scalar`](fn.clamp_scalar.html)
|
/// * [`clamp_scalar`](fn.clamp_scalar.html)
|
||||||
/// * [`clamp`](fn.clamp.html)
|
/// * [`clamp`](fn.clamp.html)
|
||||||
pub fn clamp_vec<N: Number, D: Dimension>(
|
pub fn clamp_vec<T: Number, const D: usize>(
|
||||||
x: &TVec<N, D>,
|
x: &TVec<T, D>,
|
||||||
min_val: &TVec<N, D>,
|
min_val: &TVec<T, D>,
|
||||||
max_val: &TVec<N, D>,
|
max_val: &TVec<T, D>,
|
||||||
) -> TVec<N, D>
|
) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.zip_zip_map(min_val, max_val, |a, min, max| na::clamp(a, min, max))
|
x.zip_zip_map(min_val, max_val, |a, min, max| na::clamp(a, min, max))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,10 +160,7 @@ pub fn float_bits_to_int(v: f32) -> i32 {
|
||||||
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_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`](fn.uint_bits_to_float.html)
|
||||||
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
|
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
|
||||||
pub fn float_bits_to_int_vec<D: Dimension>(v: &TVec<f32, D>) -> TVec<i32, D>
|
pub fn float_bits_to_int_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<i32, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<f32, D>,
|
|
||||||
{
|
|
||||||
v.map(float_bits_to_int)
|
v.map(float_bits_to_int)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,10 +194,7 @@ pub fn float_bits_to_uint(v: f32) -> u32 {
|
||||||
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_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`](fn.uint_bits_to_float.html)
|
||||||
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
|
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
|
||||||
pub fn float_bits_to_uint_vec<D: Dimension>(v: &TVec<f32, D>) -> TVec<u32, D>
|
pub fn float_bits_to_uint_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<u32, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<f32, D>,
|
|
||||||
{
|
|
||||||
v.map(float_bits_to_uint)
|
v.map(float_bits_to_uint)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,15 +214,12 @@ where
|
||||||
/// * [`fract`](fn.fract.html)
|
/// * [`fract`](fn.fract.html)
|
||||||
/// * [`round`](fn.round.html)
|
/// * [`round`](fn.round.html)
|
||||||
/// * [`trunc`](fn.trunc.html)
|
/// * [`trunc`](fn.trunc.html)
|
||||||
pub fn floor<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn floor<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.map(|x| x.floor())
|
x.map(|x| x.floor())
|
||||||
}
|
}
|
||||||
|
|
||||||
//// TODO: should be implemented for TVec/TMat?
|
//// TODO: should be implemented for TVec/TMat?
|
||||||
//pub fn fma<N: Number>(a: N, b: N, c: N) -> N {
|
//pub fn fma<T: Number>(a: T, b: T, c: T) -> T {
|
||||||
// // TODO: use an actual FMA
|
// // TODO: use an actual FMA
|
||||||
// a * b + c
|
// a * b + c
|
||||||
//}
|
//}
|
||||||
|
@ -261,16 +240,13 @@ where
|
||||||
/// * [`floor`](fn.floor.html)
|
/// * [`floor`](fn.floor.html)
|
||||||
/// * [`round`](fn.round.html)
|
/// * [`round`](fn.round.html)
|
||||||
/// * [`trunc`](fn.trunc.html)
|
/// * [`trunc`](fn.trunc.html)
|
||||||
pub fn fract<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn fract<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.map(|x| x.fract())
|
x.map(|x| x.fract())
|
||||||
}
|
}
|
||||||
|
|
||||||
//// TODO: should be implemented for TVec/TMat?
|
//// TODO: should be implemented for TVec/TMat?
|
||||||
///// Returns the (significant, exponent) of this float number.
|
///// Returns the (significant, exponent) of this float number.
|
||||||
//pub fn frexp<N: RealField>(x: N, exp: N) -> (N, N) {
|
//pub fn frexp<T: RealField>(x: T, exp: T) -> (T, T) {
|
||||||
// // TODO: is there a better approach?
|
// // TODO: is there a better approach?
|
||||||
// let e = x.log2().ceil();
|
// let e = x.log2().ceil();
|
||||||
// (x * (-e).exp2(), e)
|
// (x * (-e).exp2(), e)
|
||||||
|
@ -306,27 +282,22 @@ pub fn int_bits_to_float(v: i32) -> f32 {
|
||||||
/// * [`int_bits_to_float`](fn.int_bits_to_float.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`](fn.uint_bits_to_float.html)
|
||||||
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
|
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
|
||||||
pub fn int_bits_to_float_vec<D: Dimension>(v: &TVec<i32, D>) -> TVec<f32, D>
|
pub fn int_bits_to_float_vec<const D: usize>(v: &TVec<i32, D>) -> TVec<f32, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<f32, D>,
|
|
||||||
{
|
|
||||||
v.map(int_bits_to_float)
|
v.map(int_bits_to_float)
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn isinf<N: Scalar, D: Dimension>(x: &TVec<N, D>) -> TVec<bool, D>
|
//pub fn isinf<T: Scalar, const D: usize>(x: &TVec<T, D>) -> TVec<bool, D> {
|
||||||
// where DefaultAllocator: Alloc<N, D> {
|
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//
|
//
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn isnan<N: Scalar, D: Dimension>(x: &TVec<N, D>) -> TVec<bool, D>
|
//pub fn isnan<T: Scalar, const D: usize>(x: &TVec<T, D>) -> TVec<bool, D> {
|
||||||
// where DefaultAllocator: Alloc<N, D> {
|
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//
|
//
|
||||||
//}
|
//}
|
||||||
|
|
||||||
///// Returns the (significant, exponent) of this float number.
|
///// Returns the (significant, exponent) of this float number.
|
||||||
//pub fn ldexp<N: RealField>(x: N, exp: N) -> N {
|
//pub fn ldexp<T: RealField>(x: T, exp: T) -> T {
|
||||||
// // TODO: is there a better approach?
|
// // TODO: is there a better approach?
|
||||||
// x * (exp).exp2()
|
// x * (exp).exp2()
|
||||||
//}
|
//}
|
||||||
|
@ -346,8 +317,8 @@ where
|
||||||
///
|
///
|
||||||
/// * [`mix`](fn.mix.html)
|
/// * [`mix`](fn.mix.html)
|
||||||
/// * [`mix_vec`](fn.mix_vec.html)
|
/// * [`mix_vec`](fn.mix_vec.html)
|
||||||
pub fn mix_scalar<N: Number>(x: N, y: N, a: N) -> N {
|
pub fn mix_scalar<T: Number>(x: T, y: T, a: T) -> T {
|
||||||
x * (N::one() - a) + y * a
|
x * (T::one() - a) + y * a
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the vectors x and y using the scalar value a.
|
/// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the vectors x and y using the scalar value a.
|
||||||
|
@ -367,11 +338,8 @@ pub fn mix_scalar<N: Number>(x: N, y: N, a: N) -> N {
|
||||||
///
|
///
|
||||||
/// * [`mix_scalar`](fn.mix_scalar.html)
|
/// * [`mix_scalar`](fn.mix_scalar.html)
|
||||||
/// * [`mix_vec`](fn.mix_vec.html)
|
/// * [`mix_vec`](fn.mix_vec.html)
|
||||||
pub fn mix<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, a: N) -> TVec<N, D>
|
pub fn mix<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) -> TVec<T, D> {
|
||||||
where
|
x * (T::one() - a) + y * a
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x * (N::one() - a) + y * a
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `x * (1.0 - a) + y * a`, i.e., the component-wise linear blend of `x` and `y` using the components of
|
/// Returns `x * (1.0 - a) + y * a`, i.e., the component-wise linear blend of `x` and `y` using the components of
|
||||||
|
@ -393,15 +361,12 @@ where
|
||||||
///
|
///
|
||||||
/// * [`mix_scalar`](fn.mix_scalar.html)
|
/// * [`mix_scalar`](fn.mix_scalar.html)
|
||||||
/// * [`mix`](fn.mix.html)
|
/// * [`mix`](fn.mix.html)
|
||||||
pub fn mix_vec<N: Number, D: Dimension>(
|
pub fn mix_vec<T: Number, const D: usize>(
|
||||||
x: &TVec<N, D>,
|
x: &TVec<T, D>,
|
||||||
y: &TVec<N, D>,
|
y: &TVec<T, D>,
|
||||||
a: &TVec<N, D>,
|
a: &TVec<T, D>,
|
||||||
) -> TVec<N, D>
|
) -> TVec<T, D> {
|
||||||
where
|
x.component_mul(&(TVec::<T, D>::repeat(T::one()) - a)) + y.component_mul(&a)
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.component_mul(&(TVec::<N, D>::repeat(N::one()) - a)) + y.component_mul(&a)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the scalars x and y using the scalar value a.
|
/// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the scalars x and y using the scalar value a.
|
||||||
|
@ -420,7 +385,7 @@ where
|
||||||
///
|
///
|
||||||
/// * [`lerp`](fn.lerp.html)
|
/// * [`lerp`](fn.lerp.html)
|
||||||
/// * [`lerp_vec`](fn.lerp_vec.html)
|
/// * [`lerp_vec`](fn.lerp_vec.html)
|
||||||
pub fn lerp_scalar<N: Number>(x: N, y: N, a: N) -> N {
|
pub fn lerp_scalar<T: Number>(x: T, y: T, a: T) -> T {
|
||||||
mix_scalar(x, y, a)
|
mix_scalar(x, y, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,10 +407,7 @@ pub fn lerp_scalar<N: Number>(x: N, y: N, a: N) -> N {
|
||||||
///
|
///
|
||||||
/// * [`lerp_scalar`](fn.lerp_scalar.html)
|
/// * [`lerp_scalar`](fn.lerp_scalar.html)
|
||||||
/// * [`lerp_vec`](fn.lerp_vec.html)
|
/// * [`lerp_vec`](fn.lerp_vec.html)
|
||||||
pub fn lerp<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, a: N) -> TVec<N, D>
|
pub fn lerp<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
mix(x, y, a)
|
mix(x, y, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,14 +431,11 @@ where
|
||||||
///
|
///
|
||||||
/// * [`lerp_scalar`](fn.lerp_scalar.html)
|
/// * [`lerp_scalar`](fn.lerp_scalar.html)
|
||||||
/// * [`lerp`](fn.lerp.html)
|
/// * [`lerp`](fn.lerp.html)
|
||||||
pub fn lerp_vec<N: Number, D: Dimension>(
|
pub fn lerp_vec<T: Number, const D: usize>(
|
||||||
x: &TVec<N, D>,
|
x: &TVec<T, D>,
|
||||||
y: &TVec<N, D>,
|
y: &TVec<T, D>,
|
||||||
a: &TVec<N, D>,
|
a: &TVec<T, D>,
|
||||||
) -> TVec<N, D>
|
) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
mix_vec(x, y, a)
|
mix_vec(x, y, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,10 +446,7 @@ where
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`modf`](fn.modf.html)
|
/// * [`modf`](fn.modf.html)
|
||||||
pub fn modf_vec<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<N, D>
|
pub fn modf_vec<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.zip_map(y, |x, y| x % y)
|
x.zip_map(y, |x, y| x % y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,7 +455,7 @@ where
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`modf_vec`](fn.modf_vec.html)
|
/// * [`modf_vec`](fn.modf_vec.html)
|
||||||
pub fn modf<N: Number>(x: N, i: N) -> N {
|
pub fn modf<T: Number>(x: T, i: T) -> T {
|
||||||
x % i
|
x % i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,15 +477,11 @@ pub fn modf<N: Number>(x: N, i: N) -> N {
|
||||||
/// * [`floor`](fn.floor.html)
|
/// * [`floor`](fn.floor.html)
|
||||||
/// * [`fract`](fn.fract.html)
|
/// * [`fract`](fn.fract.html)
|
||||||
/// * [`trunc`](fn.trunc.html)
|
/// * [`trunc`](fn.trunc.html)
|
||||||
pub fn round<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn round<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.map(|x| x.round())
|
x.map(|x| x.round())
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn roundEven<N: Scalar, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
//pub fn roundEven<T: Scalar, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
// where DefaultAllocator: Alloc<N, D> {
|
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
@ -547,46 +499,37 @@ where
|
||||||
///
|
///
|
||||||
/// * [`abs`](fn.abs.html)
|
/// * [`abs`](fn.abs.html)
|
||||||
///
|
///
|
||||||
pub fn sign<N: Number, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn sign<T: Number, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
x.map(|x| if x.is_zero() { T::zero() } else { x.signum() })
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.map(|x| if x.is_zero() { N::zero() } else { x.signum() })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns 0.0 if `x <= edge0` and `1.0 if x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.
|
/// Returns 0.0 if `x <= edge0` and `1.0 if x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.
|
||||||
///
|
///
|
||||||
/// This is useful in cases where you would want a threshold function with a smooth transition.
|
/// This is useful in cases where you would want a threshold function with a smooth transition.
|
||||||
/// This is equivalent to: `let result = clamp((x - edge0) / (edge1 - edge0), 0, 1); return t * t * (3 - 2 * t);` Results are undefined if `edge0 >= edge1`.
|
/// This is equivalent to: `let result = clamp((x - edge0) / (edge1 - edge0), 0, 1); return t * t * (3 - 2 * t);` Results are undefined if `edge0 >= edge1`.
|
||||||
pub fn smoothstep<N: Number>(edge0: N, edge1: N, x: N) -> N {
|
pub fn smoothstep<T: Number>(edge0: T, edge1: T, x: T) -> T {
|
||||||
let _3: N = FromPrimitive::from_f64(3.0).unwrap();
|
let _3: T = FromPrimitive::from_f64(3.0).unwrap();
|
||||||
let _2: N = FromPrimitive::from_f64(2.0).unwrap();
|
let _2: T = FromPrimitive::from_f64(2.0).unwrap();
|
||||||
let t = na::clamp((x - edge0) / (edge1 - edge0), N::zero(), N::one());
|
let t = na::clamp((x - edge0) / (edge1 - edge0), T::zero(), T::one());
|
||||||
t * t * (_3 - t * _2)
|
t * t * (_3 - t * _2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns 0.0 if `x < edge`, otherwise it returns 1.0.
|
/// Returns 0.0 if `x < edge`, otherwise it returns 1.0.
|
||||||
pub fn step_scalar<N: Number>(edge: N, x: N) -> N {
|
pub fn step_scalar<T: Number>(edge: T, x: T) -> T {
|
||||||
if edge > x {
|
if edge > x {
|
||||||
N::zero()
|
T::zero()
|
||||||
} else {
|
} else {
|
||||||
N::one()
|
T::one()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns 0.0 if `x[i] < edge`, otherwise it returns 1.0.
|
/// Returns 0.0 if `x[i] < edge`, otherwise it returns 1.0.
|
||||||
pub fn step<N: Number, D: Dimension>(edge: N, x: &TVec<N, D>) -> TVec<N, D>
|
pub fn step<T: Number, const D: usize>(edge: T, x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.map(|x| step_scalar(edge, x))
|
x.map(|x| step_scalar(edge, x))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns 0.0 if `x[i] < edge[i]`, otherwise it returns 1.0.
|
/// Returns 0.0 if `x[i] < edge[i]`, otherwise it returns 1.0.
|
||||||
pub fn step_vec<N: Number, D: Dimension>(edge: &TVec<N, D>, x: &TVec<N, D>) -> TVec<N, D>
|
pub fn step_vec<T: Number, const D: usize>(edge: &TVec<T, D>, x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
edge.zip_map(x, step_scalar)
|
edge.zip_map(x, step_scalar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,10 +549,7 @@ where
|
||||||
/// * [`floor`](fn.floor.html)
|
/// * [`floor`](fn.floor.html)
|
||||||
/// * [`fract`](fn.fract.html)
|
/// * [`fract`](fn.fract.html)
|
||||||
/// * [`round`](fn.round.html)
|
/// * [`round`](fn.round.html)
|
||||||
pub fn trunc<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn trunc<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.map(|x| x.trunc())
|
x.map(|x| x.trunc())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -643,9 +583,6 @@ pub fn uint_bits_to_float_scalar(v: u32) -> f32 {
|
||||||
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
|
/// * [`int_bits_to_float`](fn.int_bits_to_float.html)
|
||||||
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.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)
|
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
|
||||||
pub fn uint_bits_to_float<D: Dimension>(v: &TVec<u32, D>) -> TVec<f32, D>
|
pub fn uint_bits_to_float<const D: usize>(v: &TVec<u32, D>) -> TVec<f32, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<f32, D>,
|
|
||||||
{
|
|
||||||
v.map(uint_bits_to_float_scalar)
|
v.map(uint_bits_to_float_scalar)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::aliases::{
|
||||||
Qua, TMat, TMat2, TMat2x3, TMat2x4, TMat3, TMat3x2, TMat3x4, TMat4, TMat4x2, TMat4x3, TVec1,
|
Qua, TMat, TMat2, TMat2x3, TMat2x4, TMat3, TMat3x2, TMat3x4, TMat4, TMat4x2, TMat4x3, TVec1,
|
||||||
TVec2, TVec3, TVec4,
|
TVec2, TVec3, TVec4,
|
||||||
};
|
};
|
||||||
use na::{RealField, Scalar, U2, U3, U4};
|
use na::{RealField, Scalar};
|
||||||
|
|
||||||
/// Creates a new 1D vector.
|
/// Creates a new 1D vector.
|
||||||
///
|
///
|
||||||
|
@ -14,30 +14,30 @@ use na::{RealField, Scalar, U2, U3, U4};
|
||||||
/// # use nalgebra_glm as glm;
|
/// # use nalgebra_glm as glm;
|
||||||
/// let v = glm::vec1(true);
|
/// let v = glm::vec1(true);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn vec1<N: Scalar>(x: N) -> TVec1<N> {
|
pub fn vec1<T: Scalar>(x: T) -> TVec1<T> {
|
||||||
TVec1::new(x)
|
TVec1::new(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new 2D vector.
|
/// Creates a new 2D vector.
|
||||||
pub fn vec2<N: Scalar>(x: N, y: N) -> TVec2<N> {
|
pub fn vec2<T: Scalar>(x: T, y: T) -> TVec2<T> {
|
||||||
TVec2::new(x, y)
|
TVec2::new(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new 3D vector.
|
/// Creates a new 3D vector.
|
||||||
pub fn vec3<N: Scalar>(x: N, y: N, z: N) -> TVec3<N> {
|
pub fn vec3<T: Scalar>(x: T, y: T, z: T) -> TVec3<T> {
|
||||||
TVec3::new(x, y, z)
|
TVec3::new(x, y, z)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new 4D vector.
|
/// Creates a new 4D vector.
|
||||||
pub fn vec4<N: Scalar>(x: N, y: N, z: N, w: N) -> TVec4<N> {
|
pub fn vec4<T: Scalar>(x: T, y: T, z: T, w: T) -> TVec4<T> {
|
||||||
TVec4::new(x, y, z, w)
|
TVec4::new(x, y, z, w)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new 2x2 matrix.
|
/// Create a new 2x2 matrix.
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub fn mat2<N: Scalar>(m11: N, m12: N,
|
pub fn mat2<T: Scalar>(m11: T, m12: T,
|
||||||
m21: N, m22: N) -> TMat2<N> {
|
m21: T, m22: T) -> TMat2<T> {
|
||||||
TMat::<N, U2, U2>::new(
|
TMat::<T, 2, 2>::new(
|
||||||
m11, m12,
|
m11, m12,
|
||||||
m21, m22,
|
m21, m22,
|
||||||
)
|
)
|
||||||
|
@ -45,9 +45,9 @@ pub fn mat2<N: Scalar>(m11: N, m12: N,
|
||||||
|
|
||||||
/// Create a new 2x2 matrix.
|
/// Create a new 2x2 matrix.
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub fn mat2x2<N: Scalar>(m11: N, m12: N,
|
pub fn mat2x2<T: Scalar>(m11: T, m12: T,
|
||||||
m21: N, m22: N) -> TMat2<N> {
|
m21: T, m22: T) -> TMat2<T> {
|
||||||
TMat::<N, U2, U2>::new(
|
TMat::<T, 2, 2>::new(
|
||||||
m11, m12,
|
m11, m12,
|
||||||
m21, m22,
|
m21, m22,
|
||||||
)
|
)
|
||||||
|
@ -55,9 +55,9 @@ pub fn mat2x2<N: Scalar>(m11: N, m12: N,
|
||||||
|
|
||||||
/// Create a new 2x3 matrix.
|
/// Create a new 2x3 matrix.
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub fn mat2x3<N: Scalar>(m11: N, m12: N, m13: N,
|
pub fn mat2x3<T: Scalar>(m11: T, m12: T, m13: T,
|
||||||
m21: N, m22: N, m23: N) -> TMat2x3<N> {
|
m21: T, m22: T, m23: T) -> TMat2x3<T> {
|
||||||
TMat::<N, U2, U3>::new(
|
TMat::<T, 2, 3>::new(
|
||||||
m11, m12, m13,
|
m11, m12, m13,
|
||||||
m21, m22, m23,
|
m21, m22, m23,
|
||||||
)
|
)
|
||||||
|
@ -65,9 +65,9 @@ pub fn mat2x3<N: Scalar>(m11: N, m12: N, m13: N,
|
||||||
|
|
||||||
/// Create a new 2x4 matrix.
|
/// Create a new 2x4 matrix.
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub fn mat2x4<N: Scalar>(m11: N, m12: N, m13: N, m14: N,
|
pub fn mat2x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
|
||||||
m21: N, m22: N, m23: N, m24: N) -> TMat2x4<N> {
|
m21: T, m22: T, m23: T, m24: T) -> TMat2x4<T> {
|
||||||
TMat::<N, U2, U4>::new(
|
TMat::<T, 2, 4>::new(
|
||||||
m11, m12, m13, m14,
|
m11, m12, m13, m14,
|
||||||
m21, m22, m23, m24,
|
m21, m22, m23, m24,
|
||||||
)
|
)
|
||||||
|
@ -75,10 +75,10 @@ pub fn mat2x4<N: Scalar>(m11: N, m12: N, m13: N, m14: N,
|
||||||
|
|
||||||
/// Create a new 3x3 matrix.
|
/// Create a new 3x3 matrix.
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub fn mat3<N: Scalar>(m11: N, m12: N, m13: N,
|
pub fn mat3<T: Scalar>(m11: T, m12: T, m13: T,
|
||||||
m21: N, m22: N, m23: N,
|
m21: T, m22: T, m23: T,
|
||||||
m31: N, m32: N, m33: N) -> TMat3<N> {
|
m31: T, m32: T, m33: T) -> TMat3<T> {
|
||||||
TMat::<N, U3, U3>::new(
|
TMat::<T, 3, 3>::new(
|
||||||
m11, m12, m13,
|
m11, m12, m13,
|
||||||
m21, m22, m23,
|
m21, m22, m23,
|
||||||
m31, m32, m33,
|
m31, m32, m33,
|
||||||
|
@ -87,10 +87,10 @@ pub fn mat3<N: Scalar>(m11: N, m12: N, m13: N,
|
||||||
|
|
||||||
/// Create a new 3x2 matrix.
|
/// Create a new 3x2 matrix.
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub fn mat3x2<N: Scalar>(m11: N, m12: N,
|
pub fn mat3x2<T: Scalar>(m11: T, m12: T,
|
||||||
m21: N, m22: N,
|
m21: T, m22: T,
|
||||||
m31: N, m32: N) -> TMat3x2<N> {
|
m31: T, m32: T) -> TMat3x2<T> {
|
||||||
TMat::<N, U3, U2>::new(
|
TMat::<T, 3, 2>::new(
|
||||||
m11, m12,
|
m11, m12,
|
||||||
m21, m22,
|
m21, m22,
|
||||||
m31, m32,
|
m31, m32,
|
||||||
|
@ -99,10 +99,10 @@ pub fn mat3x2<N: Scalar>(m11: N, m12: N,
|
||||||
|
|
||||||
/// Create a new 3x3 matrix.
|
/// Create a new 3x3 matrix.
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub fn mat3x3<N: Scalar>(m11: N, m12: N, m13: N,
|
pub fn mat3x3<T: Scalar>(m11: T, m12: T, m13: T,
|
||||||
m21: N, m22: N, m23: N,
|
m21: T, m22: T, m23: T,
|
||||||
m31: N, m32: N, m33: N) -> TMat3<N> {
|
m31: T, m32: T, m33: T) -> TMat3<T> {
|
||||||
TMat::<N, U3, U3>::new(
|
TMat::<T, 3, 3>::new(
|
||||||
m11, m12, m13,
|
m11, m12, m13,
|
||||||
m31, m32, m33,
|
m31, m32, m33,
|
||||||
m21, m22, m23,
|
m21, m22, m23,
|
||||||
|
@ -111,10 +111,10 @@ pub fn mat3x3<N: Scalar>(m11: N, m12: N, m13: N,
|
||||||
|
|
||||||
/// Create a new 3x4 matrix.
|
/// Create a new 3x4 matrix.
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub fn mat3x4<N: Scalar>(m11: N, m12: N, m13: N, m14: N,
|
pub fn mat3x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
|
||||||
m21: N, m22: N, m23: N, m24: N,
|
m21: T, m22: T, m23: T, m24: T,
|
||||||
m31: N, m32: N, m33: N, m34: N) -> TMat3x4<N> {
|
m31: T, m32: T, m33: T, m34: T) -> TMat3x4<T> {
|
||||||
TMat::<N, U3, U4>::new(
|
TMat::<T, 3, 4>::new(
|
||||||
m11, m12, m13, m14,
|
m11, m12, m13, m14,
|
||||||
m21, m22, m23, m24,
|
m21, m22, m23, m24,
|
||||||
m31, m32, m33, m34,
|
m31, m32, m33, m34,
|
||||||
|
@ -123,11 +123,11 @@ pub fn mat3x4<N: Scalar>(m11: N, m12: N, m13: N, m14: N,
|
||||||
|
|
||||||
/// Create a new 4x2 matrix.
|
/// Create a new 4x2 matrix.
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub fn mat4x2<N: Scalar>(m11: N, m12: N,
|
pub fn mat4x2<T: Scalar>(m11: T, m12: T,
|
||||||
m21: N, m22: N,
|
m21: T, m22: T,
|
||||||
m31: N, m32: N,
|
m31: T, m32: T,
|
||||||
m41: N, m42: N) -> TMat4x2<N> {
|
m41: T, m42: T) -> TMat4x2<T> {
|
||||||
TMat::<N, U4, U2>::new(
|
TMat::<T, 4, 2>::new(
|
||||||
m11, m12,
|
m11, m12,
|
||||||
m21, m22,
|
m21, m22,
|
||||||
m31, m32,
|
m31, m32,
|
||||||
|
@ -137,11 +137,11 @@ pub fn mat4x2<N: Scalar>(m11: N, m12: N,
|
||||||
|
|
||||||
/// Create a new 4x3 matrix.
|
/// Create a new 4x3 matrix.
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub fn mat4x3<N: Scalar>(m11: N, m12: N, m13: N,
|
pub fn mat4x3<T: Scalar>(m11: T, m12: T, m13: T,
|
||||||
m21: N, m22: N, m23: N,
|
m21: T, m22: T, m23: T,
|
||||||
m31: N, m32: N, m33: N,
|
m31: T, m32: T, m33: T,
|
||||||
m41: N, m42: N, m43: N) -> TMat4x3<N> {
|
m41: T, m42: T, m43: T) -> TMat4x3<T> {
|
||||||
TMat::<N, U4, U3>::new(
|
TMat::<T, 4, 3>::new(
|
||||||
m11, m12, m13,
|
m11, m12, m13,
|
||||||
m21, m22, m23,
|
m21, m22, m23,
|
||||||
m31, m32, m33,
|
m31, m32, m33,
|
||||||
|
@ -151,11 +151,11 @@ pub fn mat4x3<N: Scalar>(m11: N, m12: N, m13: N,
|
||||||
|
|
||||||
/// Create a new 4x4 matrix.
|
/// Create a new 4x4 matrix.
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub fn mat4x4<N: Scalar>(m11: N, m12: N, m13: N, m14: N,
|
pub fn mat4x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
|
||||||
m21: N, m22: N, m23: N, m24: N,
|
m21: T, m22: T, m23: T, m24: T,
|
||||||
m31: N, m32: N, m33: N, m34: N,
|
m31: T, m32: T, m33: T, m34: T,
|
||||||
m41: N, m42: N, m43: N, m44: N) -> TMat4<N> {
|
m41: T, m42: T, m43: T, m44: T) -> TMat4<T> {
|
||||||
TMat::<N, U4, U4>::new(
|
TMat::<T, 4, 4>::new(
|
||||||
m11, m12, m13, m14,
|
m11, m12, m13, m14,
|
||||||
m21, m22, m23, m24,
|
m21, m22, m23, m24,
|
||||||
m31, m32, m33, m34,
|
m31, m32, m33, m34,
|
||||||
|
@ -165,11 +165,11 @@ pub fn mat4x4<N: Scalar>(m11: N, m12: N, m13: N, m14: N,
|
||||||
|
|
||||||
/// Create a new 4x4 matrix.
|
/// Create a new 4x4 matrix.
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub fn mat4<N: Scalar>(m11: N, m12: N, m13: N, m14: N,
|
pub fn mat4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
|
||||||
m21: N, m22: N, m23: N, m24: N,
|
m21: T, m22: T, m23: T, m24: T,
|
||||||
m31: N, m32: N, m33: N, m34: N,
|
m31: T, m32: T, m33: T, m34: T,
|
||||||
m41: N, m42: N, m43: N, m44: N) -> TMat4<N> {
|
m41: T, m42: T, m43: T, m44: T) -> TMat4<T> {
|
||||||
TMat::<N, U4, U4>::new(
|
TMat::<T, 4, 4>::new(
|
||||||
m11, m12, m13, m14,
|
m11, m12, m13, m14,
|
||||||
m21, m22, m23, m24,
|
m21, m22, m23, m24,
|
||||||
m31, m32, m33, m34,
|
m31, m32, m33, m34,
|
||||||
|
@ -178,6 +178,6 @@ pub fn mat4<N: Scalar>(m11: N, m12: N, m13: N, m14: N,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new quaternion.
|
/// Creates a new quaternion.
|
||||||
pub fn quat<N: RealField>(x: N, y: N, z: N, w: N) -> Qua<N> {
|
pub fn quat<T: RealField>(x: T, y: T, z: T, w: T) -> Qua<T> {
|
||||||
Qua::new(w, x, y, z)
|
Qua::new(w, x, y, z)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,12 @@
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
use crate::traits::{Alloc, Dimension};
|
use na::RealField;
|
||||||
use na::{DefaultAllocator, RealField};
|
|
||||||
|
|
||||||
/// Component-wise exponential.
|
/// Component-wise exponential.
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`exp2`](fn.exp2.html)
|
/// * [`exp2`](fn.exp2.html)
|
||||||
pub fn exp<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
pub fn exp<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
v.map(|x| x.exp())
|
v.map(|x| x.exp())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,10 +15,7 @@ where
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`exp`](fn.exp.html)
|
/// * [`exp`](fn.exp.html)
|
||||||
pub fn exp2<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
pub fn exp2<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
v.map(|x| x.exp2())
|
v.map(|x| x.exp2())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,11 +24,8 @@ where
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`sqrt`](fn.sqrt.html)
|
/// * [`sqrt`](fn.sqrt.html)
|
||||||
pub fn inversesqrt<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
pub fn inversesqrt<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
v.map(|x| T::one() / x.sqrt())
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
v.map(|x| N::one() / x.sqrt())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise logarithm.
|
/// Component-wise logarithm.
|
||||||
|
@ -43,10 +33,7 @@ where
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`log2`](fn.log2.html)
|
/// * [`log2`](fn.log2.html)
|
||||||
pub fn log<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
pub fn log<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
v.map(|x| x.ln())
|
v.map(|x| x.ln())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,18 +42,12 @@ where
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`log`](fn.log.html)
|
/// * [`log`](fn.log.html)
|
||||||
pub fn log2<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
pub fn log2<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
v.map(|x| x.log2())
|
v.map(|x| x.log2())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise power.
|
/// Component-wise power.
|
||||||
pub fn pow<N: RealField, D: Dimension>(base: &TVec<N, D>, exponent: &TVec<N, D>) -> TVec<N, D>
|
pub fn pow<T: RealField, const D: usize>(base: &TVec<T, D>, exponent: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
base.zip_map(exponent, |b, e| b.powf(e))
|
base.zip_map(exponent, |b, e| b.powf(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,9 +59,6 @@ where
|
||||||
/// * [`exp2`](fn.exp2.html)
|
/// * [`exp2`](fn.exp2.html)
|
||||||
/// * [`inversesqrt`](fn.inversesqrt.html)
|
/// * [`inversesqrt`](fn.inversesqrt.html)
|
||||||
/// * [`pow`](fn.pow.html)
|
/// * [`pow`](fn.pow.html)
|
||||||
pub fn sqrt<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
pub fn sqrt<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
v.map(|x| x.sqrt())
|
v.map(|x| x.sqrt())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,51 +1,51 @@
|
||||||
use crate::aliases::TMat4;
|
use crate::aliases::TMat4;
|
||||||
use na::RealField;
|
use na::RealField;
|
||||||
|
|
||||||
//pub fn frustum<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
//pub fn frustum<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//pub fn frustum_lh<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
//pub fn frustum_lh<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn frustum_lr_no<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
//pub fn frustum_lr_no<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn frustum_lh_zo<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
//pub fn frustum_lh_zo<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn frustum_no<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
//pub fn frustum_no<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn frustum_rh<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
//pub fn frustum_rh<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn frustum_rh_no<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
//pub fn frustum_rh_no<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn frustum_rh_zo<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
//pub fn frustum_rh_zo<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn frustum_zo<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
//pub fn frustum_zo<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//pub fn infinite_perspective<N: RealField>(fovy: N, aspect: N, near: N) -> TMat4<N> {
|
//pub fn infinite_perspective<T: RealField>(fovy: T, aspect: T, near: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn infinite_perspective_lh<N: RealField>(fovy: N, aspect: N, near: N) -> TMat4<N> {
|
//pub fn infinite_perspective_lh<T: RealField>(fovy: T, aspect: T, near: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn infinite_ortho<N: RealField>(left: N, right: N, bottom: N, top: N) -> TMat4<N> {
|
//pub fn infinite_ortho<T: RealField>(left: T, right: T, bottom: T, top: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ use na::RealField;
|
||||||
/// * `znear` - Distance from the viewer to the near clipping plane
|
/// * `znear` - Distance from the viewer to the near clipping plane
|
||||||
/// * `zfar` - Distance from the viewer to the far clipping plane
|
/// * `zfar` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn ortho<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
pub fn ortho<T: RealField>(left: T, right: T, bottom: T, top: T, znear: T, zfar: T) -> TMat4<T> {
|
||||||
ortho_rh_no(left, right, bottom, top, znear, zfar)
|
ortho_rh_no(left, right, bottom, top, znear, zfar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ pub fn ortho<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar:
|
||||||
/// * `znear` - Distance from the viewer to the near clipping plane
|
/// * `znear` - Distance from the viewer to the near clipping plane
|
||||||
/// * `zfar` - Distance from the viewer to the far clipping plane
|
/// * `zfar` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn ortho_lh<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
pub fn ortho_lh<T: RealField>(left: T, right: T, bottom: T, top: T, znear: T, zfar: T) -> TMat4<T> {
|
||||||
ortho_lh_no(left, right, bottom, top, znear, zfar)
|
ortho_lh_no(left, right, bottom, top, znear, zfar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,16 +90,16 @@ pub fn ortho_lh<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zf
|
||||||
/// * `znear` - Distance from the viewer to the near clipping plane
|
/// * `znear` - Distance from the viewer to the near clipping plane
|
||||||
/// * `zfar` - Distance from the viewer to the far clipping plane
|
/// * `zfar` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn ortho_lh_no<N: RealField>(
|
pub fn ortho_lh_no<T: RealField>(
|
||||||
left: N,
|
left: T,
|
||||||
right: N,
|
right: T,
|
||||||
bottom: N,
|
bottom: T,
|
||||||
top: N,
|
top: T,
|
||||||
znear: N,
|
znear: T,
|
||||||
zfar: N,
|
zfar: T,
|
||||||
) -> TMat4<N> {
|
) -> TMat4<T> {
|
||||||
let two: N = crate::convert(2.0);
|
let two: T = crate::convert(2.0);
|
||||||
let mut mat: TMat4<N> = TMat4::<N>::identity();
|
let mut mat: TMat4<T> = TMat4::<T>::identity();
|
||||||
|
|
||||||
mat[(0, 0)] = two / (right - left);
|
mat[(0, 0)] = two / (right - left);
|
||||||
mat[(0, 3)] = -(right + left) / (right - left);
|
mat[(0, 3)] = -(right + left) / (right - left);
|
||||||
|
@ -122,17 +122,17 @@ pub fn ortho_lh_no<N: RealField>(
|
||||||
/// * `znear` - Distance from the viewer to the near clipping plane
|
/// * `znear` - Distance from the viewer to the near clipping plane
|
||||||
/// * `zfar` - Distance from the viewer to the far clipping plane
|
/// * `zfar` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn ortho_lh_zo<N: RealField>(
|
pub fn ortho_lh_zo<T: RealField>(
|
||||||
left: N,
|
left: T,
|
||||||
right: N,
|
right: T,
|
||||||
bottom: N,
|
bottom: T,
|
||||||
top: N,
|
top: T,
|
||||||
znear: N,
|
znear: T,
|
||||||
zfar: N,
|
zfar: T,
|
||||||
) -> TMat4<N> {
|
) -> TMat4<T> {
|
||||||
let one: N = N::one();
|
let one: T = T::one();
|
||||||
let two: N = crate::convert(2.0);
|
let two: T = crate::convert(2.0);
|
||||||
let mut mat: TMat4<N> = TMat4::<N>::identity();
|
let mut mat: TMat4<T> = TMat4::<T>::identity();
|
||||||
|
|
||||||
mat[(0, 0)] = two / (right - left);
|
mat[(0, 0)] = two / (right - left);
|
||||||
mat[(0, 3)] = -(right + left) / (right - left);
|
mat[(0, 3)] = -(right + left) / (right - left);
|
||||||
|
@ -155,7 +155,7 @@ pub fn ortho_lh_zo<N: RealField>(
|
||||||
/// * `znear` - Distance from the viewer to the near clipping plane
|
/// * `znear` - Distance from the viewer to the near clipping plane
|
||||||
/// * `zfar` - Distance from the viewer to the far clipping plane
|
/// * `zfar` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn ortho_no<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
pub fn ortho_no<T: RealField>(left: T, right: T, bottom: T, top: T, znear: T, zfar: T) -> TMat4<T> {
|
||||||
ortho_rh_no(left, right, bottom, top, znear, zfar)
|
ortho_rh_no(left, right, bottom, top, znear, zfar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ pub fn ortho_no<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zf
|
||||||
/// * `znear` - Distance from the viewer to the near clipping plane
|
/// * `znear` - Distance from the viewer to the near clipping plane
|
||||||
/// * `zfar` - Distance from the viewer to the far clipping plane
|
/// * `zfar` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn ortho_rh<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
pub fn ortho_rh<T: RealField>(left: T, right: T, bottom: T, top: T, znear: T, zfar: T) -> TMat4<T> {
|
||||||
ortho_rh_no(left, right, bottom, top, znear, zfar)
|
ortho_rh_no(left, right, bottom, top, znear, zfar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,16 +185,16 @@ pub fn ortho_rh<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zf
|
||||||
/// * `znear` - Distance from the viewer to the near clipping plane
|
/// * `znear` - Distance from the viewer to the near clipping plane
|
||||||
/// * `zfar` - Distance from the viewer to the far clipping plane
|
/// * `zfar` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn ortho_rh_no<N: RealField>(
|
pub fn ortho_rh_no<T: RealField>(
|
||||||
left: N,
|
left: T,
|
||||||
right: N,
|
right: T,
|
||||||
bottom: N,
|
bottom: T,
|
||||||
top: N,
|
top: T,
|
||||||
znear: N,
|
znear: T,
|
||||||
zfar: N,
|
zfar: T,
|
||||||
) -> TMat4<N> {
|
) -> TMat4<T> {
|
||||||
let two: N = crate::convert(2.0);
|
let two: T = crate::convert(2.0);
|
||||||
let mut mat: TMat4<N> = TMat4::<N>::identity();
|
let mut mat: TMat4<T> = TMat4::<T>::identity();
|
||||||
|
|
||||||
mat[(0, 0)] = two / (right - left);
|
mat[(0, 0)] = two / (right - left);
|
||||||
mat[(0, 3)] = -(right + left) / (right - left);
|
mat[(0, 3)] = -(right + left) / (right - left);
|
||||||
|
@ -217,17 +217,17 @@ pub fn ortho_rh_no<N: RealField>(
|
||||||
/// * `znear` - Distance from the viewer to the near clipping plane
|
/// * `znear` - Distance from the viewer to the near clipping plane
|
||||||
/// * `zfar` - Distance from the viewer to the far clipping plane
|
/// * `zfar` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn ortho_rh_zo<N: RealField>(
|
pub fn ortho_rh_zo<T: RealField>(
|
||||||
left: N,
|
left: T,
|
||||||
right: N,
|
right: T,
|
||||||
bottom: N,
|
bottom: T,
|
||||||
top: N,
|
top: T,
|
||||||
znear: N,
|
znear: T,
|
||||||
zfar: N,
|
zfar: T,
|
||||||
) -> TMat4<N> {
|
) -> TMat4<T> {
|
||||||
let one: N = N::one();
|
let one: T = T::one();
|
||||||
let two: N = crate::convert(2.0);
|
let two: T = crate::convert(2.0);
|
||||||
let mut mat: TMat4<N> = TMat4::<N>::identity();
|
let mut mat: TMat4<T> = TMat4::<T>::identity();
|
||||||
|
|
||||||
mat[(0, 0)] = two / (right - left);
|
mat[(0, 0)] = two / (right - left);
|
||||||
mat[(0, 3)] = -(right + left) / (right - left);
|
mat[(0, 3)] = -(right + left) / (right - left);
|
||||||
|
@ -250,7 +250,7 @@ pub fn ortho_rh_zo<N: RealField>(
|
||||||
/// * `znear` - Distance from the viewer to the near clipping plane
|
/// * `znear` - Distance from the viewer to the near clipping plane
|
||||||
/// * `zfar` - Distance from the viewer to the far clipping plane
|
/// * `zfar` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn ortho_zo<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
pub fn ortho_zo<T: RealField>(left: T, right: T, bottom: T, top: T, znear: T, zfar: T) -> TMat4<T> {
|
||||||
ortho_rh_zo(left, right, bottom, top, znear, zfar)
|
ortho_rh_zo(left, right, bottom, top, znear, zfar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ pub fn ortho_zo<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zf
|
||||||
/// * `near` - Distance from the viewer to the near clipping plane
|
/// * `near` - Distance from the viewer to the near clipping plane
|
||||||
/// * `far` - Distance from the viewer to the far clipping plane
|
/// * `far` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn perspective_fov<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_fov<T: RealField>(fov: T, width: T, height: T, near: T, far: T) -> TMat4<T> {
|
||||||
perspective_fov_rh_no(fov, width, height, near, far)
|
perspective_fov_rh_no(fov, width, height, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +278,7 @@ pub fn perspective_fov<N: RealField>(fov: N, width: N, height: N, near: N, far:
|
||||||
/// * `near` - Distance from the viewer to the near clipping plane
|
/// * `near` - Distance from the viewer to the near clipping plane
|
||||||
/// * `far` - Distance from the viewer to the far clipping plane
|
/// * `far` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn perspective_fov_lh<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_fov_lh<T: RealField>(fov: T, width: T, height: T, near: T, far: T) -> TMat4<T> {
|
||||||
perspective_fov_lh_no(fov, width, height, near, far)
|
perspective_fov_lh_no(fov, width, height, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,16 +292,16 @@ pub fn perspective_fov_lh<N: RealField>(fov: N, width: N, height: N, near: N, fa
|
||||||
/// * `near` - Distance from the viewer to the near clipping plane
|
/// * `near` - Distance from the viewer to the near clipping plane
|
||||||
/// * `far` - Distance from the viewer to the far clipping plane
|
/// * `far` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn perspective_fov_lh_no<N: RealField>(
|
pub fn perspective_fov_lh_no<T: RealField>(
|
||||||
fov: N,
|
fov: T,
|
||||||
width: N,
|
width: T,
|
||||||
height: N,
|
height: T,
|
||||||
near: N,
|
near: T,
|
||||||
far: N,
|
far: T,
|
||||||
) -> TMat4<N> {
|
) -> TMat4<T> {
|
||||||
assert!(width > N::zero(), "The width must be greater than zero");
|
assert!(width > T::zero(), "The width must be greater than zero");
|
||||||
assert!(height > N::zero(), "The height must be greater than zero.");
|
assert!(height > T::zero(), "The height must be greater than zero.");
|
||||||
assert!(fov > N::zero(), "The fov must be greater than zero");
|
assert!(fov > T::zero(), "The fov must be greater than zero");
|
||||||
|
|
||||||
let mut mat = TMat4::zeros();
|
let mut mat = TMat4::zeros();
|
||||||
|
|
||||||
|
@ -313,7 +313,7 @@ pub fn perspective_fov_lh_no<N: RealField>(
|
||||||
mat[(1, 1)] = h;
|
mat[(1, 1)] = h;
|
||||||
mat[(2, 2)] = (far + near) / (far - near);
|
mat[(2, 2)] = (far + near) / (far - near);
|
||||||
mat[(2, 3)] = -(far * near * crate::convert(2.0)) / (far - near);
|
mat[(2, 3)] = -(far * near * crate::convert(2.0)) / (far - near);
|
||||||
mat[(3, 2)] = N::one();
|
mat[(3, 2)] = T::one();
|
||||||
|
|
||||||
mat
|
mat
|
||||||
}
|
}
|
||||||
|
@ -328,16 +328,16 @@ pub fn perspective_fov_lh_no<N: RealField>(
|
||||||
/// * `near` - Distance from the viewer to the near clipping plane
|
/// * `near` - Distance from the viewer to the near clipping plane
|
||||||
/// * `far` - Distance from the viewer to the far clipping plane
|
/// * `far` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn perspective_fov_lh_zo<N: RealField>(
|
pub fn perspective_fov_lh_zo<T: RealField>(
|
||||||
fov: N,
|
fov: T,
|
||||||
width: N,
|
width: T,
|
||||||
height: N,
|
height: T,
|
||||||
near: N,
|
near: T,
|
||||||
far: N,
|
far: T,
|
||||||
) -> TMat4<N> {
|
) -> TMat4<T> {
|
||||||
assert!(width > N::zero(), "The width must be greater than zero");
|
assert!(width > T::zero(), "The width must be greater than zero");
|
||||||
assert!(height > N::zero(), "The height must be greater than zero.");
|
assert!(height > T::zero(), "The height must be greater than zero.");
|
||||||
assert!(fov > N::zero(), "The fov must be greater than zero");
|
assert!(fov > T::zero(), "The fov must be greater than zero");
|
||||||
|
|
||||||
let mut mat = TMat4::zeros();
|
let mut mat = TMat4::zeros();
|
||||||
|
|
||||||
|
@ -349,7 +349,7 @@ pub fn perspective_fov_lh_zo<N: RealField>(
|
||||||
mat[(1, 1)] = h;
|
mat[(1, 1)] = h;
|
||||||
mat[(2, 2)] = far / (far - near);
|
mat[(2, 2)] = far / (far - near);
|
||||||
mat[(2, 3)] = -(far * near) / (far - near);
|
mat[(2, 3)] = -(far * near) / (far - near);
|
||||||
mat[(3, 2)] = N::one();
|
mat[(3, 2)] = T::one();
|
||||||
|
|
||||||
mat
|
mat
|
||||||
}
|
}
|
||||||
|
@ -364,7 +364,7 @@ pub fn perspective_fov_lh_zo<N: RealField>(
|
||||||
/// * `near` - Distance from the viewer to the near clipping plane
|
/// * `near` - Distance from the viewer to the near clipping plane
|
||||||
/// * `far` - Distance from the viewer to the far clipping plane
|
/// * `far` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn perspective_fov_no<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_fov_no<T: RealField>(fov: T, width: T, height: T, near: T, far: T) -> TMat4<T> {
|
||||||
perspective_fov_rh_no(fov, width, height, near, far)
|
perspective_fov_rh_no(fov, width, height, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,7 +378,7 @@ pub fn perspective_fov_no<N: RealField>(fov: N, width: N, height: N, near: N, fa
|
||||||
/// * `near` - Distance from the viewer to the near clipping plane
|
/// * `near` - Distance from the viewer to the near clipping plane
|
||||||
/// * `far` - Distance from the viewer to the far clipping plane
|
/// * `far` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn perspective_fov_rh<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_fov_rh<T: RealField>(fov: T, width: T, height: T, near: T, far: T) -> TMat4<T> {
|
||||||
perspective_fov_rh_no(fov, width, height, near, far)
|
perspective_fov_rh_no(fov, width, height, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,16 +392,16 @@ pub fn perspective_fov_rh<N: RealField>(fov: N, width: N, height: N, near: N, fa
|
||||||
/// * `near` - Distance from the viewer to the near clipping plane
|
/// * `near` - Distance from the viewer to the near clipping plane
|
||||||
/// * `far` - Distance from the viewer to the far clipping plane
|
/// * `far` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn perspective_fov_rh_no<N: RealField>(
|
pub fn perspective_fov_rh_no<T: RealField>(
|
||||||
fov: N,
|
fov: T,
|
||||||
width: N,
|
width: T,
|
||||||
height: N,
|
height: T,
|
||||||
near: N,
|
near: T,
|
||||||
far: N,
|
far: T,
|
||||||
) -> TMat4<N> {
|
) -> TMat4<T> {
|
||||||
assert!(width > N::zero(), "The width must be greater than zero");
|
assert!(width > T::zero(), "The width must be greater than zero");
|
||||||
assert!(height > N::zero(), "The height must be greater than zero.");
|
assert!(height > T::zero(), "The height must be greater than zero.");
|
||||||
assert!(fov > N::zero(), "The fov must be greater than zero");
|
assert!(fov > T::zero(), "The fov must be greater than zero");
|
||||||
|
|
||||||
let mut mat = TMat4::zeros();
|
let mut mat = TMat4::zeros();
|
||||||
|
|
||||||
|
@ -413,7 +413,7 @@ pub fn perspective_fov_rh_no<N: RealField>(
|
||||||
mat[(1, 1)] = h;
|
mat[(1, 1)] = h;
|
||||||
mat[(2, 2)] = -(far + near) / (far - near);
|
mat[(2, 2)] = -(far + near) / (far - near);
|
||||||
mat[(2, 3)] = -(far * near * crate::convert(2.0)) / (far - near);
|
mat[(2, 3)] = -(far * near * crate::convert(2.0)) / (far - near);
|
||||||
mat[(3, 2)] = -N::one();
|
mat[(3, 2)] = -T::one();
|
||||||
|
|
||||||
mat
|
mat
|
||||||
}
|
}
|
||||||
|
@ -428,16 +428,16 @@ pub fn perspective_fov_rh_no<N: RealField>(
|
||||||
/// * `near` - Distance from the viewer to the near clipping plane
|
/// * `near` - Distance from the viewer to the near clipping plane
|
||||||
/// * `far` - Distance from the viewer to the far clipping plane
|
/// * `far` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn perspective_fov_rh_zo<N: RealField>(
|
pub fn perspective_fov_rh_zo<T: RealField>(
|
||||||
fov: N,
|
fov: T,
|
||||||
width: N,
|
width: T,
|
||||||
height: N,
|
height: T,
|
||||||
near: N,
|
near: T,
|
||||||
far: N,
|
far: T,
|
||||||
) -> TMat4<N> {
|
) -> TMat4<T> {
|
||||||
assert!(width > N::zero(), "The width must be greater than zero");
|
assert!(width > T::zero(), "The width must be greater than zero");
|
||||||
assert!(height > N::zero(), "The height must be greater than zero.");
|
assert!(height > T::zero(), "The height must be greater than zero.");
|
||||||
assert!(fov > N::zero(), "The fov must be greater than zero");
|
assert!(fov > T::zero(), "The fov must be greater than zero");
|
||||||
|
|
||||||
let mut mat = TMat4::zeros();
|
let mut mat = TMat4::zeros();
|
||||||
|
|
||||||
|
@ -449,7 +449,7 @@ pub fn perspective_fov_rh_zo<N: RealField>(
|
||||||
mat[(1, 1)] = h;
|
mat[(1, 1)] = h;
|
||||||
mat[(2, 2)] = far / (near - far);
|
mat[(2, 2)] = far / (near - far);
|
||||||
mat[(2, 3)] = -(far * near) / (far - near);
|
mat[(2, 3)] = -(far * near) / (far - near);
|
||||||
mat[(3, 2)] = -N::one();
|
mat[(3, 2)] = -T::one();
|
||||||
|
|
||||||
mat
|
mat
|
||||||
}
|
}
|
||||||
|
@ -464,7 +464,7 @@ pub fn perspective_fov_rh_zo<N: RealField>(
|
||||||
/// * `near` - Distance from the viewer to the near clipping plane
|
/// * `near` - Distance from the viewer to the near clipping plane
|
||||||
/// * `far` - Distance from the viewer to the far clipping plane
|
/// * `far` - Distance from the viewer to the far clipping plane
|
||||||
///
|
///
|
||||||
pub fn perspective_fov_zo<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_fov_zo<T: RealField>(fov: T, width: T, height: T, near: T, far: T) -> TMat4<T> {
|
||||||
perspective_fov_rh_zo(fov, width, height, near, far)
|
perspective_fov_rh_zo(fov, width, height, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,7 +479,7 @@ pub fn perspective_fov_zo<N: RealField>(fov: N, width: N, height: N, near: N, fa
|
||||||
///
|
///
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
pub fn perspective<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
||||||
// TODO: Breaking change - revert back to proper glm conventions?
|
// TODO: Breaking change - revert back to proper glm conventions?
|
||||||
//
|
//
|
||||||
// Prior to changes to support configuring the behaviour of this function it was simply
|
// Prior to changes to support configuring the behaviour of this function it was simply
|
||||||
|
@ -508,7 +508,7 @@ pub fn perspective<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N
|
||||||
///
|
///
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
pub fn perspective_lh<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_lh<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
||||||
perspective_lh_no(aspect, fovy, near, far)
|
perspective_lh_no(aspect, fovy, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,19 +523,19 @@ pub fn perspective_lh<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat
|
||||||
///
|
///
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
pub fn perspective_lh_no<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_lh_no<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
||||||
assert!(
|
assert!(
|
||||||
!relative_eq!(far - near, N::zero()),
|
!relative_eq!(far - near, T::zero()),
|
||||||
"The near-plane and far-plane must not be superimposed."
|
"The near-plane and far-plane must not be superimposed."
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
!relative_eq!(aspect, N::zero()),
|
!relative_eq!(aspect, T::zero()),
|
||||||
"The aspect ratio must not be zero."
|
"The aspect ratio must not be zero."
|
||||||
);
|
);
|
||||||
|
|
||||||
let one = N::one();
|
let one = T::one();
|
||||||
let two: N = crate::convert(2.0);
|
let two: T = crate::convert(2.0);
|
||||||
let mut mat: TMat4<N> = TMat4::zeros();
|
let mut mat: TMat4<T> = TMat4::zeros();
|
||||||
|
|
||||||
let tan_half_fovy = (fovy / two).tan();
|
let tan_half_fovy = (fovy / two).tan();
|
||||||
|
|
||||||
|
@ -559,19 +559,19 @@ pub fn perspective_lh_no<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> T
|
||||||
///
|
///
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
pub fn perspective_lh_zo<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_lh_zo<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
||||||
assert!(
|
assert!(
|
||||||
!relative_eq!(far - near, N::zero()),
|
!relative_eq!(far - near, T::zero()),
|
||||||
"The near-plane and far-plane must not be superimposed."
|
"The near-plane and far-plane must not be superimposed."
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
!relative_eq!(aspect, N::zero()),
|
!relative_eq!(aspect, T::zero()),
|
||||||
"The aspect ratio must not be zero."
|
"The aspect ratio must not be zero."
|
||||||
);
|
);
|
||||||
|
|
||||||
let one = N::one();
|
let one = T::one();
|
||||||
let two: N = crate::convert(2.0);
|
let two: T = crate::convert(2.0);
|
||||||
let mut mat: TMat4<N> = TMat4::zeros();
|
let mut mat: TMat4<T> = TMat4::zeros();
|
||||||
|
|
||||||
let tan_half_fovy = (fovy / two).tan();
|
let tan_half_fovy = (fovy / two).tan();
|
||||||
|
|
||||||
|
@ -595,7 +595,7 @@ pub fn perspective_lh_zo<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> T
|
||||||
///
|
///
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
pub fn perspective_no<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_no<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
||||||
perspective_rh_no(aspect, fovy, near, far)
|
perspective_rh_no(aspect, fovy, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -610,7 +610,7 @@ pub fn perspective_no<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat
|
||||||
///
|
///
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
pub fn perspective_rh<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_rh<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
||||||
perspective_rh_no(aspect, fovy, near, far)
|
perspective_rh_no(aspect, fovy, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -625,19 +625,19 @@ pub fn perspective_rh<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat
|
||||||
///
|
///
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
pub fn perspective_rh_no<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_rh_no<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
||||||
assert!(
|
assert!(
|
||||||
!relative_eq!(far - near, N::zero()),
|
!relative_eq!(far - near, T::zero()),
|
||||||
"The near-plane and far-plane must not be superimposed."
|
"The near-plane and far-plane must not be superimposed."
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
!relative_eq!(aspect, N::zero()),
|
!relative_eq!(aspect, T::zero()),
|
||||||
"The aspect ratio must not be zero."
|
"The aspect ratio must not be zero."
|
||||||
);
|
);
|
||||||
|
|
||||||
let negone = -N::one();
|
let negone = -T::one();
|
||||||
let one = N::one();
|
let one = T::one();
|
||||||
let two: N = crate::convert(2.0);
|
let two: T = crate::convert(2.0);
|
||||||
let mut mat = TMat4::zeros();
|
let mut mat = TMat4::zeros();
|
||||||
|
|
||||||
let tan_half_fovy = (fovy / two).tan();
|
let tan_half_fovy = (fovy / two).tan();
|
||||||
|
@ -662,18 +662,18 @@ pub fn perspective_rh_no<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> T
|
||||||
///
|
///
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
pub fn perspective_rh_zo<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_rh_zo<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
||||||
assert!(
|
assert!(
|
||||||
!relative_eq!(far - near, N::zero()),
|
!relative_eq!(far - near, T::zero()),
|
||||||
"The near-plane and far-plane must not be superimposed."
|
"The near-plane and far-plane must not be superimposed."
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
!relative_eq!(aspect, N::zero()),
|
!relative_eq!(aspect, T::zero()),
|
||||||
"The aspect ratio must not be zero."
|
"The aspect ratio must not be zero."
|
||||||
);
|
);
|
||||||
|
|
||||||
let negone = -N::one();
|
let negone = -T::one();
|
||||||
let one = N::one();
|
let one = T::one();
|
||||||
let two = crate::convert(2.0);
|
let two = crate::convert(2.0);
|
||||||
let mut mat = TMat4::zeros();
|
let mut mat = TMat4::zeros();
|
||||||
|
|
||||||
|
@ -699,7 +699,7 @@ pub fn perspective_rh_zo<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> T
|
||||||
///
|
///
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
pub fn perspective_zo<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_zo<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
||||||
perspective_rh_zo(aspect, fovy, near, far)
|
perspective_rh_zo(aspect, fovy, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -713,15 +713,15 @@ pub fn perspective_zo<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat
|
||||||
///
|
///
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
pub fn infinite_perspective_rh_no<N: RealField>(aspect: N, fovy: N, near: N) -> TMat4<N> {
|
pub fn infinite_perspective_rh_no<T: RealField>(aspect: T, fovy: T, near: T) -> TMat4<T> {
|
||||||
let f = N::one() / (fovy * na::convert(0.5)).tan();
|
let f = T::one() / (fovy * na::convert(0.5)).tan();
|
||||||
let mut mat = TMat4::zeros();
|
let mut mat = TMat4::zeros();
|
||||||
|
|
||||||
mat[(0, 0)] = f / aspect;
|
mat[(0, 0)] = f / aspect;
|
||||||
mat[(1, 1)] = f;
|
mat[(1, 1)] = f;
|
||||||
mat[(2, 2)] = -N::one();
|
mat[(2, 2)] = -T::one();
|
||||||
mat[(2, 3)] = -near * na::convert(2.0);
|
mat[(2, 3)] = -near * na::convert(2.0);
|
||||||
mat[(3, 2)] = -N::one();
|
mat[(3, 2)] = -T::one();
|
||||||
|
|
||||||
mat
|
mat
|
||||||
}
|
}
|
||||||
|
@ -738,15 +738,15 @@ pub fn infinite_perspective_rh_no<N: RealField>(aspect: N, fovy: N, near: N) ->
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
///
|
///
|
||||||
// https://discourse.nphysics.org/t/reversed-z-and-infinite-zfar-in-projections/341/2
|
// https://discourse.nphysics.org/t/reversed-z-and-infinite-zfar-in-projections/341/2
|
||||||
pub fn infinite_perspective_rh_zo<N: RealField>(aspect: N, fovy: N, near: N) -> TMat4<N> {
|
pub fn infinite_perspective_rh_zo<T: RealField>(aspect: T, fovy: T, near: T) -> TMat4<T> {
|
||||||
let f = N::one() / (fovy * na::convert(0.5)).tan();
|
let f = T::one() / (fovy * na::convert(0.5)).tan();
|
||||||
let mut mat = TMat4::zeros();
|
let mut mat = TMat4::zeros();
|
||||||
|
|
||||||
mat[(0, 0)] = f / aspect;
|
mat[(0, 0)] = f / aspect;
|
||||||
mat[(1, 1)] = f;
|
mat[(1, 1)] = f;
|
||||||
mat[(2, 2)] = -N::one();
|
mat[(2, 2)] = -T::one();
|
||||||
mat[(2, 3)] = -near;
|
mat[(2, 3)] = -near;
|
||||||
mat[(3, 2)] = -N::one();
|
mat[(3, 2)] = -T::one();
|
||||||
|
|
||||||
mat
|
mat
|
||||||
}
|
}
|
||||||
|
@ -763,8 +763,8 @@ pub fn infinite_perspective_rh_zo<N: RealField>(aspect: N, fovy: N, near: N) ->
|
||||||
/// # Important note
|
/// # Important note
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
// NOTE: The variants `_no` of reversed perspective are not useful.
|
// NOTE: The variants `_no` of reversed perspective are not useful.
|
||||||
pub fn reversed_perspective_rh_zo<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
pub fn reversed_perspective_rh_zo<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
|
||||||
let one = N::one();
|
let one = T::one();
|
||||||
let two = crate::convert(2.0);
|
let two = crate::convert(2.0);
|
||||||
let mut mat = TMat4::zeros();
|
let mut mat = TMat4::zeros();
|
||||||
|
|
||||||
|
@ -791,22 +791,22 @@ pub fn reversed_perspective_rh_zo<N: RealField>(aspect: N, fovy: N, near: N, far
|
||||||
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
|
||||||
// Credit: https://discourse.nphysics.org/t/reversed-z-and-infinite-zfar-in-projections/341/2
|
// Credit: https://discourse.nphysics.org/t/reversed-z-and-infinite-zfar-in-projections/341/2
|
||||||
// NOTE: The variants `_no` of reversed perspective are not useful.
|
// NOTE: The variants `_no` of reversed perspective are not useful.
|
||||||
pub fn reversed_infinite_perspective_rh_zo<N: RealField>(aspect: N, fovy: N, near: N) -> TMat4<N> {
|
pub fn reversed_infinite_perspective_rh_zo<T: RealField>(aspect: T, fovy: T, near: T) -> TMat4<T> {
|
||||||
let f = N::one() / (fovy * na::convert(0.5)).tan();
|
let f = T::one() / (fovy * na::convert(0.5)).tan();
|
||||||
let mut mat = TMat4::zeros();
|
let mut mat = TMat4::zeros();
|
||||||
|
|
||||||
mat[(0, 0)] = f / aspect;
|
mat[(0, 0)] = f / aspect;
|
||||||
mat[(1, 1)] = f;
|
mat[(1, 1)] = f;
|
||||||
mat[(2, 3)] = near;
|
mat[(2, 3)] = near;
|
||||||
mat[(3, 2)] = -N::one();
|
mat[(3, 2)] = -T::one();
|
||||||
|
|
||||||
mat
|
mat
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn tweaked_infinite_perspective<N: RealField>(fovy: N, aspect: N, near: N) -> TMat4<N> {
|
//pub fn tweaked_infinite_perspective<T: RealField>(fovy: T, aspect: T, near: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn tweaked_infinite_perspective_ep<N: RealField>(fovy: N, aspect: N, near: N, ep: N) -> TMat4<N> {
|
//pub fn tweaked_infinite_perspective_ep<T: RealField>(fovy: T, aspect: T, near: T, ep: T) -> TMat4<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use na::{self, RealField, U3};
|
use na::{self, RealField};
|
||||||
|
|
||||||
use crate::aliases::{TMat4, TVec2, TVec3, TVec4};
|
use crate::aliases::{TMat4, TVec2, TVec3, TVec4};
|
||||||
|
|
||||||
|
@ -9,22 +9,22 @@ use crate::aliases::{TMat4, TVec2, TVec3, TVec4};
|
||||||
/// * `center` - Specify the center of a picking region in window coordinates.
|
/// * `center` - Specify the center of a picking region in window coordinates.
|
||||||
/// * `delta` - Specify the width and height, respectively, of the picking region in window coordinates.
|
/// * `delta` - Specify the width and height, respectively, of the picking region in window coordinates.
|
||||||
/// * `viewport` - Rendering viewport.
|
/// * `viewport` - Rendering viewport.
|
||||||
pub fn pick_matrix<N: RealField>(
|
pub fn pick_matrix<T: RealField>(
|
||||||
center: &TVec2<N>,
|
center: &TVec2<T>,
|
||||||
delta: &TVec2<N>,
|
delta: &TVec2<T>,
|
||||||
viewport: &TVec4<N>,
|
viewport: &TVec4<T>,
|
||||||
) -> TMat4<N> {
|
) -> TMat4<T> {
|
||||||
let shift = TVec3::new(
|
let shift = TVec3::new(
|
||||||
(viewport.z - (center.x - viewport.x) * na::convert(2.0)) / delta.x,
|
(viewport.z - (center.x - viewport.x) * na::convert(2.0)) / delta.x,
|
||||||
(viewport.w - (center.y - viewport.y) * na::convert(2.0)) / delta.y,
|
(viewport.w - (center.y - viewport.y) * na::convert(2.0)) / delta.y,
|
||||||
N::zero(),
|
T::zero(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let result = TMat4::new_translation(&shift);
|
let result = TMat4::new_translation(&shift);
|
||||||
result.prepend_nonuniform_scaling(&TVec3::new(
|
result.prepend_nonuniform_scaling(&TVec3::new(
|
||||||
viewport.z / delta.x,
|
viewport.z / delta.x,
|
||||||
viewport.w / delta.y,
|
viewport.w / delta.y,
|
||||||
N::one(),
|
T::one(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,12 +45,12 @@ pub fn pick_matrix<N: RealField>(
|
||||||
/// * [`unproject`](fn.unproject.html)
|
/// * [`unproject`](fn.unproject.html)
|
||||||
/// * [`unproject_no`](fn.unproject_no.html)
|
/// * [`unproject_no`](fn.unproject_no.html)
|
||||||
/// * [`unproject_zo`](fn.unproject_zo.html)
|
/// * [`unproject_zo`](fn.unproject_zo.html)
|
||||||
pub fn project<N: RealField>(
|
pub fn project<T: RealField>(
|
||||||
obj: &TVec3<N>,
|
obj: &TVec3<T>,
|
||||||
model: &TMat4<N>,
|
model: &TMat4<T>,
|
||||||
proj: &TMat4<N>,
|
proj: &TMat4<T>,
|
||||||
viewport: TVec4<N>,
|
viewport: TVec4<T>,
|
||||||
) -> TVec3<N> {
|
) -> TVec3<T> {
|
||||||
project_no(obj, model, proj, viewport)
|
project_no(obj, model, proj, viewport)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,12 +72,12 @@ pub fn project<N: RealField>(
|
||||||
/// * [`unproject`](fn.unproject.html)
|
/// * [`unproject`](fn.unproject.html)
|
||||||
/// * [`unproject_no`](fn.unproject_no.html)
|
/// * [`unproject_no`](fn.unproject_no.html)
|
||||||
/// * [`unproject_zo`](fn.unproject_zo.html)
|
/// * [`unproject_zo`](fn.unproject_zo.html)
|
||||||
pub fn project_no<N: RealField>(
|
pub fn project_no<T: RealField>(
|
||||||
obj: &TVec3<N>,
|
obj: &TVec3<T>,
|
||||||
model: &TMat4<N>,
|
model: &TMat4<T>,
|
||||||
proj: &TMat4<N>,
|
proj: &TMat4<T>,
|
||||||
viewport: TVec4<N>,
|
viewport: TVec4<T>,
|
||||||
) -> TVec3<N> {
|
) -> TVec3<T> {
|
||||||
let proj = project_zo(obj, model, proj, viewport);
|
let proj = project_zo(obj, model, proj, viewport);
|
||||||
TVec3::new(proj.x, proj.y, proj.z * na::convert(0.5) + na::convert(0.5))
|
TVec3::new(proj.x, proj.y, proj.z * na::convert(0.5) + na::convert(0.5))
|
||||||
}
|
}
|
||||||
|
@ -100,18 +100,18 @@ pub fn project_no<N: RealField>(
|
||||||
/// * [`unproject`](fn.unproject.html)
|
/// * [`unproject`](fn.unproject.html)
|
||||||
/// * [`unproject_no`](fn.unproject_no.html)
|
/// * [`unproject_no`](fn.unproject_no.html)
|
||||||
/// * [`unproject_zo`](fn.unproject_zo.html)
|
/// * [`unproject_zo`](fn.unproject_zo.html)
|
||||||
pub fn project_zo<N: RealField>(
|
pub fn project_zo<T: RealField>(
|
||||||
obj: &TVec3<N>,
|
obj: &TVec3<T>,
|
||||||
model: &TMat4<N>,
|
model: &TMat4<T>,
|
||||||
proj: &TMat4<N>,
|
proj: &TMat4<T>,
|
||||||
viewport: TVec4<N>,
|
viewport: TVec4<T>,
|
||||||
) -> TVec3<N> {
|
) -> TVec3<T> {
|
||||||
let normalized = proj * model * TVec4::new(obj.x, obj.y, obj.z, N::one());
|
let normalized = proj * model * TVec4::new(obj.x, obj.y, obj.z, T::one());
|
||||||
let scale = N::one() / normalized.w;
|
let scale = T::one() / normalized.w;
|
||||||
|
|
||||||
TVec3::new(
|
TVec3::new(
|
||||||
viewport.x + (viewport.z * (normalized.x * scale + N::one()) * na::convert(0.5)),
|
viewport.x + (viewport.z * (normalized.x * scale + T::one()) * na::convert(0.5)),
|
||||||
viewport.y + (viewport.w * (normalized.y * scale + N::one()) * na::convert(0.5)),
|
viewport.y + (viewport.w * (normalized.y * scale + T::one()) * na::convert(0.5)),
|
||||||
normalized.z * scale,
|
normalized.z * scale,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -133,12 +133,12 @@ pub fn project_zo<N: RealField>(
|
||||||
/// * [`project_zo`](fn.project_zo.html)
|
/// * [`project_zo`](fn.project_zo.html)
|
||||||
/// * [`unproject_no`](fn.unproject_no.html)
|
/// * [`unproject_no`](fn.unproject_no.html)
|
||||||
/// * [`unproject_zo`](fn.unproject_zo.html)
|
/// * [`unproject_zo`](fn.unproject_zo.html)
|
||||||
pub fn unproject<N: RealField>(
|
pub fn unproject<T: RealField>(
|
||||||
win: &TVec3<N>,
|
win: &TVec3<T>,
|
||||||
model: &TMat4<N>,
|
model: &TMat4<T>,
|
||||||
proj: &TMat4<N>,
|
proj: &TMat4<T>,
|
||||||
viewport: TVec4<N>,
|
viewport: TVec4<T>,
|
||||||
) -> TVec3<N> {
|
) -> TVec3<T> {
|
||||||
unproject_no(win, model, proj, viewport)
|
unproject_no(win, model, proj, viewport)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,23 +160,23 @@ pub fn unproject<N: RealField>(
|
||||||
/// * [`project_zo`](fn.project_zo.html)
|
/// * [`project_zo`](fn.project_zo.html)
|
||||||
/// * [`unproject`](fn.unproject.html)
|
/// * [`unproject`](fn.unproject.html)
|
||||||
/// * [`unproject_zo`](fn.unproject_zo.html)
|
/// * [`unproject_zo`](fn.unproject_zo.html)
|
||||||
pub fn unproject_no<N: RealField>(
|
pub fn unproject_no<T: RealField>(
|
||||||
win: &TVec3<N>,
|
win: &TVec3<T>,
|
||||||
model: &TMat4<N>,
|
model: &TMat4<T>,
|
||||||
proj: &TMat4<N>,
|
proj: &TMat4<T>,
|
||||||
viewport: TVec4<N>,
|
viewport: TVec4<T>,
|
||||||
) -> TVec3<N> {
|
) -> TVec3<T> {
|
||||||
let _2: N = na::convert(2.0);
|
let _2: T = na::convert(2.0);
|
||||||
let transform = (proj * model).try_inverse().unwrap_or_else(TMat4::zeros);
|
let transform = (proj * model).try_inverse().unwrap_or_else(TMat4::zeros);
|
||||||
let pt = TVec4::new(
|
let pt = TVec4::new(
|
||||||
_2 * (win.x - viewport.x) / viewport.z - N::one(),
|
_2 * (win.x - viewport.x) / viewport.z - T::one(),
|
||||||
_2 * (win.y - viewport.y) / viewport.w - N::one(),
|
_2 * (win.y - viewport.y) / viewport.w - T::one(),
|
||||||
_2 * win.z - N::one(),
|
_2 * win.z - T::one(),
|
||||||
N::one(),
|
T::one(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let result = transform * pt;
|
let result = transform * pt;
|
||||||
result.fixed_rows::<U3>(0) / result.w
|
result.fixed_rows::<3>(0) / result.w
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates.
|
/// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates.
|
||||||
|
@ -197,21 +197,21 @@ pub fn unproject_no<N: RealField>(
|
||||||
/// * [`project_zo`](fn.project_zo.html)
|
/// * [`project_zo`](fn.project_zo.html)
|
||||||
/// * [`unproject`](fn.unproject.html)
|
/// * [`unproject`](fn.unproject.html)
|
||||||
/// * [`unproject_no`](fn.unproject_no.html)
|
/// * [`unproject_no`](fn.unproject_no.html)
|
||||||
pub fn unproject_zo<N: RealField>(
|
pub fn unproject_zo<T: RealField>(
|
||||||
win: &TVec3<N>,
|
win: &TVec3<T>,
|
||||||
model: &TMat4<N>,
|
model: &TMat4<T>,
|
||||||
proj: &TMat4<N>,
|
proj: &TMat4<T>,
|
||||||
viewport: TVec4<N>,
|
viewport: TVec4<T>,
|
||||||
) -> TVec3<N> {
|
) -> TVec3<T> {
|
||||||
let _2: N = na::convert(2.0);
|
let _2: T = na::convert(2.0);
|
||||||
let transform = (proj * model).try_inverse().unwrap_or_else(TMat4::zeros);
|
let transform = (proj * model).try_inverse().unwrap_or_else(TMat4::zeros);
|
||||||
let pt = TVec4::new(
|
let pt = TVec4::new(
|
||||||
_2 * (win.x - viewport.x) / viewport.z - N::one(),
|
_2 * (win.x - viewport.x) / viewport.z - T::one(),
|
||||||
_2 * (win.y - viewport.y) / viewport.w - N::one(),
|
_2 * (win.y - viewport.y) / viewport.w - T::one(),
|
||||||
win.z,
|
win.z,
|
||||||
N::one(),
|
T::one(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let result = transform * pt;
|
let result = transform * pt;
|
||||||
result.fixed_rows::<U3>(0) / result.w
|
result.fixed_rows::<3>(0) / result.w
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,16 @@
|
||||||
use na::DefaultAllocator;
|
|
||||||
|
|
||||||
use crate::aliases::{TMat, TVec};
|
use crate::aliases::{TMat, TVec};
|
||||||
use crate::traits::{Alloc, Dimension, Number};
|
use crate::traits::Number;
|
||||||
|
|
||||||
/// Perform a component-wise equal-to comparison of two matrices.
|
/// Perform a component-wise equal-to comparison of two matrices.
|
||||||
///
|
///
|
||||||
/// Return a boolean vector which components value is True if this expression is satisfied per column of the matrices.
|
/// Return a boolean vector which components value is True if this expression is satisfied per column of the matrices.
|
||||||
pub fn equal_columns<N: Number, R: Dimension, C: Dimension>(
|
pub fn equal_columns<T: Number, const R: usize, const C: usize>(
|
||||||
x: &TMat<N, R, C>,
|
x: &TMat<T, R, C>,
|
||||||
y: &TMat<N, R, C>,
|
y: &TMat<T, R, C>,
|
||||||
) -> TVec<bool, C>
|
) -> TVec<bool, C> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, R, C>,
|
|
||||||
{
|
|
||||||
let mut res = TVec::<_, C>::repeat(false);
|
let mut res = TVec::<_, C>::repeat(false);
|
||||||
|
|
||||||
for i in 0..C::dim() {
|
for i in 0..C {
|
||||||
res[i] = x.column(i) == y.column(i)
|
res[i] = x.column(i) == y.column(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,31 +20,25 @@ where
|
||||||
/// Returns the component-wise comparison of `|x - y| < epsilon`.
|
/// Returns the component-wise comparison of `|x - y| < epsilon`.
|
||||||
///
|
///
|
||||||
/// True if this expression is satisfied.
|
/// True if this expression is satisfied.
|
||||||
pub fn equal_columns_eps<N: Number, R: Dimension, C: Dimension>(
|
pub fn equal_columns_eps<T: Number, const R: usize, const C: usize>(
|
||||||
x: &TMat<N, R, C>,
|
x: &TMat<T, R, C>,
|
||||||
y: &TMat<N, R, C>,
|
y: &TMat<T, R, C>,
|
||||||
epsilon: N,
|
epsilon: T,
|
||||||
) -> TVec<bool, C>
|
) -> TVec<bool, C> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, R, C>,
|
|
||||||
{
|
|
||||||
equal_columns_eps_vec(x, y, &TVec::<_, C>::repeat(epsilon))
|
equal_columns_eps_vec(x, y, &TVec::<_, C>::repeat(epsilon))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the component-wise comparison on each matrix column `|x - y| < epsilon`.
|
/// Returns the component-wise comparison on each matrix column `|x - y| < epsilon`.
|
||||||
///
|
///
|
||||||
/// True if this expression is satisfied.
|
/// True if this expression is satisfied.
|
||||||
pub fn equal_columns_eps_vec<N: Number, R: Dimension, C: Dimension>(
|
pub fn equal_columns_eps_vec<T: Number, const R: usize, const C: usize>(
|
||||||
x: &TMat<N, R, C>,
|
x: &TMat<T, R, C>,
|
||||||
y: &TMat<N, R, C>,
|
y: &TMat<T, R, C>,
|
||||||
epsilon: &TVec<N, C>,
|
epsilon: &TVec<T, C>,
|
||||||
) -> TVec<bool, C>
|
) -> TVec<bool, C> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, R, C>,
|
|
||||||
{
|
|
||||||
let mut res = TVec::<_, C>::repeat(false);
|
let mut res = TVec::<_, C>::repeat(false);
|
||||||
|
|
||||||
for i in 0..C::dim() {
|
for i in 0..C {
|
||||||
res[i] = (x.column(i) - y.column(i)).abs() < TVec::<_, R>::repeat(epsilon[i])
|
res[i] = (x.column(i) - y.column(i)).abs() < TVec::<_, R>::repeat(epsilon[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,16 +48,13 @@ where
|
||||||
/// Perform a component-wise not-equal-to comparison of two matrices.
|
/// Perform a component-wise not-equal-to comparison of two matrices.
|
||||||
///
|
///
|
||||||
/// Return a boolean vector which components value is True if this expression is satisfied per column of the matrices.
|
/// Return a boolean vector which components value is True if this expression is satisfied per column of the matrices.
|
||||||
pub fn not_equal_columns<N: Number, R: Dimension, C: Dimension>(
|
pub fn not_equal_columns<T: Number, const R: usize, const C: usize>(
|
||||||
x: &TMat<N, R, C>,
|
x: &TMat<T, R, C>,
|
||||||
y: &TMat<N, R, C>,
|
y: &TMat<T, R, C>,
|
||||||
) -> TVec<bool, C>
|
) -> TVec<bool, C> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, R, C>,
|
|
||||||
{
|
|
||||||
let mut res = TVec::<_, C>::repeat(false);
|
let mut res = TVec::<_, C>::repeat(false);
|
||||||
|
|
||||||
for i in 0..C::dim() {
|
for i in 0..C {
|
||||||
res[i] = x.column(i) != y.column(i)
|
res[i] = x.column(i) != y.column(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,31 +64,25 @@ where
|
||||||
/// Returns the component-wise comparison of `|x - y| < epsilon`.
|
/// Returns the component-wise comparison of `|x - y| < epsilon`.
|
||||||
///
|
///
|
||||||
/// True if this expression is not satisfied.
|
/// True if this expression is not satisfied.
|
||||||
pub fn not_equal_columns_eps<N: Number, R: Dimension, C: Dimension>(
|
pub fn not_equal_columns_eps<T: Number, const R: usize, const C: usize>(
|
||||||
x: &TMat<N, R, C>,
|
x: &TMat<T, R, C>,
|
||||||
y: &TMat<N, R, C>,
|
y: &TMat<T, R, C>,
|
||||||
epsilon: N,
|
epsilon: T,
|
||||||
) -> TVec<bool, C>
|
) -> TVec<bool, C> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, R, C>,
|
|
||||||
{
|
|
||||||
not_equal_columns_eps_vec(x, y, &TVec::<_, C>::repeat(epsilon))
|
not_equal_columns_eps_vec(x, y, &TVec::<_, C>::repeat(epsilon))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the component-wise comparison of `|x - y| >= epsilon`.
|
/// Returns the component-wise comparison of `|x - y| >= epsilon`.
|
||||||
///
|
///
|
||||||
/// True if this expression is not satisfied.
|
/// True if this expression is not satisfied.
|
||||||
pub fn not_equal_columns_eps_vec<N: Number, R: Dimension, C: Dimension>(
|
pub fn not_equal_columns_eps_vec<T: Number, const R: usize, const C: usize>(
|
||||||
x: &TMat<N, R, C>,
|
x: &TMat<T, R, C>,
|
||||||
y: &TMat<N, R, C>,
|
y: &TMat<T, R, C>,
|
||||||
epsilon: &TVec<N, C>,
|
epsilon: &TVec<T, C>,
|
||||||
) -> TVec<bool, C>
|
) -> TVec<bool, C> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, R, C>,
|
|
||||||
{
|
|
||||||
let mut res = TVec::<_, C>::repeat(false);
|
let mut res = TVec::<_, C>::repeat(false);
|
||||||
|
|
||||||
for i in 0..C::dim() {
|
for i in 0..C {
|
||||||
res[i] = (x.column(i) - y.column(i)).abs() >= TVec::<_, R>::repeat(epsilon[i])
|
res[i] = (x.column(i) - y.column(i)).abs() >= TVec::<_, R>::repeat(epsilon[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
use na::{DefaultAllocator, Point3, RealField, Rotation3, Unit};
|
use na::{Point3, RealField, Rotation3, Unit};
|
||||||
|
|
||||||
use crate::aliases::{TMat, TMat4, TVec, TVec3};
|
use crate::aliases::{TMat, TMat4, TVec, TVec3};
|
||||||
use crate::traits::{Alloc, Dimension, Number};
|
use crate::traits::Number;
|
||||||
|
|
||||||
/// The identity matrix.
|
/// The identity matrix.
|
||||||
pub fn identity<N: Number, D: Dimension>() -> TMat<N, D, D>
|
pub fn identity<T: Number, const D: usize>() -> TMat<T, D, D> {
|
||||||
where
|
TMat::<T, D, D>::identity()
|
||||||
DefaultAllocator: Alloc<N, D, D>,
|
|
||||||
{
|
|
||||||
TMat::<N, D, D>::identity()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build a look at view matrix based on the right handedness.
|
/// Build a look at view matrix based on the right handedness.
|
||||||
|
@ -23,7 +20,7 @@ where
|
||||||
///
|
///
|
||||||
/// * [`look_at_lh`](fn.look_at_lh.html)
|
/// * [`look_at_lh`](fn.look_at_lh.html)
|
||||||
/// * [`look_at_rh`](fn.look_at_rh.html)
|
/// * [`look_at_rh`](fn.look_at_rh.html)
|
||||||
pub fn look_at<N: RealField>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> {
|
pub fn look_at<T: RealField>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
|
||||||
look_at_rh(eye, center, up)
|
look_at_rh(eye, center, up)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +36,7 @@ pub fn look_at<N: RealField>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>) -
|
||||||
///
|
///
|
||||||
/// * [`look_at`](fn.look_at.html)
|
/// * [`look_at`](fn.look_at.html)
|
||||||
/// * [`look_at_rh`](fn.look_at_rh.html)
|
/// * [`look_at_rh`](fn.look_at_rh.html)
|
||||||
pub fn look_at_lh<N: RealField>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> {
|
pub fn look_at_lh<T: RealField>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
|
||||||
TMat::look_at_lh(&Point3::from(*eye), &Point3::from(*center), up)
|
TMat::look_at_lh(&Point3::from(*eye), &Point3::from(*center), up)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +52,7 @@ pub fn look_at_lh<N: RealField>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>
|
||||||
///
|
///
|
||||||
/// * [`look_at`](fn.look_at.html)
|
/// * [`look_at`](fn.look_at.html)
|
||||||
/// * [`look_at_lh`](fn.look_at_lh.html)
|
/// * [`look_at_lh`](fn.look_at_lh.html)
|
||||||
pub fn look_at_rh<N: RealField>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> {
|
pub fn look_at_rh<T: RealField>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
|
||||||
TMat::look_at_rh(&Point3::from(*eye), &Point3::from(*center), up)
|
TMat::look_at_rh(&Point3::from(*eye), &Point3::from(*center), up)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +71,7 @@ pub fn look_at_rh<N: RealField>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>
|
||||||
/// * [`rotate_z`](fn.rotate_z.html)
|
/// * [`rotate_z`](fn.rotate_z.html)
|
||||||
/// * [`scale`](fn.scale.html)
|
/// * [`scale`](fn.scale.html)
|
||||||
/// * [`translate`](fn.translate.html)
|
/// * [`translate`](fn.translate.html)
|
||||||
pub fn rotate<N: RealField>(m: &TMat4<N>, angle: N, axis: &TVec3<N>) -> TMat4<N> {
|
pub fn rotate<T: RealField>(m: &TMat4<T>, angle: T, axis: &TVec3<T>) -> TMat4<T> {
|
||||||
m * Rotation3::from_axis_angle(&Unit::new_normalize(*axis), angle).to_homogeneous()
|
m * Rotation3::from_axis_angle(&Unit::new_normalize(*axis), angle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +89,7 @@ pub fn rotate<N: RealField>(m: &TMat4<N>, angle: N, axis: &TVec3<N>) -> TMat4<N>
|
||||||
/// * [`rotate_z`](fn.rotate_z.html)
|
/// * [`rotate_z`](fn.rotate_z.html)
|
||||||
/// * [`scale`](fn.scale.html)
|
/// * [`scale`](fn.scale.html)
|
||||||
/// * [`translate`](fn.translate.html)
|
/// * [`translate`](fn.translate.html)
|
||||||
pub fn rotate_x<N: RealField>(m: &TMat4<N>, angle: N) -> TMat4<N> {
|
pub fn rotate_x<T: RealField>(m: &TMat4<T>, angle: T) -> TMat4<T> {
|
||||||
rotate(m, angle, &TVec::x())
|
rotate(m, angle, &TVec::x())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +107,7 @@ pub fn rotate_x<N: RealField>(m: &TMat4<N>, angle: N) -> TMat4<N> {
|
||||||
/// * [`rotate_z`](fn.rotate_z.html)
|
/// * [`rotate_z`](fn.rotate_z.html)
|
||||||
/// * [`scale`](fn.scale.html)
|
/// * [`scale`](fn.scale.html)
|
||||||
/// * [`translate`](fn.translate.html)
|
/// * [`translate`](fn.translate.html)
|
||||||
pub fn rotate_y<N: RealField>(m: &TMat4<N>, angle: N) -> TMat4<N> {
|
pub fn rotate_y<T: RealField>(m: &TMat4<T>, angle: T) -> TMat4<T> {
|
||||||
rotate(m, angle, &TVec::y())
|
rotate(m, angle, &TVec::y())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +125,7 @@ pub fn rotate_y<N: RealField>(m: &TMat4<N>, angle: N) -> TMat4<N> {
|
||||||
/// * [`rotate_y`](fn.rotate_y.html)
|
/// * [`rotate_y`](fn.rotate_y.html)
|
||||||
/// * [`scale`](fn.scale.html)
|
/// * [`scale`](fn.scale.html)
|
||||||
/// * [`translate`](fn.translate.html)
|
/// * [`translate`](fn.translate.html)
|
||||||
pub fn rotate_z<N: RealField>(m: &TMat4<N>, angle: N) -> TMat4<N> {
|
pub fn rotate_z<T: RealField>(m: &TMat4<T>, angle: T) -> TMat4<T> {
|
||||||
rotate(m, angle, &TVec::z())
|
rotate(m, angle, &TVec::z())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +143,7 @@ pub fn rotate_z<N: RealField>(m: &TMat4<N>, angle: N) -> TMat4<N> {
|
||||||
/// * [`rotate_y`](fn.rotate_y.html)
|
/// * [`rotate_y`](fn.rotate_y.html)
|
||||||
/// * [`rotate_z`](fn.rotate_z.html)
|
/// * [`rotate_z`](fn.rotate_z.html)
|
||||||
/// * [`translate`](fn.translate.html)
|
/// * [`translate`](fn.translate.html)
|
||||||
pub fn scale<N: Number>(m: &TMat4<N>, v: &TVec3<N>) -> TMat4<N> {
|
pub fn scale<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> {
|
||||||
m.prepend_nonuniform_scaling(v)
|
m.prepend_nonuniform_scaling(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,6 +161,6 @@ pub fn scale<N: Number>(m: &TMat4<N>, v: &TVec3<N>) -> TMat4<N> {
|
||||||
/// * [`rotate_y`](fn.rotate_y.html)
|
/// * [`rotate_y`](fn.rotate_y.html)
|
||||||
/// * [`rotate_z`](fn.rotate_z.html)
|
/// * [`rotate_z`](fn.rotate_z.html)
|
||||||
/// * [`scale`](fn.scale.html)
|
/// * [`scale`](fn.scale.html)
|
||||||
pub fn translate<N: Number>(m: &TMat4<N>, v: &TVec3<N>) -> TMat4<N> {
|
pub fn translate<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> {
|
||||||
m.prepend_translation(v)
|
m.prepend_translation(v)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,34 +3,34 @@ use na::{self, RealField, Unit};
|
||||||
use crate::aliases::Qua;
|
use crate::aliases::Qua;
|
||||||
|
|
||||||
/// The conjugate of `q`.
|
/// The conjugate of `q`.
|
||||||
pub fn quat_conjugate<N: RealField>(q: &Qua<N>) -> Qua<N> {
|
pub fn quat_conjugate<T: RealField>(q: &Qua<T>) -> Qua<T> {
|
||||||
q.conjugate()
|
q.conjugate()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The inverse of `q`.
|
/// The inverse of `q`.
|
||||||
pub fn quat_inverse<N: RealField>(q: &Qua<N>) -> Qua<N> {
|
pub fn quat_inverse<T: RealField>(q: &Qua<T>) -> Qua<T> {
|
||||||
q.try_inverse().unwrap_or_else(na::zero)
|
q.try_inverse().unwrap_or_else(na::zero)
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn quat_isinf<N: RealField>(x: &Qua<N>) -> TVec<bool, U4> {
|
//pub fn quat_isinf<T: RealField>(x: &Qua<T>) -> TVec<bool, U4> {
|
||||||
// x.coords.map(|e| e.is_inf())
|
// x.coords.map(|e| e.is_inf())
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//pub fn quat_isnan<N: RealField>(x: &Qua<N>) -> TVec<bool, U4> {
|
//pub fn quat_isnan<T: RealField>(x: &Qua<T>) -> TVec<bool, U4> {
|
||||||
// x.coords.map(|e| e.is_nan())
|
// x.coords.map(|e| e.is_nan())
|
||||||
//}
|
//}
|
||||||
|
|
||||||
/// Interpolate linearly between `x` and `y`.
|
/// Interpolate linearly between `x` and `y`.
|
||||||
pub fn quat_lerp<N: RealField>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> {
|
pub fn quat_lerp<T: RealField>(x: &Qua<T>, y: &Qua<T>, a: T) -> Qua<T> {
|
||||||
x.lerp(y, a)
|
x.lerp(y, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn quat_mix<N: RealField>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> {
|
//pub fn quat_mix<T: RealField>(x: &Qua<T>, y: &Qua<T>, a: T) -> Qua<T> {
|
||||||
// x * (N::one() - a) + y * a
|
// x * (T::one() - a) + y * a
|
||||||
//}
|
//}
|
||||||
|
|
||||||
/// Interpolate spherically between `x` and `y`.
|
/// Interpolate spherically between `x` and `y`.
|
||||||
pub fn quat_slerp<N: RealField>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> {
|
pub fn quat_slerp<T: RealField>(x: &Qua<T>, y: &Qua<T>, a: T) -> Qua<T> {
|
||||||
Unit::new_normalize(*x)
|
Unit::new_normalize(*x)
|
||||||
.slerp(&Unit::new_normalize(*y), a)
|
.slerp(&Unit::new_normalize(*y), a)
|
||||||
.into_inner()
|
.into_inner()
|
||||||
|
|
|
@ -3,26 +3,26 @@ use na::RealField;
|
||||||
use crate::aliases::Qua;
|
use crate::aliases::Qua;
|
||||||
|
|
||||||
/// Multiplies two quaternions.
|
/// Multiplies two quaternions.
|
||||||
pub fn quat_cross<N: RealField>(q1: &Qua<N>, q2: &Qua<N>) -> Qua<N> {
|
pub fn quat_cross<T: RealField>(q1: &Qua<T>, q2: &Qua<T>) -> Qua<T> {
|
||||||
q1 * q2
|
q1 * q2
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The scalar product of two quaternions.
|
/// The scalar product of two quaternions.
|
||||||
pub fn quat_dot<N: RealField>(x: &Qua<N>, y: &Qua<N>) -> N {
|
pub fn quat_dot<T: RealField>(x: &Qua<T>, y: &Qua<T>) -> T {
|
||||||
x.dot(y)
|
x.dot(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The magnitude of the quaternion `q`.
|
/// The magnitude of the quaternion `q`.
|
||||||
pub fn quat_length<N: RealField>(q: &Qua<N>) -> N {
|
pub fn quat_length<T: RealField>(q: &Qua<T>) -> T {
|
||||||
q.norm()
|
q.norm()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The magnitude of the quaternion `q`.
|
/// The magnitude of the quaternion `q`.
|
||||||
pub fn quat_magnitude<N: RealField>(q: &Qua<N>) -> N {
|
pub fn quat_magnitude<T: RealField>(q: &Qua<T>) -> T {
|
||||||
q.norm()
|
q.norm()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Normalizes the quaternion `q`.
|
/// Normalizes the quaternion `q`.
|
||||||
pub fn quat_normalize<N: RealField>(q: &Qua<N>) -> Qua<N> {
|
pub fn quat_normalize<T: RealField>(q: &Qua<T>) -> Qua<T> {
|
||||||
q.normalize()
|
q.normalize()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
use na::{RealField, U4};
|
use na::RealField;
|
||||||
|
|
||||||
use crate::aliases::{Qua, TVec};
|
use crate::aliases::{Qua, TVec};
|
||||||
|
|
||||||
/// Component-wise equality comparison between two quaternions.
|
/// Component-wise equality comparison between two quaternions.
|
||||||
pub fn quat_equal<N: RealField>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> {
|
pub fn quat_equal<T: RealField>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
|
||||||
crate::equal(&x.coords, &y.coords)
|
crate::equal(&x.coords, &y.coords)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise approximate equality comparison between two quaternions.
|
/// Component-wise approximate equality comparison between two quaternions.
|
||||||
pub fn quat_equal_eps<N: RealField>(x: &Qua<N>, y: &Qua<N>, epsilon: N) -> TVec<bool, U4> {
|
pub fn quat_equal_eps<T: RealField>(x: &Qua<T>, y: &Qua<T>, epsilon: T) -> TVec<bool, 4> {
|
||||||
crate::equal_eps(&x.coords, &y.coords, epsilon)
|
crate::equal_eps(&x.coords, &y.coords, epsilon)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise non-equality comparison between two quaternions.
|
/// Component-wise non-equality comparison between two quaternions.
|
||||||
pub fn quat_not_equal<N: RealField>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> {
|
pub fn quat_not_equal<T: RealField>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
|
||||||
crate::not_equal(&x.coords, &y.coords)
|
crate::not_equal(&x.coords, &y.coords)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise approximate non-equality comparison between two quaternions.
|
/// Component-wise approximate non-equality comparison between two quaternions.
|
||||||
pub fn quat_not_equal_eps<N: RealField>(x: &Qua<N>, y: &Qua<N>, epsilon: N) -> TVec<bool, U4> {
|
pub fn quat_not_equal_eps<T: RealField>(x: &Qua<T>, y: &Qua<T>, epsilon: T) -> TVec<bool, 4> {
|
||||||
crate::not_equal_eps(&x.coords, &y.coords, epsilon)
|
crate::not_equal_eps(&x.coords, &y.coords, epsilon)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,25 +3,25 @@ use na::{RealField, Unit, UnitQuaternion};
|
||||||
use crate::aliases::{Qua, TVec3};
|
use crate::aliases::{Qua, TVec3};
|
||||||
|
|
||||||
/// Computes the quaternion exponential.
|
/// Computes the quaternion exponential.
|
||||||
pub fn quat_exp<N: RealField>(q: &Qua<N>) -> Qua<N> {
|
pub fn quat_exp<T: RealField>(q: &Qua<T>) -> Qua<T> {
|
||||||
q.exp()
|
q.exp()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the quaternion logarithm.
|
/// Computes the quaternion logarithm.
|
||||||
pub fn quat_log<N: RealField>(q: &Qua<N>) -> Qua<N> {
|
pub fn quat_log<T: RealField>(q: &Qua<T>) -> Qua<T> {
|
||||||
q.ln()
|
q.ln()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Raises the quaternion `q` to the power `y`.
|
/// Raises the quaternion `q` to the power `y`.
|
||||||
pub fn quat_pow<N: RealField>(q: &Qua<N>, y: N) -> Qua<N> {
|
pub fn quat_pow<T: RealField>(q: &Qua<T>, y: T) -> Qua<T> {
|
||||||
q.powf(y)
|
q.powf(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a quaternion from an axis and an angle, and right-multiply it to the quaternion `q`.
|
/// Builds a quaternion from an axis and an angle, and right-multiply it to the quaternion `q`.
|
||||||
pub fn quat_rotate<N: RealField>(q: &Qua<N>, angle: N, axis: &TVec3<N>) -> Qua<N> {
|
pub fn quat_rotate<T: RealField>(q: &Qua<T>, angle: T, axis: &TVec3<T>) -> Qua<T> {
|
||||||
q * UnitQuaternion::from_axis_angle(&Unit::new_normalize(*axis), angle).into_inner()
|
q * UnitQuaternion::from_axis_angle(&Unit::new_normalize(*axis), angle).into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn quat_sqrt<N: RealField>(q: &Qua<N>) -> Qua<N> {
|
//pub fn quat_sqrt<T: RealField>(q: &Qua<T>) -> Qua<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
|
@ -3,17 +3,17 @@ use na::{RealField, Unit, UnitQuaternion};
|
||||||
use crate::aliases::{Qua, TVec3};
|
use crate::aliases::{Qua, TVec3};
|
||||||
|
|
||||||
/// The rotation angle of this quaternion assumed to be normalized.
|
/// The rotation angle of this quaternion assumed to be normalized.
|
||||||
pub fn quat_angle<N: RealField>(x: &Qua<N>) -> N {
|
pub fn quat_angle<T: RealField>(x: &Qua<T>) -> T {
|
||||||
UnitQuaternion::from_quaternion(*x).angle()
|
UnitQuaternion::from_quaternion(*x).angle()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a quaternion from an axis and an angle.
|
/// Creates a quaternion from an axis and an angle.
|
||||||
pub fn quat_angle_axis<N: RealField>(angle: N, axis: &TVec3<N>) -> Qua<N> {
|
pub fn quat_angle_axis<T: RealField>(angle: T, axis: &TVec3<T>) -> Qua<T> {
|
||||||
UnitQuaternion::from_axis_angle(&Unit::new_normalize(*axis), angle).into_inner()
|
UnitQuaternion::from_axis_angle(&Unit::new_normalize(*axis), angle).into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The rotation axis of a quaternion assumed to be normalized.
|
/// The rotation axis of a quaternion assumed to be normalized.
|
||||||
pub fn quat_axis<N: RealField>(x: &Qua<N>) -> TVec3<N> {
|
pub fn quat_axis<T: RealField>(x: &Qua<T>) -> TVec3<T> {
|
||||||
if let Some(a) = UnitQuaternion::from_quaternion(*x).axis() {
|
if let Some(a) = UnitQuaternion::from_quaternion(*x).axis() {
|
||||||
a.into_inner()
|
a.into_inner()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -15,7 +15,7 @@ use crate::traits::Number;
|
||||||
/// * [`max4_scalar`](fn.max4_scalar.html)
|
/// * [`max4_scalar`](fn.max4_scalar.html)
|
||||||
/// * [`min3_scalar`](fn.min3_scalar.html)
|
/// * [`min3_scalar`](fn.min3_scalar.html)
|
||||||
/// * [`min4_scalar`](fn.min4_scalar.html)
|
/// * [`min4_scalar`](fn.min4_scalar.html)
|
||||||
pub fn max2_scalar<N: Number>(a: N, b: N) -> N {
|
pub fn max2_scalar<T: Number>(a: T, b: T) -> T {
|
||||||
if a >= b {
|
if a >= b {
|
||||||
a
|
a
|
||||||
} else {
|
} else {
|
||||||
|
@ -38,7 +38,7 @@ pub fn max2_scalar<N: Number>(a: N, b: N) -> N {
|
||||||
/// * [`max4_scalar`](fn.max4_scalar.html)
|
/// * [`max4_scalar`](fn.max4_scalar.html)
|
||||||
/// * [`min3_scalar`](fn.min3_scalar.html)
|
/// * [`min3_scalar`](fn.min3_scalar.html)
|
||||||
/// * [`min4_scalar`](fn.min4_scalar.html)
|
/// * [`min4_scalar`](fn.min4_scalar.html)
|
||||||
pub fn min2_scalar<N: Number>(a: N, b: N) -> N {
|
pub fn min2_scalar<T: Number>(a: T, b: T) -> T {
|
||||||
if a <= b {
|
if a <= b {
|
||||||
a
|
a
|
||||||
} else {
|
} else {
|
||||||
|
@ -61,7 +61,7 @@ pub fn min2_scalar<N: Number>(a: N, b: N) -> N {
|
||||||
/// * [`max4_scalar`](fn.max4_scalar.html)
|
/// * [`max4_scalar`](fn.max4_scalar.html)
|
||||||
/// * [`min3_scalar`](fn.min3_scalar.html)
|
/// * [`min3_scalar`](fn.min3_scalar.html)
|
||||||
/// * [`min4_scalar`](fn.min4_scalar.html)
|
/// * [`min4_scalar`](fn.min4_scalar.html)
|
||||||
pub fn max3_scalar<N: Number>(a: N, b: N, c: N) -> N {
|
pub fn max3_scalar<T: Number>(a: T, b: T, c: T) -> T {
|
||||||
max2_scalar(max2_scalar(a, b), c)
|
max2_scalar(max2_scalar(a, b), c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ pub fn max3_scalar<N: Number>(a: N, b: N, c: N) -> N {
|
||||||
/// * [`max3_scalar`](fn.max3_scalar.html)
|
/// * [`max3_scalar`](fn.max3_scalar.html)
|
||||||
/// * [`min3_scalar`](fn.min3_scalar.html)
|
/// * [`min3_scalar`](fn.min3_scalar.html)
|
||||||
/// * [`min4_scalar`](fn.min4_scalar.html)
|
/// * [`min4_scalar`](fn.min4_scalar.html)
|
||||||
pub fn max4_scalar<N: Number>(a: N, b: N, c: N, d: N) -> N {
|
pub fn max4_scalar<T: Number>(a: T, b: T, c: T, d: T) -> T {
|
||||||
max2_scalar(max2_scalar(a, b), max2_scalar(c, d))
|
max2_scalar(max2_scalar(a, b), max2_scalar(c, d))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ pub fn max4_scalar<N: Number>(a: N, b: N, c: N, d: N) -> N {
|
||||||
/// * [`max3_scalar`](fn.max3_scalar.html)
|
/// * [`max3_scalar`](fn.max3_scalar.html)
|
||||||
/// * [`max4_scalar`](fn.max4_scalar.html)
|
/// * [`max4_scalar`](fn.max4_scalar.html)
|
||||||
/// * [`min4_scalar`](fn.min4_scalar.html)
|
/// * [`min4_scalar`](fn.min4_scalar.html)
|
||||||
pub fn min3_scalar<N: Number>(a: N, b: N, c: N) -> N {
|
pub fn min3_scalar<T: Number>(a: T, b: T, c: T) -> T {
|
||||||
min2_scalar(min2_scalar(a, b), c)
|
min2_scalar(min2_scalar(a, b), c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,6 +118,6 @@ pub fn min3_scalar<N: Number>(a: N, b: N, c: N) -> N {
|
||||||
/// * [`max3_scalar`](fn.max3_scalar.html)
|
/// * [`max3_scalar`](fn.max3_scalar.html)
|
||||||
/// * [`max4_scalar`](fn.max4_scalar.html)
|
/// * [`max4_scalar`](fn.max4_scalar.html)
|
||||||
/// * [`min3_scalar`](fn.min3_scalar.html)
|
/// * [`min3_scalar`](fn.min3_scalar.html)
|
||||||
pub fn min4_scalar<N: Number>(a: N, b: N, c: N, d: N) -> N {
|
pub fn min4_scalar<T: Number>(a: T, b: T, c: T, d: T) -> T {
|
||||||
min2_scalar(min2_scalar(a, b), min2_scalar(c, d))
|
min2_scalar(min2_scalar(a, b), min2_scalar(c, d))
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@ use approx::AbsDiffEq;
|
||||||
use na::RealField;
|
use na::RealField;
|
||||||
|
|
||||||
/// Default epsilon value used for approximate comparison.
|
/// Default epsilon value used for approximate comparison.
|
||||||
pub fn epsilon<N: AbsDiffEq<Epsilon = N>>() -> N {
|
pub fn epsilon<T: AbsDiffEq<Epsilon = T>>() -> T {
|
||||||
N::default_epsilon()
|
T::default_epsilon()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The value of PI.
|
/// The value of PI.
|
||||||
|
@ -22,6 +22,6 @@ pub fn epsilon<N: AbsDiffEq<Epsilon = N>>() -> N {
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn pi<N: RealField>() -> N {
|
pub fn pi<T: RealField>() -> T {
|
||||||
N::pi()
|
T::pi()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
use na::{self, DefaultAllocator};
|
|
||||||
|
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
use crate::traits::{Alloc, Dimension, Number};
|
use crate::traits::Number;
|
||||||
|
|
||||||
/// Component-wise maximum between a vector and a scalar.
|
/// Component-wise maximum between a vector and a scalar.
|
||||||
///
|
///
|
||||||
|
@ -16,10 +14,7 @@ use crate::traits::{Alloc, Dimension, Number};
|
||||||
/// * [`min2`](fn.min2.html)
|
/// * [`min2`](fn.min2.html)
|
||||||
/// * [`min3`](fn.min3.html)
|
/// * [`min3`](fn.min3.html)
|
||||||
/// * [`min4`](fn.min4.html)
|
/// * [`min4`](fn.min4.html)
|
||||||
pub fn max<N: Number, D: Dimension>(a: &TVec<N, D>, b: N) -> TVec<N, D>
|
pub fn max<T: Number, const D: usize>(a: &TVec<T, D>, b: T) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
a.map(|a| crate::max2_scalar(a, b))
|
a.map(|a| crate::max2_scalar(a, b))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,10 +31,7 @@ where
|
||||||
/// * [`min2`](fn.min2.html)
|
/// * [`min2`](fn.min2.html)
|
||||||
/// * [`min3`](fn.min3.html)
|
/// * [`min3`](fn.min3.html)
|
||||||
/// * [`min4`](fn.min4.html)
|
/// * [`min4`](fn.min4.html)
|
||||||
pub fn max2<N: Number, D: Dimension>(a: &TVec<N, D>, b: &TVec<N, D>) -> TVec<N, D>
|
pub fn max2<T: Number, const D: usize>(a: &TVec<T, D>, b: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
a.zip_map(b, |a, b| crate::max2_scalar(a, b))
|
a.zip_map(b, |a, b| crate::max2_scalar(a, b))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,10 +48,11 @@ where
|
||||||
/// * [`min2`](fn.min2.html)
|
/// * [`min2`](fn.min2.html)
|
||||||
/// * [`min3`](fn.min3.html)
|
/// * [`min3`](fn.min3.html)
|
||||||
/// * [`min4`](fn.min4.html)
|
/// * [`min4`](fn.min4.html)
|
||||||
pub fn max3<N: Number, D: Dimension>(a: &TVec<N, D>, b: &TVec<N, D>, c: &TVec<N, D>) -> TVec<N, D>
|
pub fn max3<T: Number, const D: usize>(
|
||||||
where
|
a: &TVec<T, D>,
|
||||||
DefaultAllocator: Alloc<N, D>,
|
b: &TVec<T, D>,
|
||||||
{
|
c: &TVec<T, D>,
|
||||||
|
) -> TVec<T, D> {
|
||||||
max2(&max2(a, b), c)
|
max2(&max2(a, b), c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,15 +69,12 @@ where
|
||||||
/// * [`min2`](fn.min2.html)
|
/// * [`min2`](fn.min2.html)
|
||||||
/// * [`min3`](fn.min3.html)
|
/// * [`min3`](fn.min3.html)
|
||||||
/// * [`min4`](fn.min4.html)
|
/// * [`min4`](fn.min4.html)
|
||||||
pub fn max4<N: Number, D: Dimension>(
|
pub fn max4<T: Number, const D: usize>(
|
||||||
a: &TVec<N, D>,
|
a: &TVec<T, D>,
|
||||||
b: &TVec<N, D>,
|
b: &TVec<T, D>,
|
||||||
c: &TVec<N, D>,
|
c: &TVec<T, D>,
|
||||||
d: &TVec<N, D>,
|
d: &TVec<T, D>,
|
||||||
) -> TVec<N, D>
|
) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
max2(&max2(a, b), &max2(c, d))
|
max2(&max2(a, b), &max2(c, d))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,10 +91,7 @@ where
|
||||||
/// * [`min2`](fn.min2.html)
|
/// * [`min2`](fn.min2.html)
|
||||||
/// * [`min3`](fn.min3.html)
|
/// * [`min3`](fn.min3.html)
|
||||||
/// * [`min4`](fn.min4.html)
|
/// * [`min4`](fn.min4.html)
|
||||||
pub fn min<N: Number, D: Dimension>(x: &TVec<N, D>, y: N) -> TVec<N, D>
|
pub fn min<T: Number, const D: usize>(x: &TVec<T, D>, y: T) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.map(|x| crate::min2_scalar(x, y))
|
x.map(|x| crate::min2_scalar(x, y))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,10 +108,7 @@ where
|
||||||
/// * [`min`](fn.min.html)
|
/// * [`min`](fn.min.html)
|
||||||
/// * [`min3`](fn.min3.html)
|
/// * [`min3`](fn.min3.html)
|
||||||
/// * [`min4`](fn.min4.html)
|
/// * [`min4`](fn.min4.html)
|
||||||
pub fn min2<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<N, D>
|
pub fn min2<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.zip_map(y, |a, b| crate::min2_scalar(a, b))
|
x.zip_map(y, |a, b| crate::min2_scalar(a, b))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,10 +125,11 @@ where
|
||||||
/// * [`min`](fn.min.html)
|
/// * [`min`](fn.min.html)
|
||||||
/// * [`min2`](fn.min2.html)
|
/// * [`min2`](fn.min2.html)
|
||||||
/// * [`min4`](fn.min4.html)
|
/// * [`min4`](fn.min4.html)
|
||||||
pub fn min3<N: Number, D: Dimension>(a: &TVec<N, D>, b: &TVec<N, D>, c: &TVec<N, D>) -> TVec<N, D>
|
pub fn min3<T: Number, const D: usize>(
|
||||||
where
|
a: &TVec<T, D>,
|
||||||
DefaultAllocator: Alloc<N, D>,
|
b: &TVec<T, D>,
|
||||||
{
|
c: &TVec<T, D>,
|
||||||
|
) -> TVec<T, D> {
|
||||||
min2(&min2(a, b), c)
|
min2(&min2(a, b), c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,14 +146,11 @@ where
|
||||||
/// * [`min`](fn.min.html)
|
/// * [`min`](fn.min.html)
|
||||||
/// * [`min2`](fn.min2.html)
|
/// * [`min2`](fn.min2.html)
|
||||||
/// * [`min3`](fn.min3.html)
|
/// * [`min3`](fn.min3.html)
|
||||||
pub fn min4<N: Number, D: Dimension>(
|
pub fn min4<T: Number, const D: usize>(
|
||||||
a: &TVec<N, D>,
|
a: &TVec<T, D>,
|
||||||
b: &TVec<N, D>,
|
b: &TVec<T, D>,
|
||||||
c: &TVec<N, D>,
|
c: &TVec<T, D>,
|
||||||
d: &TVec<N, D>,
|
d: &TVec<T, D>,
|
||||||
) -> TVec<N, D>
|
) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
min2(&min2(a, b), &min2(c, d))
|
min2(&min2(a, b), &min2(c, d))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
use na::DefaultAllocator;
|
|
||||||
|
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
use crate::traits::{Alloc, Dimension, Number};
|
use crate::traits::Number;
|
||||||
|
|
||||||
/// Component-wise approximate equality of two vectors, using a scalar epsilon.
|
/// Component-wise approximate equality of two vectors, using a scalar epsilon.
|
||||||
///
|
///
|
||||||
|
@ -10,14 +8,11 @@ use crate::traits::{Alloc, Dimension, Number};
|
||||||
/// * [`equal_eps_vec`](fn.equal_eps_vec.html)
|
/// * [`equal_eps_vec`](fn.equal_eps_vec.html)
|
||||||
/// * [`not_equal_eps`](fn.not_equal_eps.html)
|
/// * [`not_equal_eps`](fn.not_equal_eps.html)
|
||||||
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
|
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
|
||||||
pub fn equal_eps<N: Number, D: Dimension>(
|
pub fn equal_eps<T: Number, const D: usize>(
|
||||||
x: &TVec<N, D>,
|
x: &TVec<T, D>,
|
||||||
y: &TVec<N, D>,
|
y: &TVec<T, D>,
|
||||||
epsilon: N,
|
epsilon: T,
|
||||||
) -> TVec<bool, D>
|
) -> TVec<bool, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.zip_map(y, |x, y| abs_diff_eq!(x, y, epsilon = epsilon))
|
x.zip_map(y, |x, y| abs_diff_eq!(x, y, epsilon = epsilon))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,14 +23,11 @@ where
|
||||||
/// * [`equal_eps`](fn.equal_eps.html)
|
/// * [`equal_eps`](fn.equal_eps.html)
|
||||||
/// * [`not_equal_eps`](fn.not_equal_eps.html)
|
/// * [`not_equal_eps`](fn.not_equal_eps.html)
|
||||||
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
|
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
|
||||||
pub fn equal_eps_vec<N: Number, D: Dimension>(
|
pub fn equal_eps_vec<T: Number, const D: usize>(
|
||||||
x: &TVec<N, D>,
|
x: &TVec<T, D>,
|
||||||
y: &TVec<N, D>,
|
y: &TVec<T, D>,
|
||||||
epsilon: &TVec<N, D>,
|
epsilon: &TVec<T, D>,
|
||||||
) -> TVec<bool, D>
|
) -> TVec<bool, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.zip_zip_map(y, epsilon, |x, y, eps| abs_diff_eq!(x, y, epsilon = eps))
|
x.zip_zip_map(y, epsilon, |x, y, eps| abs_diff_eq!(x, y, epsilon = eps))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,14 +38,11 @@ where
|
||||||
/// * [`equal_eps`](fn.equal_eps.html)
|
/// * [`equal_eps`](fn.equal_eps.html)
|
||||||
/// * [`equal_eps_vec`](fn.equal_eps_vec.html)
|
/// * [`equal_eps_vec`](fn.equal_eps_vec.html)
|
||||||
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
|
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
|
||||||
pub fn not_equal_eps<N: Number, D: Dimension>(
|
pub fn not_equal_eps<T: Number, const D: usize>(
|
||||||
x: &TVec<N, D>,
|
x: &TVec<T, D>,
|
||||||
y: &TVec<N, D>,
|
y: &TVec<T, D>,
|
||||||
epsilon: N,
|
epsilon: T,
|
||||||
) -> TVec<bool, D>
|
) -> TVec<bool, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.zip_map(y, |x, y| abs_diff_ne!(x, y, epsilon = epsilon))
|
x.zip_map(y, |x, y| abs_diff_ne!(x, y, epsilon = epsilon))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,13 +53,10 @@ where
|
||||||
/// * [`equal_eps`](fn.equal_eps.html)
|
/// * [`equal_eps`](fn.equal_eps.html)
|
||||||
/// * [`equal_eps_vec`](fn.equal_eps_vec.html)
|
/// * [`equal_eps_vec`](fn.equal_eps_vec.html)
|
||||||
/// * [`not_equal_eps`](fn.not_equal_eps.html)
|
/// * [`not_equal_eps`](fn.not_equal_eps.html)
|
||||||
pub fn not_equal_eps_vec<N: Number, D: Dimension>(
|
pub fn not_equal_eps_vec<T: Number, const D: usize>(
|
||||||
x: &TVec<N, D>,
|
x: &TVec<T, D>,
|
||||||
y: &TVec<N, D>,
|
y: &TVec<T, D>,
|
||||||
epsilon: &TVec<N, D>,
|
epsilon: &TVec<T, D>,
|
||||||
) -> TVec<bool, D>
|
) -> TVec<bool, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.zip_zip_map(y, epsilon, |x, y, eps| abs_diff_ne!(x, y, epsilon = eps))
|
x.zip_zip_map(y, epsilon, |x, y, eps| abs_diff_ne!(x, y, epsilon = eps))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use na::{DefaultAllocator, RealField};
|
use na::RealField;
|
||||||
|
|
||||||
use crate::aliases::{TVec, TVec3};
|
use crate::aliases::{TVec, TVec3};
|
||||||
use crate::traits::{Alloc, Dimension, Number};
|
use crate::traits::Number;
|
||||||
|
|
||||||
/// The cross product of two vectors.
|
/// The cross product of two vectors.
|
||||||
pub fn cross<N: Number>(x: &TVec3<N>, y: &TVec3<N>) -> TVec3<N> {
|
pub fn cross<T: Number>(x: &TVec3<T>, y: &TVec3<T>) -> TVec3<T> {
|
||||||
x.cross(y)
|
x.cross(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,31 +13,22 @@ pub fn cross<N: Number>(x: &TVec3<N>, y: &TVec3<N>) -> TVec3<N> {
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`distance2`](fn.distance2.html)
|
/// * [`distance2`](fn.distance2.html)
|
||||||
pub fn distance<N: RealField, D: Dimension>(p0: &TVec<N, D>, p1: &TVec<N, D>) -> N
|
pub fn distance<T: RealField, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
(p1 - p0).norm()
|
(p1 - p0).norm()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The dot product of two vectors.
|
/// The dot product of two vectors.
|
||||||
pub fn dot<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
|
pub fn dot<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.dot(y)
|
x.dot(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If `dot(nref, i) < 0.0`, return `n`, otherwise, return `-n`.
|
/// If `dot(nref, i) < 0.0`, return `n`, otherwise, return `-n`.
|
||||||
pub fn faceforward<N: Number, D: Dimension>(
|
pub fn faceforward<T: Number, const D: usize>(
|
||||||
n: &TVec<N, D>,
|
n: &TVec<T, D>,
|
||||||
i: &TVec<N, D>,
|
i: &TVec<T, D>,
|
||||||
nref: &TVec<N, D>,
|
nref: &TVec<T, D>,
|
||||||
) -> TVec<N, D>
|
) -> TVec<T, D> {
|
||||||
where
|
if nref.dot(i) < T::zero() {
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
if nref.dot(i) < N::zero() {
|
|
||||||
n.clone()
|
n.clone()
|
||||||
} else {
|
} else {
|
||||||
-n.clone()
|
-n.clone()
|
||||||
|
@ -53,10 +44,7 @@ where
|
||||||
/// * [`length2`](fn.length2.html)
|
/// * [`length2`](fn.length2.html)
|
||||||
/// * [`magnitude`](fn.magnitude.html)
|
/// * [`magnitude`](fn.magnitude.html)
|
||||||
/// * [`magnitude2`](fn.magnitude2.html)
|
/// * [`magnitude2`](fn.magnitude2.html)
|
||||||
pub fn length<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N
|
pub fn length<T: RealField, const D: usize>(x: &TVec<T, D>) -> T {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.norm()
|
x.norm()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,39 +57,31 @@ where
|
||||||
/// * [`length`](fn.length.html)
|
/// * [`length`](fn.length.html)
|
||||||
/// * [`magnitude2`](fn.magnitude2.html)
|
/// * [`magnitude2`](fn.magnitude2.html)
|
||||||
/// * [`nalgebra::norm`](../nalgebra/fn.norm.html)
|
/// * [`nalgebra::norm`](../nalgebra/fn.norm.html)
|
||||||
pub fn magnitude<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N
|
pub fn magnitude<T: RealField, const D: usize>(x: &TVec<T, D>) -> T {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.norm()
|
x.norm()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Normalizes a vector.
|
/// Normalizes a vector.
|
||||||
pub fn normalize<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn normalize<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.normalize()
|
x.normalize()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For the incident vector `i` and surface orientation `n`, returns the reflection direction : `result = i - 2.0 * dot(n, i) * n`.
|
/// For the incident vector `i` and surface orientation `n`, returns the reflection direction : `result = i - 2.0 * dot(n, i) * n`.
|
||||||
pub fn reflect_vec<N: Number, D: Dimension>(i: &TVec<N, D>, n: &TVec<N, D>) -> TVec<N, D>
|
pub fn reflect_vec<T: Number, const D: usize>(i: &TVec<T, D>, n: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
let _2 = T::one() + T::one();
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
let _2 = N::one() + N::one();
|
|
||||||
i - n * (n.dot(i) * _2)
|
i - n * (n.dot(i) * _2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For the incident vector `i` and surface normal `n`, and the ratio of indices of refraction `eta`, return the refraction vector.
|
/// For the incident vector `i` and surface normal `n`, and the ratio of indices of refraction `eta`, return the refraction vector.
|
||||||
pub fn refract_vec<N: RealField, D: Dimension>(i: &TVec<N, D>, n: &TVec<N, D>, eta: N) -> TVec<N, D>
|
pub fn refract_vec<T: RealField, const D: usize>(
|
||||||
where
|
i: &TVec<T, D>,
|
||||||
DefaultAllocator: Alloc<N, D>,
|
n: &TVec<T, D>,
|
||||||
{
|
eta: T,
|
||||||
|
) -> TVec<T, D> {
|
||||||
let ni = n.dot(i);
|
let ni = n.dot(i);
|
||||||
let k = N::one() - eta * eta * (N::one() - ni * ni);
|
let k = T::one() - eta * eta * (T::one() - ni * ni);
|
||||||
|
|
||||||
if k < N::zero() {
|
if k < T::zero() {
|
||||||
TVec::<_, D>::zeros()
|
TVec::<_, D>::zeros()
|
||||||
} else {
|
} else {
|
||||||
i * eta - n * (eta * dot(n, i) + k.sqrt())
|
i * eta - n * (eta * dot(n, i) + k.sqrt())
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use na::{Scalar, DefaultAllocator};
|
use na::{DefaultAllocator, Scalar};
|
||||||
|
|
||||||
use crate::traits::{Alloc, Dimension};
|
|
||||||
use crate::aliases::*;
|
use crate::aliases::*;
|
||||||
|
|
||||||
pub fn bitfieldDeinterleave(x: u16) -> U8Vec2 {
|
pub fn bitfieldDeinterleave(x: u16) -> U8Vec2 {
|
||||||
|
@ -19,8 +18,11 @@ pub fn bitfieldFillOne<IU>(Value: IU, FirstBit: i32, BitCount: i32) -> IU {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bitfieldFillOne2<N: Scalar, D: Dimension>(Value: &TVec<N, D>, FirstBit: i32, BitCount: i32) -> TVec<N, D>
|
pub fn bitfieldFillOne2<T: Scalar, const D: usize>(
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
Value: &TVec<T, D>,
|
||||||
|
FirstBit: i32,
|
||||||
|
BitCount: i32,
|
||||||
|
) -> TVec<T, D> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,8 +30,11 @@ pub fn bitfieldFillZero<IU>(Value: IU, FirstBit: i32, BitCount: i32) -> IU {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bitfieldFillZero2<N: Scalar, D: Dimension>(Value: &TVec<N, D>, FirstBit: i32, BitCount: i32) -> TVec<N, D>
|
pub fn bitfieldFillZero2<T: Scalar, const D: usize>(
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
Value: &TVec<T, D>,
|
||||||
|
FirstBit: i32,
|
||||||
|
BitCount: i32,
|
||||||
|
) -> TVec<T, D> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,8 +118,7 @@ pub fn bitfieldRotateLeft<IU>(In: IU, Shift: i32) -> IU {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bitfieldRotateLeft2<N: Scalar, D: Dimension>(In: &TVec<N, D>, Shift: i32) -> TVec<N, D>
|
pub fn bitfieldRotateLeft2<T: Scalar, const D: usize>(In: &TVec<T, D>, Shift: i32) -> TVec<T, D> {
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,8 +126,7 @@ pub fn bitfieldRotateRight<IU>(In: IU, Shift: i32) -> IU {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bitfieldRotateRight2<N: Scalar, D: Dimension>(In: &TVec<N, D>, Shift: i32) -> TVec<N, D>
|
pub fn bitfieldRotateRight2<T: Scalar, const D: usize>(In: &TVec<T, D>, Shift: i32) -> TVec<T, D> {
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +134,6 @@ pub fn mask<IU>(Bits: IU) -> IU {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mask2<N: Scalar, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
pub fn mask2<T: Scalar, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,13 @@ use na::{self, RealField};
|
||||||
/// The Euler constant.
|
/// The Euler constant.
|
||||||
///
|
///
|
||||||
/// This is a shorthand alias for [`euler`](fn.euler.html).
|
/// This is a shorthand alias for [`euler`](fn.euler.html).
|
||||||
pub fn e<N: RealField>() -> N {
|
pub fn e<T: RealField>() -> T {
|
||||||
N::e()
|
T::e()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The Euler constant.
|
/// The Euler constant.
|
||||||
pub fn euler<N: RealField>() -> N {
|
pub fn euler<T: RealField>() -> T {
|
||||||
N::e()
|
T::e()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `4 / pi`.
|
/// Returns `4 / pi`.
|
||||||
|
@ -28,13 +28,13 @@ pub fn euler<N: RealField>() -> N {
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn four_over_pi<N: RealField>() -> N {
|
pub fn four_over_pi<T: RealField>() -> T {
|
||||||
na::convert::<_, N>(4.0) / N::pi()
|
na::convert::<_, T>(4.0) / T::pi()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the golden ratio.
|
/// Returns the golden ratio.
|
||||||
pub fn golden_ratio<N: RealField>() -> N {
|
pub fn golden_ratio<T: RealField>() -> T {
|
||||||
(N::one() + root_five()) / na::convert(2.0)
|
(T::one() + root_five()) / na::convert(2.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `pi / 2`.
|
/// Returns `pi / 2`.
|
||||||
|
@ -53,8 +53,8 @@ pub fn golden_ratio<N: RealField>() -> N {
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn half_pi<N: RealField>() -> N {
|
pub fn half_pi<T: RealField>() -> T {
|
||||||
N::frac_pi_2()
|
T::frac_pi_2()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `ln(ln(2))`.
|
/// Returns `ln(ln(2))`.
|
||||||
|
@ -63,8 +63,8 @@ pub fn half_pi<N: RealField>() -> N {
|
||||||
///
|
///
|
||||||
/// * [`ln_ten`](fn.ln_ten.html)
|
/// * [`ln_ten`](fn.ln_ten.html)
|
||||||
/// * [`ln_two`](fn.ln_two.html)
|
/// * [`ln_two`](fn.ln_two.html)
|
||||||
pub fn ln_ln_two<N: RealField>() -> N {
|
pub fn ln_ln_two<T: RealField>() -> T {
|
||||||
N::ln_2().ln()
|
T::ln_2().ln()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `ln(10)`.
|
/// Returns `ln(10)`.
|
||||||
|
@ -73,8 +73,8 @@ pub fn ln_ln_two<N: RealField>() -> N {
|
||||||
///
|
///
|
||||||
/// * [`ln_ln_two`](fn.ln_ln_two.html)
|
/// * [`ln_ln_two`](fn.ln_ln_two.html)
|
||||||
/// * [`ln_two`](fn.ln_two.html)
|
/// * [`ln_two`](fn.ln_two.html)
|
||||||
pub fn ln_ten<N: RealField>() -> N {
|
pub fn ln_ten<T: RealField>() -> T {
|
||||||
N::ln_10()
|
T::ln_10()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `ln(2)`.
|
/// Returns `ln(2)`.
|
||||||
|
@ -83,8 +83,8 @@ pub fn ln_ten<N: RealField>() -> N {
|
||||||
///
|
///
|
||||||
/// * [`ln_ln_two`](fn.ln_ln_two.html)
|
/// * [`ln_ln_two`](fn.ln_ln_two.html)
|
||||||
/// * [`ln_ten`](fn.ln_ten.html)
|
/// * [`ln_ten`](fn.ln_ten.html)
|
||||||
pub fn ln_two<N: RealField>() -> N {
|
pub fn ln_two<T: RealField>() -> T {
|
||||||
N::ln_2()
|
T::ln_2()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `1`.
|
/// Returns `1`.
|
||||||
|
@ -106,13 +106,13 @@ pub use na::one;
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn one_over_pi<N: RealField>() -> N {
|
pub fn one_over_pi<T: RealField>() -> T {
|
||||||
N::frac_1_pi()
|
T::frac_1_pi()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `1 / sqrt(2)`.
|
/// Returns `1 / sqrt(2)`.
|
||||||
pub fn one_over_root_two<N: RealField>() -> N {
|
pub fn one_over_root_two<T: RealField>() -> T {
|
||||||
N::one() / root_two()
|
T::one() / root_two()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `1 / (2pi)`.
|
/// Returns `1 / (2pi)`.
|
||||||
|
@ -131,8 +131,8 @@ pub fn one_over_root_two<N: RealField>() -> N {
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn one_over_two_pi<N: RealField>() -> N {
|
pub fn one_over_two_pi<T: RealField>() -> T {
|
||||||
N::frac_1_pi() * na::convert(0.5)
|
T::frac_1_pi() * na::convert(0.5)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `pi / 4`.
|
/// Returns `pi / 4`.
|
||||||
|
@ -151,8 +151,8 @@ pub fn one_over_two_pi<N: RealField>() -> N {
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn quarter_pi<N: RealField>() -> N {
|
pub fn quarter_pi<T: RealField>() -> T {
|
||||||
N::frac_pi_4()
|
T::frac_pi_4()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `sqrt(5)`.
|
/// Returns `sqrt(5)`.
|
||||||
|
@ -161,8 +161,8 @@ pub fn quarter_pi<N: RealField>() -> N {
|
||||||
///
|
///
|
||||||
/// * [`root_three`](fn.root_three.html)
|
/// * [`root_three`](fn.root_three.html)
|
||||||
/// * [`root_two`](fn.root_two.html)
|
/// * [`root_two`](fn.root_two.html)
|
||||||
pub fn root_five<N: RealField>() -> N {
|
pub fn root_five<T: RealField>() -> T {
|
||||||
na::convert::<_, N>(5.0).sqrt()
|
na::convert::<_, T>(5.0).sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `sqrt(pi / 2)`.
|
/// Returns `sqrt(pi / 2)`.
|
||||||
|
@ -181,13 +181,13 @@ pub fn root_five<N: RealField>() -> N {
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn root_half_pi<N: RealField>() -> N {
|
pub fn root_half_pi<T: RealField>() -> T {
|
||||||
(N::pi() / na::convert(2.0)).sqrt()
|
(T::pi() / na::convert(2.0)).sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `sqrt(ln(4))`.
|
/// Returns `sqrt(ln(4))`.
|
||||||
pub fn root_ln_four<N: RealField>() -> N {
|
pub fn root_ln_four<T: RealField>() -> T {
|
||||||
na::convert::<_, N>(4.0).ln().sqrt()
|
na::convert::<_, T>(4.0).ln().sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the square root of pi.
|
/// Returns the square root of pi.
|
||||||
|
@ -206,8 +206,8 @@ pub fn root_ln_four<N: RealField>() -> N {
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn root_pi<N: RealField>() -> N {
|
pub fn root_pi<T: RealField>() -> T {
|
||||||
N::pi().sqrt()
|
T::pi().sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the square root of 3.
|
/// Returns the square root of 3.
|
||||||
|
@ -216,8 +216,8 @@ pub fn root_pi<N: RealField>() -> N {
|
||||||
///
|
///
|
||||||
/// * [`root_five`](fn.root_five.html)
|
/// * [`root_five`](fn.root_five.html)
|
||||||
/// * [`root_two`](fn.root_two.html)
|
/// * [`root_two`](fn.root_two.html)
|
||||||
pub fn root_three<N: RealField>() -> N {
|
pub fn root_three<T: RealField>() -> T {
|
||||||
na::convert::<_, N>(3.0).sqrt()
|
na::convert::<_, T>(3.0).sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the square root of 2.
|
/// Returns the square root of 2.
|
||||||
|
@ -226,9 +226,9 @@ pub fn root_three<N: RealField>() -> N {
|
||||||
///
|
///
|
||||||
/// * [`root_five`](fn.root_five.html)
|
/// * [`root_five`](fn.root_five.html)
|
||||||
/// * [`root_three`](fn.root_three.html)
|
/// * [`root_three`](fn.root_three.html)
|
||||||
pub fn root_two<N: RealField>() -> N {
|
pub fn root_two<T: RealField>() -> T {
|
||||||
// TODO: there should be a crate::sqrt_2() on the RealField trait.
|
// TODO: there should be a crate::sqrt_2() on the RealField trait.
|
||||||
na::convert::<_, N>(2.0).sqrt()
|
na::convert::<_, T>(2.0).sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the square root of 2pi.
|
/// Returns the square root of 2pi.
|
||||||
|
@ -247,8 +247,8 @@ pub fn root_two<N: RealField>() -> N {
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn root_two_pi<N: RealField>() -> N {
|
pub fn root_two_pi<T: RealField>() -> T {
|
||||||
N::two_pi().sqrt()
|
T::two_pi().sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `1 / 3`.
|
/// Returns `1 / 3`.
|
||||||
|
@ -256,7 +256,7 @@ pub fn root_two_pi<N: RealField>() -> N {
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`two_thirds`](fn.two_thirds.html)
|
/// * [`two_thirds`](fn.two_thirds.html)
|
||||||
pub fn third<N: RealField>() -> N {
|
pub fn third<T: RealField>() -> T {
|
||||||
na::convert(1.0 / 3.0)
|
na::convert(1.0 / 3.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,8 +276,8 @@ pub fn third<N: RealField>() -> N {
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn three_over_two_pi<N: RealField>() -> N {
|
pub fn three_over_two_pi<T: RealField>() -> T {
|
||||||
na::convert::<_, N>(3.0) / N::two_pi()
|
na::convert::<_, T>(3.0) / T::two_pi()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `2 / pi`.
|
/// Returns `2 / pi`.
|
||||||
|
@ -295,8 +295,8 @@ pub fn three_over_two_pi<N: RealField>() -> N {
|
||||||
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn two_over_pi<N: RealField>() -> N {
|
pub fn two_over_pi<T: RealField>() -> T {
|
||||||
N::frac_2_pi()
|
T::frac_2_pi()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `2 / sqrt(pi)`.
|
/// Returns `2 / sqrt(pi)`.
|
||||||
|
@ -315,8 +315,8 @@ pub fn two_over_pi<N: RealField>() -> N {
|
||||||
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_pi`](fn.two_pi.html)
|
/// * [`two_pi`](fn.two_pi.html)
|
||||||
pub fn two_over_root_pi<N: RealField>() -> N {
|
pub fn two_over_root_pi<T: RealField>() -> T {
|
||||||
N::frac_2_sqrt_pi()
|
T::frac_2_sqrt_pi()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `2pi`.
|
/// Returns `2pi`.
|
||||||
|
@ -335,8 +335,8 @@ pub fn two_over_root_pi<N: RealField>() -> N {
|
||||||
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
/// * [`three_over_two_pi`](fn.three_over_two_pi.html)
|
||||||
/// * [`two_over_pi`](fn.two_over_pi.html)
|
/// * [`two_over_pi`](fn.two_over_pi.html)
|
||||||
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
/// * [`two_over_root_pi`](fn.two_over_root_pi.html)
|
||||||
pub fn two_pi<N: RealField>() -> N {
|
pub fn two_pi<T: RealField>() -> T {
|
||||||
N::two_pi()
|
T::two_pi()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `2 / 3`.
|
/// Returns `2 / 3`.
|
||||||
|
@ -344,7 +344,7 @@ pub fn two_pi<N: RealField>() -> N {
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`third`](fn.third.html)
|
/// * [`third`](fn.third.html)
|
||||||
pub fn two_thirds<N: RealField>() -> N {
|
pub fn two_thirds<T: RealField>() -> T {
|
||||||
na::convert(2.0 / 3.0)
|
na::convert(2.0 / 3.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,24 +8,24 @@ use crate::traits::{Alloc, Number, Dimension};
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
|
|
||||||
/// Component-wise approximate equality beween two vectors.
|
/// Component-wise approximate equality beween two vectors.
|
||||||
pub fn epsilon_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, epsilon: N) -> TVec<bool, D>
|
pub fn epsilon_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, epsilon: T) -> TVec<bool, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<T, D> {
|
||||||
x.zip_map(y, |x, y| abs_diff_eq!(x, y, epsilon = epsilon))
|
x.zip_map(y, |x, y| abs_diff_eq!(x, y, epsilon = epsilon))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise approximate equality beween two scalars.
|
/// Component-wise approximate equality beween two scalars.
|
||||||
pub fn epsilon_equal2<N: AbsDiffEq<Epsilon = N>>(x: N, y: N, epsilon: N) -> bool {
|
pub fn epsilon_equal2<T: AbsDiffEq<Epsilon = T>>(x: T, y: T, epsilon: T) -> bool {
|
||||||
abs_diff_eq!(x, y, epsilon = epsilon)
|
abs_diff_eq!(x, y, epsilon = epsilon)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise approximate non-equality beween two vectors.
|
/// Component-wise approximate non-equality beween two vectors.
|
||||||
pub fn epsilon_not_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, epsilon: N) -> TVec<bool, D>
|
pub fn epsilon_not_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, epsilon: T) -> TVec<bool, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<T, D> {
|
||||||
x.zip_map(y, |x, y| abs_diff_ne!(x, y, epsilon = epsilon))
|
x.zip_map(y, |x, y| abs_diff_ne!(x, y, epsilon = epsilon))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise approximate non-equality beween two scalars.
|
/// Component-wise approximate non-equality beween two scalars.
|
||||||
pub fn epsilon_not_equal2<N: AbsDiffEq<Epsilon = N>>(x: N, y: N, epsilon: N) -> bool {
|
pub fn epsilon_not_equal2<T: AbsDiffEq<Epsilon = T>>(x: T, y: T, epsilon: T) -> bool {
|
||||||
abs_diff_ne!(x, y, epsilon = epsilon)
|
abs_diff_ne!(x, y, epsilon = epsilon)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
//use na::{Scalar, DefaultAllocator};
|
//use na::Scalar;
|
||||||
|
//
|
||||||
//
|
//
|
||||||
//use crate::traits::{Alloc, Dimension};
|
|
||||||
//use crate::aliases::TVec;
|
//use crate::aliases::TVec;
|
||||||
|
|
||||||
//pub fn iround<N: Scalar, D: Dimension>(x: &TVec<N, D>) -> TVec<i32, D>
|
//pub fn iround<T: Scalar, const D: usize>(x: &TVec<T, D>) -> TVec<i32, D> {
|
||||||
// where DefaultAllocator: Alloc<N, D> {
|
|
||||||
// x.map(|x| x.round())
|
// x.map(|x| x.round())
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
|
@ -12,7 +11,6 @@
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn uround<N: Scalar, D: Dimension>(x: &TVec<N, D>) -> TVec<u32, D>
|
//pub fn uround<T: Scalar, const D: usize>(x: &TVec<T, D>) -> TVec<u32, D> {
|
||||||
// where DefaultAllocator: Alloc<N, D> {
|
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use na::{DefaultAllocator, Scalar};
|
use na::Scalar;
|
||||||
|
|
||||||
use crate::aliases::{TMat, TVec};
|
use crate::aliases::{TMat, TVec};
|
||||||
use crate::traits::{Alloc, Dimension};
|
|
||||||
|
|
||||||
/// The `index`-th column of the matrix `m`.
|
/// The `index`-th column of the matrix `m`.
|
||||||
///
|
///
|
||||||
|
@ -10,10 +9,10 @@ use crate::traits::{Alloc, Dimension};
|
||||||
/// * [`row`](fn.row.html)
|
/// * [`row`](fn.row.html)
|
||||||
/// * [`set_column`](fn.set_column.html)
|
/// * [`set_column`](fn.set_column.html)
|
||||||
/// * [`set_row`](fn.set_row.html)
|
/// * [`set_row`](fn.set_row.html)
|
||||||
pub fn column<N: Scalar, R: Dimension, C: Dimension>(m: &TMat<N, R, C>, index: usize) -> TVec<N, R>
|
pub fn column<T: Scalar, const R: usize, const C: usize>(
|
||||||
where
|
m: &TMat<T, R, C>,
|
||||||
DefaultAllocator: Alloc<N, R, C>,
|
index: usize,
|
||||||
{
|
) -> TVec<T, R> {
|
||||||
m.column(index).into_owned()
|
m.column(index).into_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,14 +23,11 @@ where
|
||||||
/// * [`column`](fn.column.html)
|
/// * [`column`](fn.column.html)
|
||||||
/// * [`row`](fn.row.html)
|
/// * [`row`](fn.row.html)
|
||||||
/// * [`set_row`](fn.set_row.html)
|
/// * [`set_row`](fn.set_row.html)
|
||||||
pub fn set_column<N: Scalar, R: Dimension, C: Dimension>(
|
pub fn set_column<T: Scalar, const R: usize, const C: usize>(
|
||||||
m: &TMat<N, R, C>,
|
m: &TMat<T, R, C>,
|
||||||
index: usize,
|
index: usize,
|
||||||
x: &TVec<N, R>,
|
x: &TVec<T, R>,
|
||||||
) -> TMat<N, R, C>
|
) -> TMat<T, R, C> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, R, C>,
|
|
||||||
{
|
|
||||||
let mut res = m.clone();
|
let mut res = m.clone();
|
||||||
res.set_column(index, x);
|
res.set_column(index, x);
|
||||||
res
|
res
|
||||||
|
@ -44,10 +40,10 @@ where
|
||||||
/// * [`column`](fn.column.html)
|
/// * [`column`](fn.column.html)
|
||||||
/// * [`set_column`](fn.set_column.html)
|
/// * [`set_column`](fn.set_column.html)
|
||||||
/// * [`set_row`](fn.set_row.html)
|
/// * [`set_row`](fn.set_row.html)
|
||||||
pub fn row<N: Scalar, R: Dimension, C: Dimension>(m: &TMat<N, R, C>, index: usize) -> TVec<N, C>
|
pub fn row<T: Scalar, const R: usize, const C: usize>(
|
||||||
where
|
m: &TMat<T, R, C>,
|
||||||
DefaultAllocator: Alloc<N, R, C>,
|
index: usize,
|
||||||
{
|
) -> TVec<T, C> {
|
||||||
m.row(index).into_owned().transpose()
|
m.row(index).into_owned().transpose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,14 +54,11 @@ where
|
||||||
/// * [`column`](fn.column.html)
|
/// * [`column`](fn.column.html)
|
||||||
/// * [`row`](fn.row.html)
|
/// * [`row`](fn.row.html)
|
||||||
/// * [`set_column`](fn.set_column.html)
|
/// * [`set_column`](fn.set_column.html)
|
||||||
pub fn set_row<N: Scalar, R: Dimension, C: Dimension>(
|
pub fn set_row<T: Scalar, const R: usize, const C: usize>(
|
||||||
m: &TMat<N, R, C>,
|
m: &TMat<T, R, C>,
|
||||||
index: usize,
|
index: usize,
|
||||||
x: &TVec<N, C>,
|
x: &TVec<T, C>,
|
||||||
) -> TMat<N, R, C>
|
) -> TMat<T, R, C> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, R, C>,
|
|
||||||
{
|
|
||||||
let mut res = m.clone();
|
let mut res = m.clone();
|
||||||
res.set_row(index, &x.transpose());
|
res.set_row(index, &x.transpose());
|
||||||
res
|
res
|
||||||
|
|
|
@ -1,22 +1,15 @@
|
||||||
use na::{DefaultAllocator, RealField};
|
use na::RealField;
|
||||||
|
|
||||||
use crate::aliases::TMat;
|
use crate::aliases::TMat;
|
||||||
use crate::traits::{Alloc, Dimension};
|
|
||||||
|
|
||||||
/// Fast matrix inverse for affine matrix.
|
/// Fast matrix inverse for affine matrix.
|
||||||
pub fn affine_inverse<N: RealField, D: Dimension>(m: TMat<N, D, D>) -> TMat<N, D, D>
|
pub fn affine_inverse<T: RealField, const D: usize>(m: TMat<T, D, D>) -> TMat<T, D, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D, D>,
|
|
||||||
{
|
|
||||||
// TODO: this should be optimized.
|
// TODO: this should be optimized.
|
||||||
m.try_inverse().unwrap_or_else(TMat::<_, D, D>::zeros)
|
m.try_inverse().unwrap_or_else(TMat::<_, D, D>::zeros)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the transpose of the inverse of a matrix.
|
/// Compute the transpose of the inverse of a matrix.
|
||||||
pub fn inverse_transpose<N: RealField, D: Dimension>(m: TMat<N, D, D>) -> TMat<N, D, D>
|
pub fn inverse_transpose<T: RealField, const D: usize>(m: TMat<T, D, D>) -> TMat<T, D, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D, D>,
|
|
||||||
{
|
|
||||||
m.try_inverse()
|
m.try_inverse()
|
||||||
.unwrap_or_else(TMat::<_, D, D>::zeros)
|
.unwrap_or_else(TMat::<_, D, D>::zeros)
|
||||||
.transpose()
|
.transpose()
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
use na::{Scalar, RealField, DefaultAllocator, U3, U4};
|
use na::{DefaultAllocator, RealField, Scalar, U3, U4};
|
||||||
|
|
||||||
use crate::traits::{Alloc, Dimension};
|
|
||||||
use crate::aliases::*;
|
use crate::aliases::*;
|
||||||
|
|
||||||
|
|
||||||
pub fn packF2x11_1x10(v: &Vec3) -> i32 {
|
pub fn packF2x11_1x10(v: &Vec3) -> i32 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
@ -12,8 +10,10 @@ pub fn packF3x9_E1x5(v: &Vec3) -> i32 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn packHalf<D: Dimension>(v: &TVec<f32, D>) -> TVec<u16, D>
|
pub fn packHalf<const D: usize>(v: &TVec<f32, D>) -> TVec<u16, D>
|
||||||
where DefaultAllocator: Alloc<u16, D> {
|
where
|
||||||
|
DefaultAllocator: Alloc<u16, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,12 +49,14 @@ pub fn packInt4x8(v: &I8Vec4) -> i32 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn packRGBM<N: Scalar>(rgb: &TVec3<N>) -> TVec4<N> {
|
pub fn packRGBM<T: Scalar>(rgb: &TVec3<T>) -> TVec4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn packSnorm<I: Scalar, N: RealField, D: Dimension>(v: TVec<N, D>) -> TVec<I, D>
|
pub fn packSnorm<I: Scalar, T: RealField, const D: usize>(v: TVec<T, D>) -> TVec<I, D>
|
||||||
where DefaultAllocator: Alloc<N, D> + Alloc<I, D> {
|
where
|
||||||
|
DefaultAllocator: Alloc<T, D> + Alloc<I, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,8 +104,10 @@ pub fn packUint4x8(v: &U8Vec4) -> i32 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn packUnorm<UI: Scalar, N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<UI, D>
|
pub fn packUnorm<UI: Scalar, T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<UI, D>
|
||||||
where DefaultAllocator: Alloc<N, D> + Alloc<UI, D> {
|
where
|
||||||
|
DefaultAllocator: Alloc<T, D> + Alloc<UI, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,8 +159,7 @@ pub fn unpackF3x9_E1x5(p: i32) -> Vec3 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unpackHalf<N: Scalar, D: Dimension>(p: TVec<i16, D>) -> TVec<N, D>
|
pub fn unpackHalf<T: Scalar, const D: usize>(p: TVec<i16, D>) -> TVec<T, D> {
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,12 +195,14 @@ pub fn unpackInt4x8(p: i32) -> I8Vec4 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unpackRGBM<N: Scalar>(rgbm: &TVec4<N>) -> TVec3<N> {
|
pub fn unpackRGBM<T: Scalar>(rgbm: &TVec4<T>) -> TVec3<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unpackSnorm<I: Scalar, N: RealField, D: Dimension>(v: &TVec<I, D>) -> TVec<N, D>
|
pub fn unpackSnorm<I: Scalar, T: RealField, const D: usize>(v: &TVec<I, D>) -> TVec<T, D>
|
||||||
where DefaultAllocator: Alloc<N, D> + Alloc<I, D> {
|
where
|
||||||
|
DefaultAllocator: Alloc<T, D> + Alloc<I, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,8 +250,10 @@ pub fn unpackUint4x8(p: i32) -> U8Vec4 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unpackUnorm<UI: Scalar, N: RealField, D: Dimension>(v: &TVec<UI, D>) -> TVec<N, D>
|
pub fn unpackUnorm<UI: Scalar, T: RealField, const D: usize>(v: &TVec<UI, D>) -> TVec<T, D>
|
||||||
where DefaultAllocator: Alloc<N, D> + Alloc<UI, D> {
|
where
|
||||||
|
DefaultAllocator: Alloc<T, D> + Alloc<UI, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
use na::{RealField, UnitQuaternion, U4};
|
use na::{RealField, UnitQuaternion};
|
||||||
|
|
||||||
use crate::aliases::{Qua, TMat4, TVec, TVec3};
|
use crate::aliases::{Qua, TMat4, TVec, TVec3};
|
||||||
|
|
||||||
/// Euler angles of the quaternion `q` as (pitch, yaw, roll).
|
/// Euler angles of the quaternion `q` as (pitch, yaw, roll).
|
||||||
pub fn quat_euler_angles<N: RealField>(x: &Qua<N>) -> TVec3<N> {
|
pub fn quat_euler_angles<T: RealField>(x: &Qua<T>) -> TVec3<T> {
|
||||||
let q = UnitQuaternion::new_unchecked(*x);
|
let q = UnitQuaternion::new_unchecked(*x);
|
||||||
let a = q.euler_angles();
|
let a = q.euler_angles();
|
||||||
TVec3::new(a.2, a.1, a.0)
|
TVec3::new(a.2, a.1, a.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise `>` comparison between two quaternions.
|
/// Component-wise `>` comparison between two quaternions.
|
||||||
pub fn quat_greater_than<N: RealField>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> {
|
pub fn quat_greater_than<T: RealField>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
|
||||||
crate::greater_than(&x.coords, &y.coords)
|
crate::greater_than(&x.coords, &y.coords)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise `>=` comparison between two quaternions.
|
/// Component-wise `>=` comparison between two quaternions.
|
||||||
pub fn quat_greater_than_equal<N: RealField>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> {
|
pub fn quat_greater_than_equal<T: RealField>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
|
||||||
crate::greater_than_equal(&x.coords, &y.coords)
|
crate::greater_than_equal(&x.coords, &y.coords)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise `<` comparison between two quaternions.
|
/// Component-wise `<` comparison between two quaternions.
|
||||||
pub fn quat_less_than<N: RealField>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> {
|
pub fn quat_less_than<T: RealField>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
|
||||||
crate::less_than(&x.coords, &y.coords)
|
crate::less_than(&x.coords, &y.coords)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise `<=` comparison between two quaternions.
|
/// Component-wise `<=` comparison between two quaternions.
|
||||||
pub fn quat_less_than_equal<N: RealField>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> {
|
pub fn quat_less_than_equal<T: RealField>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
|
||||||
crate::less_than_equal(&x.coords, &y.coords)
|
crate::less_than_equal(&x.coords, &y.coords)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a quaternion to a rotation matrix in homogeneous coordinates.
|
/// Convert a quaternion to a rotation matrix in homogeneous coordinates.
|
||||||
pub fn quat_cast<N: RealField>(x: &Qua<N>) -> TMat4<N> {
|
pub fn quat_cast<T: RealField>(x: &Qua<T>) -> TMat4<T> {
|
||||||
crate::quat_to_mat4(x)
|
crate::quat_to_mat4(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,34 +41,34 @@ pub fn quat_cast<N: RealField>(x: &Qua<N>) -> TMat4<N> {
|
||||||
/// * `direction` - Direction vector point at where to look
|
/// * `direction` - Direction vector point at where to look
|
||||||
/// * `up` - Object up vector
|
/// * `up` - Object up vector
|
||||||
///
|
///
|
||||||
pub fn quat_look_at<N: RealField>(direction: &TVec3<N>, up: &TVec3<N>) -> Qua<N> {
|
pub fn quat_look_at<T: RealField>(direction: &TVec3<T>, up: &TVec3<T>) -> Qua<T> {
|
||||||
quat_look_at_rh(direction, up)
|
quat_look_at_rh(direction, up)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes a left-handed look-at quaternion (equivalent to a left-handed look-at matrix).
|
/// Computes a left-handed look-at quaternion (equivalent to a left-handed look-at matrix).
|
||||||
pub fn quat_look_at_lh<N: RealField>(direction: &TVec3<N>, up: &TVec3<N>) -> Qua<N> {
|
pub fn quat_look_at_lh<T: RealField>(direction: &TVec3<T>, up: &TVec3<T>) -> Qua<T> {
|
||||||
UnitQuaternion::look_at_lh(direction, up).into_inner()
|
UnitQuaternion::look_at_lh(direction, up).into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes a right-handed look-at quaternion (equivalent to a right-handed look-at matrix).
|
/// Computes a right-handed look-at quaternion (equivalent to a right-handed look-at matrix).
|
||||||
pub fn quat_look_at_rh<N: RealField>(direction: &TVec3<N>, up: &TVec3<N>) -> Qua<N> {
|
pub fn quat_look_at_rh<T: RealField>(direction: &TVec3<T>, up: &TVec3<T>) -> Qua<T> {
|
||||||
UnitQuaternion::look_at_rh(direction, up).into_inner()
|
UnitQuaternion::look_at_rh(direction, up).into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The "roll" Euler angle of the quaternion `x` assumed to be normalized.
|
/// The "roll" Euler angle of the quaternion `x` assumed to be normalized.
|
||||||
pub fn quat_roll<N: RealField>(x: &Qua<N>) -> N {
|
pub fn quat_roll<T: RealField>(x: &Qua<T>) -> T {
|
||||||
// TODO: optimize this.
|
// TODO: optimize this.
|
||||||
quat_euler_angles(x).z
|
quat_euler_angles(x).z
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The "yaw" Euler angle of the quaternion `x` assumed to be normalized.
|
/// The "yaw" Euler angle of the quaternion `x` assumed to be normalized.
|
||||||
pub fn quat_yaw<N: RealField>(x: &Qua<N>) -> N {
|
pub fn quat_yaw<T: RealField>(x: &Qua<T>) -> T {
|
||||||
// TODO: optimize this.
|
// TODO: optimize this.
|
||||||
quat_euler_angles(x).y
|
quat_euler_angles(x).y
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The "pitch" Euler angle of the quaternion `x` assumed to be normalized.
|
/// The "pitch" Euler angle of the quaternion `x` assumed to be normalized.
|
||||||
pub fn quat_pitch<N: RealField>(x: &Qua<N>) -> N {
|
pub fn quat_pitch<T: RealField>(x: &Qua<T>) -> T {
|
||||||
// TODO: optimize this.
|
// TODO: optimize this.
|
||||||
quat_euler_angles(x).x
|
quat_euler_angles(x).x
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
use na::{Scalar, RealField, U3, DefaultAllocator};
|
use na::{DefaultAllocator, RealField, Scalar, U3};
|
||||||
|
|
||||||
use crate::traits::{Number, Alloc, Dimension};
|
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
|
use crate::traits::{Alloc, Dimension, Number};
|
||||||
|
|
||||||
pub fn ceilMultiple<T>(v: T, Multiple: T) -> T {
|
pub fn ceilMultiple<T>(v: T, Multiple: T) -> T {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ceilMultiple2<N: Scalar, D: Dimension>(v: &TVec<N, D>, Multiple: &TVec<N, D>) -> TVec<N, D>
|
pub fn ceilMultiple2<T: Scalar, const D: usize>(v: &TVec<T, D>, Multiple: &TVec<T, D>) -> TVec<T, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where
|
||||||
|
DefaultAllocator: Alloc<T, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,8 +18,10 @@ pub fn ceilPowerOfTwo<IU>(v: IU) -> IU {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ceilPowerOfTwo2<N: Scalar, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
pub fn ceilPowerOfTwo2<T: Scalar, const D: usize>(v: &TVec<T, D>) -> TVec<T, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where
|
||||||
|
DefaultAllocator: Alloc<T, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,8 +29,13 @@ pub fn floorMultiple<T>(v: T, Multiple: T) -> T {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn floorMultiple2<N: Scalar, D: Dimension>(v: &TVec<N, D>, Multiple: &TVec<N, D>) -> TVec<N, D>
|
pub fn floorMultiple2<T: Scalar, const D: usize>(
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
v: &TVec<T, D>,
|
||||||
|
Multiple: &TVec<T, D>,
|
||||||
|
) -> TVec<T, D>
|
||||||
|
where
|
||||||
|
DefaultAllocator: Alloc<T, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,8 +43,10 @@ pub fn floorPowerOfTwo<IU>(v: IU) -> IU {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn floorPowerOfTwo2<N: Scalar, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
pub fn floorPowerOfTwo2<T: Scalar, const D: usize>(v: &TVec<T, D>) -> TVec<T, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where
|
||||||
|
DefaultAllocator: Alloc<T, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,13 +54,20 @@ pub fn isMultiple<IU>(v: IU, Multiple: IU) -> bool {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn isMultiple2<N: Scalar, D: Dimension>(v: &TVec<N, D>,Multiple: N) -> TVec<bool, D>
|
pub fn isMultiple2<T: Scalar, const D: usize>(v: &TVec<T, D>, Multiple: T) -> TVec<bool, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where
|
||||||
|
DefaultAllocator: Alloc<T, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn isMultiple3<N: Scalar, D: Dimension>(v: &TVec<N, D>, Multiple: &TVec<N, D>) -> TVec<bool, D>
|
pub fn isMultiple3<T: Scalar, const D: usize>(
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
v: &TVec<T, D>,
|
||||||
|
Multiple: &TVec<T, D>,
|
||||||
|
) -> TVec<bool, D>
|
||||||
|
where
|
||||||
|
DefaultAllocator: Alloc<T, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,8 +75,10 @@ pub fn isPowerOfTwo2<IU>(v: IU) -> bool {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn isPowerOfTwo<N: Scalar, D: Dimension>(v: &TVec<N, D>) -> TVec<bool, D>
|
pub fn isPowerOfTwo<T: Scalar, const D: usize>(v: &TVec<T, D>) -> TVec<bool, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where
|
||||||
|
DefaultAllocator: Alloc<T, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,8 +86,13 @@ pub fn roundMultiple<T>(v: T, Multiple: T) -> T {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn roundMultiple2<N: Scalar, D: Dimension>(v: &TVec<N, D>, Multiple: &TVec<N, D>) -> TVec<N, D>
|
pub fn roundMultiple2<T: Scalar, const D: usize>(
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
v: &TVec<T, D>,
|
||||||
|
Multiple: &TVec<T, D>,
|
||||||
|
) -> TVec<T, D>
|
||||||
|
where
|
||||||
|
DefaultAllocator: Alloc<T, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +100,9 @@ pub fn roundPowerOfTwo<IU>(v: IU) -> IU {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn roundPowerOfTwo2<N: Scalar, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
pub fn roundPowerOfTwo2<T: Scalar, const D: usize>(v: &TVec<T, D>) -> TVec<T, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where
|
||||||
|
DefaultAllocator: Alloc<T, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,81 +1,81 @@
|
||||||
use na::{DefaultAllocator, Quaternion, RealField, Scalar};
|
use na::{Quaternion, RealField, Scalar};
|
||||||
|
|
||||||
use crate::aliases::{
|
use crate::aliases::{
|
||||||
Qua, TMat, TMat2, TMat2x3, TMat2x4, TMat3, TMat3x2, TMat3x4, TMat4, TMat4x2, TMat4x3, TVec1,
|
Qua, TMat, TMat2, TMat2x3, TMat2x4, TMat3, TMat3x2, TMat3x4, TMat4, TMat4x2, TMat4x3, TVec1,
|
||||||
TVec2, TVec3, TVec4,
|
TVec2, TVec3, TVec4,
|
||||||
};
|
};
|
||||||
use crate::traits::{Alloc, Dimension, Number};
|
use crate::traits::Number;
|
||||||
|
|
||||||
/// Creates a 2x2 matrix from a slice arranged in column-major order.
|
/// Creates a 2x2 matrix from a slice arranged in column-major order.
|
||||||
pub fn make_mat2<N: Scalar>(ptr: &[N]) -> TMat2<N> {
|
pub fn make_mat2<T: Scalar>(ptr: &[T]) -> TMat2<T> {
|
||||||
TMat2::from_column_slice(ptr)
|
TMat2::from_column_slice(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 2x2 matrix from a slice arranged in column-major order.
|
/// Creates a 2x2 matrix from a slice arranged in column-major order.
|
||||||
pub fn make_mat2x2<N: Scalar>(ptr: &[N]) -> TMat2<N> {
|
pub fn make_mat2x2<T: Scalar>(ptr: &[T]) -> TMat2<T> {
|
||||||
TMat2::from_column_slice(ptr)
|
TMat2::from_column_slice(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 2x3 matrix from a slice arranged in column-major order.
|
/// Creates a 2x3 matrix from a slice arranged in column-major order.
|
||||||
pub fn make_mat2x3<N: Scalar>(ptr: &[N]) -> TMat2x3<N> {
|
pub fn make_mat2x3<T: Scalar>(ptr: &[T]) -> TMat2x3<T> {
|
||||||
TMat2x3::from_column_slice(ptr)
|
TMat2x3::from_column_slice(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 2x4 matrix from a slice arranged in column-major order.
|
/// Creates a 2x4 matrix from a slice arranged in column-major order.
|
||||||
pub fn make_mat2x4<N: Scalar>(ptr: &[N]) -> TMat2x4<N> {
|
pub fn make_mat2x4<T: Scalar>(ptr: &[T]) -> TMat2x4<T> {
|
||||||
TMat2x4::from_column_slice(ptr)
|
TMat2x4::from_column_slice(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 3 matrix from a slice arranged in column-major order.
|
/// Creates a 3 matrix from a slice arranged in column-major order.
|
||||||
pub fn make_mat3<N: Scalar>(ptr: &[N]) -> TMat3<N> {
|
pub fn make_mat3<T: Scalar>(ptr: &[T]) -> TMat3<T> {
|
||||||
TMat3::from_column_slice(ptr)
|
TMat3::from_column_slice(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 3x2 matrix from a slice arranged in column-major order.
|
/// Creates a 3x2 matrix from a slice arranged in column-major order.
|
||||||
pub fn make_mat3x2<N: Scalar>(ptr: &[N]) -> TMat3x2<N> {
|
pub fn make_mat3x2<T: Scalar>(ptr: &[T]) -> TMat3x2<T> {
|
||||||
TMat3x2::from_column_slice(ptr)
|
TMat3x2::from_column_slice(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 3x3 matrix from a slice arranged in column-major order.
|
/// Creates a 3x3 matrix from a slice arranged in column-major order.
|
||||||
pub fn make_mat3x3<N: Scalar>(ptr: &[N]) -> TMat3<N> {
|
pub fn make_mat3x3<T: Scalar>(ptr: &[T]) -> TMat3<T> {
|
||||||
TMat3::from_column_slice(ptr)
|
TMat3::from_column_slice(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 3x4 matrix from a slice arranged in column-major order.
|
/// Creates a 3x4 matrix from a slice arranged in column-major order.
|
||||||
pub fn make_mat3x4<N: Scalar>(ptr: &[N]) -> TMat3x4<N> {
|
pub fn make_mat3x4<T: Scalar>(ptr: &[T]) -> TMat3x4<T> {
|
||||||
TMat3x4::from_column_slice(ptr)
|
TMat3x4::from_column_slice(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 4x4 matrix from a slice arranged in column-major order.
|
/// Creates a 4x4 matrix from a slice arranged in column-major order.
|
||||||
pub fn make_mat4<N: Scalar>(ptr: &[N]) -> TMat4<N> {
|
pub fn make_mat4<T: Scalar>(ptr: &[T]) -> TMat4<T> {
|
||||||
TMat4::from_column_slice(ptr)
|
TMat4::from_column_slice(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 4x2 matrix from a slice arranged in column-major order.
|
/// Creates a 4x2 matrix from a slice arranged in column-major order.
|
||||||
pub fn make_mat4x2<N: Scalar>(ptr: &[N]) -> TMat4x2<N> {
|
pub fn make_mat4x2<T: Scalar>(ptr: &[T]) -> TMat4x2<T> {
|
||||||
TMat4x2::from_column_slice(ptr)
|
TMat4x2::from_column_slice(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 4x3 matrix from a slice arranged in column-major order.
|
/// Creates a 4x3 matrix from a slice arranged in column-major order.
|
||||||
pub fn make_mat4x3<N: Scalar>(ptr: &[N]) -> TMat4x3<N> {
|
pub fn make_mat4x3<T: Scalar>(ptr: &[T]) -> TMat4x3<T> {
|
||||||
TMat4x3::from_column_slice(ptr)
|
TMat4x3::from_column_slice(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 4x4 matrix from a slice arranged in column-major order.
|
/// Creates a 4x4 matrix from a slice arranged in column-major order.
|
||||||
pub fn make_mat4x4<N: Scalar>(ptr: &[N]) -> TMat4<N> {
|
pub fn make_mat4x4<T: Scalar>(ptr: &[T]) -> TMat4<T> {
|
||||||
TMat4::from_column_slice(ptr)
|
TMat4::from_column_slice(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a 2x2 matrix to a 3x3 matrix.
|
/// Converts a 2x2 matrix to a 3x3 matrix.
|
||||||
pub fn mat2_to_mat3<N: Number>(m: &TMat2<N>) -> TMat3<N> {
|
pub fn mat2_to_mat3<T: Number>(m: &TMat2<T>) -> TMat3<T> {
|
||||||
let _0 = N::zero();
|
let _0 = T::zero();
|
||||||
let _1 = N::one();
|
let _1 = T::one();
|
||||||
|
|
||||||
TMat3::new(m.m11, m.m12, _0, m.m21, m.m22, _0, _0, _0, _1)
|
TMat3::new(m.m11, m.m12, _0, m.m21, m.m22, _0, _0, _0, _1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a 3x3 matrix to a 2x2 matrix.
|
/// Converts a 3x3 matrix to a 2x2 matrix.
|
||||||
pub fn mat3_to_mat2<N: Scalar>(m: &TMat3<N>) -> TMat2<N> {
|
pub fn mat3_to_mat2<T: Scalar>(m: &TMat3<T>) -> TMat2<T> {
|
||||||
TMat2::new(
|
TMat2::new(
|
||||||
m.m11.inlined_clone(),
|
m.m11.inlined_clone(),
|
||||||
m.m12.inlined_clone(),
|
m.m12.inlined_clone(),
|
||||||
|
@ -85,9 +85,9 @@ pub fn mat3_to_mat2<N: Scalar>(m: &TMat3<N>) -> TMat2<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a 3x3 matrix to a 4x4 matrix.
|
/// Converts a 3x3 matrix to a 4x4 matrix.
|
||||||
pub fn mat3_to_mat4<N: Number>(m: &TMat3<N>) -> TMat4<N> {
|
pub fn mat3_to_mat4<T: Number>(m: &TMat3<T>) -> TMat4<T> {
|
||||||
let _0 = N::zero();
|
let _0 = T::zero();
|
||||||
let _1 = N::one();
|
let _1 = T::one();
|
||||||
|
|
||||||
TMat4::new(
|
TMat4::new(
|
||||||
m.m11, m.m12, m.m13, _0, m.m21, m.m22, m.m23, _0, m.m31, m.m32, m.m33, _0, _0, _0, _0, _1,
|
m.m11, m.m12, m.m13, _0, m.m21, m.m22, m.m23, _0, m.m31, m.m32, m.m33, _0, _0, _0, _0, _1,
|
||||||
|
@ -95,7 +95,7 @@ pub fn mat3_to_mat4<N: Number>(m: &TMat3<N>) -> TMat4<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a 4x4 matrix to a 3x3 matrix.
|
/// Converts a 4x4 matrix to a 3x3 matrix.
|
||||||
pub fn mat4_to_mat3<N: Scalar>(m: &TMat4<N>) -> TMat3<N> {
|
pub fn mat4_to_mat3<T: Scalar>(m: &TMat4<T>) -> TMat3<T> {
|
||||||
TMat3::new(
|
TMat3::new(
|
||||||
m.m11.inlined_clone(),
|
m.m11.inlined_clone(),
|
||||||
m.m12.inlined_clone(),
|
m.m12.inlined_clone(),
|
||||||
|
@ -110,9 +110,9 @@ pub fn mat4_to_mat3<N: Scalar>(m: &TMat4<N>) -> TMat3<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a 2x2 matrix to a 4x4 matrix.
|
/// Converts a 2x2 matrix to a 4x4 matrix.
|
||||||
pub fn mat2_to_mat4<N: Number>(m: &TMat2<N>) -> TMat4<N> {
|
pub fn mat2_to_mat4<T: Number>(m: &TMat2<T>) -> TMat4<T> {
|
||||||
let _0 = N::zero();
|
let _0 = T::zero();
|
||||||
let _1 = N::one();
|
let _1 = T::one();
|
||||||
|
|
||||||
TMat4::new(
|
TMat4::new(
|
||||||
m.m11, m.m12, _0, _0, m.m21, m.m22, _0, _0, _0, _0, _1, _0, _0, _0, _0, _1,
|
m.m11, m.m12, _0, _0, m.m21, m.m22, _0, _0, _0, _0, _1, _0, _0, _0, _0, _1,
|
||||||
|
@ -120,7 +120,7 @@ pub fn mat2_to_mat4<N: Number>(m: &TMat2<N>) -> TMat4<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a 4x4 matrix to a 2x2 matrix.
|
/// Converts a 4x4 matrix to a 2x2 matrix.
|
||||||
pub fn mat4_to_mat2<N: Scalar>(m: &TMat4<N>) -> TMat2<N> {
|
pub fn mat4_to_mat2<T: Scalar>(m: &TMat4<T>) -> TMat2<T> {
|
||||||
TMat2::new(
|
TMat2::new(
|
||||||
m.m11.inlined_clone(),
|
m.m11.inlined_clone(),
|
||||||
m.m12.inlined_clone(),
|
m.m12.inlined_clone(),
|
||||||
|
@ -130,7 +130,7 @@ pub fn mat4_to_mat2<N: Scalar>(m: &TMat4<N>) -> TMat2<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a quaternion from a slice arranged as `[x, y, z, w]`.
|
/// Creates a quaternion from a slice arranged as `[x, y, z, w]`.
|
||||||
pub fn make_quat<N: RealField>(ptr: &[N]) -> Qua<N> {
|
pub fn make_quat<T: RealField>(ptr: &[T]) -> Qua<T> {
|
||||||
Quaternion::from(TVec4::from_column_slice(ptr))
|
Quaternion::from(TVec4::from_column_slice(ptr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ pub fn make_quat<N: RealField>(ptr: &[N]) -> Qua<N> {
|
||||||
/// * [`make_vec2`](fn.make_vec2.html)
|
/// * [`make_vec2`](fn.make_vec2.html)
|
||||||
/// * [`make_vec3`](fn.make_vec3.html)
|
/// * [`make_vec3`](fn.make_vec3.html)
|
||||||
/// * [`make_vec4`](fn.make_vec4.html)
|
/// * [`make_vec4`](fn.make_vec4.html)
|
||||||
pub fn make_vec1<N: Scalar>(v: &TVec1<N>) -> TVec1<N> {
|
pub fn make_vec1<T: Scalar>(v: &TVec1<T>) -> TVec1<T> {
|
||||||
v.clone()
|
v.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ pub fn make_vec1<N: Scalar>(v: &TVec1<N>) -> TVec1<N> {
|
||||||
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
|
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
|
||||||
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
||||||
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
||||||
pub fn vec2_to_vec1<N: Scalar>(v: &TVec2<N>) -> TVec1<N> {
|
pub fn vec2_to_vec1<T: Scalar>(v: &TVec2<T>) -> TVec1<T> {
|
||||||
TVec1::new(v.x.inlined_clone())
|
TVec1::new(v.x.inlined_clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ pub fn vec2_to_vec1<N: Scalar>(v: &TVec2<N>) -> TVec1<N> {
|
||||||
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
|
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
|
||||||
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
||||||
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
||||||
pub fn vec3_to_vec1<N: Scalar>(v: &TVec3<N>) -> TVec1<N> {
|
pub fn vec3_to_vec1<T: Scalar>(v: &TVec3<T>) -> TVec1<T> {
|
||||||
TVec1::new(v.x.inlined_clone())
|
TVec1::new(v.x.inlined_clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ pub fn vec3_to_vec1<N: Scalar>(v: &TVec3<N>) -> TVec1<N> {
|
||||||
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
|
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
|
||||||
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
||||||
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
||||||
pub fn vec4_to_vec1<N: Scalar>(v: &TVec4<N>) -> TVec1<N> {
|
pub fn vec4_to_vec1<T: Scalar>(v: &TVec4<T>) -> TVec1<T> {
|
||||||
TVec1::new(v.x.inlined_clone())
|
TVec1::new(v.x.inlined_clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,8 +199,8 @@ pub fn vec4_to_vec1<N: Scalar>(v: &TVec4<N>) -> TVec1<N> {
|
||||||
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
|
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
|
||||||
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
||||||
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
||||||
pub fn vec1_to_vec2<N: Number>(v: &TVec1<N>) -> TVec2<N> {
|
pub fn vec1_to_vec2<T: Number>(v: &TVec1<T>) -> TVec2<T> {
|
||||||
TVec2::new(v.x.inlined_clone(), N::zero())
|
TVec2::new(v.x.inlined_clone(), T::zero())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 2D vector from another vector.
|
/// Creates a 2D vector from another vector.
|
||||||
|
@ -214,7 +214,7 @@ pub fn vec1_to_vec2<N: Number>(v: &TVec1<N>) -> TVec2<N> {
|
||||||
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
|
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
|
||||||
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
||||||
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
||||||
pub fn vec2_to_vec2<N: Scalar>(v: &TVec2<N>) -> TVec2<N> {
|
pub fn vec2_to_vec2<T: Scalar>(v: &TVec2<T>) -> TVec2<T> {
|
||||||
v.clone()
|
v.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ pub fn vec2_to_vec2<N: Scalar>(v: &TVec2<N>) -> TVec2<N> {
|
||||||
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
|
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
|
||||||
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
||||||
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
||||||
pub fn vec3_to_vec2<N: Scalar>(v: &TVec3<N>) -> TVec2<N> {
|
pub fn vec3_to_vec2<T: Scalar>(v: &TVec3<T>) -> TVec2<T> {
|
||||||
TVec2::new(v.x.inlined_clone(), v.y.inlined_clone())
|
TVec2::new(v.x.inlined_clone(), v.y.inlined_clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ pub fn vec3_to_vec2<N: Scalar>(v: &TVec3<N>) -> TVec2<N> {
|
||||||
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
|
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
|
||||||
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
||||||
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
|
||||||
pub fn vec4_to_vec2<N: Scalar>(v: &TVec4<N>) -> TVec2<N> {
|
pub fn vec4_to_vec2<T: Scalar>(v: &TVec4<T>) -> TVec2<T> {
|
||||||
TVec2::new(v.x.inlined_clone(), v.y.inlined_clone())
|
TVec2::new(v.x.inlined_clone(), v.y.inlined_clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +253,7 @@ pub fn vec4_to_vec2<N: Scalar>(v: &TVec4<N>) -> TVec2<N> {
|
||||||
/// * [`make_vec1`](fn.make_vec1.html)
|
/// * [`make_vec1`](fn.make_vec1.html)
|
||||||
/// * [`make_vec3`](fn.make_vec3.html)
|
/// * [`make_vec3`](fn.make_vec3.html)
|
||||||
/// * [`make_vec4`](fn.make_vec4.html)
|
/// * [`make_vec4`](fn.make_vec4.html)
|
||||||
pub fn make_vec2<N: Scalar>(ptr: &[N]) -> TVec2<N> {
|
pub fn make_vec2<T: Scalar>(ptr: &[T]) -> TVec2<T> {
|
||||||
TVec2::from_column_slice(ptr)
|
TVec2::from_column_slice(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,8 +268,8 @@ pub fn make_vec2<N: Scalar>(ptr: &[N]) -> TVec2<N> {
|
||||||
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
|
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
|
||||||
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
|
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
|
||||||
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
||||||
pub fn vec1_to_vec3<N: Number>(v: &TVec1<N>) -> TVec3<N> {
|
pub fn vec1_to_vec3<T: Number>(v: &TVec1<T>) -> TVec3<T> {
|
||||||
TVec3::new(v.x.inlined_clone(), N::zero(), N::zero())
|
TVec3::new(v.x.inlined_clone(), T::zero(), T::zero())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 3D vector from another vector.
|
/// Creates a 3D vector from another vector.
|
||||||
|
@ -284,8 +284,8 @@ pub fn vec1_to_vec3<N: Number>(v: &TVec1<N>) -> TVec3<N> {
|
||||||
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
|
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
|
||||||
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
|
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
|
||||||
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
|
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
|
||||||
pub fn vec2_to_vec3<N: Number>(v: &TVec2<N>) -> TVec3<N> {
|
pub fn vec2_to_vec3<T: Number>(v: &TVec2<T>) -> TVec3<T> {
|
||||||
TVec3::new(v.x.inlined_clone(), v.y.inlined_clone(), N::zero())
|
TVec3::new(v.x.inlined_clone(), v.y.inlined_clone(), T::zero())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 3D vector from another vector.
|
/// Creates a 3D vector from another vector.
|
||||||
|
@ -298,7 +298,7 @@ pub fn vec2_to_vec3<N: Number>(v: &TVec2<N>) -> TVec3<N> {
|
||||||
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
|
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
|
||||||
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
|
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
|
||||||
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
|
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
|
||||||
pub fn vec3_to_vec3<N: Scalar>(v: &TVec3<N>) -> TVec3<N> {
|
pub fn vec3_to_vec3<T: Scalar>(v: &TVec3<T>) -> TVec3<T> {
|
||||||
v.clone()
|
v.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,7 +312,7 @@ pub fn vec3_to_vec3<N: Scalar>(v: &TVec3<N>) -> TVec3<N> {
|
||||||
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
|
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
|
||||||
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
|
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
|
||||||
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
|
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
|
||||||
pub fn vec4_to_vec3<N: Scalar>(v: &TVec4<N>) -> TVec3<N> {
|
pub fn vec4_to_vec3<T: Scalar>(v: &TVec4<T>) -> TVec3<T> {
|
||||||
TVec3::new(
|
TVec3::new(
|
||||||
v.x.inlined_clone(),
|
v.x.inlined_clone(),
|
||||||
v.y.inlined_clone(),
|
v.y.inlined_clone(),
|
||||||
|
@ -327,7 +327,7 @@ pub fn vec4_to_vec3<N: Scalar>(v: &TVec4<N>) -> TVec3<N> {
|
||||||
/// * [`make_vec1`](fn.make_vec1.html)
|
/// * [`make_vec1`](fn.make_vec1.html)
|
||||||
/// * [`make_vec2`](fn.make_vec2.html)
|
/// * [`make_vec2`](fn.make_vec2.html)
|
||||||
/// * [`make_vec4`](fn.make_vec4.html)
|
/// * [`make_vec4`](fn.make_vec4.html)
|
||||||
pub fn make_vec3<N: Scalar>(ptr: &[N]) -> TVec3<N> {
|
pub fn make_vec3<T: Scalar>(ptr: &[T]) -> TVec3<T> {
|
||||||
TVec3::from_column_slice(ptr)
|
TVec3::from_column_slice(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,8 +343,8 @@ pub fn make_vec3<N: Scalar>(ptr: &[N]) -> TVec3<N> {
|
||||||
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
|
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
|
||||||
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
|
||||||
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
|
||||||
pub fn vec1_to_vec4<N: Number>(v: &TVec1<N>) -> TVec4<N> {
|
pub fn vec1_to_vec4<T: Number>(v: &TVec1<T>) -> TVec4<T> {
|
||||||
TVec4::new(v.x, N::zero(), N::zero(), N::zero())
|
TVec4::new(v.x, T::zero(), T::zero(), T::zero())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 4D vector from another vector.
|
/// Creates a 4D vector from another vector.
|
||||||
|
@ -359,8 +359,8 @@ pub fn vec1_to_vec4<N: Number>(v: &TVec1<N>) -> TVec4<N> {
|
||||||
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
|
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
|
||||||
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
|
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
|
||||||
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
|
||||||
pub fn vec2_to_vec4<N: Number>(v: &TVec2<N>) -> TVec4<N> {
|
pub fn vec2_to_vec4<T: Number>(v: &TVec2<T>) -> TVec4<T> {
|
||||||
TVec4::new(v.x, v.y, N::zero(), N::zero())
|
TVec4::new(v.x, v.y, T::zero(), T::zero())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 4D vector from another vector.
|
/// Creates a 4D vector from another vector.
|
||||||
|
@ -375,8 +375,8 @@ pub fn vec2_to_vec4<N: Number>(v: &TVec2<N>) -> TVec4<N> {
|
||||||
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
|
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
|
||||||
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
|
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
|
||||||
/// * [`vec3_to_vec3`](fn.vec3_to_vec3.html)
|
/// * [`vec3_to_vec3`](fn.vec3_to_vec3.html)
|
||||||
pub fn vec3_to_vec4<N: Number>(v: &TVec3<N>) -> TVec4<N> {
|
pub fn vec3_to_vec4<T: Number>(v: &TVec3<T>) -> TVec4<T> {
|
||||||
TVec4::new(v.x, v.y, v.z, N::zero())
|
TVec4::new(v.x, v.y, v.z, T::zero())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a 4D vector from another vector.
|
/// Creates a 4D vector from another vector.
|
||||||
|
@ -389,7 +389,7 @@ pub fn vec3_to_vec4<N: Number>(v: &TVec3<N>) -> TVec4<N> {
|
||||||
/// * [`vec4_to_vec1`](fn.vec4_to_vec1.html)
|
/// * [`vec4_to_vec1`](fn.vec4_to_vec1.html)
|
||||||
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
|
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
|
||||||
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
|
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
|
||||||
pub fn vec4_to_vec4<N: Scalar>(v: &TVec4<N>) -> TVec4<N> {
|
pub fn vec4_to_vec4<T: Scalar>(v: &TVec4<T>) -> TVec4<T> {
|
||||||
v.clone()
|
v.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,22 +400,16 @@ pub fn vec4_to_vec4<N: Scalar>(v: &TVec4<N>) -> TVec4<N> {
|
||||||
/// * [`make_vec1`](fn.make_vec1.html)
|
/// * [`make_vec1`](fn.make_vec1.html)
|
||||||
/// * [`make_vec2`](fn.make_vec2.html)
|
/// * [`make_vec2`](fn.make_vec2.html)
|
||||||
/// * [`make_vec3`](fn.make_vec3.html)
|
/// * [`make_vec3`](fn.make_vec3.html)
|
||||||
pub fn make_vec4<N: Scalar>(ptr: &[N]) -> TVec4<N> {
|
pub fn make_vec4<T: Scalar>(ptr: &[T]) -> TVec4<T> {
|
||||||
TVec4::from_column_slice(ptr)
|
TVec4::from_column_slice(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a matrix or vector to a slice arranged in column-major order.
|
/// Converts a matrix or vector to a slice arranged in column-major order.
|
||||||
pub fn value_ptr<N: Scalar, R: Dimension, C: Dimension>(x: &TMat<N, R, C>) -> &[N]
|
pub fn value_ptr<T: Scalar, const R: usize, const C: usize>(x: &TMat<T, R, C>) -> &[T] {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, R, C>,
|
|
||||||
{
|
|
||||||
x.as_slice()
|
x.as_slice()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a matrix or vector to a mutable slice arranged in column-major order.
|
/// Converts a matrix or vector to a mutable slice arranged in column-major order.
|
||||||
pub fn value_ptr_mut<N: Scalar, R: Dimension, C: Dimension>(x: &mut TMat<N, R, C>) -> &mut [N]
|
pub fn value_ptr_mut<T: Scalar, const R: usize, const C: usize>(x: &mut TMat<T, R, C>) -> &mut [T] {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, R, C>,
|
|
||||||
{
|
|
||||||
x.as_mut_slice()
|
x.as_mut_slice()
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,11 @@ use na::{Scalar, U2};
|
||||||
|
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
|
|
||||||
|
|
||||||
pub fn float_distance<T>(x: T, y: T) -> u64 {
|
pub fn float_distance<T>(x: T, y: T) -> u64 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn float_distance2<N: Scalar>(x: &TVec2<N>, y: &TVec2<N>) -> TVec<u64, U2> {
|
pub fn float_distance2<T: Scalar>(x: &TVec2<T>, y: &TVec2<T>) -> TVec<u64, U2> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
use na::{self, DefaultAllocator};
|
|
||||||
|
|
||||||
use crate::aliases::TMat;
|
use crate::aliases::TMat;
|
||||||
use crate::traits::{Alloc, Dimension, Number};
|
use crate::traits::Number;
|
||||||
|
|
||||||
/// The sum of every component of the given matrix or vector.
|
/// The sum of every component of the given matrix or vector.
|
||||||
///
|
///
|
||||||
|
@ -21,11 +19,8 @@ use crate::traits::{Alloc, Dimension, Number};
|
||||||
/// * [`comp_max`](fn.comp_max.html)
|
/// * [`comp_max`](fn.comp_max.html)
|
||||||
/// * [`comp_min`](fn.comp_min.html)
|
/// * [`comp_min`](fn.comp_min.html)
|
||||||
/// * [`comp_mul`](fn.comp_mul.html)
|
/// * [`comp_mul`](fn.comp_mul.html)
|
||||||
pub fn comp_add<N: Number, R: Dimension, C: Dimension>(m: &TMat<N, R, C>) -> N
|
pub fn comp_add<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
|
||||||
where
|
m.iter().fold(T::zero(), |x, y| x + *y)
|
||||||
DefaultAllocator: Alloc<N, R, C>,
|
|
||||||
{
|
|
||||||
m.iter().fold(N::zero(), |x, y| x + *y)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The maximum of every component of the given matrix or vector.
|
/// The maximum of every component of the given matrix or vector.
|
||||||
|
@ -50,12 +45,9 @@ where
|
||||||
/// * [`max2`](fn.max2.html)
|
/// * [`max2`](fn.max2.html)
|
||||||
/// * [`max3`](fn.max3.html)
|
/// * [`max3`](fn.max3.html)
|
||||||
/// * [`max4`](fn.max4.html)
|
/// * [`max4`](fn.max4.html)
|
||||||
pub fn comp_max<N: Number, R: Dimension, C: Dimension>(m: &TMat<N, R, C>) -> N
|
pub fn comp_max<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, R, C>,
|
|
||||||
{
|
|
||||||
m.iter()
|
m.iter()
|
||||||
.fold(N::min_value(), |x, y| crate::max2_scalar(x, *y))
|
.fold(T::min_value(), |x, y| crate::max2_scalar(x, *y))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The minimum of every component of the given matrix or vector.
|
/// The minimum of every component of the given matrix or vector.
|
||||||
|
@ -80,12 +72,9 @@ where
|
||||||
/// * [`min2`](fn.min2.html)
|
/// * [`min2`](fn.min2.html)
|
||||||
/// * [`min3`](fn.min3.html)
|
/// * [`min3`](fn.min3.html)
|
||||||
/// * [`min4`](fn.min4.html)
|
/// * [`min4`](fn.min4.html)
|
||||||
pub fn comp_min<N: Number, R: Dimension, C: Dimension>(m: &TMat<N, R, C>) -> N
|
pub fn comp_min<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, R, C>,
|
|
||||||
{
|
|
||||||
m.iter()
|
m.iter()
|
||||||
.fold(N::max_value(), |x, y| crate::min2_scalar(x, *y))
|
.fold(T::max_value(), |x, y| crate::min2_scalar(x, *y))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The product of every component of the given matrix or vector.
|
/// The product of every component of the given matrix or vector.
|
||||||
|
@ -106,11 +95,8 @@ where
|
||||||
/// * [`comp_add`](fn.comp_add.html)
|
/// * [`comp_add`](fn.comp_add.html)
|
||||||
/// * [`comp_max`](fn.comp_max.html)
|
/// * [`comp_max`](fn.comp_max.html)
|
||||||
/// * [`comp_min`](fn.comp_min.html)
|
/// * [`comp_min`](fn.comp_min.html)
|
||||||
pub fn comp_mul<N: Number, R: Dimension, C: Dimension>(m: &TMat<N, R, C>) -> N
|
pub fn comp_mul<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
|
||||||
where
|
m.iter().fold(T::one(), |x, y| x * *y)
|
||||||
DefaultAllocator: Alloc<N, R, C>,
|
|
||||||
{
|
|
||||||
m.iter().fold(N::one(), |x, y| x * *y)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn vec< L, floatType, Q > compNormalize (vec< L, T, Q > const &v)
|
//pub fn vec< L, floatType, Q > compNormalize (vec< L, T, Q > const &v)
|
||||||
|
|
|
@ -1,163 +1,163 @@
|
||||||
use na::{RealField, U3, U4};
|
use na::{RealField, U3, U4};
|
||||||
|
|
||||||
use crate::aliases::{TVec, TMat};
|
use crate::aliases::{TMat, TVec};
|
||||||
|
|
||||||
pub fn derivedEulerAngleX<N: RealField>(angleX: N, angularVelocityX: N) -> TMat4<N> {
|
pub fn derivedEulerAngleX<T: RealField>(angleX: T, angularVelocityX: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn derivedEulerAngleY<N: RealField>(angleY: N, angularVelocityY: N) -> TMat4<N> {
|
pub fn derivedEulerAngleY<T: RealField>(angleY: T, angularVelocityY: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn derivedEulerAngleZ<N: RealField>(angleZ: N, angularVelocityZ: N) -> TMat4<N> {
|
pub fn derivedEulerAngleZ<T: RealField>(angleZ: T, angularVelocityZ: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleX<N: RealField>(angleX: N) -> TMat4<N> {
|
pub fn eulerAngleX<T: RealField>(angleX: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleXY<N: RealField>(angleX: N, angleY: N) -> TMat4<N> {
|
pub fn eulerAngleXY<T: RealField>(angleX: T, angleY: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleXYX<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleXYX<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleXYZ<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleXYZ<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleXZ<N: RealField>(angleX: N, angleZ: N) -> TMat4<N> {
|
pub fn eulerAngleXZ<T: RealField>(angleX: T, angleZ: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleXZX<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleXZX<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleXZY<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleXZY<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleY<N: RealField>(angleY: N) -> TMat4<N> {
|
pub fn eulerAngleY<T: RealField>(angleY: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleYX<N: RealField>(angleY: N, angleX: N) -> TMat4<N> {
|
pub fn eulerAngleYX<T: RealField>(angleY: T, angleX: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleYXY<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleYXY<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleYXZ<N: RealField>(yaw: N, pitch: N, roll: N) -> TMat4<N> {
|
pub fn eulerAngleYXZ<T: RealField>(yaw: T, pitch: T, roll: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleYZ<N: RealField>(angleY: N, angleZ: N) -> TMat4<N> {
|
pub fn eulerAngleYZ<T: RealField>(angleY: T, angleZ: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleYZX<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleYZX<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleYZY<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleYZY<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleZ<N: RealField>(angleZ: N) -> TMat4<N> {
|
pub fn eulerAngleZ<T: RealField>(angleZ: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleZX<N: RealField>(angle: N, angleX: N) -> TMat4<N> {
|
pub fn eulerAngleZX<T: RealField>(angle: T, angleX: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleZXY<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleZXY<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleZXZ<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleZXZ<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleZY<N: RealField>(angleZ: N, angleY: N) -> TMat4<N> {
|
pub fn eulerAngleZY<T: RealField>(angleZ: T, angleY: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleZYX<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleZYX<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleZYZ<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleZYZ<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleXYX<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleXYX<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleXYZ<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleXYZ<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleXZX<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleXZX<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleXZY<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleXZY<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleYXY<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleYXY<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleYXZ<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleYXZ<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleYZX<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleYZX<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleYZY<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleYZY<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleZXY<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleZXY<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleZXZ<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleZXZ<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleZYX<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleZYX<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleZYZ<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleZYZ<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn orientate2<N: RealField>(angle: N) -> TMat3x3<N> {
|
pub fn orientate2<T: RealField>(angle: T) -> TMat3x3<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn orientate3<N: RealField>(angles: TVec3<N>) -> TMat3x3<N> {
|
pub fn orientate3<T: RealField>(angles: TVec3<T>) -> TMat3x3<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn orientate4<N: RealField>(angles: TVec3<N>) -> TMat4<N> {
|
pub fn orientate4<T: RealField>(angles: TVec3<T>) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn yawPitchRoll<N: RealField>(yaw: N, pitch: N, roll: N) -> TMat4<N> {
|
pub fn yawPitchRoll<T: RealField>(yaw: T, pitch: T, roll: T) -> TMat4<T> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,6 @@ use crate::aliases::TVec2;
|
||||||
use crate::traits::Number;
|
use crate::traits::Number;
|
||||||
|
|
||||||
/// The 2D perpendicular product between two vectors.
|
/// The 2D perpendicular product between two vectors.
|
||||||
pub fn cross2d<N: Number>(v: &TVec2<N>, u: &TVec2<N>) -> N {
|
pub fn cross2d<T: Number>(v: &TVec2<T>, u: &TVec2<T>) -> T {
|
||||||
v.perp(u)
|
v.perp(u)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,8 @@ use crate::traits::Number;
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`right_handed`](fn.right_handed.html)
|
/// * [`right_handed`](fn.right_handed.html)
|
||||||
pub fn left_handed<N: Number>(a: &TVec3<N>, b: &TVec3<N>, c: &TVec3<N>) -> bool {
|
pub fn left_handed<T: Number>(a: &TVec3<T>, b: &TVec3<T>, c: &TVec3<T>) -> bool {
|
||||||
a.cross(b).dot(c) < N::zero()
|
a.cross(b).dot(c) < T::zero()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if `{a, b, c}` forms a right-handed trihedron.
|
/// Returns `true` if `{a, b, c}` forms a right-handed trihedron.
|
||||||
|
@ -15,6 +15,6 @@ pub fn left_handed<N: Number>(a: &TVec3<N>, b: &TVec3<N>, c: &TVec3<N>) -> bool
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`left_handed`](fn.left_handed.html)
|
/// * [`left_handed`](fn.left_handed.html)
|
||||||
pub fn right_handed<N: Number>(a: &TVec3<N>, b: &TVec3<N>, c: &TVec3<N>) -> bool {
|
pub fn right_handed<T: Number>(a: &TVec3<T>, b: &TVec3<T>, c: &TVec3<T>) -> bool {
|
||||||
a.cross(b).dot(c) > N::zero()
|
a.cross(b).dot(c) > T::zero()
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::aliases::{TMat3, TMat4, TVec3};
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`matrix_cross`](fn.matrix_cross.html)
|
/// * [`matrix_cross`](fn.matrix_cross.html)
|
||||||
pub fn matrix_cross3<N: RealField>(x: &TVec3<N>) -> TMat3<N> {
|
pub fn matrix_cross3<T: RealField>(x: &TVec3<T>) -> TMat3<T> {
|
||||||
x.cross_matrix()
|
x.cross_matrix()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,6 @@ pub fn matrix_cross3<N: RealField>(x: &TVec3<N>) -> TMat3<N> {
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`matrix_cross3`](fn.matrix_cross3.html)
|
/// * [`matrix_cross3`](fn.matrix_cross3.html)
|
||||||
pub fn matrix_cross<N: RealField>(x: &TVec3<N>) -> TMat4<N> {
|
pub fn matrix_cross<T: RealField>(x: &TVec3<T>) -> TMat4<T> {
|
||||||
crate::mat3_to_mat4(&x.cross_matrix())
|
crate::mat3_to_mat4(&x.cross_matrix())
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ use crate::traits::Number;
|
||||||
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
||||||
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
||||||
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
||||||
pub fn diagonal2x2<N: Number>(v: &TVec2<N>) -> TMat2<N> {
|
pub fn diagonal2x2<T: Number>(v: &TVec2<T>) -> TMat2<T> {
|
||||||
TMat2::from_diagonal(v)
|
TMat2::from_diagonal(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ pub fn diagonal2x2<N: Number>(v: &TVec2<N>) -> TMat2<N> {
|
||||||
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
||||||
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
||||||
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
||||||
pub fn diagonal2x3<N: Number>(v: &TVec2<N>) -> TMat2x3<N> {
|
pub fn diagonal2x3<T: Number>(v: &TVec2<T>) -> TMat2x3<T> {
|
||||||
TMat2x3::from_partial_diagonal(v.as_slice())
|
TMat2x3::from_partial_diagonal(v.as_slice())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ pub fn diagonal2x3<N: Number>(v: &TVec2<N>) -> TMat2x3<N> {
|
||||||
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
||||||
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
||||||
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
||||||
pub fn diagonal2x4<N: Number>(v: &TVec2<N>) -> TMat2x4<N> {
|
pub fn diagonal2x4<T: Number>(v: &TVec2<T>) -> TMat2x4<T> {
|
||||||
TMat2x4::from_partial_diagonal(v.as_slice())
|
TMat2x4::from_partial_diagonal(v.as_slice())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ pub fn diagonal2x4<N: Number>(v: &TVec2<N>) -> TMat2x4<N> {
|
||||||
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
||||||
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
||||||
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
||||||
pub fn diagonal3x2<N: Number>(v: &TVec2<N>) -> TMat3x2<N> {
|
pub fn diagonal3x2<T: Number>(v: &TVec2<T>) -> TMat3x2<T> {
|
||||||
TMat3x2::from_partial_diagonal(v.as_slice())
|
TMat3x2::from_partial_diagonal(v.as_slice())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ pub fn diagonal3x2<N: Number>(v: &TVec2<N>) -> TMat3x2<N> {
|
||||||
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
||||||
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
||||||
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
||||||
pub fn diagonal3x3<N: Number>(v: &TVec3<N>) -> TMat3<N> {
|
pub fn diagonal3x3<T: Number>(v: &TVec3<T>) -> TMat3<T> {
|
||||||
TMat3::from_diagonal(v)
|
TMat3::from_diagonal(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ pub fn diagonal3x3<N: Number>(v: &TVec3<N>) -> TMat3<N> {
|
||||||
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
||||||
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
||||||
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
||||||
pub fn diagonal3x4<N: Number>(v: &TVec3<N>) -> TMat3x4<N> {
|
pub fn diagonal3x4<T: Number>(v: &TVec3<T>) -> TMat3x4<T> {
|
||||||
TMat3x4::from_partial_diagonal(v.as_slice())
|
TMat3x4::from_partial_diagonal(v.as_slice())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ pub fn diagonal3x4<N: Number>(v: &TVec3<N>) -> TMat3x4<N> {
|
||||||
/// * [`diagonal3x4`](fn.diagonal3x4.html)
|
/// * [`diagonal3x4`](fn.diagonal3x4.html)
|
||||||
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
||||||
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
||||||
pub fn diagonal4x2<N: Number>(v: &TVec2<N>) -> TMat4x2<N> {
|
pub fn diagonal4x2<T: Number>(v: &TVec2<T>) -> TMat4x2<T> {
|
||||||
TMat4x2::from_partial_diagonal(v.as_slice())
|
TMat4x2::from_partial_diagonal(v.as_slice())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ pub fn diagonal4x2<N: Number>(v: &TVec2<N>) -> TMat4x2<N> {
|
||||||
/// * [`diagonal3x4`](fn.diagonal3x4.html)
|
/// * [`diagonal3x4`](fn.diagonal3x4.html)
|
||||||
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
||||||
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
/// * [`diagonal4x4`](fn.diagonal4x4.html)
|
||||||
pub fn diagonal4x3<N: Number>(v: &TVec3<N>) -> TMat4x3<N> {
|
pub fn diagonal4x3<T: Number>(v: &TVec3<T>) -> TMat4x3<T> {
|
||||||
TMat4x3::from_partial_diagonal(v.as_slice())
|
TMat4x3::from_partial_diagonal(v.as_slice())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,6 +143,6 @@ pub fn diagonal4x3<N: Number>(v: &TVec3<N>) -> TMat4x3<N> {
|
||||||
/// * [`diagonal3x4`](fn.diagonal3x4.html)
|
/// * [`diagonal3x4`](fn.diagonal3x4.html)
|
||||||
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
/// * [`diagonal4x2`](fn.diagonal4x2.html)
|
||||||
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
/// * [`diagonal4x3`](fn.diagonal4x3.html)
|
||||||
pub fn diagonal4x4<N: Number>(v: &TVec4<N>) -> TMat4<N> {
|
pub fn diagonal4x4<T: Number>(v: &TVec4<T>) -> TMat4<T> {
|
||||||
TMat4::from_diagonal(v)
|
TMat4::from_diagonal(v)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,13 @@
|
||||||
use na::{DefaultAllocator, RealField};
|
use na::RealField;
|
||||||
|
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
use crate::traits::{Alloc, Dimension};
|
|
||||||
|
|
||||||
/// The squared distance between two points.
|
/// The squared distance between two points.
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`distance`](fn.distance.html)
|
/// * [`distance`](fn.distance.html)
|
||||||
pub fn distance2<N: RealField, D: Dimension>(p0: &TVec<N, D>, p1: &TVec<N, D>) -> N
|
pub fn distance2<T: RealField, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
(p1 - p0).norm_squared()
|
(p1 - p0).norm_squared()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,10 +18,7 @@ where
|
||||||
/// * [`l1_norm`](fn.l1_norm.html)
|
/// * [`l1_norm`](fn.l1_norm.html)
|
||||||
/// * [`l2_distance`](fn.l2_distance.html)
|
/// * [`l2_distance`](fn.l2_distance.html)
|
||||||
/// * [`l2_norm`](fn.l2_norm.html)
|
/// * [`l2_norm`](fn.l2_norm.html)
|
||||||
pub fn l1_distance<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
|
pub fn l1_distance<T: RealField, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
l1_norm(&(y - x))
|
l1_norm(&(y - x))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,10 +32,7 @@ where
|
||||||
/// * [`l1_distance`](fn.l1_distance.html)
|
/// * [`l1_distance`](fn.l1_distance.html)
|
||||||
/// * [`l2_distance`](fn.l2_distance.html)
|
/// * [`l2_distance`](fn.l2_distance.html)
|
||||||
/// * [`l2_norm`](fn.l2_norm.html)
|
/// * [`l2_norm`](fn.l2_norm.html)
|
||||||
pub fn l1_norm<N: RealField, D: Dimension>(v: &TVec<N, D>) -> N
|
pub fn l1_norm<T: RealField, const D: usize>(v: &TVec<T, D>) -> T {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
crate::comp_add(&v.abs())
|
crate::comp_add(&v.abs())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,10 +50,7 @@ where
|
||||||
/// * [`length2`](fn.length2.html)
|
/// * [`length2`](fn.length2.html)
|
||||||
/// * [`magnitude`](fn.magnitude.html)
|
/// * [`magnitude`](fn.magnitude.html)
|
||||||
/// * [`magnitude2`](fn.magnitude2.html)
|
/// * [`magnitude2`](fn.magnitude2.html)
|
||||||
pub fn l2_distance<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
|
pub fn l2_distance<T: RealField, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
l2_norm(&(y - x))
|
l2_norm(&(y - x))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,10 +70,7 @@ where
|
||||||
/// * [`length2`](fn.length2.html)
|
/// * [`length2`](fn.length2.html)
|
||||||
/// * [`magnitude`](fn.magnitude.html)
|
/// * [`magnitude`](fn.magnitude.html)
|
||||||
/// * [`magnitude2`](fn.magnitude2.html)
|
/// * [`magnitude2`](fn.magnitude2.html)
|
||||||
pub fn l2_norm<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N
|
pub fn l2_norm<T: RealField, const D: usize>(x: &TVec<T, D>) -> T {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.norm()
|
x.norm()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,10 +85,7 @@ where
|
||||||
/// * [`length`](fn.length.html)
|
/// * [`length`](fn.length.html)
|
||||||
/// * [`magnitude`](fn.magnitude.html)
|
/// * [`magnitude`](fn.magnitude.html)
|
||||||
/// * [`magnitude2`](fn.magnitude2.html)
|
/// * [`magnitude2`](fn.magnitude2.html)
|
||||||
pub fn length2<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N
|
pub fn length2<T: RealField, const D: usize>(x: &TVec<T, D>) -> T {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.norm_squared()
|
x.norm_squared()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,19 +100,14 @@ where
|
||||||
/// * [`length2`](fn.length2.html)
|
/// * [`length2`](fn.length2.html)
|
||||||
/// * [`magnitude`](fn.magnitude.html)
|
/// * [`magnitude`](fn.magnitude.html)
|
||||||
/// * [`nalgebra::norm_squared`](../nalgebra/fn.norm_squared.html)
|
/// * [`nalgebra::norm_squared`](../nalgebra/fn.norm_squared.html)
|
||||||
pub fn magnitude2<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N
|
pub fn magnitude2<T: RealField, const D: usize>(x: &TVec<T, D>) -> T {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.norm_squared()
|
x.norm_squared()
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn lxNorm<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, unsigned int Depth) -> N
|
//pub fn lxNorm<T: RealField, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, unsigned int Depth) -> T {
|
||||||
// where DefaultAllocator: Alloc<N, D> {
|
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn lxNorm<N: RealField, D: Dimension>(x: &TVec<N, D>, unsigned int Depth) -> N
|
//pub fn lxNorm<T: RealField, const D: usize>(x: &TVec<T, D>, unsigned int Depth) -> T {
|
||||||
// where DefaultAllocator: Alloc<N, D> {
|
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
|
@ -5,6 +5,6 @@ use crate::aliases::TVec3;
|
||||||
/// The normal vector of the given triangle.
|
/// The normal vector of the given triangle.
|
||||||
///
|
///
|
||||||
/// The normal is computed as the normalized vector `cross(p2 - p1, p3 - p1)`.
|
/// The normal is computed as the normalized vector `cross(p2 - p1, p3 - p1)`.
|
||||||
pub fn triangle_normal<N: RealField>(p1: &TVec3<N>, p2: &TVec3<N>, p3: &TVec3<N>) -> TVec3<N> {
|
pub fn triangle_normal<T: RealField>(p1: &TVec3<T>, p2: &TVec3<T>, p3: &TVec3<T>) -> TVec3<T> {
|
||||||
(p2 - p1).cross(&(p3 - p1)).normalize()
|
(p2 - p1).cross(&(p3 - p1)).normalize()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use na::{DefaultAllocator, RealField};
|
use na::RealField;
|
||||||
|
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
use crate::traits::{Alloc, Dimension};
|
|
||||||
|
|
||||||
/// The dot product of the normalized version of `x` and `y`.
|
/// The dot product of the normalized version of `x` and `y`.
|
||||||
///
|
///
|
||||||
|
@ -10,10 +9,7 @@ use crate::traits::{Alloc, Dimension};
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`normalize_dot`](fn.normalize_dot.html`)
|
/// * [`normalize_dot`](fn.normalize_dot.html`)
|
||||||
pub fn fast_normalize_dot<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
|
pub fn fast_normalize_dot<T: RealField, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
// XXX: improve those.
|
// XXX: improve those.
|
||||||
x.normalize().dot(&y.normalize())
|
x.normalize().dot(&y.normalize())
|
||||||
}
|
}
|
||||||
|
@ -23,10 +19,7 @@ where
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`fast_normalize_dot`](fn.fast_normalize_dot.html`)
|
/// * [`fast_normalize_dot`](fn.fast_normalize_dot.html`)
|
||||||
pub fn normalize_dot<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
|
pub fn normalize_dot<T: RealField, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
// XXX: improve those.
|
// XXX: improve those.
|
||||||
x.normalize().dot(&y.normalize())
|
x.normalize().dot(&y.normalize())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,97 +1,97 @@
|
||||||
use na::{RealField, Rotation3, Unit, UnitQuaternion, U3};
|
use na::{RealField, Rotation3, Unit, UnitQuaternion};
|
||||||
|
|
||||||
use crate::aliases::{Qua, TMat3, TMat4, TVec3, TVec4};
|
use crate::aliases::{Qua, TMat3, TMat4, TVec3, TVec4};
|
||||||
|
|
||||||
/// Rotate the vector `v` by the quaternion `q` assumed to be normalized.
|
/// Rotate the vector `v` by the quaternion `q` assumed to be normalized.
|
||||||
pub fn quat_cross_vec<N: RealField>(q: &Qua<N>, v: &TVec3<N>) -> TVec3<N> {
|
pub fn quat_cross_vec<T: RealField>(q: &Qua<T>, v: &TVec3<T>) -> TVec3<T> {
|
||||||
UnitQuaternion::new_unchecked(*q) * v
|
UnitQuaternion::new_unchecked(*q) * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate the vector `v` by the inverse of the quaternion `q` assumed to be normalized.
|
/// Rotate the vector `v` by the inverse of the quaternion `q` assumed to be normalized.
|
||||||
pub fn quat_inv_cross_vec<N: RealField>(v: &TVec3<N>, q: &Qua<N>) -> TVec3<N> {
|
pub fn quat_inv_cross_vec<T: RealField>(v: &TVec3<T>, q: &Qua<T>) -> TVec3<T> {
|
||||||
UnitQuaternion::new_unchecked(*q).inverse() * v
|
UnitQuaternion::new_unchecked(*q).inverse() * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The quaternion `w` component.
|
/// The quaternion `w` component.
|
||||||
pub fn quat_extract_real_component<N: RealField>(q: &Qua<N>) -> N {
|
pub fn quat_extract_real_component<T: RealField>(q: &Qua<T>) -> T {
|
||||||
q.w
|
q.w
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Normalized linear interpolation between two quaternions.
|
/// Normalized linear interpolation between two quaternions.
|
||||||
pub fn quat_fast_mix<N: RealField>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> {
|
pub fn quat_fast_mix<T: RealField>(x: &Qua<T>, y: &Qua<T>, a: T) -> Qua<T> {
|
||||||
Unit::new_unchecked(*x)
|
Unit::new_unchecked(*x)
|
||||||
.nlerp(&Unit::new_unchecked(*y), a)
|
.nlerp(&Unit::new_unchecked(*y), a)
|
||||||
.into_inner()
|
.into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn quat_intermediate<N: RealField>(prev: &Qua<N>, curr: &Qua<N>, next: &Qua<N>) -> Qua<N> {
|
//pub fn quat_intermediate<T: RealField>(prev: &Qua<T>, curr: &Qua<T>, next: &Qua<T>) -> Qua<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
/// The squared magnitude of a quaternion `q`.
|
/// The squared magnitude of a quaternion `q`.
|
||||||
pub fn quat_length2<N: RealField>(q: &Qua<N>) -> N {
|
pub fn quat_length2<T: RealField>(q: &Qua<T>) -> T {
|
||||||
q.norm_squared()
|
q.norm_squared()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The squared magnitude of a quaternion `q`.
|
/// The squared magnitude of a quaternion `q`.
|
||||||
pub fn quat_magnitude2<N: RealField>(q: &Qua<N>) -> N {
|
pub fn quat_magnitude2<T: RealField>(q: &Qua<T>) -> T {
|
||||||
q.norm_squared()
|
q.norm_squared()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The quaternion representing the identity rotation.
|
/// The quaternion representing the identity rotation.
|
||||||
pub fn quat_identity<N: RealField>() -> Qua<N> {
|
pub fn quat_identity<T: RealField>() -> Qua<T> {
|
||||||
UnitQuaternion::identity().into_inner()
|
UnitQuaternion::identity().into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotates a vector by a quaternion assumed to be normalized.
|
/// Rotates a vector by a quaternion assumed to be normalized.
|
||||||
pub fn quat_rotate_vec3<N: RealField>(q: &Qua<N>, v: &TVec3<N>) -> TVec3<N> {
|
pub fn quat_rotate_vec3<T: RealField>(q: &Qua<T>, v: &TVec3<T>) -> TVec3<T> {
|
||||||
UnitQuaternion::new_unchecked(*q) * v
|
UnitQuaternion::new_unchecked(*q) * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotates a vector in homogeneous coordinates by a quaternion assumed to be normalized.
|
/// Rotates a vector in homogeneous coordinates by a quaternion assumed to be normalized.
|
||||||
pub fn quat_rotate_vec<N: RealField>(q: &Qua<N>, v: &TVec4<N>) -> TVec4<N> {
|
pub fn quat_rotate_vec<T: RealField>(q: &Qua<T>, v: &TVec4<T>) -> TVec4<T> {
|
||||||
let rotated = Unit::new_unchecked(*q) * v.fixed_rows::<U3>(0);
|
let rotated = Unit::new_unchecked(*q) * v.fixed_rows::<3>(0);
|
||||||
TVec4::new(rotated.x, rotated.y, rotated.z, v.w)
|
TVec4::new(rotated.x, rotated.y, rotated.z, v.w)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The rotation required to align `orig` to `dest`.
|
/// The rotation required to align `orig` to `dest`.
|
||||||
pub fn quat_rotation<N: RealField>(orig: &TVec3<N>, dest: &TVec3<N>) -> Qua<N> {
|
pub fn quat_rotation<T: RealField>(orig: &TVec3<T>, dest: &TVec3<T>) -> Qua<T> {
|
||||||
UnitQuaternion::rotation_between(orig, dest)
|
UnitQuaternion::rotation_between(orig, dest)
|
||||||
.unwrap_or_else(UnitQuaternion::identity)
|
.unwrap_or_else(UnitQuaternion::identity)
|
||||||
.into_inner()
|
.into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The spherical linear interpolation between two quaternions.
|
/// The spherical linear interpolation between two quaternions.
|
||||||
pub fn quat_short_mix<N: RealField>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> {
|
pub fn quat_short_mix<T: RealField>(x: &Qua<T>, y: &Qua<T>, a: T) -> Qua<T> {
|
||||||
Unit::new_normalize(*x)
|
Unit::new_normalize(*x)
|
||||||
.slerp(&Unit::new_normalize(*y), a)
|
.slerp(&Unit::new_normalize(*y), a)
|
||||||
.into_inner()
|
.into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn quat_squad<N: RealField>(q1: &Qua<N>, q2: &Qua<N>, s1: &Qua<N>, s2: &Qua<N>, h: N) -> Qua<N> {
|
//pub fn quat_squad<T: RealField>(q1: &Qua<T>, q2: &Qua<T>, s1: &Qua<T>, s2: &Qua<T>, h: T) -> Qua<T> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
/// Converts a quaternion to a rotation matrix.
|
/// Converts a quaternion to a rotation matrix.
|
||||||
pub fn quat_to_mat3<N: RealField>(x: &Qua<N>) -> TMat3<N> {
|
pub fn quat_to_mat3<T: RealField>(x: &Qua<T>) -> TMat3<T> {
|
||||||
UnitQuaternion::new_unchecked(*x)
|
UnitQuaternion::new_unchecked(*x)
|
||||||
.to_rotation_matrix()
|
.to_rotation_matrix()
|
||||||
.into_inner()
|
.into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a quaternion to a rotation matrix in homogenous coordinates.
|
/// Converts a quaternion to a rotation matrix in homogenous coordinates.
|
||||||
pub fn quat_to_mat4<N: RealField>(x: &Qua<N>) -> TMat4<N> {
|
pub fn quat_to_mat4<T: RealField>(x: &Qua<T>) -> TMat4<T> {
|
||||||
UnitQuaternion::new_unchecked(*x).to_homogeneous()
|
UnitQuaternion::new_unchecked(*x).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a rotation matrix to a quaternion.
|
/// Converts a rotation matrix to a quaternion.
|
||||||
pub fn mat3_to_quat<N: RealField>(x: &TMat3<N>) -> Qua<N> {
|
pub fn mat3_to_quat<T: RealField>(x: &TMat3<T>) -> Qua<T> {
|
||||||
let r = Rotation3::from_matrix_unchecked(*x);
|
let r = Rotation3::from_matrix_unchecked(*x);
|
||||||
UnitQuaternion::from_rotation_matrix(&r).into_inner()
|
UnitQuaternion::from_rotation_matrix(&r).into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a rotation matrix in homogeneous coordinates to a quaternion.
|
/// Converts a rotation matrix in homogeneous coordinates to a quaternion.
|
||||||
pub fn to_quat<N: RealField>(x: &TMat4<N>) -> Qua<N> {
|
pub fn to_quat<T: RealField>(x: &TMat4<T>) -> Qua<T> {
|
||||||
let rot = x.fixed_slice::<U3, U3>(0, 0).into_owned();
|
let rot = x.fixed_slice::<3, 3>(0, 0).into_owned();
|
||||||
mat3_to_quat(&rot)
|
mat3_to_quat(&rot)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::aliases::{Qua, TMat4, TVec3};
|
||||||
/// * `m` - Input matrix multiplied by this rotation matrix.
|
/// * `m` - Input matrix multiplied by this rotation matrix.
|
||||||
/// * `angle` - Rotation angle expressed in radians.
|
/// * `angle` - Rotation angle expressed in radians.
|
||||||
/// * `axis` - Rotation axis, must be normalized.
|
/// * `axis` - Rotation axis, must be normalized.
|
||||||
pub fn rotate_normalized_axis<N: RealField>(m: &TMat4<N>, angle: N, axis: &TVec3<N>) -> TMat4<N> {
|
pub fn rotate_normalized_axis<T: RealField>(m: &TMat4<T>, angle: T, axis: &TVec3<T>) -> TMat4<T> {
|
||||||
m * Rotation3::from_axis_angle(&Unit::new_unchecked(*axis), angle).to_homogeneous()
|
m * Rotation3::from_axis_angle(&Unit::new_unchecked(*axis), angle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,6 @@ pub fn rotate_normalized_axis<N: RealField>(m: &TMat4<N>, angle: N, axis: &TVec3
|
||||||
/// * `q` - Source orientation.
|
/// * `q` - Source orientation.
|
||||||
/// * `angle` - Angle expressed in radians.
|
/// * `angle` - Angle expressed in radians.
|
||||||
/// * `axis` - Normalized axis of the rotation, must be normalized.
|
/// * `axis` - Normalized axis of the rotation, must be normalized.
|
||||||
pub fn quat_rotate_normalized_axis<N: RealField>(q: &Qua<N>, angle: N, axis: &TVec3<N>) -> Qua<N> {
|
pub fn quat_rotate_normalized_axis<T: RealField>(q: &Qua<T>, angle: T, axis: &TVec3<T>) -> Qua<T> {
|
||||||
q * UnitQuaternion::from_axis_angle(&Unit::new_unchecked(*axis), angle).into_inner()
|
q * UnitQuaternion::from_axis_angle(&Unit::new_unchecked(*axis), angle).into_inner()
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use na::{RealField, Rotation3, Unit, UnitComplex};
|
||||||
use crate::aliases::{TMat4, TVec2, TVec3, TVec4};
|
use crate::aliases::{TMat4, TVec2, TVec3, TVec4};
|
||||||
|
|
||||||
/// Build the rotation matrix needed to align `normal` and `up`.
|
/// Build the rotation matrix needed to align `normal` and `up`.
|
||||||
pub fn orientation<N: RealField>(normal: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> {
|
pub fn orientation<T: RealField>(normal: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
|
||||||
if let Some(r) = Rotation3::rotation_between(normal, up) {
|
if let Some(r) = Rotation3::rotation_between(normal, up) {
|
||||||
r.to_homogeneous()
|
r.to_homogeneous()
|
||||||
} else {
|
} else {
|
||||||
|
@ -12,52 +12,52 @@ pub fn orientation<N: RealField>(normal: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate a two dimensional vector.
|
/// Rotate a two dimensional vector.
|
||||||
pub fn rotate_vec2<N: RealField>(v: &TVec2<N>, angle: N) -> TVec2<N> {
|
pub fn rotate_vec2<T: RealField>(v: &TVec2<T>, angle: T) -> TVec2<T> {
|
||||||
UnitComplex::new(angle) * v
|
UnitComplex::new(angle) * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate a three dimensional vector around an axis.
|
/// Rotate a three dimensional vector around an axis.
|
||||||
pub fn rotate_vec3<N: RealField>(v: &TVec3<N>, angle: N, normal: &TVec3<N>) -> TVec3<N> {
|
pub fn rotate_vec3<T: RealField>(v: &TVec3<T>, angle: T, normal: &TVec3<T>) -> TVec3<T> {
|
||||||
Rotation3::from_axis_angle(&Unit::new_normalize(*normal), angle) * v
|
Rotation3::from_axis_angle(&Unit::new_normalize(*normal), angle) * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate a thee dimensional vector in homogeneous coordinates around an axis.
|
/// Rotate a thee dimensional vector in homogeneous coordinates around an axis.
|
||||||
pub fn rotate_vec4<N: RealField>(v: &TVec4<N>, angle: N, normal: &TVec3<N>) -> TVec4<N> {
|
pub fn rotate_vec4<T: RealField>(v: &TVec4<T>, angle: T, normal: &TVec3<T>) -> TVec4<T> {
|
||||||
Rotation3::from_axis_angle(&Unit::new_normalize(*normal), angle).to_homogeneous() * v
|
Rotation3::from_axis_angle(&Unit::new_normalize(*normal), angle).to_homogeneous() * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate a three dimensional vector around the `X` axis.
|
/// Rotate a three dimensional vector around the `X` axis.
|
||||||
pub fn rotate_x_vec3<N: RealField>(v: &TVec3<N>, angle: N) -> TVec3<N> {
|
pub fn rotate_x_vec3<T: RealField>(v: &TVec3<T>, angle: T) -> TVec3<T> {
|
||||||
Rotation3::from_axis_angle(&TVec3::x_axis(), angle) * v
|
Rotation3::from_axis_angle(&TVec3::x_axis(), angle) * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate a three dimensional vector in homogeneous coordinates around the `X` axis.
|
/// Rotate a three dimensional vector in homogeneous coordinates around the `X` axis.
|
||||||
pub fn rotate_x_vec4<N: RealField>(v: &TVec4<N>, angle: N) -> TVec4<N> {
|
pub fn rotate_x_vec4<T: RealField>(v: &TVec4<T>, angle: T) -> TVec4<T> {
|
||||||
Rotation3::from_axis_angle(&TVec3::x_axis(), angle).to_homogeneous() * v
|
Rotation3::from_axis_angle(&TVec3::x_axis(), angle).to_homogeneous() * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate a three dimensional vector around the `Y` axis.
|
/// Rotate a three dimensional vector around the `Y` axis.
|
||||||
pub fn rotate_y_vec3<N: RealField>(v: &TVec3<N>, angle: N) -> TVec3<N> {
|
pub fn rotate_y_vec3<T: RealField>(v: &TVec3<T>, angle: T) -> TVec3<T> {
|
||||||
Rotation3::from_axis_angle(&TVec3::y_axis(), angle) * v
|
Rotation3::from_axis_angle(&TVec3::y_axis(), angle) * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate a three dimensional vector in homogeneous coordinates around the `Y` axis.
|
/// Rotate a three dimensional vector in homogeneous coordinates around the `Y` axis.
|
||||||
pub fn rotate_y_vec4<N: RealField>(v: &TVec4<N>, angle: N) -> TVec4<N> {
|
pub fn rotate_y_vec4<T: RealField>(v: &TVec4<T>, angle: T) -> TVec4<T> {
|
||||||
Rotation3::from_axis_angle(&TVec3::y_axis(), angle).to_homogeneous() * v
|
Rotation3::from_axis_angle(&TVec3::y_axis(), angle).to_homogeneous() * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate a three dimensional vector around the `Z` axis.
|
/// Rotate a three dimensional vector around the `Z` axis.
|
||||||
pub fn rotate_z_vec3<N: RealField>(v: &TVec3<N>, angle: N) -> TVec3<N> {
|
pub fn rotate_z_vec3<T: RealField>(v: &TVec3<T>, angle: T) -> TVec3<T> {
|
||||||
Rotation3::from_axis_angle(&TVec3::z_axis(), angle) * v
|
Rotation3::from_axis_angle(&TVec3::z_axis(), angle) * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate a three dimensional vector in homogeneous coordinates around the `Z` axis.
|
/// Rotate a three dimensional vector in homogeneous coordinates around the `Z` axis.
|
||||||
pub fn rotate_z_vec4<N: RealField>(v: &TVec4<N>, angle: N) -> TVec4<N> {
|
pub fn rotate_z_vec4<T: RealField>(v: &TVec4<T>, angle: T) -> TVec4<T> {
|
||||||
Rotation3::from_axis_angle(&TVec3::z_axis(), angle).to_homogeneous() * v
|
Rotation3::from_axis_angle(&TVec3::z_axis(), angle).to_homogeneous() * v
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes a spherical linear interpolation between the vectors `x` and `y` assumed to be normalized.
|
/// Computes a spherical linear interpolation between the vectors `x` and `y` assumed to be normalized.
|
||||||
pub fn slerp<N: RealField>(x: &TVec3<N>, y: &TVec3<N>, a: N) -> TVec3<N> {
|
pub fn slerp<T: RealField>(x: &TVec3<T>, y: &TVec3<T>, a: T) -> TVec3<T> {
|
||||||
Unit::new_unchecked(*x)
|
Unit::new_unchecked(*x)
|
||||||
.slerp(&Unit::new_unchecked(*y), a)
|
.slerp(&Unit::new_unchecked(*y), a)
|
||||||
.into_inner()
|
.into_inner()
|
||||||
|
|
|
@ -12,7 +12,7 @@ use crate::traits::Number;
|
||||||
/// * [`rotation2d`](fn.rotation2d.html)
|
/// * [`rotation2d`](fn.rotation2d.html)
|
||||||
/// * [`scaling2d`](fn.scaling2d.html)
|
/// * [`scaling2d`](fn.scaling2d.html)
|
||||||
/// * [`translation2d`](fn.translation2d.html)
|
/// * [`translation2d`](fn.translation2d.html)
|
||||||
pub fn rotation<N: RealField>(angle: N, v: &TVec3<N>) -> TMat4<N> {
|
pub fn rotation<T: RealField>(angle: T, v: &TVec3<T>) -> TMat4<T> {
|
||||||
Rotation3::from_axis_angle(&Unit::new_normalize(*v), angle).to_homogeneous()
|
Rotation3::from_axis_angle(&Unit::new_normalize(*v), angle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ pub fn rotation<N: RealField>(angle: N, v: &TVec3<N>) -> TMat4<N> {
|
||||||
/// * [`rotation2d`](fn.rotation2d.html)
|
/// * [`rotation2d`](fn.rotation2d.html)
|
||||||
/// * [`scaling2d`](fn.scaling2d.html)
|
/// * [`scaling2d`](fn.scaling2d.html)
|
||||||
/// * [`translation2d`](fn.translation2d.html)
|
/// * [`translation2d`](fn.translation2d.html)
|
||||||
pub fn scaling<N: Number>(v: &TVec3<N>) -> TMat4<N> {
|
pub fn scaling<T: Number>(v: &TVec3<T>) -> TMat4<T> {
|
||||||
TMat4::new_nonuniform_scaling(v)
|
TMat4::new_nonuniform_scaling(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ pub fn scaling<N: Number>(v: &TVec3<N>) -> TMat4<N> {
|
||||||
/// * [`rotation2d`](fn.rotation2d.html)
|
/// * [`rotation2d`](fn.rotation2d.html)
|
||||||
/// * [`scaling2d`](fn.scaling2d.html)
|
/// * [`scaling2d`](fn.scaling2d.html)
|
||||||
/// * [`translation2d`](fn.translation2d.html)
|
/// * [`translation2d`](fn.translation2d.html)
|
||||||
pub fn translation<N: Number>(v: &TVec3<N>) -> TMat4<N> {
|
pub fn translation<T: Number>(v: &TVec3<T>) -> TMat4<T> {
|
||||||
TMat4::new_translation(v)
|
TMat4::new_translation(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ pub fn translation<N: Number>(v: &TVec3<N>) -> TMat4<N> {
|
||||||
/// * [`translation`](fn.translation.html)
|
/// * [`translation`](fn.translation.html)
|
||||||
/// * [`scaling2d`](fn.scaling2d.html)
|
/// * [`scaling2d`](fn.scaling2d.html)
|
||||||
/// * [`translation2d`](fn.translation2d.html)
|
/// * [`translation2d`](fn.translation2d.html)
|
||||||
pub fn rotation2d<N: RealField>(angle: N) -> TMat3<N> {
|
pub fn rotation2d<T: RealField>(angle: T) -> TMat3<T> {
|
||||||
Rotation2::new(angle).to_homogeneous()
|
Rotation2::new(angle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ pub fn rotation2d<N: RealField>(angle: N) -> TMat3<N> {
|
||||||
/// * [`translation`](fn.translation.html)
|
/// * [`translation`](fn.translation.html)
|
||||||
/// * [`rotation2d`](fn.rotation2d.html)
|
/// * [`rotation2d`](fn.rotation2d.html)
|
||||||
/// * [`translation2d`](fn.translation2d.html)
|
/// * [`translation2d`](fn.translation2d.html)
|
||||||
pub fn scaling2d<N: Number>(v: &TVec2<N>) -> TMat3<N> {
|
pub fn scaling2d<T: Number>(v: &TVec2<T>) -> TMat3<T> {
|
||||||
TMat3::new_nonuniform_scaling(v)
|
TMat3::new_nonuniform_scaling(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +77,6 @@ pub fn scaling2d<N: Number>(v: &TVec2<N>) -> TMat3<N> {
|
||||||
/// * [`translation`](fn.translation.html)
|
/// * [`translation`](fn.translation.html)
|
||||||
/// * [`rotation2d`](fn.rotation2d.html)
|
/// * [`rotation2d`](fn.rotation2d.html)
|
||||||
/// * [`scaling2d`](fn.scaling2d.html)
|
/// * [`scaling2d`](fn.scaling2d.html)
|
||||||
pub fn translation2d<N: Number>(v: &TVec2<N>) -> TMat3<N> {
|
pub fn translation2d<T: Number>(v: &TVec2<T>) -> TMat3<T> {
|
||||||
TMat3::new_translation(v)
|
TMat3::new_translation(v)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
use na::{U2, U3};
|
|
||||||
|
|
||||||
use crate::aliases::{TMat3, TMat4, TVec2, TVec3};
|
use crate::aliases::{TMat3, TMat4, TVec2, TVec3};
|
||||||
use crate::traits::Number;
|
use crate::traits::Number;
|
||||||
|
|
||||||
/// Build planar projection matrix along normal axis and right-multiply it to `m`.
|
/// Build planar projection matrix along normal axis and right-multiply it to `m`.
|
||||||
pub fn proj2d<N: Number>(m: &TMat3<N>, normal: &TVec2<N>) -> TMat3<N> {
|
pub fn proj2d<T: Number>(m: &TMat3<T>, normal: &TVec2<T>) -> TMat3<T> {
|
||||||
let mut res = TMat3::identity();
|
let mut res = TMat3::identity();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut part = res.fixed_slice_mut::<U2, U2>(0, 0);
|
let mut part = res.fixed_slice_mut::<2, 2>(0, 0);
|
||||||
part -= normal * normal.transpose();
|
part -= normal * normal.transpose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,11 +14,11 @@ pub fn proj2d<N: Number>(m: &TMat3<N>, normal: &TVec2<N>) -> TMat3<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build planar projection matrix along normal axis, and right-multiply it to `m`.
|
/// Build planar projection matrix along normal axis, and right-multiply it to `m`.
|
||||||
pub fn proj<N: Number>(m: &TMat4<N>, normal: &TVec3<N>) -> TMat4<N> {
|
pub fn proj<T: Number>(m: &TMat4<T>, normal: &TVec3<T>) -> TMat4<T> {
|
||||||
let mut res = TMat4::identity();
|
let mut res = TMat4::identity();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut part = res.fixed_slice_mut::<U3, U3>(0, 0);
|
let mut part = res.fixed_slice_mut::<3, 3>(0, 0);
|
||||||
part -= normal * normal.transpose();
|
part -= normal * normal.transpose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,33 +26,33 @@ pub fn proj<N: Number>(m: &TMat4<N>, normal: &TVec3<N>) -> TMat4<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a reflection matrix and right-multiply it to `m`.
|
/// Builds a reflection matrix and right-multiply it to `m`.
|
||||||
pub fn reflect2d<N: Number>(m: &TMat3<N>, normal: &TVec2<N>) -> TMat3<N> {
|
pub fn reflect2d<T: Number>(m: &TMat3<T>, normal: &TVec2<T>) -> TMat3<T> {
|
||||||
let mut res = TMat3::identity();
|
let mut res = TMat3::identity();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut part = res.fixed_slice_mut::<U2, U2>(0, 0);
|
let mut part = res.fixed_slice_mut::<2, 2>(0, 0);
|
||||||
part -= (normal * N::from_f64(2.0).unwrap()) * normal.transpose();
|
part -= (normal * T::from_f64(2.0).unwrap()) * normal.transpose();
|
||||||
}
|
}
|
||||||
|
|
||||||
m * res
|
m * res
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a reflection matrix, and right-multiply it to `m`.
|
/// Builds a reflection matrix, and right-multiply it to `m`.
|
||||||
pub fn reflect<N: Number>(m: &TMat4<N>, normal: &TVec3<N>) -> TMat4<N> {
|
pub fn reflect<T: Number>(m: &TMat4<T>, normal: &TVec3<T>) -> TMat4<T> {
|
||||||
let mut res = TMat4::identity();
|
let mut res = TMat4::identity();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut part = res.fixed_slice_mut::<U3, U3>(0, 0);
|
let mut part = res.fixed_slice_mut::<3, 3>(0, 0);
|
||||||
part -= (normal * N::from_f64(2.0).unwrap()) * normal.transpose();
|
part -= (normal * T::from_f64(2.0).unwrap()) * normal.transpose();
|
||||||
}
|
}
|
||||||
|
|
||||||
m * res
|
m * res
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a scale-bias matrix.
|
/// Builds a scale-bias matrix.
|
||||||
pub fn scale_bias_matrix<N: Number>(scale: N, bias: N) -> TMat4<N> {
|
pub fn scale_bias_matrix<T: Number>(scale: T, bias: T) -> TMat4<T> {
|
||||||
let _0 = N::zero();
|
let _0 = T::zero();
|
||||||
let _1 = N::one();
|
let _1 = T::one();
|
||||||
|
|
||||||
TMat4::new(
|
TMat4::new(
|
||||||
scale, _0, _0, bias, _0, scale, _0, bias, _0, _0, scale, bias, _0, _0, _0, _1,
|
scale, _0, _0, bias, _0, scale, _0, bias, _0, _0, scale, bias, _0, _0, _0, _1,
|
||||||
|
@ -62,50 +60,50 @@ pub fn scale_bias_matrix<N: Number>(scale: N, bias: N) -> TMat4<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a scale-bias matrix, and right-multiply it to `m`.
|
/// Builds a scale-bias matrix, and right-multiply it to `m`.
|
||||||
pub fn scale_bias<N: Number>(m: &TMat4<N>, scale: N, bias: N) -> TMat4<N> {
|
pub fn scale_bias<T: Number>(m: &TMat4<T>, scale: T, bias: T) -> TMat4<T> {
|
||||||
m * scale_bias_matrix(scale, bias)
|
m * scale_bias_matrix(scale, bias)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transforms a matrix with a shearing on X axis.
|
/// Transforms a matrix with a shearing on X axis.
|
||||||
pub fn shear2d_x<N: Number>(m: &TMat3<N>, y: N) -> TMat3<N> {
|
pub fn shear2d_x<T: Number>(m: &TMat3<T>, y: T) -> TMat3<T> {
|
||||||
let _0 = N::zero();
|
let _0 = T::zero();
|
||||||
let _1 = N::one();
|
let _1 = T::one();
|
||||||
|
|
||||||
let shear = TMat3::new(_1, y, _0, _0, _1, _0, _0, _0, _1);
|
let shear = TMat3::new(_1, y, _0, _0, _1, _0, _0, _0, _1);
|
||||||
m * shear
|
m * shear
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transforms a matrix with a shearing on Y axis.
|
/// Transforms a matrix with a shearing on Y axis.
|
||||||
pub fn shear_x<N: Number>(m: &TMat4<N>, y: N, z: N) -> TMat4<N> {
|
pub fn shear_x<T: Number>(m: &TMat4<T>, y: T, z: T) -> TMat4<T> {
|
||||||
let _0 = N::zero();
|
let _0 = T::zero();
|
||||||
let _1 = N::one();
|
let _1 = T::one();
|
||||||
let shear = TMat4::new(_1, _0, _0, _0, y, _1, _0, _0, z, _0, _1, _0, _0, _0, _0, _1);
|
let shear = TMat4::new(_1, _0, _0, _0, y, _1, _0, _0, z, _0, _1, _0, _0, _0, _0, _1);
|
||||||
|
|
||||||
m * shear
|
m * shear
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transforms a matrix with a shearing on Y axis.
|
/// Transforms a matrix with a shearing on Y axis.
|
||||||
pub fn shear2d_y<N: Number>(m: &TMat3<N>, x: N) -> TMat3<N> {
|
pub fn shear2d_y<T: Number>(m: &TMat3<T>, x: T) -> TMat3<T> {
|
||||||
let _0 = N::zero();
|
let _0 = T::zero();
|
||||||
let _1 = N::one();
|
let _1 = T::one();
|
||||||
|
|
||||||
let shear = TMat3::new(_1, _0, _0, x, _1, _0, _0, _0, _1);
|
let shear = TMat3::new(_1, _0, _0, x, _1, _0, _0, _0, _1);
|
||||||
m * shear
|
m * shear
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transforms a matrix with a shearing on Y axis.
|
/// Transforms a matrix with a shearing on Y axis.
|
||||||
pub fn shear_y<N: Number>(m: &TMat4<N>, x: N, z: N) -> TMat4<N> {
|
pub fn shear_y<T: Number>(m: &TMat4<T>, x: T, z: T) -> TMat4<T> {
|
||||||
let _0 = N::zero();
|
let _0 = T::zero();
|
||||||
let _1 = N::one();
|
let _1 = T::one();
|
||||||
let shear = TMat4::new(_1, x, _0, _0, _0, _1, _0, _0, _0, z, _1, _0, _0, _0, _0, _1);
|
let shear = TMat4::new(_1, x, _0, _0, _0, _1, _0, _0, _0, z, _1, _0, _0, _0, _0, _1);
|
||||||
|
|
||||||
m * shear
|
m * shear
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transforms a matrix with a shearing on Z axis.
|
/// Transforms a matrix with a shearing on Z axis.
|
||||||
pub fn shear_z<N: Number>(m: &TMat4<N>, x: N, y: N) -> TMat4<N> {
|
pub fn shear_z<T: Number>(m: &TMat4<T>, x: T, y: T) -> TMat4<T> {
|
||||||
let _0 = N::zero();
|
let _0 = T::zero();
|
||||||
let _1 = N::one();
|
let _1 = T::one();
|
||||||
let shear = TMat4::new(_1, _0, x, _0, _0, _1, y, _0, _0, _0, _1, _0, _0, _0, _0, _1);
|
let shear = TMat4::new(_1, _0, x, _0, _0, _1, y, _0, _0, _0, _1, _0, _0, _0, _0, _1);
|
||||||
|
|
||||||
m * shear
|
m * shear
|
||||||
|
|
|
@ -12,7 +12,7 @@ use crate::traits::Number;
|
||||||
/// * [`scaling2d`](fn.scaling2d.html)
|
/// * [`scaling2d`](fn.scaling2d.html)
|
||||||
/// * [`translate2d`](fn.translate2d.html)
|
/// * [`translate2d`](fn.translate2d.html)
|
||||||
/// * [`translation2d`](fn.translation2d.html)
|
/// * [`translation2d`](fn.translation2d.html)
|
||||||
pub fn rotate2d<N: RealField>(m: &TMat3<N>, angle: N) -> TMat3<N> {
|
pub fn rotate2d<T: RealField>(m: &TMat3<T>, angle: T) -> TMat3<T> {
|
||||||
m * UnitComplex::new(angle).to_homogeneous()
|
m * UnitComplex::new(angle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ pub fn rotate2d<N: RealField>(m: &TMat3<N>, angle: N) -> TMat3<N> {
|
||||||
/// * [`scaling2d`](fn.scaling2d.html)
|
/// * [`scaling2d`](fn.scaling2d.html)
|
||||||
/// * [`translate2d`](fn.translate2d.html)
|
/// * [`translate2d`](fn.translate2d.html)
|
||||||
/// * [`translation2d`](fn.translation2d.html)
|
/// * [`translation2d`](fn.translation2d.html)
|
||||||
pub fn scale2d<N: Number>(m: &TMat3<N>, v: &TVec2<N>) -> TMat3<N> {
|
pub fn scale2d<T: Number>(m: &TMat3<T>, v: &TVec2<T>) -> TMat3<T> {
|
||||||
m.prepend_nonuniform_scaling(v)
|
m.prepend_nonuniform_scaling(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,6 @@ pub fn scale2d<N: Number>(m: &TMat3<N>, v: &TVec2<N>) -> TMat3<N> {
|
||||||
/// * [`scale2d`](fn.scale2d.html)
|
/// * [`scale2d`](fn.scale2d.html)
|
||||||
/// * [`scaling2d`](fn.scaling2d.html)
|
/// * [`scaling2d`](fn.scaling2d.html)
|
||||||
/// * [`translation2d`](fn.translation2d.html)
|
/// * [`translation2d`](fn.translation2d.html)
|
||||||
pub fn translate2d<N: Number>(m: &TMat3<N>, v: &TVec2<N>) -> TMat3<N> {
|
pub fn translate2d<T: Number>(m: &TMat3<T>, v: &TVec2<T>) -> TMat3<T> {
|
||||||
m.prepend_translation(v)
|
m.prepend_translation(v)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,16 @@
|
||||||
use na::{DefaultAllocator, RealField};
|
use na::RealField;
|
||||||
|
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
use crate::traits::{Alloc, Dimension};
|
|
||||||
|
|
||||||
/// The angle between two vectors.
|
/// The angle between two vectors.
|
||||||
pub fn angle<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
|
pub fn angle<T: RealField, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.angle(y)
|
x.angle(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn oriented_angle<N: RealField>(x: &TVec2<N>, y: &TVec2<N>) -> N {
|
//pub fn oriented_angle<T: RealField>(x: &TVec2<T>, y: &TVec2<T>) -> T {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn oriented_angle_ref<N: RealField>(x: &TVec3<N>, y: &TVec3<N>, refv: &TVec3<N>) -> N {
|
//pub fn oriented_angle_ref<T: RealField>(x: &TVec3<T>, y: &TVec3<T>, refv: &TVec3<T>) -> T {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
use na::{DefaultAllocator, RealField};
|
use na::RealField;
|
||||||
|
|
||||||
use crate::aliases::{TVec, TVec2, TVec3};
|
use crate::aliases::{TVec, TVec2, TVec3};
|
||||||
use crate::traits::{Alloc, Dimension, Number};
|
use crate::traits::Number;
|
||||||
|
|
||||||
/// Returns `true` if two vectors are collinear (up to an epsilon).
|
/// Returns `true` if two vectors are collinear (up to an epsilon).
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`are_collinear2d`](fn.are_collinear2d.html)
|
/// * [`are_collinear2d`](fn.are_collinear2d.html)
|
||||||
pub fn are_collinear<N: Number>(v0: &TVec3<N>, v1: &TVec3<N>, epsilon: N) -> bool {
|
pub fn are_collinear<T: Number>(v0: &TVec3<T>, v1: &TVec3<T>, epsilon: T) -> bool {
|
||||||
is_null(&v0.cross(v1), epsilon)
|
is_null(&v0.cross(v1), epsilon)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,43 +17,34 @@ pub fn are_collinear<N: Number>(v0: &TVec3<N>, v1: &TVec3<N>, epsilon: N) -> boo
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`are_collinear`](fn.are_collinear.html)
|
/// * [`are_collinear`](fn.are_collinear.html)
|
||||||
pub fn are_collinear2d<N: Number>(v0: &TVec2<N>, v1: &TVec2<N>, epsilon: N) -> bool {
|
pub fn are_collinear2d<T: Number>(v0: &TVec2<T>, v1: &TVec2<T>, epsilon: T) -> bool {
|
||||||
abs_diff_eq!(v0.perp(v1), N::zero(), epsilon = epsilon)
|
abs_diff_eq!(v0.perp(v1), T::zero(), epsilon = epsilon)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if two vectors are orthogonal (up to an epsilon).
|
/// Returns `true` if two vectors are orthogonal (up to an epsilon).
|
||||||
pub fn are_orthogonal<N: Number, D: Dimension>(v0: &TVec<N, D>, v1: &TVec<N, D>, epsilon: N) -> bool
|
pub fn are_orthogonal<T: Number, const D: usize>(
|
||||||
where
|
v0: &TVec<T, D>,
|
||||||
DefaultAllocator: Alloc<N, D>,
|
v1: &TVec<T, D>,
|
||||||
{
|
epsilon: T,
|
||||||
abs_diff_eq!(v0.dot(v1), N::zero(), epsilon = epsilon)
|
) -> bool {
|
||||||
|
abs_diff_eq!(v0.dot(v1), T::zero(), epsilon = epsilon)
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn are_orthonormal<N: Number, D: Dimension>(v0: &TVec<N, D>, v1: &TVec<N, D>, epsilon: N) -> bool
|
//pub fn are_orthonormal<T: Number, const D: usize>(v0: &TVec<T, D>, v1: &TVec<T, D>, epsilon: T) -> bool {
|
||||||
// where DefaultAllocator: Alloc<N, D> {
|
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
/// Returns `true` if all the components of `v` are zero (up to an epsilon).
|
/// Returns `true` if all the components of `v` are zero (up to an epsilon).
|
||||||
pub fn is_comp_null<N: Number, D: Dimension>(v: &TVec<N, D>, epsilon: N) -> TVec<bool, D>
|
pub fn is_comp_null<T: Number, const D: usize>(v: &TVec<T, D>, epsilon: T) -> TVec<bool, D> {
|
||||||
where
|
v.map(|x| abs_diff_eq!(x, T::zero(), epsilon = epsilon))
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
v.map(|x| abs_diff_eq!(x, N::zero(), epsilon = epsilon))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if `v` has a magnitude of 1 (up to an epsilon).
|
/// Returns `true` if `v` has a magnitude of 1 (up to an epsilon).
|
||||||
pub fn is_normalized<N: RealField, D: Dimension>(v: &TVec<N, D>, epsilon: N) -> bool
|
pub fn is_normalized<T: RealField, const D: usize>(v: &TVec<T, D>, epsilon: T) -> bool {
|
||||||
where
|
abs_diff_eq!(v.norm_squared(), T::one(), epsilon = epsilon * epsilon)
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
abs_diff_eq!(v.norm_squared(), N::one(), epsilon = epsilon * epsilon)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if `v` is zero (up to an epsilon).
|
/// Returns `true` if `v` is zero (up to an epsilon).
|
||||||
pub fn is_null<N: Number, D: Dimension>(v: &TVec<N, D>, epsilon: N) -> bool
|
pub fn is_null<T: Number, const D: usize>(v: &TVec<T, D>, epsilon: T) -> bool {
|
||||||
where
|
abs_diff_eq!(*v, TVec::<T, D>::zeros(), epsilon = epsilon)
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
abs_diff_eq!(*v, TVec::<N, D>::zeros(), epsilon = epsilon)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,46 @@
|
||||||
use na::{Scalar, RealField, U3, DefaultAllocator};
|
use na::{DefaultAllocator, RealField, Scalar, U3};
|
||||||
|
|
||||||
use crate::traits::{Number, Alloc, Dimension};
|
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
|
use crate::traits::{Alloc, Dimension, Number};
|
||||||
|
|
||||||
pub fn bitCount<T>(v: T) -> i32 {
|
pub fn bitCount<T>(v: T) -> i32 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bitCount2<N: Scalar, D: Dimension>(v: &TVec<N, D>) -> TVec<i32, D>
|
pub fn bitCount2<T: Scalar, const D: usize>(v: &TVec<T, D>) -> TVec<i32, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where
|
||||||
|
DefaultAllocator: Alloc<T, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bitfieldExtract<N: Scalar, D: Dimension>(Value: &TVec<N, D>, Offset: i32, Bits: i32) -> TVec<N, D>
|
pub fn bitfieldExtract<T: Scalar, const D: usize>(
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
Value: &TVec<T, D>,
|
||||||
|
Offset: i32,
|
||||||
|
Bits: i32,
|
||||||
|
) -> TVec<T, D>
|
||||||
|
where
|
||||||
|
DefaultAllocator: Alloc<T, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bitfieldInsert<N: Scalar, D: Dimension>(Base: &TVec<N, D>, Insert: &TVec<N, D>, Offset: i32, Bits: i32) -> TVec<N, D>
|
pub fn bitfieldInsert<T: Scalar, const D: usize>(
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
Base: &TVec<T, D>,
|
||||||
|
Insert: &TVec<T, D>,
|
||||||
|
Offset: i32,
|
||||||
|
Bits: i32,
|
||||||
|
) -> TVec<T, D>
|
||||||
|
where
|
||||||
|
DefaultAllocator: Alloc<T, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bitfieldReverse<N: Scalar, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
pub fn bitfieldReverse<T: Scalar, const D: usize>(v: &TVec<T, D>) -> TVec<T, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where
|
||||||
|
DefaultAllocator: Alloc<T, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +48,10 @@ pub fn findLSB<IU>(x: IU) -> u32 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn findLSB2<N: Scalar, D: Dimension>(v: &TVec<N, D>) -> TVec<i32, D>
|
pub fn findLSB2<T: Scalar, const D: usize>(v: &TVec<T, D>) -> TVec<i32, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where
|
||||||
|
DefaultAllocator: Alloc<T, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,27 +59,53 @@ pub fn findMSB<IU>(x: IU) -> i32 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn findMSB2<N: Scalar, D: Dimension>(v: &TVec<N, D>) -> TVec<i32, D>
|
pub fn findMSB2<T: Scalar, const D: usize>(v: &TVec<T, D>) -> TVec<i32, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where
|
||||||
|
DefaultAllocator: Alloc<T, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn imulExtended<N: Scalar, D: Dimension>(x: &TVec<i32, D>, y: &TVec<i32, D>, msb: &TVec<i32, D>, lsb: &TVec<i32, D>)
|
pub fn imulExtended<T: Scalar, const D: usize>(
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
x: &TVec<i32, D>,
|
||||||
|
y: &TVec<i32, D>,
|
||||||
|
msb: &TVec<i32, D>,
|
||||||
|
lsb: &TVec<i32, D>,
|
||||||
|
) where
|
||||||
|
DefaultAllocator: Alloc<T, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uaddCarry<N: Scalar, D: Dimension>(x: &TVec<u32, D>, y: &TVec<u32, D>, carry: &TVec<u32, D>) -> TVec<u32, D>
|
pub fn uaddCarry<T: Scalar, const D: usize>(
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
x: &TVec<u32, D>,
|
||||||
|
y: &TVec<u32, D>,
|
||||||
|
carry: &TVec<u32, D>,
|
||||||
|
) -> TVec<u32, D>
|
||||||
|
where
|
||||||
|
DefaultAllocator: Alloc<T, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn umulExtended<N: Scalar, D: Dimension>(x: &TVec<u32, D>, y: &TVec<u32, D>, msb: &TVec<u32, D>, lsb: &TVec<u32, D>)
|
pub fn umulExtended<T: Scalar, const D: usize>(
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
x: &TVec<u32, D>,
|
||||||
unimplemented!()
|
y: &TVec<u32, D>,
|
||||||
}
|
msb: &TVec<u32, D>,
|
||||||
|
lsb: &TVec<u32, D>,
|
||||||
pub fn usubBorrow<N: Scalar, D: Dimension>(x: &TVec<u32, D>, y: &TVec<u32, D>, borrow: &TVec<u32, D>) -> TVec<u32, D>
|
) where
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
DefaultAllocator: Alloc<T, D>,
|
||||||
|
{
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn usubBorrow<T: Scalar, const D: usize>(
|
||||||
|
x: &TVec<u32, D>,
|
||||||
|
y: &TVec<u32, D>,
|
||||||
|
borrow: &TVec<u32, D>,
|
||||||
|
) -> TVec<u32, D>
|
||||||
|
where
|
||||||
|
DefaultAllocator: Alloc<T, D>,
|
||||||
|
{
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
### Vector and matrix construction
|
### Vector and matrix construction
|
||||||
Vectors, matrices, and quaternions can be constructed using several approaches:
|
Vectors, matrices, and quaternions can be constructed using several approaches:
|
||||||
* Using functions with the same name as their type in lower-case. For example [`glm::vec3(x, y, z)`](fn.vec3.html) will create a 3D vector.
|
* Using functions with the same name as their type in lower-case. For example [`glm::vec3(x, y, z)`](fn.vec3.html) will create a 3D vector.
|
||||||
* Using the `::new` constructor. For example [`Vec3::new(x, y, z)`](../nalgebra/base/type.MatrixMN.html#method.new-27) will create a 3D vector.
|
* Using the `::new` constructor. For example [`Vec3::new(x, y, z)`](../nalgebra/base/type.OMatrix.html#method.new-27) will create a 3D vector.
|
||||||
* Using the functions prefixed by `make_` to build a vector a matrix from a slice. For example [`glm::make_vec3(&[x, y, z])`](fn.make_vec3.html) will create a 3D vector.
|
* Using the functions prefixed by `make_` to build a vector a matrix from a slice. For example [`glm::make_vec3(&[x, y, z])`](fn.make_vec3.html) will create a 3D vector.
|
||||||
Keep in mind that constructing a matrix using this type of functions require its components to be arranged in column-major order on the slice.
|
Keep in mind that constructing a matrix using this type of functions require its components to be arranged in column-major order on the slice.
|
||||||
* Using a geometric construction function. For example [`glm::rotation(angle, axis)`](fn.rotation.html) will build a 4x4 homogeneous rotation matrix from an angle (in radians) and an axis.
|
* Using a geometric construction function. For example [`glm::rotation(angle, axis)`](fn.rotation.html) will build a 4x4 homogeneous rotation matrix from an angle (in radians) and an axis.
|
||||||
|
@ -119,7 +119,7 @@ extern crate approx;
|
||||||
extern crate nalgebra as na;
|
extern crate nalgebra as na;
|
||||||
|
|
||||||
pub use crate::aliases::*;
|
pub use crate::aliases::*;
|
||||||
pub use crate::traits::{Alloc, Dimension, Number};
|
pub use crate::traits::Number;
|
||||||
pub use common::{
|
pub use common::{
|
||||||
abs, ceil, clamp, clamp_scalar, clamp_vec, float_bits_to_int, float_bits_to_int_vec,
|
abs, ceil, clamp, clamp_scalar, clamp_vec, float_bits_to_int, float_bits_to_int_vec,
|
||||||
float_bits_to_uint, float_bits_to_uint_vec, floor, fract, int_bits_to_float,
|
float_bits_to_uint, float_bits_to_uint_vec, floor, fract, int_bits_to_float,
|
||||||
|
|
|
@ -1,52 +1,40 @@
|
||||||
use na::{DefaultAllocator, RealField, Scalar};
|
use na::{Const, DimMin, RealField, Scalar};
|
||||||
|
|
||||||
use crate::aliases::{TMat, TVec};
|
use crate::aliases::{TMat, TVec};
|
||||||
use crate::traits::{Alloc, Dimension, Number};
|
use crate::traits::Number;
|
||||||
|
|
||||||
/// The determinant of the matrix `m`.
|
/// The determinant of the matrix `m`.
|
||||||
pub fn determinant<N: RealField, D: Dimension>(m: &TMat<N, D, D>) -> N
|
pub fn determinant<T: RealField, const D: usize>(m: &TMat<T, D, D>) -> T
|
||||||
where
|
where
|
||||||
DefaultAllocator: Alloc<N, D, D>,
|
Const<D>: DimMin<Const<D>, Output = Const<D>>,
|
||||||
{
|
{
|
||||||
m.determinant()
|
m.determinant()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The inverse of the matrix `m`.
|
/// The inverse of the matrix `m`.
|
||||||
pub fn inverse<N: RealField, D: Dimension>(m: &TMat<N, D, D>) -> TMat<N, D, D>
|
pub fn inverse<T: RealField, const D: usize>(m: &TMat<T, D, D>) -> TMat<T, D, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D, D>,
|
|
||||||
{
|
|
||||||
m.clone()
|
m.clone()
|
||||||
.try_inverse()
|
.try_inverse()
|
||||||
.unwrap_or_else(TMat::<N, D, D>::zeros)
|
.unwrap_or_else(TMat::<T, D, D>::zeros)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise multiplication of two matrices.
|
/// Component-wise multiplication of two matrices.
|
||||||
pub fn matrix_comp_mult<N: Number, R: Dimension, C: Dimension>(
|
pub fn matrix_comp_mult<T: Number, const R: usize, const C: usize>(
|
||||||
x: &TMat<N, R, C>,
|
x: &TMat<T, R, C>,
|
||||||
y: &TMat<N, R, C>,
|
y: &TMat<T, R, C>,
|
||||||
) -> TMat<N, R, C>
|
) -> TMat<T, R, C> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, R, C>,
|
|
||||||
{
|
|
||||||
x.component_mul(y)
|
x.component_mul(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Treats the first parameter `c` as a column vector and the second parameter `r` as a row vector and does a linear algebraic matrix multiply `c * r`.
|
/// Treats the first parameter `c` as a column vector and the second parameter `r` as a row vector and does a linear algebraic matrix multiply `c * r`.
|
||||||
pub fn outer_product<N: Number, R: Dimension, C: Dimension>(
|
pub fn outer_product<T: Number, const R: usize, const C: usize>(
|
||||||
c: &TVec<N, R>,
|
c: &TVec<T, R>,
|
||||||
r: &TVec<N, C>,
|
r: &TVec<T, C>,
|
||||||
) -> TMat<N, R, C>
|
) -> TMat<T, R, C> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, R, C>,
|
|
||||||
{
|
|
||||||
c * r.transpose()
|
c * r.transpose()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The transpose of the matrix `m`.
|
/// The transpose of the matrix `m`.
|
||||||
pub fn transpose<N: Scalar, R: Dimension, C: Dimension>(x: &TMat<N, R, C>) -> TMat<N, C, R>
|
pub fn transpose<T: Scalar, const R: usize, const C: usize>(x: &TMat<T, R, C>) -> TMat<T, C, R> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, R, C>,
|
|
||||||
{
|
|
||||||
x.transpose()
|
x.transpose()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,52 +1,51 @@
|
||||||
use na::Scalar;
|
use na::Scalar;
|
||||||
|
|
||||||
use crate::aliases::{Vec2, Vec4, UVec2};
|
use crate::aliases::{UVec2, Vec2, Vec4};
|
||||||
|
|
||||||
|
pub fn packDouble2x32<T: Scalar>(v: &UVec2) -> f64 {
|
||||||
pub fn packDouble2x32<N: Scalar>(v: &UVec2) -> f64 {
|
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn packHalf2x16<N: Scalar>(v: &Vec2) -> u32 {
|
pub fn packHalf2x16<T: Scalar>(v: &Vec2) -> u32 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn packSnorm2x16<N: Scalar>(v: &Vec2) -> u32 {
|
pub fn packSnorm2x16<T: Scalar>(v: &Vec2) -> u32 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn packSnorm4x8<N: Scalar>(v: &Vec4) -> u32 {
|
pub fn packSnorm4x8<T: Scalar>(v: &Vec4) -> u32 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn packUnorm2x16<N: Scalar>(v: &Vec2) -> u32 {
|
pub fn packUnorm2x16<T: Scalar>(v: &Vec2) -> u32 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn packUnorm4x8<N: Scalar>(v: &Vec4) -> u32 {
|
pub fn packUnorm4x8<T: Scalar>(v: &Vec4) -> u32 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unpackDouble2x32<N: Scalar>(v: f64) -> UVec2 {
|
pub fn unpackDouble2x32<T: Scalar>(v: f64) -> UVec2 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unpackHalf2x16<N: Scalar>(v: u32) -> Vec2 {
|
pub fn unpackHalf2x16<T: Scalar>(v: u32) -> Vec2 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unpackSnorm2x16<N: Scalar>(p: u32) -> Vec2 {
|
pub fn unpackSnorm2x16<T: Scalar>(p: u32) -> Vec2 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unpackSnorm4x8<N: Scalar>(p: u32) -> Vec4 {
|
pub fn unpackSnorm4x8<T: Scalar>(p: u32) -> Vec4 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unpackUnorm2x16<N: Scalar>(p: u32) -> Vec2 {
|
pub fn unpackUnorm2x16<T: Scalar>(p: u32) -> Vec2 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unpackUnorm4x8<N: Scalar>(p: u32) -> Vec4 {
|
pub fn unpackUnorm4x8<T: Scalar>(p: u32) -> Vec4 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,10 @@
|
||||||
use approx::AbsDiffEq;
|
use approx::AbsDiffEq;
|
||||||
use num::{Bounded, FromPrimitive, Signed};
|
use num::{Bounded, FromPrimitive, Signed};
|
||||||
|
|
||||||
use na::allocator::Allocator;
|
use na::Scalar;
|
||||||
use na::{DimMin, DimName, Scalar, U1};
|
|
||||||
use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub};
|
use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub};
|
||||||
use std::cmp::PartialOrd;
|
use std::cmp::PartialOrd;
|
||||||
|
|
||||||
/// A type-level number representing a vector, matrix row, or matrix column, dimension.
|
|
||||||
pub trait Dimension: DimName + DimMin<Self, Output = Self> {}
|
|
||||||
impl<D: DimName + DimMin<D, Output = Self>> Dimension for D {}
|
|
||||||
|
|
||||||
/// A number that can either be an integer or a float.
|
/// A number that can either be an integer or a float.
|
||||||
pub trait Number:
|
pub trait Number:
|
||||||
Scalar
|
Scalar
|
||||||
|
@ -39,64 +34,3 @@ impl<
|
||||||
> Number for T
|
> Number for T
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub trait Alloc<N: Scalar, R: Dimension, C: Dimension = U1>:
|
|
||||||
Allocator<N, R>
|
|
||||||
+ Allocator<N, C>
|
|
||||||
+ Allocator<N, U1, R>
|
|
||||||
+ Allocator<N, U1, C>
|
|
||||||
+ Allocator<N, R, C>
|
|
||||||
+ Allocator<N, C, R>
|
|
||||||
+ Allocator<N, R, R>
|
|
||||||
+ Allocator<N, C, C>
|
|
||||||
+ Allocator<bool, R>
|
|
||||||
+ Allocator<bool, C>
|
|
||||||
+ Allocator<f32, R>
|
|
||||||
+ Allocator<f32, C>
|
|
||||||
+ Allocator<u32, R>
|
|
||||||
+ Allocator<u32, C>
|
|
||||||
+ Allocator<i32, R>
|
|
||||||
+ Allocator<i32, C>
|
|
||||||
+ Allocator<f64, R>
|
|
||||||
+ Allocator<f64, C>
|
|
||||||
+ Allocator<u64, R>
|
|
||||||
+ Allocator<u64, C>
|
|
||||||
+ Allocator<i64, R>
|
|
||||||
+ Allocator<i64, C>
|
|
||||||
+ Allocator<i16, R>
|
|
||||||
+ Allocator<i16, C>
|
|
||||||
+ Allocator<(usize, usize), R>
|
|
||||||
+ Allocator<(usize, usize), C>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N: Scalar, R: Dimension, C: Dimension, T> Alloc<N, R, C> for T where
|
|
||||||
T: Allocator<N, R>
|
|
||||||
+ Allocator<N, C>
|
|
||||||
+ Allocator<N, U1, R>
|
|
||||||
+ Allocator<N, U1, C>
|
|
||||||
+ Allocator<N, R, C>
|
|
||||||
+ Allocator<N, C, R>
|
|
||||||
+ Allocator<N, R, R>
|
|
||||||
+ Allocator<N, C, C>
|
|
||||||
+ Allocator<bool, R>
|
|
||||||
+ Allocator<bool, C>
|
|
||||||
+ Allocator<f32, R>
|
|
||||||
+ Allocator<f32, C>
|
|
||||||
+ Allocator<u32, R>
|
|
||||||
+ Allocator<u32, C>
|
|
||||||
+ Allocator<i32, R>
|
|
||||||
+ Allocator<i32, C>
|
|
||||||
+ Allocator<f64, R>
|
|
||||||
+ Allocator<f64, C>
|
|
||||||
+ Allocator<u64, R>
|
|
||||||
+ Allocator<u64, C>
|
|
||||||
+ Allocator<i64, R>
|
|
||||||
+ Allocator<i64, C>
|
|
||||||
+ Allocator<i16, R>
|
|
||||||
+ Allocator<i16, C>
|
|
||||||
+ Allocator<(usize, usize), R>
|
|
||||||
+ Allocator<(usize, usize), C>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,124 +1,78 @@
|
||||||
use na::{self, DefaultAllocator, RealField};
|
use na::{self, RealField};
|
||||||
|
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
use crate::traits::{Alloc, Dimension};
|
|
||||||
|
|
||||||
/// Component-wise arc-cosinus.
|
/// Component-wise arc-cosinus.
|
||||||
pub fn acos<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn acos<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.map(|e| e.acos())
|
x.map(|e| e.acos())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise hyperbolic arc-cosinus.
|
/// Component-wise hyperbolic arc-cosinus.
|
||||||
pub fn acosh<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn acosh<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.map(|e| e.acosh())
|
x.map(|e| e.acosh())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise arc-sinus.
|
/// Component-wise arc-sinus.
|
||||||
pub fn asin<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn asin<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.map(|e| e.asin())
|
x.map(|e| e.asin())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise hyperbolic arc-sinus.
|
/// Component-wise hyperbolic arc-sinus.
|
||||||
pub fn asinh<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn asinh<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.map(|e| e.asinh())
|
x.map(|e| e.asinh())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise arc-tangent of `y / x`.
|
/// Component-wise arc-tangent of `y / x`.
|
||||||
pub fn atan2<N: RealField, D: Dimension>(y: &TVec<N, D>, x: &TVec<N, D>) -> TVec<N, D>
|
pub fn atan2<T: RealField, const D: usize>(y: &TVec<T, D>, x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
y.zip_map(x, |y, x| y.atan2(x))
|
y.zip_map(x, |y, x| y.atan2(x))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise arc-tangent.
|
/// Component-wise arc-tangent.
|
||||||
pub fn atan<N: RealField, D: Dimension>(y_over_x: &TVec<N, D>) -> TVec<N, D>
|
pub fn atan<T: RealField, const D: usize>(y_over_x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
y_over_x.map(|e| e.atan())
|
y_over_x.map(|e| e.atan())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise hyperbolic arc-tangent.
|
/// Component-wise hyperbolic arc-tangent.
|
||||||
pub fn atanh<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn atanh<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.map(|e| e.atanh())
|
x.map(|e| e.atanh())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise cosinus.
|
/// Component-wise cosinus.
|
||||||
pub fn cos<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
|
pub fn cos<T: RealField, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
angle.map(|e| e.cos())
|
angle.map(|e| e.cos())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise hyperbolic cosinus.
|
/// Component-wise hyperbolic cosinus.
|
||||||
pub fn cosh<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
|
pub fn cosh<T: RealField, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
angle.map(|e| e.cosh())
|
angle.map(|e| e.cosh())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise conversion from radians to degrees.
|
/// Component-wise conversion from radians to degrees.
|
||||||
pub fn degrees<N: RealField, D: Dimension>(radians: &TVec<N, D>) -> TVec<N, D>
|
pub fn degrees<T: RealField, const D: usize>(radians: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
radians.map(|e| e * na::convert(180.0) / T::pi())
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
radians.map(|e| e * na::convert(180.0) / N::pi())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise conversion fro degrees to radians.
|
/// Component-wise conversion fro degrees to radians.
|
||||||
pub fn radians<N: RealField, D: Dimension>(degrees: &TVec<N, D>) -> TVec<N, D>
|
pub fn radians<T: RealField, const D: usize>(degrees: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
degrees.map(|e| e * T::pi() / na::convert(180.0))
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
degrees.map(|e| e * N::pi() / na::convert(180.0))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise sinus.
|
/// Component-wise sinus.
|
||||||
pub fn sin<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
|
pub fn sin<T: RealField, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
angle.map(|e| e.sin())
|
angle.map(|e| e.sin())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise hyperbolic sinus.
|
/// Component-wise hyperbolic sinus.
|
||||||
pub fn sinh<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
|
pub fn sinh<T: RealField, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
angle.map(|e| e.sinh())
|
angle.map(|e| e.sinh())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise tangent.
|
/// Component-wise tangent.
|
||||||
pub fn tan<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
|
pub fn tan<T: RealField, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
angle.map(|e| e.tan())
|
angle.map(|e| e.tan())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise hyperbolic tangent.
|
/// Component-wise hyperbolic tangent.
|
||||||
pub fn tanh<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
|
pub fn tanh<T: RealField, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
angle.map(|e| e.tanh())
|
angle.map(|e| e.tanh())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
use na::DefaultAllocator;
|
|
||||||
|
|
||||||
use crate::aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
use crate::traits::{Alloc, Dimension, Number};
|
use crate::traits::Number;
|
||||||
|
|
||||||
/// Checks that all the vector components are `true`.
|
/// Checks that all the vector components are `true`.
|
||||||
///
|
///
|
||||||
|
@ -20,10 +18,7 @@ use crate::traits::{Alloc, Dimension, Number};
|
||||||
///
|
///
|
||||||
/// * [`any`](fn.any.html)
|
/// * [`any`](fn.any.html)
|
||||||
/// * [`not`](fn.not.html)
|
/// * [`not`](fn.not.html)
|
||||||
pub fn all<D: Dimension>(v: &TVec<bool, D>) -> bool
|
pub fn all<const D: usize>(v: &TVec<bool, D>) -> bool {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<bool, D>,
|
|
||||||
{
|
|
||||||
v.iter().all(|x| *x)
|
v.iter().all(|x| *x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,10 +42,7 @@ where
|
||||||
///
|
///
|
||||||
/// * [`all`](fn.all.html)
|
/// * [`all`](fn.all.html)
|
||||||
/// * [`not`](fn.not.html)
|
/// * [`not`](fn.not.html)
|
||||||
pub fn any<D: Dimension>(v: &TVec<bool, D>) -> bool
|
pub fn any<const D: usize>(v: &TVec<bool, D>) -> bool {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<bool, D>,
|
|
||||||
{
|
|
||||||
v.iter().any(|x| *x)
|
v.iter().any(|x| *x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,10 +65,7 @@ where
|
||||||
/// * [`less_than_equal`](fn.less_than_equal.html)
|
/// * [`less_than_equal`](fn.less_than_equal.html)
|
||||||
/// * [`not`](fn.not.html)
|
/// * [`not`](fn.not.html)
|
||||||
/// * [`not_equal`](fn.not_equal.html)
|
/// * [`not_equal`](fn.not_equal.html)
|
||||||
pub fn equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
|
pub fn equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.zip_map(y, |x, y| x == y)
|
x.zip_map(y, |x, y| x == y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,10 +88,7 @@ where
|
||||||
/// * [`less_than_equal`](fn.less_than_equal.html)
|
/// * [`less_than_equal`](fn.less_than_equal.html)
|
||||||
/// * [`not`](fn.not.html)
|
/// * [`not`](fn.not.html)
|
||||||
/// * [`not_equal`](fn.not_equal.html)
|
/// * [`not_equal`](fn.not_equal.html)
|
||||||
pub fn greater_than<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
|
pub fn greater_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.zip_map(y, |x, y| x > y)
|
x.zip_map(y, |x, y| x > y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,10 +111,10 @@ where
|
||||||
/// * [`less_than_equal`](fn.less_than_equal.html)
|
/// * [`less_than_equal`](fn.less_than_equal.html)
|
||||||
/// * [`not`](fn.not.html)
|
/// * [`not`](fn.not.html)
|
||||||
/// * [`not_equal`](fn.not_equal.html)
|
/// * [`not_equal`](fn.not_equal.html)
|
||||||
pub fn greater_than_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
|
pub fn greater_than_equal<T: Number, const D: usize>(
|
||||||
where
|
x: &TVec<T, D>,
|
||||||
DefaultAllocator: Alloc<N, D>,
|
y: &TVec<T, D>,
|
||||||
{
|
) -> TVec<bool, D> {
|
||||||
x.zip_map(y, |x, y| x >= y)
|
x.zip_map(y, |x, y| x >= y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,10 +137,7 @@ where
|
||||||
/// * [`less_than_equal`](fn.less_than_equal.html)
|
/// * [`less_than_equal`](fn.less_than_equal.html)
|
||||||
/// * [`not`](fn.not.html)
|
/// * [`not`](fn.not.html)
|
||||||
/// * [`not_equal`](fn.not_equal.html)
|
/// * [`not_equal`](fn.not_equal.html)
|
||||||
pub fn less_than<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
|
pub fn less_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.zip_map(y, |x, y| x < y)
|
x.zip_map(y, |x, y| x < y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,10 +160,7 @@ where
|
||||||
/// * [`less_than`](fn.less_than.html)
|
/// * [`less_than`](fn.less_than.html)
|
||||||
/// * [`not`](fn.not.html)
|
/// * [`not`](fn.not.html)
|
||||||
/// * [`not_equal`](fn.not_equal.html)
|
/// * [`not_equal`](fn.not_equal.html)
|
||||||
pub fn less_than_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
|
pub fn less_than_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.zip_map(y, |x, y| x <= y)
|
x.zip_map(y, |x, y| x <= y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,10 +184,7 @@ where
|
||||||
/// * [`less_than`](fn.less_than.html)
|
/// * [`less_than`](fn.less_than.html)
|
||||||
/// * [`less_than_equal`](fn.less_than_equal.html)
|
/// * [`less_than_equal`](fn.less_than_equal.html)
|
||||||
/// * [`not_equal`](fn.not_equal.html)
|
/// * [`not_equal`](fn.not_equal.html)
|
||||||
pub fn not<D: Dimension>(v: &TVec<bool, D>) -> TVec<bool, D>
|
pub fn not<const D: usize>(v: &TVec<bool, D>) -> TVec<bool, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<bool, D>,
|
|
||||||
{
|
|
||||||
v.map(|x| !x)
|
v.map(|x| !x)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,9 +207,6 @@ where
|
||||||
/// * [`less_than`](fn.less_than.html)
|
/// * [`less_than`](fn.less_than.html)
|
||||||
/// * [`less_than_equal`](fn.less_than_equal.html)
|
/// * [`less_than_equal`](fn.less_than_equal.html)
|
||||||
/// * [`not`](fn.not.html)
|
/// * [`not`](fn.not.html)
|
||||||
pub fn not_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D>
|
pub fn not_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
|
||||||
where
|
|
||||||
DefaultAllocator: Alloc<N, D>,
|
|
||||||
{
|
|
||||||
x.zip_map(y, |x, y| x != y)
|
x.zip_map(y, |x, y| x != y)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "nalgebra-lapack"
|
name = "nalgebra-lapack"
|
||||||
version = "0.16.0"
|
version = "0.17.0"
|
||||||
authors = [ "Sébastien Crozet <developer@crozet.re>", "Andrew Straw <strawman@astraw.com>" ]
|
authors = [ "Sébastien Crozet <developer@crozet.re>", "Andrew Straw <strawman@astraw.com>" ]
|
||||||
|
|
||||||
description = "Matrix decompositions using nalgebra matrices and Lapack bindings."
|
description = "Matrix decompositions using nalgebra matrices and Lapack bindings."
|
||||||
|
@ -17,7 +17,7 @@ edition = "2018"
|
||||||
maintenance = { status = "actively-developed" }
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
serde-serialize = [ "serde", "serde_derive" ]
|
serde-serialize = [ "serde", "nalgebra/serde-serialize" ]
|
||||||
proptest-support = [ "nalgebra/proptest-support" ]
|
proptest-support = [ "nalgebra/proptest-support" ]
|
||||||
arbitrary = [ "nalgebra/arbitrary" ]
|
arbitrary = [ "nalgebra/arbitrary" ]
|
||||||
|
|
||||||
|
@ -29,18 +29,17 @@ accelerate = ["lapack-src/accelerate"]
|
||||||
intel-mkl = ["lapack-src/intel-mkl"]
|
intel-mkl = ["lapack-src/intel-mkl"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nalgebra = { version = "0.25", path = ".." }
|
nalgebra = { version = "0.26", path = ".." }
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
num-complex = { version = "0.3", default-features = false }
|
num-complex = { version = "0.3", default-features = false }
|
||||||
simba = "0.4"
|
simba = "0.4"
|
||||||
serde = { version = "1.0", optional = true }
|
serde = { version = "1.0", features = [ "derive" ], optional = true }
|
||||||
serde_derive = { version = "1.0", optional = true }
|
|
||||||
lapack = { version = "0.17", default-features = false }
|
lapack = { version = "0.17", default-features = false }
|
||||||
lapack-src = { version = "0.6", default-features = false }
|
lapack-src = { version = "0.6", default-features = false }
|
||||||
# clippy = "*"
|
# clippy = "*"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
nalgebra = { version = "0.25", features = [ "arbitrary" ], path = ".." }
|
nalgebra = { version = "0.26", features = [ "arbitrary", "rand" ], path = ".." }
|
||||||
proptest = { version = "1", default-features = false, features = ["std"] }
|
proptest = { version = "1", default-features = false, features = ["std"] }
|
||||||
quickcheck = "1"
|
quickcheck = "1"
|
||||||
approx = "0.4"
|
approx = "0.4"
|
||||||
|
|
|
@ -5,17 +5,17 @@ use test::{self, Bencher};
|
||||||
#[bench]
|
#[bench]
|
||||||
fn hessenberg_decompose_100x100(bh: &mut Bencher) {
|
fn hessenberg_decompose_100x100(bh: &mut Bencher) {
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
bh.iter(|| test::black_box(Hessenberg::new(m.clone())))
|
bh.iter(|| std::hint::black_box(Hessenberg::new(m.clone())))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn hessenberg_decompose_4x4(bh: &mut Bencher) {
|
fn hessenberg_decompose_4x4(bh: &mut Bencher) {
|
||||||
let m = Matrix4::<f64>::new_random();
|
let m = Matrix4::<f64>::new_random();
|
||||||
bh.iter(|| test::black_box(Hessenberg::new(m.clone())))
|
bh.iter(|| std::hint::black_box(Hessenberg::new(m.clone())))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn hessenberg_decompose_500x500(bh: &mut Bencher) {
|
fn hessenberg_decompose_500x500(bh: &mut Bencher) {
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
bh.iter(|| test::black_box(Hessenberg::new(m.clone())))
|
bh.iter(|| std::hint::black_box(Hessenberg::new(m.clone())))
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,29 +5,29 @@ use test::{self, Bencher};
|
||||||
#[bench]
|
#[bench]
|
||||||
fn lu_decompose_100x100(bh: &mut Bencher) {
|
fn lu_decompose_100x100(bh: &mut Bencher) {
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
bh.iter(|| test::black_box(LU::new(m.clone())))
|
bh.iter(|| std::hint::black_box(LU::new(m.clone())))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn lu_decompose_100x500(bh: &mut Bencher) {
|
fn lu_decompose_100x500(bh: &mut Bencher) {
|
||||||
let m = DMatrix::<f64>::new_random(100, 500);
|
let m = DMatrix::<f64>::new_random(100, 500);
|
||||||
bh.iter(|| test::black_box(LU::new(m.clone())))
|
bh.iter(|| std::hint::black_box(LU::new(m.clone())))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn lu_decompose_4x4(bh: &mut Bencher) {
|
fn lu_decompose_4x4(bh: &mut Bencher) {
|
||||||
let m = Matrix4::<f64>::new_random();
|
let m = Matrix4::<f64>::new_random();
|
||||||
bh.iter(|| test::black_box(LU::new(m.clone())))
|
bh.iter(|| std::hint::black_box(LU::new(m.clone())))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn lu_decompose_500x100(bh: &mut Bencher) {
|
fn lu_decompose_500x100(bh: &mut Bencher) {
|
||||||
let m = DMatrix::<f64>::new_random(500, 100);
|
let m = DMatrix::<f64>::new_random(500, 100);
|
||||||
bh.iter(|| test::black_box(LU::new(m.clone())))
|
bh.iter(|| std::hint::black_box(LU::new(m.clone())))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn lu_decompose_500x500(bh: &mut Bencher) {
|
fn lu_decompose_500x500(bh: &mut Bencher) {
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
bh.iter(|| test::black_box(LU::new(m.clone())))
|
bh.iter(|| std::hint::black_box(LU::new(m.clone())))
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,29 +5,29 @@ use test::{self, Bencher};
|
||||||
#[bench]
|
#[bench]
|
||||||
fn qr_decompose_100x100(bh: &mut Bencher) {
|
fn qr_decompose_100x100(bh: &mut Bencher) {
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
bh.iter(|| test::black_box(QR::new(m.clone())))
|
bh.iter(|| std::hint::black_box(QR::new(m.clone())))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn qr_decompose_100x500(bh: &mut Bencher) {
|
fn qr_decompose_100x500(bh: &mut Bencher) {
|
||||||
let m = DMatrix::<f64>::new_random(100, 500);
|
let m = DMatrix::<f64>::new_random(100, 500);
|
||||||
bh.iter(|| test::black_box(QR::new(m.clone())))
|
bh.iter(|| std::hint::black_box(QR::new(m.clone())))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn qr_decompose_4x4(bh: &mut Bencher) {
|
fn qr_decompose_4x4(bh: &mut Bencher) {
|
||||||
let m = Matrix4::<f64>::new_random();
|
let m = Matrix4::<f64>::new_random();
|
||||||
bh.iter(|| test::black_box(QR::new(m.clone())))
|
bh.iter(|| std::hint::black_box(QR::new(m.clone())))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn qr_decompose_500x100(bh: &mut Bencher) {
|
fn qr_decompose_500x100(bh: &mut Bencher) {
|
||||||
let m = DMatrix::<f64>::new_random(500, 100);
|
let m = DMatrix::<f64>::new_random(500, 100);
|
||||||
bh.iter(|| test::black_box(QR::new(m.clone())))
|
bh.iter(|| std::hint::black_box(QR::new(m.clone())))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn qr_decompose_500x500(bh: &mut Bencher) {
|
fn qr_decompose_500x500(bh: &mut Bencher) {
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
bh.iter(|| test::black_box(QR::new(m.clone())))
|
bh.iter(|| std::hint::black_box(QR::new(m.clone())))
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use num_complex::Complex;
|
||||||
use na::allocator::Allocator;
|
use na::allocator::Allocator;
|
||||||
use na::dimension::Dim;
|
use na::dimension::Dim;
|
||||||
use na::storage::Storage;
|
use na::storage::Storage;
|
||||||
use na::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Scalar};
|
use na::{DefaultAllocator, Matrix, OMatrix, Scalar};
|
||||||
|
|
||||||
use lapack;
|
use lapack;
|
||||||
|
|
||||||
|
@ -15,39 +15,39 @@ use lapack;
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serde-serialize",
|
feature = "serde-serialize",
|
||||||
serde(bound(serialize = "DefaultAllocator: Allocator<N, D>,
|
serde(bound(serialize = "DefaultAllocator: Allocator<T, D>,
|
||||||
MatrixN<N, D>: Serialize"))
|
OMatrix<T, D, D>: Serialize"))
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serde-serialize",
|
feature = "serde-serialize",
|
||||||
serde(bound(deserialize = "DefaultAllocator: Allocator<N, D>,
|
serde(bound(deserialize = "DefaultAllocator: Allocator<T, D>,
|
||||||
MatrixN<N, D>: Deserialize<'de>"))
|
OMatrix<T, D, D>: Deserialize<'de>"))
|
||||||
)]
|
)]
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Cholesky<N: Scalar, D: Dim>
|
pub struct Cholesky<T: Scalar, D: Dim>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
DefaultAllocator: Allocator<T, D, D>,
|
||||||
{
|
{
|
||||||
l: MatrixN<N, D>,
|
l: OMatrix<T, D, D>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Copy, D: Dim> Copy for Cholesky<N, D>
|
impl<T: Scalar + Copy, D: Dim> Copy for Cholesky<T, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
DefaultAllocator: Allocator<T, D, D>,
|
||||||
MatrixN<N, D>: Copy,
|
OMatrix<T, D, D>: Copy,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: CholeskyScalar + Zero, D: Dim> Cholesky<N, D>
|
impl<T: CholeskyScalar + Zero, D: Dim> Cholesky<T, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
DefaultAllocator: Allocator<T, D, D>,
|
||||||
{
|
{
|
||||||
/// Computes the cholesky decomposition of the given symmetric-definite-positive square
|
/// Computes the cholesky decomposition of the given symmetric-definite-positive square
|
||||||
/// matrix.
|
/// matrix.
|
||||||
///
|
///
|
||||||
/// Only the lower-triangular part of the input matrix is considered.
|
/// Only the lower-triangular part of the input matrix is considered.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(mut m: MatrixN<N, D>) -> Option<Self> {
|
pub fn new(mut m: OMatrix<T, D, D>) -> Option<Self> {
|
||||||
// TODO: check symmetry as well?
|
// TODO: check symmetry as well?
|
||||||
assert!(
|
assert!(
|
||||||
m.is_square(),
|
m.is_square(),
|
||||||
|
@ -58,14 +58,14 @@ where
|
||||||
let dim = m.nrows() as i32;
|
let dim = m.nrows() as i32;
|
||||||
let mut info = 0;
|
let mut info = 0;
|
||||||
|
|
||||||
N::xpotrf(uplo, dim, m.as_mut_slice(), dim, &mut info);
|
T::xpotrf(uplo, dim, m.as_mut_slice(), dim, &mut info);
|
||||||
lapack_check!(info);
|
lapack_check!(info);
|
||||||
|
|
||||||
Some(Self { l: m })
|
Some(Self { l: m })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves the lower-triangular factor of the cholesky decomposition.
|
/// Retrieves the lower-triangular factor of the cholesky decomposition.
|
||||||
pub fn unpack(mut self) -> MatrixN<N, D> {
|
pub fn unpack(mut self) -> OMatrix<T, D, D> {
|
||||||
self.l.fill_upper_triangle(Zero::zero(), 1);
|
self.l.fill_upper_triangle(Zero::zero(), 1);
|
||||||
self.l
|
self.l
|
||||||
}
|
}
|
||||||
|
@ -75,12 +75,12 @@ where
|
||||||
///
|
///
|
||||||
/// This is an allocation-less version of `self.l()`. The values of the strict upper-triangular
|
/// This is an allocation-less version of `self.l()`. The values of the strict upper-triangular
|
||||||
/// part are garbage and should be ignored by further computations.
|
/// part are garbage and should be ignored by further computations.
|
||||||
pub fn unpack_dirty(self) -> MatrixN<N, D> {
|
pub fn unpack_dirty(self) -> OMatrix<T, D, D> {
|
||||||
self.l
|
self.l
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves the lower-triangular factor of the cholesky decomposition.
|
/// Retrieves the lower-triangular factor of the cholesky decomposition.
|
||||||
pub fn l(&self) -> MatrixN<N, D> {
|
pub fn l(&self) -> OMatrix<T, D, D> {
|
||||||
let mut res = self.l.clone();
|
let mut res = self.l.clone();
|
||||||
res.fill_upper_triangle(Zero::zero(), 1);
|
res.fill_upper_triangle(Zero::zero(), 1);
|
||||||
res
|
res
|
||||||
|
@ -91,7 +91,7 @@ where
|
||||||
///
|
///
|
||||||
/// This is an allocation-less version of `self.l()`. The values of the strict upper-triangular
|
/// This is an allocation-less version of `self.l()`. The values of the strict upper-triangular
|
||||||
/// part are garbage and should be ignored by further computations.
|
/// part are garbage and should be ignored by further computations.
|
||||||
pub fn l_dirty(&self) -> &MatrixN<N, D> {
|
pub fn l_dirty(&self) -> &OMatrix<T, D, D> {
|
||||||
&self.l
|
&self.l
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,11 +99,11 @@ where
|
||||||
/// unknown to be determined.
|
/// unknown to be determined.
|
||||||
pub fn solve<R2: Dim, C2: Dim, S2>(
|
pub fn solve<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
b: &Matrix<N, R2, C2, S2>,
|
b: &Matrix<T, R2, C2, S2>,
|
||||||
) -> Option<MatrixMN<N, R2, C2>>
|
) -> Option<OMatrix<T, R2, C2>>
|
||||||
where
|
where
|
||||||
S2: Storage<N, R2, C2>,
|
S2: Storage<T, R2, C2>,
|
||||||
DefaultAllocator: Allocator<N, R2, C2>,
|
DefaultAllocator: Allocator<T, R2, C2>,
|
||||||
{
|
{
|
||||||
let mut res = b.clone_owned();
|
let mut res = b.clone_owned();
|
||||||
if self.solve_mut(&mut res) {
|
if self.solve_mut(&mut res) {
|
||||||
|
@ -115,9 +115,9 @@ where
|
||||||
|
|
||||||
/// Solves in-place the symmetric-definite-positive linear system `self * x = b`, where `x` is
|
/// Solves in-place the symmetric-definite-positive linear system `self * x = b`, where `x` is
|
||||||
/// the unknown to be determined.
|
/// the unknown to be determined.
|
||||||
pub fn solve_mut<R2: Dim, C2: Dim>(&self, b: &mut MatrixMN<N, R2, C2>) -> bool
|
pub fn solve_mut<R2: Dim, C2: Dim>(&self, b: &mut OMatrix<T, R2, C2>) -> bool
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, R2, C2>,
|
DefaultAllocator: Allocator<T, R2, C2>,
|
||||||
{
|
{
|
||||||
let dim = self.l.nrows();
|
let dim = self.l.nrows();
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ where
|
||||||
let ldb = dim as i32;
|
let ldb = dim as i32;
|
||||||
let mut info = 0;
|
let mut info = 0;
|
||||||
|
|
||||||
N::xpotrs(
|
T::xpotrs(
|
||||||
b'L',
|
b'L',
|
||||||
dim as i32,
|
dim as i32,
|
||||||
nrhs,
|
nrhs,
|
||||||
|
@ -145,11 +145,11 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the inverse of the decomposed matrix.
|
/// Computes the inverse of the decomposed matrix.
|
||||||
pub fn inverse(mut self) -> Option<MatrixN<N, D>> {
|
pub fn inverse(mut self) -> Option<OMatrix<T, D, D>> {
|
||||||
let dim = self.l.nrows();
|
let dim = self.l.nrows();
|
||||||
let mut info = 0;
|
let mut info = 0;
|
||||||
|
|
||||||
N::xpotri(
|
T::xpotri(
|
||||||
b'L',
|
b'L',
|
||||||
dim as i32,
|
dim as i32,
|
||||||
self.l.as_mut_slice(),
|
self.l.as_mut_slice(),
|
||||||
|
|
|
@ -8,9 +8,9 @@ use simba::scalar::RealField;
|
||||||
|
|
||||||
use crate::ComplexHelper;
|
use crate::ComplexHelper;
|
||||||
use na::allocator::Allocator;
|
use na::allocator::Allocator;
|
||||||
use na::dimension::{Dim, U1};
|
use na::dimension::{Const, Dim};
|
||||||
use na::storage::Storage;
|
use na::storage::Storage;
|
||||||
use na::{DefaultAllocator, Matrix, MatrixN, Scalar, VectorN};
|
use na::{DefaultAllocator, Matrix, OMatrix, OVector, Scalar};
|
||||||
|
|
||||||
use lapack;
|
use lapack;
|
||||||
|
|
||||||
|
@ -19,74 +19,74 @@ use lapack;
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serde-serialize",
|
feature = "serde-serialize",
|
||||||
serde(
|
serde(
|
||||||
bound(serialize = "DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
|
bound(serialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
|
||||||
VectorN<N, D>: Serialize,
|
OVector<T, D>: Serialize,
|
||||||
MatrixN<N, D>: Serialize")
|
OMatrix<T, D, D>: Serialize")
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serde-serialize",
|
feature = "serde-serialize",
|
||||||
serde(
|
serde(
|
||||||
bound(deserialize = "DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
|
bound(deserialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
|
||||||
VectorN<N, D>: Serialize,
|
OVector<T, D>: Serialize,
|
||||||
MatrixN<N, D>: Deserialize<'de>")
|
OMatrix<T, D, D>: Deserialize<'de>")
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Eigen<N: Scalar, D: Dim>
|
pub struct Eigen<T: Scalar, D: Dim>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N, D, D>,
|
DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
|
||||||
{
|
{
|
||||||
/// The eigenvalues of the decomposed matrix.
|
/// The eigenvalues of the decomposed matrix.
|
||||||
pub eigenvalues: VectorN<N, D>,
|
pub eigenvalues: OVector<T, D>,
|
||||||
/// The (right) eigenvectors of the decomposed matrix.
|
/// The (right) eigenvectors of the decomposed matrix.
|
||||||
pub eigenvectors: Option<MatrixN<N, D>>,
|
pub eigenvectors: Option<OMatrix<T, D, D>>,
|
||||||
/// The left eigenvectors of the decomposed matrix.
|
/// The left eigenvectors of the decomposed matrix.
|
||||||
pub left_eigenvectors: Option<MatrixN<N, D>>,
|
pub left_eigenvectors: Option<OMatrix<T, D, D>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Copy, D: Dim> Copy for Eigen<N, D>
|
impl<T: Scalar + Copy, D: Dim> Copy for Eigen<T, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N, D, D>,
|
DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
|
||||||
VectorN<N, D>: Copy,
|
OVector<T, D>: Copy,
|
||||||
MatrixN<N, D>: Copy,
|
OMatrix<T, D, D>: Copy,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: EigenScalar + RealField, D: Dim> Eigen<N, D>
|
impl<T: EigenScalar + RealField, D: Dim> Eigen<T, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
|
DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
|
||||||
{
|
{
|
||||||
/// Computes the eigenvalues and eigenvectors of the square matrix `m`.
|
/// Computes the eigenvalues and eigenvectors of the square matrix `m`.
|
||||||
///
|
///
|
||||||
/// If `eigenvectors` is `false` then, the eigenvectors are not computed explicitly.
|
/// If `eigenvectors` is `false` then, the eigenvectors are not computed explicitly.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
mut m: MatrixN<N, D>,
|
mut m: OMatrix<T, D, D>,
|
||||||
left_eigenvectors: bool,
|
left_eigenvectors: bool,
|
||||||
eigenvectors: bool,
|
eigenvectors: bool,
|
||||||
) -> Option<Eigen<N, D>> {
|
) -> Option<Eigen<T, D>> {
|
||||||
assert!(
|
assert!(
|
||||||
m.is_square(),
|
m.is_square(),
|
||||||
"Unable to compute the eigenvalue decomposition of a non-square matrix."
|
"Unable to compute the eigenvalue decomposition of a non-square matrix."
|
||||||
);
|
);
|
||||||
|
|
||||||
let ljob = if left_eigenvectors { b'V' } else { b'N' };
|
let ljob = if left_eigenvectors { b'V' } else { b'T' };
|
||||||
let rjob = if eigenvectors { b'V' } else { b'N' };
|
let rjob = if eigenvectors { b'V' } else { b'T' };
|
||||||
|
|
||||||
let (nrows, ncols) = m.data.shape();
|
let (nrows, ncols) = m.data.shape();
|
||||||
let n = nrows.value();
|
let n = nrows.value();
|
||||||
|
|
||||||
let lda = n as i32;
|
let lda = n as i32;
|
||||||
|
|
||||||
let mut wr = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() };
|
let mut wr = unsafe { Matrix::new_uninitialized_generic(nrows, Const::<1>).assume_init() };
|
||||||
// TODO: Tap into the workspace.
|
// TODO: Tap into the workspace.
|
||||||
let mut wi = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() };
|
let mut wi = unsafe { Matrix::new_uninitialized_generic(nrows, Const::<1>).assume_init() };
|
||||||
|
|
||||||
let mut info = 0;
|
let mut info = 0;
|
||||||
let mut placeholder1 = [N::zero()];
|
let mut placeholder1 = [T::zero()];
|
||||||
let mut placeholder2 = [N::zero()];
|
let mut placeholder2 = [T::zero()];
|
||||||
|
|
||||||
let lwork = N::xgeev_work_size(
|
let lwork = T::xgeev_work_size(
|
||||||
ljob,
|
ljob,
|
||||||
rjob,
|
rjob,
|
||||||
n as i32,
|
n as i32,
|
||||||
|
@ -112,7 +112,7 @@ where
|
||||||
let mut vr =
|
let mut vr =
|
||||||
unsafe { Matrix::new_uninitialized_generic(nrows, ncols).assume_init() };
|
unsafe { Matrix::new_uninitialized_generic(nrows, ncols).assume_init() };
|
||||||
|
|
||||||
N::xgeev(
|
T::xgeev(
|
||||||
ljob,
|
ljob,
|
||||||
rjob,
|
rjob,
|
||||||
n as i32,
|
n as i32,
|
||||||
|
@ -142,7 +142,7 @@ where
|
||||||
let mut vl =
|
let mut vl =
|
||||||
unsafe { Matrix::new_uninitialized_generic(nrows, ncols).assume_init() };
|
unsafe { Matrix::new_uninitialized_generic(nrows, ncols).assume_init() };
|
||||||
|
|
||||||
N::xgeev(
|
T::xgeev(
|
||||||
ljob,
|
ljob,
|
||||||
rjob,
|
rjob,
|
||||||
n as i32,
|
n as i32,
|
||||||
|
@ -172,7 +172,7 @@ where
|
||||||
let mut vr =
|
let mut vr =
|
||||||
unsafe { Matrix::new_uninitialized_generic(nrows, ncols).assume_init() };
|
unsafe { Matrix::new_uninitialized_generic(nrows, ncols).assume_init() };
|
||||||
|
|
||||||
N::xgeev(
|
T::xgeev(
|
||||||
ljob,
|
ljob,
|
||||||
rjob,
|
rjob,
|
||||||
n as i32,
|
n as i32,
|
||||||
|
@ -199,7 +199,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(false, false) => {
|
(false, false) => {
|
||||||
N::xgeev(
|
T::xgeev(
|
||||||
ljob,
|
ljob,
|
||||||
rjob,
|
rjob,
|
||||||
n as i32,
|
n as i32,
|
||||||
|
@ -233,9 +233,9 @@ where
|
||||||
/// The complex eigenvalues of the given matrix.
|
/// The complex eigenvalues of the given matrix.
|
||||||
///
|
///
|
||||||
/// Panics if the eigenvalue computation does not converge.
|
/// Panics if the eigenvalue computation does not converge.
|
||||||
pub fn complex_eigenvalues(mut m: MatrixN<N, D>) -> VectorN<Complex<N>, D>
|
pub fn complex_eigenvalues(mut m: OMatrix<T, D, D>) -> OVector<Complex<T>, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<Complex<N>, D>,
|
DefaultAllocator: Allocator<Complex<T>, D>,
|
||||||
{
|
{
|
||||||
assert!(
|
assert!(
|
||||||
m.is_square(),
|
m.is_square(),
|
||||||
|
@ -247,16 +247,16 @@ where
|
||||||
|
|
||||||
let lda = n as i32;
|
let lda = n as i32;
|
||||||
|
|
||||||
let mut wr = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() };
|
let mut wr = unsafe { Matrix::new_uninitialized_generic(nrows, Const::<1>).assume_init() };
|
||||||
let mut wi = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() };
|
let mut wi = unsafe { Matrix::new_uninitialized_generic(nrows, Const::<1>).assume_init() };
|
||||||
|
|
||||||
let mut info = 0;
|
let mut info = 0;
|
||||||
let mut placeholder1 = [N::zero()];
|
let mut placeholder1 = [T::zero()];
|
||||||
let mut placeholder2 = [N::zero()];
|
let mut placeholder2 = [T::zero()];
|
||||||
|
|
||||||
let lwork = N::xgeev_work_size(
|
let lwork = T::xgeev_work_size(
|
||||||
b'N',
|
b'T',
|
||||||
b'N',
|
b'T',
|
||||||
n as i32,
|
n as i32,
|
||||||
m.as_mut_slice(),
|
m.as_mut_slice(),
|
||||||
lda,
|
lda,
|
||||||
|
@ -273,9 +273,9 @@ where
|
||||||
|
|
||||||
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
|
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
|
||||||
|
|
||||||
N::xgeev(
|
T::xgeev(
|
||||||
b'N',
|
b'T',
|
||||||
b'N',
|
b'T',
|
||||||
n as i32,
|
n as i32,
|
||||||
m.as_mut_slice(),
|
m.as_mut_slice(),
|
||||||
lda,
|
lda,
|
||||||
|
@ -291,7 +291,7 @@ where
|
||||||
);
|
);
|
||||||
lapack_panic!(info);
|
lapack_panic!(info);
|
||||||
|
|
||||||
let mut res = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() };
|
let mut res = unsafe { Matrix::new_uninitialized_generic(nrows, Const::<1>).assume_init() };
|
||||||
|
|
||||||
for i in 0..res.len() {
|
for i in 0..res.len() {
|
||||||
res[i] = Complex::new(wr[i], wi[i]);
|
res[i] = Complex::new(wr[i], wi[i]);
|
||||||
|
@ -302,8 +302,8 @@ where
|
||||||
|
|
||||||
/// The determinant of the decomposed matrix.
|
/// The determinant of the decomposed matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn determinant(&self) -> N {
|
pub fn determinant(&self) -> T {
|
||||||
let mut det = N::one();
|
let mut det = T::one();
|
||||||
for e in self.eigenvalues.iter() {
|
for e in self.eigenvalues.iter() {
|
||||||
det *= *e;
|
det *= *e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,9 @@ use num_complex::Complex;
|
||||||
|
|
||||||
use crate::ComplexHelper;
|
use crate::ComplexHelper;
|
||||||
use na::allocator::Allocator;
|
use na::allocator::Allocator;
|
||||||
use na::dimension::{DimDiff, DimSub, U1};
|
use na::dimension::{Const, DimDiff, DimSub, U1};
|
||||||
use na::storage::Storage;
|
use na::storage::Storage;
|
||||||
use na::{DefaultAllocator, Matrix, MatrixN, Scalar, VectorN};
|
use na::{DefaultAllocator, Matrix, OMatrix, OVector, Scalar};
|
||||||
|
|
||||||
use lapack;
|
use lapack;
|
||||||
|
|
||||||
|
@ -13,41 +13,41 @@ use lapack;
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serde-serialize",
|
feature = "serde-serialize",
|
||||||
serde(bound(serialize = "DefaultAllocator: Allocator<N, D, D> +
|
serde(bound(serialize = "DefaultAllocator: Allocator<T, D, D> +
|
||||||
Allocator<N, DimDiff<D, U1>>,
|
Allocator<T, DimDiff<D, U1>>,
|
||||||
MatrixN<N, D>: Serialize,
|
OMatrix<T, D, D>: Serialize,
|
||||||
VectorN<N, DimDiff<D, U1>>: Serialize"))
|
OVector<T, DimDiff<D, U1>>: Serialize"))
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serde-serialize",
|
feature = "serde-serialize",
|
||||||
serde(bound(deserialize = "DefaultAllocator: Allocator<N, D, D> +
|
serde(bound(deserialize = "DefaultAllocator: Allocator<T, D, D> +
|
||||||
Allocator<N, DimDiff<D, U1>>,
|
Allocator<T, DimDiff<D, U1>>,
|
||||||
MatrixN<N, D>: Deserialize<'de>,
|
OMatrix<T, D, D>: Deserialize<'de>,
|
||||||
VectorN<N, DimDiff<D, U1>>: Deserialize<'de>"))
|
OVector<T, DimDiff<D, U1>>: Deserialize<'de>"))
|
||||||
)]
|
)]
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Hessenberg<N: Scalar, D: DimSub<U1>>
|
pub struct Hessenberg<T: Scalar, D: DimSub<U1>>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimDiff<D, U1>>,
|
DefaultAllocator: Allocator<T, D, D> + Allocator<T, DimDiff<D, U1>>,
|
||||||
{
|
{
|
||||||
h: MatrixN<N, D>,
|
h: OMatrix<T, D, D>,
|
||||||
tau: VectorN<N, DimDiff<D, U1>>,
|
tau: OVector<T, DimDiff<D, U1>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Copy, D: DimSub<U1>> Copy for Hessenberg<N, D>
|
impl<T: Scalar + Copy, D: DimSub<U1>> Copy for Hessenberg<T, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimDiff<D, U1>>,
|
DefaultAllocator: Allocator<T, D, D> + Allocator<T, DimDiff<D, U1>>,
|
||||||
MatrixN<N, D>: Copy,
|
OMatrix<T, D, D>: Copy,
|
||||||
VectorN<N, DimDiff<D, U1>>: Copy,
|
OVector<T, DimDiff<D, U1>>: Copy,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: HessenbergScalar + Zero, D: DimSub<U1>> Hessenberg<N, D>
|
impl<T: HessenbergScalar + Zero, D: DimSub<U1>> Hessenberg<T, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimDiff<D, U1>>,
|
DefaultAllocator: Allocator<T, D, D> + Allocator<T, DimDiff<D, U1>>,
|
||||||
{
|
{
|
||||||
/// Computes the hessenberg decomposition of the matrix `m`.
|
/// Computes the hessenberg decomposition of the matrix `m`.
|
||||||
pub fn new(mut m: MatrixN<N, D>) -> Self {
|
pub fn new(mut m: OMatrix<T, D, D>) -> Self {
|
||||||
let nrows = m.data.shape().0;
|
let nrows = m.data.shape().0;
|
||||||
let n = nrows.value() as i32;
|
let n = nrows.value() as i32;
|
||||||
|
|
||||||
|
@ -60,16 +60,18 @@ where
|
||||||
"Unable to compute the hessenberg decomposition of an empty matrix."
|
"Unable to compute the hessenberg decomposition of an empty matrix."
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut tau = unsafe { Matrix::new_uninitialized_generic(nrows.sub(U1), U1).assume_init() };
|
let mut tau = unsafe {
|
||||||
|
Matrix::new_uninitialized_generic(nrows.sub(Const::<1>), Const::<1>).assume_init()
|
||||||
|
};
|
||||||
|
|
||||||
let mut info = 0;
|
let mut info = 0;
|
||||||
let lwork =
|
let lwork =
|
||||||
N::xgehrd_work_size(n, 1, n, m.as_mut_slice(), n, tau.as_mut_slice(), &mut info);
|
T::xgehrd_work_size(n, 1, n, m.as_mut_slice(), n, tau.as_mut_slice(), &mut info);
|
||||||
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
|
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
|
||||||
|
|
||||||
lapack_panic!(info);
|
lapack_panic!(info);
|
||||||
|
|
||||||
N::xgehrd(
|
T::xgehrd(
|
||||||
n,
|
n,
|
||||||
1,
|
1,
|
||||||
n,
|
n,
|
||||||
|
@ -87,36 +89,36 @@ where
|
||||||
|
|
||||||
/// Computes the hessenberg matrix of this decomposition.
|
/// Computes the hessenberg matrix of this decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn h(&self) -> MatrixN<N, D> {
|
pub fn h(&self) -> OMatrix<T, D, D> {
|
||||||
let mut h = self.h.clone_owned();
|
let mut h = self.h.clone_owned();
|
||||||
h.fill_lower_triangle(N::zero(), 2);
|
h.fill_lower_triangle(T::zero(), 2);
|
||||||
|
|
||||||
h
|
h
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: HessenbergReal + Zero, D: DimSub<U1>> Hessenberg<N, D>
|
impl<T: HessenbergReal + Zero, D: DimSub<U1>> Hessenberg<T, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimDiff<D, U1>>,
|
DefaultAllocator: Allocator<T, D, D> + Allocator<T, DimDiff<D, U1>>,
|
||||||
{
|
{
|
||||||
/// Computes the matrices `(Q, H)` of this decomposition.
|
/// Computes the matrices `(Q, H)` of this decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn unpack(self) -> (MatrixN<N, D>, MatrixN<N, D>) {
|
pub fn unpack(self) -> (OMatrix<T, D, D>, OMatrix<T, D, D>) {
|
||||||
(self.q(), self.h())
|
(self.q(), self.h())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the unitary matrix `Q` of this decomposition.
|
/// Computes the unitary matrix `Q` of this decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn q(&self) -> MatrixN<N, D> {
|
pub fn q(&self) -> OMatrix<T, D, D> {
|
||||||
let n = self.h.nrows() as i32;
|
let n = self.h.nrows() as i32;
|
||||||
let mut q = self.h.clone_owned();
|
let mut q = self.h.clone_owned();
|
||||||
let mut info = 0;
|
let mut info = 0;
|
||||||
|
|
||||||
let lwork =
|
let lwork =
|
||||||
N::xorghr_work_size(n, 1, n, q.as_mut_slice(), n, self.tau.as_slice(), &mut info);
|
T::xorghr_work_size(n, 1, n, q.as_mut_slice(), n, self.tau.as_slice(), &mut info);
|
||||||
let mut work = vec![N::zero(); lwork as usize];
|
let mut work = vec![T::zero(); lwork as usize];
|
||||||
|
|
||||||
N::xorghr(
|
T::xorghr(
|
||||||
n,
|
n,
|
||||||
1,
|
1,
|
||||||
n,
|
n,
|
||||||
|
|
|
@ -3,9 +3,9 @@ use num_complex::Complex;
|
||||||
|
|
||||||
use crate::ComplexHelper;
|
use crate::ComplexHelper;
|
||||||
use na::allocator::Allocator;
|
use na::allocator::Allocator;
|
||||||
use na::dimension::{Dim, DimMin, DimMinimum, U1};
|
use na::dimension::{Const, Dim, DimMin, DimMinimum};
|
||||||
use na::storage::Storage;
|
use na::storage::Storage;
|
||||||
use na::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Scalar, VectorN};
|
use na::{DefaultAllocator, Matrix, OMatrix, OVector, Scalar};
|
||||||
|
|
||||||
use lapack;
|
use lapack;
|
||||||
|
|
||||||
|
@ -20,57 +20,57 @@ use lapack;
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serde-serialize",
|
feature = "serde-serialize",
|
||||||
serde(bound(serialize = "DefaultAllocator: Allocator<N, R, C> +
|
serde(bound(serialize = "DefaultAllocator: Allocator<T, R, C> +
|
||||||
Allocator<i32, DimMinimum<R, C>>,
|
Allocator<i32, DimMinimum<R, C>>,
|
||||||
MatrixMN<N, R, C>: Serialize,
|
OMatrix<T, R, C>: Serialize,
|
||||||
PermutationSequence<DimMinimum<R, C>>: Serialize"))
|
PermutationSequence<DimMinimum<R, C>>: Serialize"))
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serde-serialize",
|
feature = "serde-serialize",
|
||||||
serde(bound(deserialize = "DefaultAllocator: Allocator<N, R, C> +
|
serde(bound(deserialize = "DefaultAllocator: Allocator<T, R, C> +
|
||||||
Allocator<i32, DimMinimum<R, C>>,
|
Allocator<i32, DimMinimum<R, C>>,
|
||||||
MatrixMN<N, R, C>: Deserialize<'de>,
|
OMatrix<T, R, C>: Deserialize<'de>,
|
||||||
PermutationSequence<DimMinimum<R, C>>: Deserialize<'de>"))
|
PermutationSequence<DimMinimum<R, C>>: Deserialize<'de>"))
|
||||||
)]
|
)]
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct LU<N: Scalar, R: DimMin<C>, C: Dim>
|
pub struct LU<T: Scalar, R: DimMin<C>, C: Dim>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<i32, DimMinimum<R, C>> + Allocator<N, R, C>,
|
DefaultAllocator: Allocator<i32, DimMinimum<R, C>> + Allocator<T, R, C>,
|
||||||
{
|
{
|
||||||
lu: MatrixMN<N, R, C>,
|
lu: OMatrix<T, R, C>,
|
||||||
p: VectorN<i32, DimMinimum<R, C>>,
|
p: OVector<i32, DimMinimum<R, C>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Copy, R: DimMin<C>, C: Dim> Copy for LU<N, R, C>
|
impl<T: Scalar + Copy, R: DimMin<C>, C: Dim> Copy for LU<T, R, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, R, C> + Allocator<i32, DimMinimum<R, C>>,
|
DefaultAllocator: Allocator<T, R, C> + Allocator<i32, DimMinimum<R, C>>,
|
||||||
MatrixMN<N, R, C>: Copy,
|
OMatrix<T, R, C>: Copy,
|
||||||
VectorN<i32, DimMinimum<R, C>>: Copy,
|
OVector<i32, DimMinimum<R, C>>: Copy,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: LUScalar, R: Dim, C: Dim> LU<N, R, C>
|
impl<T: LUScalar, R: Dim, C: Dim> LU<T, R, C>
|
||||||
where
|
where
|
||||||
N: Zero + One,
|
T: Zero + One,
|
||||||
R: DimMin<C>,
|
R: DimMin<C>,
|
||||||
DefaultAllocator: Allocator<N, R, C>
|
DefaultAllocator: Allocator<T, R, C>
|
||||||
+ Allocator<N, R, R>
|
+ Allocator<T, R, R>
|
||||||
+ Allocator<N, R, DimMinimum<R, C>>
|
+ Allocator<T, R, DimMinimum<R, C>>
|
||||||
+ Allocator<N, DimMinimum<R, C>, C>
|
+ Allocator<T, DimMinimum<R, C>, C>
|
||||||
+ Allocator<i32, DimMinimum<R, C>>,
|
+ Allocator<i32, DimMinimum<R, C>>,
|
||||||
{
|
{
|
||||||
/// Computes the LU decomposition with partial (row) pivoting of `matrix`.
|
/// Computes the LU decomposition with partial (row) pivoting of `matrix`.
|
||||||
pub fn new(mut m: MatrixMN<N, R, C>) -> Self {
|
pub fn new(mut m: OMatrix<T, R, C>) -> Self {
|
||||||
let (nrows, ncols) = m.data.shape();
|
let (nrows, ncols) = m.data.shape();
|
||||||
let min_nrows_ncols = nrows.min(ncols);
|
let min_nrows_ncols = nrows.min(ncols);
|
||||||
let nrows = nrows.value() as i32;
|
let nrows = nrows.value() as i32;
|
||||||
let ncols = ncols.value() as i32;
|
let ncols = ncols.value() as i32;
|
||||||
|
|
||||||
let mut ipiv: VectorN<i32, _> = Matrix::zeros_generic(min_nrows_ncols, U1);
|
let mut ipiv: OVector<i32, _> = Matrix::zeros_generic(min_nrows_ncols, Const::<1>);
|
||||||
|
|
||||||
let mut info = 0;
|
let mut info = 0;
|
||||||
|
|
||||||
N::xgetrf(
|
T::xgetrf(
|
||||||
nrows,
|
nrows,
|
||||||
ncols,
|
ncols,
|
||||||
m.as_mut_slice(),
|
m.as_mut_slice(),
|
||||||
|
@ -85,7 +85,7 @@ where
|
||||||
|
|
||||||
/// Gets the lower-triangular matrix part of the decomposition.
|
/// Gets the lower-triangular matrix part of the decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn l(&self) -> MatrixMN<N, R, DimMinimum<R, C>> {
|
pub fn l(&self) -> OMatrix<T, R, DimMinimum<R, C>> {
|
||||||
let (nrows, ncols) = self.lu.data.shape();
|
let (nrows, ncols) = self.lu.data.shape();
|
||||||
let mut res = self.lu.columns_generic(0, nrows.min(ncols)).into_owned();
|
let mut res = self.lu.columns_generic(0, nrows.min(ncols)).into_owned();
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ where
|
||||||
|
|
||||||
/// Gets the upper-triangular matrix part of the decomposition.
|
/// Gets the upper-triangular matrix part of the decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn u(&self) -> MatrixMN<N, DimMinimum<R, C>, C> {
|
pub fn u(&self) -> OMatrix<T, DimMinimum<R, C>, C> {
|
||||||
let (nrows, ncols) = self.lu.data.shape();
|
let (nrows, ncols) = self.lu.data.shape();
|
||||||
let mut res = self.lu.rows_generic(0, nrows.min(ncols)).into_owned();
|
let mut res = self.lu.rows_generic(0, nrows.min(ncols)).into_owned();
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ where
|
||||||
/// Computing the permutation matrix explicitly is costly and usually not necessary.
|
/// Computing the permutation matrix explicitly is costly and usually not necessary.
|
||||||
/// To permute rows of a matrix or vector, use the method `self.permute(...)` instead.
|
/// To permute rows of a matrix or vector, use the method `self.permute(...)` instead.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn p(&self) -> MatrixN<N, R> {
|
pub fn p(&self) -> OMatrix<T, R, R> {
|
||||||
let (dim, _) = self.lu.data.shape();
|
let (dim, _) = self.lu.data.shape();
|
||||||
let mut id = Matrix::identity_generic(dim, dim);
|
let mut id = Matrix::identity_generic(dim, dim);
|
||||||
self.permute(&mut id);
|
self.permute(&mut id);
|
||||||
|
@ -124,19 +124,19 @@ where
|
||||||
|
|
||||||
/// Gets the LAPACK permutation indices.
|
/// Gets the LAPACK permutation indices.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn permutation_indices(&self) -> &VectorN<i32, DimMinimum<R, C>> {
|
pub fn permutation_indices(&self) -> &OVector<i32, DimMinimum<R, C>> {
|
||||||
&self.p
|
&self.p
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Applies the permutation matrix to a given matrix or vector in-place.
|
/// Applies the permutation matrix to a given matrix or vector in-place.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn permute<C2: Dim>(&self, rhs: &mut MatrixMN<N, R, C2>)
|
pub fn permute<C2: Dim>(&self, rhs: &mut OMatrix<T, R, C2>)
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, R, C2>,
|
DefaultAllocator: Allocator<T, R, C2>,
|
||||||
{
|
{
|
||||||
let (nrows, ncols) = rhs.shape();
|
let (nrows, ncols) = rhs.shape();
|
||||||
|
|
||||||
N::xlaswp(
|
T::xlaswp(
|
||||||
ncols as i32,
|
ncols as i32,
|
||||||
rhs.as_mut_slice(),
|
rhs.as_mut_slice(),
|
||||||
nrows as i32,
|
nrows as i32,
|
||||||
|
@ -147,9 +147,9 @@ where
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generic_solve_mut<R2: Dim, C2: Dim>(&self, trans: u8, b: &mut MatrixMN<N, R2, C2>) -> bool
|
fn generic_solve_mut<R2: Dim, C2: Dim>(&self, trans: u8, b: &mut OMatrix<T, R2, C2>) -> bool
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2>,
|
DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
|
||||||
{
|
{
|
||||||
let dim = self.lu.nrows();
|
let dim = self.lu.nrows();
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ where
|
||||||
let ldb = dim as i32;
|
let ldb = dim as i32;
|
||||||
let mut info = 0;
|
let mut info = 0;
|
||||||
|
|
||||||
N::xgetrs(
|
T::xgetrs(
|
||||||
trans,
|
trans,
|
||||||
dim as i32,
|
dim as i32,
|
||||||
nrhs,
|
nrhs,
|
||||||
|
@ -184,14 +184,14 @@ where
|
||||||
/// Solves the linear system `self * x = b`, where `x` is the unknown to be determined.
|
/// Solves the linear system `self * x = b`, where `x` is the unknown to be determined.
|
||||||
pub fn solve<R2: Dim, C2: Dim, S2>(
|
pub fn solve<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
b: &Matrix<N, R2, C2, S2>,
|
b: &Matrix<T, R2, C2, S2>,
|
||||||
) -> Option<MatrixMN<N, R2, C2>>
|
) -> Option<OMatrix<T, R2, C2>>
|
||||||
where
|
where
|
||||||
S2: Storage<N, R2, C2>,
|
S2: Storage<T, R2, C2>,
|
||||||
DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2>,
|
DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
|
||||||
{
|
{
|
||||||
let mut res = b.clone_owned();
|
let mut res = b.clone_owned();
|
||||||
if self.generic_solve_mut(b'N', &mut res) {
|
if self.generic_solve_mut(b'T', &mut res) {
|
||||||
Some(res)
|
Some(res)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -202,11 +202,11 @@ where
|
||||||
/// determined.
|
/// determined.
|
||||||
pub fn solve_transpose<R2: Dim, C2: Dim, S2>(
|
pub fn solve_transpose<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
b: &Matrix<N, R2, C2, S2>,
|
b: &Matrix<T, R2, C2, S2>,
|
||||||
) -> Option<MatrixMN<N, R2, C2>>
|
) -> Option<OMatrix<T, R2, C2>>
|
||||||
where
|
where
|
||||||
S2: Storage<N, R2, C2>,
|
S2: Storage<T, R2, C2>,
|
||||||
DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2>,
|
DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
|
||||||
{
|
{
|
||||||
let mut res = b.clone_owned();
|
let mut res = b.clone_owned();
|
||||||
if self.generic_solve_mut(b'T', &mut res) {
|
if self.generic_solve_mut(b'T', &mut res) {
|
||||||
|
@ -220,11 +220,11 @@ where
|
||||||
/// be determined.
|
/// be determined.
|
||||||
pub fn solve_conjugate_transpose<R2: Dim, C2: Dim, S2>(
|
pub fn solve_conjugate_transpose<R2: Dim, C2: Dim, S2>(
|
||||||
&self,
|
&self,
|
||||||
b: &Matrix<N, R2, C2, S2>,
|
b: &Matrix<T, R2, C2, S2>,
|
||||||
) -> Option<MatrixMN<N, R2, C2>>
|
) -> Option<OMatrix<T, R2, C2>>
|
||||||
where
|
where
|
||||||
S2: Storage<N, R2, C2>,
|
S2: Storage<T, R2, C2>,
|
||||||
DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2>,
|
DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
|
||||||
{
|
{
|
||||||
let mut res = b.clone_owned();
|
let mut res = b.clone_owned();
|
||||||
if self.generic_solve_mut(b'T', &mut res) {
|
if self.generic_solve_mut(b'T', &mut res) {
|
||||||
|
@ -237,20 +237,20 @@ where
|
||||||
/// Solves in-place the linear system `self * x = b`, where `x` is the unknown to be determined.
|
/// Solves in-place the linear system `self * x = b`, where `x` is the unknown to be determined.
|
||||||
///
|
///
|
||||||
/// Returns `false` if no solution was found (the decomposed matrix is singular).
|
/// Returns `false` if no solution was found (the decomposed matrix is singular).
|
||||||
pub fn solve_mut<R2: Dim, C2: Dim>(&self, b: &mut MatrixMN<N, R2, C2>) -> bool
|
pub fn solve_mut<R2: Dim, C2: Dim>(&self, b: &mut OMatrix<T, R2, C2>) -> bool
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2>,
|
DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
|
||||||
{
|
{
|
||||||
self.generic_solve_mut(b'N', b)
|
self.generic_solve_mut(b'T', b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Solves in-place the linear system `self.transpose() * x = b`, where `x` is the unknown to be
|
/// Solves in-place the linear system `self.transpose() * x = b`, where `x` is the unknown to be
|
||||||
/// determined.
|
/// determined.
|
||||||
///
|
///
|
||||||
/// Returns `false` if no solution was found (the decomposed matrix is singular).
|
/// Returns `false` if no solution was found (the decomposed matrix is singular).
|
||||||
pub fn solve_transpose_mut<R2: Dim, C2: Dim>(&self, b: &mut MatrixMN<N, R2, C2>) -> bool
|
pub fn solve_transpose_mut<R2: Dim, C2: Dim>(&self, b: &mut OMatrix<T, R2, C2>) -> bool
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2>,
|
DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
|
||||||
{
|
{
|
||||||
self.generic_solve_mut(b'T', b)
|
self.generic_solve_mut(b'T', b)
|
||||||
}
|
}
|
||||||
|
@ -259,25 +259,25 @@ where
|
||||||
/// be determined.
|
/// be determined.
|
||||||
///
|
///
|
||||||
/// Returns `false` if no solution was found (the decomposed matrix is singular).
|
/// Returns `false` if no solution was found (the decomposed matrix is singular).
|
||||||
pub fn solve_adjoint_mut<R2: Dim, C2: Dim>(&self, b: &mut MatrixMN<N, R2, C2>) -> bool
|
pub fn solve_adjoint_mut<R2: Dim, C2: Dim>(&self, b: &mut OMatrix<T, R2, C2>) -> bool
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2>,
|
DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
|
||||||
{
|
{
|
||||||
self.generic_solve_mut(b'T', b)
|
self.generic_solve_mut(b'T', b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: LUScalar, D: Dim> LU<N, D, D>
|
impl<T: LUScalar, D: Dim> LU<T, D, D>
|
||||||
where
|
where
|
||||||
N: Zero + One,
|
T: Zero + One,
|
||||||
D: DimMin<D, Output = D>,
|
D: DimMin<D, Output = D>,
|
||||||
DefaultAllocator: Allocator<N, D, D> + Allocator<i32, D>,
|
DefaultAllocator: Allocator<T, D, D> + Allocator<i32, D>,
|
||||||
{
|
{
|
||||||
/// Computes the inverse of the decomposed matrix.
|
/// Computes the inverse of the decomposed matrix.
|
||||||
pub fn inverse(mut self) -> Option<MatrixN<N, D>> {
|
pub fn inverse(mut self) -> Option<OMatrix<T, D, D>> {
|
||||||
let dim = self.lu.nrows() as i32;
|
let dim = self.lu.nrows() as i32;
|
||||||
let mut info = 0;
|
let mut info = 0;
|
||||||
let lwork = N::xgetri_work_size(
|
let lwork = T::xgetri_work_size(
|
||||||
dim,
|
dim,
|
||||||
self.lu.as_mut_slice(),
|
self.lu.as_mut_slice(),
|
||||||
dim,
|
dim,
|
||||||
|
@ -288,7 +288,7 @@ where
|
||||||
|
|
||||||
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
|
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
|
||||||
|
|
||||||
N::xgetri(
|
T::xgetri(
|
||||||
dim,
|
dim,
|
||||||
self.lu.as_mut_slice(),
|
self.lu.as_mut_slice(),
|
||||||
dim,
|
dim,
|
||||||
|
|
|
@ -6,9 +6,9 @@ use num_complex::Complex;
|
||||||
|
|
||||||
use crate::ComplexHelper;
|
use crate::ComplexHelper;
|
||||||
use na::allocator::Allocator;
|
use na::allocator::Allocator;
|
||||||
use na::dimension::{Dim, DimMin, DimMinimum, U1};
|
use na::dimension::{Const, Dim, DimMin, DimMinimum};
|
||||||
use na::storage::Storage;
|
use na::storage::Storage;
|
||||||
use na::{DefaultAllocator, Matrix, MatrixMN, Scalar, VectorN};
|
use na::{DefaultAllocator, Matrix, OMatrix, OVector, Scalar};
|
||||||
|
|
||||||
use lapack;
|
use lapack;
|
||||||
|
|
||||||
|
@ -16,55 +16,56 @@ use lapack;
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serde-serialize",
|
feature = "serde-serialize",
|
||||||
serde(bound(serialize = "DefaultAllocator: Allocator<N, R, C> +
|
serde(bound(serialize = "DefaultAllocator: Allocator<T, R, C> +
|
||||||
Allocator<N, DimMinimum<R, C>>,
|
Allocator<T, DimMinimum<R, C>>,
|
||||||
MatrixMN<N, R, C>: Serialize,
|
OMatrix<T, R, C>: Serialize,
|
||||||
VectorN<N, DimMinimum<R, C>>: Serialize"))
|
OVector<T, DimMinimum<R, C>>: Serialize"))
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serde-serialize",
|
feature = "serde-serialize",
|
||||||
serde(bound(deserialize = "DefaultAllocator: Allocator<N, R, C> +
|
serde(bound(deserialize = "DefaultAllocator: Allocator<T, R, C> +
|
||||||
Allocator<N, DimMinimum<R, C>>,
|
Allocator<T, DimMinimum<R, C>>,
|
||||||
MatrixMN<N, R, C>: Deserialize<'de>,
|
OMatrix<T, R, C>: Deserialize<'de>,
|
||||||
VectorN<N, DimMinimum<R, C>>: Deserialize<'de>"))
|
OVector<T, DimMinimum<R, C>>: Deserialize<'de>"))
|
||||||
)]
|
)]
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct QR<N: Scalar, R: DimMin<C>, C: Dim>
|
pub struct QR<T: Scalar, R: DimMin<C>, C: Dim>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, R, C> + Allocator<N, DimMinimum<R, C>>,
|
DefaultAllocator: Allocator<T, R, C> + Allocator<T, DimMinimum<R, C>>,
|
||||||
{
|
{
|
||||||
qr: MatrixMN<N, R, C>,
|
qr: OMatrix<T, R, C>,
|
||||||
tau: VectorN<N, DimMinimum<R, C>>,
|
tau: OVector<T, DimMinimum<R, C>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Copy, R: DimMin<C>, C: Dim> Copy for QR<N, R, C>
|
impl<T: Scalar + Copy, R: DimMin<C>, C: Dim> Copy for QR<T, R, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, R, C> + Allocator<N, DimMinimum<R, C>>,
|
DefaultAllocator: Allocator<T, R, C> + Allocator<T, DimMinimum<R, C>>,
|
||||||
MatrixMN<N, R, C>: Copy,
|
OMatrix<T, R, C>: Copy,
|
||||||
VectorN<N, DimMinimum<R, C>>: Copy,
|
OVector<T, DimMinimum<R, C>>: Copy,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: QRScalar + Zero, R: DimMin<C>, C: Dim> QR<N, R, C>
|
impl<T: QRScalar + Zero, R: DimMin<C>, C: Dim> QR<T, R, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, R, C>
|
DefaultAllocator: Allocator<T, R, C>
|
||||||
+ Allocator<N, R, DimMinimum<R, C>>
|
+ Allocator<T, R, DimMinimum<R, C>>
|
||||||
+ Allocator<N, DimMinimum<R, C>, C>
|
+ Allocator<T, DimMinimum<R, C>, C>
|
||||||
+ Allocator<N, DimMinimum<R, C>>,
|
+ Allocator<T, DimMinimum<R, C>>,
|
||||||
{
|
{
|
||||||
/// Computes the QR decomposition of the matrix `m`.
|
/// Computes the QR decomposition of the matrix `m`.
|
||||||
pub fn new(mut m: MatrixMN<N, R, C>) -> Self {
|
pub fn new(mut m: OMatrix<T, R, C>) -> Self {
|
||||||
let (nrows, ncols) = m.data.shape();
|
let (nrows, ncols) = m.data.shape();
|
||||||
|
|
||||||
let mut info = 0;
|
let mut info = 0;
|
||||||
let mut tau =
|
let mut tau = unsafe {
|
||||||
unsafe { Matrix::new_uninitialized_generic(nrows.min(ncols), U1).assume_init() };
|
Matrix::new_uninitialized_generic(nrows.min(ncols), Const::<1>).assume_init()
|
||||||
|
};
|
||||||
|
|
||||||
if nrows.value() == 0 || ncols.value() == 0 {
|
if nrows.value() == 0 || ncols.value() == 0 {
|
||||||
return Self { qr: m, tau: tau };
|
return Self { qr: m, tau: tau };
|
||||||
}
|
}
|
||||||
|
|
||||||
let lwork = N::xgeqrf_work_size(
|
let lwork = T::xgeqrf_work_size(
|
||||||
nrows.value() as i32,
|
nrows.value() as i32,
|
||||||
ncols.value() as i32,
|
ncols.value() as i32,
|
||||||
m.as_mut_slice(),
|
m.as_mut_slice(),
|
||||||
|
@ -75,7 +76,7 @@ where
|
||||||
|
|
||||||
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
|
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
|
||||||
|
|
||||||
N::xgeqrf(
|
T::xgeqrf(
|
||||||
nrows.value() as i32,
|
nrows.value() as i32,
|
||||||
ncols.value() as i32,
|
ncols.value() as i32,
|
||||||
m.as_mut_slice(),
|
m.as_mut_slice(),
|
||||||
|
@ -91,37 +92,37 @@ where
|
||||||
|
|
||||||
/// Retrieves the upper trapezoidal submatrix `R` of this decomposition.
|
/// Retrieves the upper trapezoidal submatrix `R` of this decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn r(&self) -> MatrixMN<N, DimMinimum<R, C>, C> {
|
pub fn r(&self) -> OMatrix<T, DimMinimum<R, C>, C> {
|
||||||
let (nrows, ncols) = self.qr.data.shape();
|
let (nrows, ncols) = self.qr.data.shape();
|
||||||
self.qr.rows_generic(0, nrows.min(ncols)).upper_triangle()
|
self.qr.rows_generic(0, nrows.min(ncols)).upper_triangle()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: QRReal + Zero, R: DimMin<C>, C: Dim> QR<N, R, C>
|
impl<T: QRReal + Zero, R: DimMin<C>, C: Dim> QR<T, R, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, R, C>
|
DefaultAllocator: Allocator<T, R, C>
|
||||||
+ Allocator<N, R, DimMinimum<R, C>>
|
+ Allocator<T, R, DimMinimum<R, C>>
|
||||||
+ Allocator<N, DimMinimum<R, C>, C>
|
+ Allocator<T, DimMinimum<R, C>, C>
|
||||||
+ Allocator<N, DimMinimum<R, C>>,
|
+ Allocator<T, DimMinimum<R, C>>,
|
||||||
{
|
{
|
||||||
/// Retrieves the matrices `(Q, R)` of this decompositions.
|
/// Retrieves the matrices `(Q, R)` of this decompositions.
|
||||||
pub fn unpack(
|
pub fn unpack(
|
||||||
self,
|
self,
|
||||||
) -> (
|
) -> (
|
||||||
MatrixMN<N, R, DimMinimum<R, C>>,
|
OMatrix<T, R, DimMinimum<R, C>>,
|
||||||
MatrixMN<N, DimMinimum<R, C>, C>,
|
OMatrix<T, DimMinimum<R, C>, C>,
|
||||||
) {
|
) {
|
||||||
(self.q(), self.r())
|
(self.q(), self.r())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the orthogonal matrix `Q` of this decomposition.
|
/// Computes the orthogonal matrix `Q` of this decomposition.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn q(&self) -> MatrixMN<N, R, DimMinimum<R, C>> {
|
pub fn q(&self) -> OMatrix<T, R, DimMinimum<R, C>> {
|
||||||
let (nrows, ncols) = self.qr.data.shape();
|
let (nrows, ncols) = self.qr.data.shape();
|
||||||
let min_nrows_ncols = nrows.min(ncols);
|
let min_nrows_ncols = nrows.min(ncols);
|
||||||
|
|
||||||
if min_nrows_ncols.value() == 0 {
|
if min_nrows_ncols.value() == 0 {
|
||||||
return MatrixMN::from_element_generic(nrows, min_nrows_ncols, N::zero());
|
return OMatrix::from_element_generic(nrows, min_nrows_ncols, T::zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut q = self
|
let mut q = self
|
||||||
|
@ -132,7 +133,7 @@ where
|
||||||
let mut info = 0;
|
let mut info = 0;
|
||||||
let nrows = nrows.value() as i32;
|
let nrows = nrows.value() as i32;
|
||||||
|
|
||||||
let lwork = N::xorgqr_work_size(
|
let lwork = T::xorgqr_work_size(
|
||||||
nrows,
|
nrows,
|
||||||
min_nrows_ncols.value() as i32,
|
min_nrows_ncols.value() as i32,
|
||||||
self.tau.len() as i32,
|
self.tau.len() as i32,
|
||||||
|
@ -142,9 +143,9 @@ where
|
||||||
&mut info,
|
&mut info,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut work = vec![N::zero(); lwork as usize];
|
let mut work = vec![T::zero(); lwork as usize];
|
||||||
|
|
||||||
N::xorgqr(
|
T::xorgqr(
|
||||||
nrows,
|
nrows,
|
||||||
min_nrows_ncols.value() as i32,
|
min_nrows_ncols.value() as i32,
|
||||||
self.tau.len() as i32,
|
self.tau.len() as i32,
|
||||||
|
|
|
@ -8,9 +8,9 @@ use simba::scalar::RealField;
|
||||||
|
|
||||||
use crate::ComplexHelper;
|
use crate::ComplexHelper;
|
||||||
use na::allocator::Allocator;
|
use na::allocator::Allocator;
|
||||||
use na::dimension::{Dim, U1};
|
use na::dimension::{Const, Dim};
|
||||||
use na::storage::Storage;
|
use na::storage::Storage;
|
||||||
use na::{DefaultAllocator, Matrix, MatrixN, Scalar, VectorN};
|
use na::{DefaultAllocator, Matrix, OMatrix, OVector, Scalar};
|
||||||
|
|
||||||
use lapack;
|
use lapack;
|
||||||
|
|
||||||
|
@ -19,53 +19,53 @@ use lapack;
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serde-serialize",
|
feature = "serde-serialize",
|
||||||
serde(
|
serde(
|
||||||
bound(serialize = "DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
|
bound(serialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
|
||||||
VectorN<N, D>: Serialize,
|
OVector<T, D>: Serialize,
|
||||||
MatrixN<N, D>: Serialize")
|
OMatrix<T, D, D>: Serialize")
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serde-serialize",
|
feature = "serde-serialize",
|
||||||
serde(
|
serde(
|
||||||
bound(deserialize = "DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
|
bound(deserialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
|
||||||
VectorN<N, D>: Serialize,
|
OVector<T, D>: Serialize,
|
||||||
MatrixN<N, D>: Deserialize<'de>")
|
OMatrix<T, D, D>: Deserialize<'de>")
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Schur<N: Scalar, D: Dim>
|
pub struct Schur<T: Scalar, D: Dim>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N, D, D>,
|
DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
|
||||||
{
|
{
|
||||||
re: VectorN<N, D>,
|
re: OVector<T, D>,
|
||||||
im: VectorN<N, D>,
|
im: OVector<T, D>,
|
||||||
t: MatrixN<N, D>,
|
t: OMatrix<T, D, D>,
|
||||||
q: MatrixN<N, D>,
|
q: OMatrix<T, D, D>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Copy, D: Dim> Copy for Schur<N, D>
|
impl<T: Scalar + Copy, D: Dim> Copy for Schur<T, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
|
DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
|
||||||
MatrixN<N, D>: Copy,
|
OMatrix<T, D, D>: Copy,
|
||||||
VectorN<N, D>: Copy,
|
OVector<T, D>: Copy,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SchurScalar + RealField, D: Dim> Schur<N, D>
|
impl<T: SchurScalar + RealField, D: Dim> Schur<T, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
|
DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
|
||||||
{
|
{
|
||||||
/// Computes the eigenvalues and real Schur form of the matrix `m`.
|
/// Computes the eigenvalues and real Schur form of the matrix `m`.
|
||||||
///
|
///
|
||||||
/// Panics if the method did not converge.
|
/// Panics if the method did not converge.
|
||||||
pub fn new(m: MatrixN<N, D>) -> Self {
|
pub fn new(m: OMatrix<T, D, D>) -> Self {
|
||||||
Self::try_new(m).expect("Schur decomposition: convergence failed.")
|
Self::try_new(m).expect("Schur decomposition: convergence failed.")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the eigenvalues and real Schur form of the matrix `m`.
|
/// Computes the eigenvalues and real Schur form of the matrix `m`.
|
||||||
///
|
///
|
||||||
/// Returns `None` if the method did not converge.
|
/// Returns `None` if the method did not converge.
|
||||||
pub fn try_new(mut m: MatrixN<N, D>) -> Option<Self> {
|
pub fn try_new(mut m: OMatrix<T, D, D>) -> Option<Self> {
|
||||||
assert!(
|
assert!(
|
||||||
m.is_square(),
|
m.is_square(),
|
||||||
"Unable to compute the eigenvalue decomposition of a non-square matrix."
|
"Unable to compute the eigenvalue decomposition of a non-square matrix."
|
||||||
|
@ -78,16 +78,16 @@ where
|
||||||
|
|
||||||
let mut info = 0;
|
let mut info = 0;
|
||||||
|
|
||||||
let mut wr = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() };
|
let mut wr = unsafe { Matrix::new_uninitialized_generic(nrows, Const::<1>).assume_init() };
|
||||||
let mut wi = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() };
|
let mut wi = unsafe { Matrix::new_uninitialized_generic(nrows, Const::<1>).assume_init() };
|
||||||
let mut q = unsafe { Matrix::new_uninitialized_generic(nrows, ncols).assume_init() };
|
let mut q = unsafe { Matrix::new_uninitialized_generic(nrows, ncols).assume_init() };
|
||||||
// Placeholders:
|
// Placeholders:
|
||||||
let mut bwork = [0i32];
|
let mut bwork = [0i32];
|
||||||
let mut unused = 0;
|
let mut unused = 0;
|
||||||
|
|
||||||
let lwork = N::xgees_work_size(
|
let lwork = T::xgees_work_size(
|
||||||
b'V',
|
b'V',
|
||||||
b'N',
|
b'T',
|
||||||
n as i32,
|
n as i32,
|
||||||
m.as_mut_slice(),
|
m.as_mut_slice(),
|
||||||
lda,
|
lda,
|
||||||
|
@ -103,9 +103,9 @@ where
|
||||||
|
|
||||||
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
|
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
|
||||||
|
|
||||||
N::xgees(
|
T::xgees(
|
||||||
b'V',
|
b'V',
|
||||||
b'N',
|
b'T',
|
||||||
n as i32,
|
n as i32,
|
||||||
m.as_mut_slice(),
|
m.as_mut_slice(),
|
||||||
lda,
|
lda,
|
||||||
|
@ -131,14 +131,14 @@ where
|
||||||
|
|
||||||
/// Retrieves the unitary matrix `Q` and the upper-quasitriangular matrix `T` such that the
|
/// Retrieves the unitary matrix `Q` and the upper-quasitriangular matrix `T` such that the
|
||||||
/// decomposed matrix equals `Q * T * Q.transpose()`.
|
/// decomposed matrix equals `Q * T * Q.transpose()`.
|
||||||
pub fn unpack(self) -> (MatrixN<N, D>, MatrixN<N, D>) {
|
pub fn unpack(self) -> (OMatrix<T, D, D>, OMatrix<T, D, D>) {
|
||||||
(self.q, self.t)
|
(self.q, self.t)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the real eigenvalues of the decomposed matrix.
|
/// Computes the real eigenvalues of the decomposed matrix.
|
||||||
///
|
///
|
||||||
/// Return `None` if some eigenvalues are complex.
|
/// Return `None` if some eigenvalues are complex.
|
||||||
pub fn eigenvalues(&self) -> Option<VectorN<N, D>> {
|
pub fn eigenvalues(&self) -> Option<OVector<T, D>> {
|
||||||
if self.im.iter().all(|e| e.is_zero()) {
|
if self.im.iter().all(|e| e.is_zero()) {
|
||||||
Some(self.re.clone())
|
Some(self.re.clone())
|
||||||
} else {
|
} else {
|
||||||
|
@ -147,12 +147,13 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the complex eigenvalues of the decomposed matrix.
|
/// Computes the complex eigenvalues of the decomposed matrix.
|
||||||
pub fn complex_eigenvalues(&self) -> VectorN<Complex<N>, D>
|
pub fn complex_eigenvalues(&self) -> OVector<Complex<T>, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<Complex<N>, D>,
|
DefaultAllocator: Allocator<Complex<T>, D>,
|
||||||
{
|
{
|
||||||
let mut out =
|
let mut out = unsafe {
|
||||||
unsafe { VectorN::new_uninitialized_generic(self.t.data.shape().0, U1).assume_init() };
|
OVector::new_uninitialized_generic(self.t.data.shape().0, Const::<1>).assume_init()
|
||||||
|
};
|
||||||
|
|
||||||
for i in 0..out.len() {
|
for i in 0..out.len() {
|
||||||
out[i] = Complex::new(self.re[i], self.im[i])
|
out[i] = Complex::new(self.re[i], self.im[i])
|
||||||
|
|
|
@ -5,9 +5,9 @@ use num::Signed;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
|
|
||||||
use na::allocator::Allocator;
|
use na::allocator::Allocator;
|
||||||
use na::dimension::{Dim, DimMin, DimMinimum, U1};
|
use na::dimension::{Const, Dim, DimMin, DimMinimum, U1};
|
||||||
use na::storage::Storage;
|
use na::storage::Storage;
|
||||||
use na::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Scalar, VectorN};
|
use na::{DefaultAllocator, Matrix, OMatrix, OVector, Scalar};
|
||||||
|
|
||||||
use lapack;
|
use lapack;
|
||||||
|
|
||||||
|
@ -15,41 +15,41 @@ use lapack;
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serde-serialize",
|
feature = "serde-serialize",
|
||||||
serde(bound(serialize = "DefaultAllocator: Allocator<N, DimMinimum<R, C>> +
|
serde(bound(serialize = "DefaultAllocator: Allocator<T, DimMinimum<R, C>> +
|
||||||
Allocator<N, R, R> +
|
Allocator<T, R, R> +
|
||||||
Allocator<N, C, C>,
|
Allocator<T, C, C>,
|
||||||
MatrixN<N, R>: Serialize,
|
OMatrix<T, R>: Serialize,
|
||||||
MatrixN<N, C>: Serialize,
|
OMatrix<T, C>: Serialize,
|
||||||
VectorN<N, DimMinimum<R, C>>: Serialize"))
|
OVector<T, DimMinimum<R, C>>: Serialize"))
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serde-serialize",
|
feature = "serde-serialize",
|
||||||
serde(bound(serialize = "DefaultAllocator: Allocator<N, DimMinimum<R, C>> +
|
serde(bound(serialize = "DefaultAllocator: Allocator<T, DimMinimum<R, C>> +
|
||||||
Allocator<N, R, R> +
|
Allocator<T, R, R> +
|
||||||
Allocator<N, C, C>,
|
Allocator<T, C, C>,
|
||||||
MatrixN<N, R>: Deserialize<'de>,
|
OMatrix<T, R>: Deserialize<'de>,
|
||||||
MatrixN<N, C>: Deserialize<'de>,
|
OMatrix<T, C>: Deserialize<'de>,
|
||||||
VectorN<N, DimMinimum<R, C>>: Deserialize<'de>"))
|
OVector<T, DimMinimum<R, C>>: Deserialize<'de>"))
|
||||||
)]
|
)]
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SVD<N: Scalar, R: DimMin<C>, C: Dim>
|
pub struct SVD<T: Scalar, R: DimMin<C>, C: Dim>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, R, R> + Allocator<N, DimMinimum<R, C>> + Allocator<N, C, C>,
|
DefaultAllocator: Allocator<T, R, R> + Allocator<T, DimMinimum<R, C>> + Allocator<T, C, C>,
|
||||||
{
|
{
|
||||||
/// The left-singular vectors `U` of this SVD.
|
/// The left-singular vectors `U` of this SVD.
|
||||||
pub u: MatrixN<N, R>, // TODO: should be MatrixMN<N, R, DimMinimum<R, C>>
|
pub u: OMatrix<T, R, R>, // TODO: should be OMatrix<T, R, DimMinimum<R, C>>
|
||||||
/// The right-singular vectors `V^t` of this SVD.
|
/// The right-singular vectors `V^t` of this SVD.
|
||||||
pub vt: MatrixN<N, C>, // TODO: should be MatrixMN<N, DimMinimum<R, C>, C>
|
pub vt: OMatrix<T, C, C>, // TODO: should be OMatrix<T, DimMinimum<R, C>, C>
|
||||||
/// The singular values of this SVD.
|
/// The singular values of this SVD.
|
||||||
pub singular_values: VectorN<N, DimMinimum<R, C>>,
|
pub singular_values: OVector<T, DimMinimum<R, C>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Copy, R: DimMin<C>, C: Dim> Copy for SVD<N, R, C>
|
impl<T: Scalar + Copy, R: DimMin<C>, C: Dim> Copy for SVD<T, R, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, C, C> + Allocator<N, R, R> + Allocator<N, DimMinimum<R, C>>,
|
DefaultAllocator: Allocator<T, C, C> + Allocator<T, R, R> + Allocator<T, DimMinimum<R, C>>,
|
||||||
MatrixMN<N, R, R>: Copy,
|
OMatrix<T, R, R>: Copy,
|
||||||
MatrixMN<N, C, C>: Copy,
|
OMatrix<T, C, C>: Copy,
|
||||||
VectorN<N, DimMinimum<R, C>>: Copy,
|
OVector<T, DimMinimum<R, C>>: Copy,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,19 +63,19 @@ where
|
||||||
+ Allocator<Self, C, C>,
|
+ Allocator<Self, C, C>,
|
||||||
{
|
{
|
||||||
/// Computes the SVD decomposition of `m`.
|
/// Computes the SVD decomposition of `m`.
|
||||||
fn compute(m: MatrixMN<Self, R, C>) -> Option<SVD<Self, R, C>>;
|
fn compute(m: OMatrix<Self, R, C>) -> Option<SVD<Self, R, C>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SVDScalar<R, C>, R: DimMin<C>, C: Dim> SVD<N, R, C>
|
impl<T: SVDScalar<R, C>, R: DimMin<C>, C: Dim> SVD<T, R, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, R, R>
|
DefaultAllocator: Allocator<T, R, R>
|
||||||
+ Allocator<N, R, C>
|
+ Allocator<T, R, C>
|
||||||
+ Allocator<N, DimMinimum<R, C>>
|
+ Allocator<T, DimMinimum<R, C>>
|
||||||
+ Allocator<N, C, C>,
|
+ Allocator<T, C, C>,
|
||||||
{
|
{
|
||||||
/// Computes the Singular Value Decomposition of `matrix`.
|
/// Computes the Singular Value Decomposition of `matrix`.
|
||||||
pub fn new(m: MatrixMN<N, R, C>) -> Option<Self> {
|
pub fn new(m: OMatrix<T, R, C>) -> Option<Self> {
|
||||||
N::compute(m)
|
T::compute(m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ macro_rules! svd_impl(
|
||||||
Allocator<$t, C, C> +
|
Allocator<$t, C, C> +
|
||||||
Allocator<$t, DimMinimum<R, C>> {
|
Allocator<$t, DimMinimum<R, C>> {
|
||||||
|
|
||||||
fn compute(mut m: MatrixMN<$t, R, C>) -> Option<SVD<$t, R, C>> {
|
fn compute(mut m: OMatrix<$t, R, C>) -> Option<SVD<$t, R, C>> {
|
||||||
let (nrows, ncols) = m.data.shape();
|
let (nrows, ncols) = m.data.shape();
|
||||||
|
|
||||||
if nrows.value() == 0 || ncols.value() == 0 {
|
if nrows.value() == 0 || ncols.value() == 0 {
|
||||||
|
@ -100,7 +100,7 @@ macro_rules! svd_impl(
|
||||||
let lda = nrows.value() as i32;
|
let lda = nrows.value() as i32;
|
||||||
|
|
||||||
let mut u = unsafe { Matrix::new_uninitialized_generic(nrows, nrows).assume_init() };
|
let mut u = unsafe { Matrix::new_uninitialized_generic(nrows, nrows).assume_init() };
|
||||||
let mut s = unsafe { Matrix::new_uninitialized_generic(nrows.min(ncols), U1).assume_init() };
|
let mut s = unsafe { Matrix::new_uninitialized_generic(nrows.min(ncols), Const::<1>).assume_init() };
|
||||||
let mut vt = unsafe { Matrix::new_uninitialized_generic(ncols, ncols).assume_init() };
|
let mut vt = unsafe { Matrix::new_uninitialized_generic(ncols, ncols).assume_init() };
|
||||||
|
|
||||||
let ldu = nrows.value();
|
let ldu = nrows.value();
|
||||||
|
@ -150,12 +150,12 @@ macro_rules! svd_impl(
|
||||||
/// Useful if some components (e.g. some singular values) of this decomposition have
|
/// Useful if some components (e.g. some singular values) of this decomposition have
|
||||||
/// been manually changed by the user.
|
/// been manually changed by the user.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn recompose(self) -> MatrixMN<$t, R, C> {
|
pub fn recompose(self) -> OMatrix<$t, R, C> {
|
||||||
let nrows = self.u.data.shape().0;
|
let nrows = self.u.data.shape().0;
|
||||||
let ncols = self.vt.data.shape().1;
|
let ncols = self.vt.data.shape().1;
|
||||||
let min_nrows_ncols = nrows.min(ncols);
|
let min_nrows_ncols = nrows.min(ncols);
|
||||||
|
|
||||||
let mut res: MatrixMN<_, R, C> = Matrix::zeros_generic(nrows, ncols);
|
let mut res: OMatrix<_, R, C> = Matrix::zeros_generic(nrows, ncols);
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut sres = res.generic_slice_mut((0, 0), (min_nrows_ncols, ncols));
|
let mut sres = res.generic_slice_mut((0, 0), (min_nrows_ncols, ncols));
|
||||||
|
@ -175,12 +175,12 @@ macro_rules! svd_impl(
|
||||||
///
|
///
|
||||||
/// All singular value below epsilon will be set to zero instead of being inverted.
|
/// All singular value below epsilon will be set to zero instead of being inverted.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn pseudo_inverse(&self, epsilon: $t) -> MatrixMN<$t, C, R> {
|
pub fn pseudo_inverse(&self, epsilon: $t) -> OMatrix<$t, C, R> {
|
||||||
let nrows = self.u.data.shape().0;
|
let nrows = self.u.data.shape().0;
|
||||||
let ncols = self.vt.data.shape().1;
|
let ncols = self.vt.data.shape().1;
|
||||||
let min_nrows_ncols = nrows.min(ncols);
|
let min_nrows_ncols = nrows.min(ncols);
|
||||||
|
|
||||||
let mut res: MatrixMN<_, C, R> = Matrix::zeros_generic(ncols, nrows);
|
let mut res: OMatrix<_, C, R> = Matrix::zeros_generic(ncols, nrows);
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut sres = res.generic_slice_mut((0, 0), (min_nrows_ncols, nrows));
|
let mut sres = res.generic_slice_mut((0, 0), (min_nrows_ncols, nrows));
|
||||||
|
@ -230,9 +230,9 @@ macro_rules! svd_complex_impl(
|
||||||
($name: ident, $t: ty, $lapack_func: path) => (
|
($name: ident, $t: ty, $lapack_func: path) => (
|
||||||
impl SVDScalar for Complex<$t> {
|
impl SVDScalar for Complex<$t> {
|
||||||
fn compute<R: Dim, C: Dim, S>(mut m: Matrix<$t, R, C, S>) -> Option<SVD<$t, R, C, S::Alloc>>
|
fn compute<R: Dim, C: Dim, S>(mut m: Matrix<$t, R, C, S>) -> Option<SVD<$t, R, C, S::Alloc>>
|
||||||
Option<(MatrixN<Complex<$t>, R, S::Alloc>,
|
Option<(OMatrix<Complex<$t>, R, S::Alloc>,
|
||||||
VectorN<$t, DimMinimum<R, C>, S::Alloc>,
|
OVector<$t, DimMinimum<R, C>, S::Alloc>,
|
||||||
MatrixN<Complex<$t>, C, S::Alloc>)>
|
OMatrix<Complex<$t>, C, S::Alloc>)>
|
||||||
where R: DimMin<C>,
|
where R: DimMin<C>,
|
||||||
S: ContiguousStorage<Complex<$t>, R, C>,
|
S: ContiguousStorage<Complex<$t>, R, C>,
|
||||||
S::Alloc: OwnedAllocator<Complex<$t>, R, C, S> +
|
S::Alloc: OwnedAllocator<Complex<$t>, R, C, S> +
|
||||||
|
|
|
@ -8,9 +8,9 @@ use simba::scalar::RealField;
|
||||||
|
|
||||||
use crate::ComplexHelper;
|
use crate::ComplexHelper;
|
||||||
use na::allocator::Allocator;
|
use na::allocator::Allocator;
|
||||||
use na::dimension::{Dim, U1};
|
use na::dimension::{Const, Dim};
|
||||||
use na::storage::Storage;
|
use na::storage::Storage;
|
||||||
use na::{DefaultAllocator, Matrix, MatrixN, Scalar, VectorN};
|
use na::{DefaultAllocator, Matrix, OMatrix, OVector, Scalar};
|
||||||
|
|
||||||
use lapack;
|
use lapack;
|
||||||
|
|
||||||
|
@ -18,47 +18,47 @@ use lapack;
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serde-serialize",
|
feature = "serde-serialize",
|
||||||
serde(bound(serialize = "DefaultAllocator: Allocator<N, D, D> +
|
serde(bound(serialize = "DefaultAllocator: Allocator<T, D, D> +
|
||||||
Allocator<N, D>,
|
Allocator<T, D>,
|
||||||
VectorN<N, D>: Serialize,
|
OVector<T, D>: Serialize,
|
||||||
MatrixN<N, D>: Serialize"))
|
OMatrix<T, D, D>: Serialize"))
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "serde-serialize",
|
feature = "serde-serialize",
|
||||||
serde(bound(deserialize = "DefaultAllocator: Allocator<N, D, D> +
|
serde(bound(deserialize = "DefaultAllocator: Allocator<T, D, D> +
|
||||||
Allocator<N, D>,
|
Allocator<T, D>,
|
||||||
VectorN<N, D>: Deserialize<'de>,
|
OVector<T, D>: Deserialize<'de>,
|
||||||
MatrixN<N, D>: Deserialize<'de>"))
|
OMatrix<T, D, D>: Deserialize<'de>"))
|
||||||
)]
|
)]
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SymmetricEigen<N: Scalar, D: Dim>
|
pub struct SymmetricEigen<T: Scalar, D: Dim>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D> + Allocator<N, D, D>,
|
DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
|
||||||
{
|
{
|
||||||
/// The eigenvectors of the decomposed matrix.
|
/// The eigenvectors of the decomposed matrix.
|
||||||
pub eigenvectors: MatrixN<N, D>,
|
pub eigenvectors: OMatrix<T, D, D>,
|
||||||
|
|
||||||
/// The unsorted eigenvalues of the decomposed matrix.
|
/// The unsorted eigenvalues of the decomposed matrix.
|
||||||
pub eigenvalues: VectorN<N, D>,
|
pub eigenvalues: OVector<T, D>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + Copy, D: Dim> Copy for SymmetricEigen<N, D>
|
impl<T: Scalar + Copy, D: Dim> Copy for SymmetricEigen<T, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
|
DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
|
||||||
MatrixN<N, D>: Copy,
|
OMatrix<T, D, D>: Copy,
|
||||||
VectorN<N, D>: Copy,
|
OVector<T, D>: Copy,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SymmetricEigenScalar + RealField, D: Dim> SymmetricEigen<N, D>
|
impl<T: SymmetricEigenScalar + RealField, D: Dim> SymmetricEigen<T, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
|
DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
|
||||||
{
|
{
|
||||||
/// Computes the eigenvalues and eigenvectors of the symmetric matrix `m`.
|
/// Computes the eigenvalues and eigenvectors of the symmetric matrix `m`.
|
||||||
///
|
///
|
||||||
/// Only the lower-triangular part of `m` is read. If `eigenvectors` is `false` then, the
|
/// Only the lower-triangular part of `m` is read. If `eigenvectors` is `false` then, the
|
||||||
/// eigenvectors are not computed explicitly. Panics if the method did not converge.
|
/// eigenvectors are not computed explicitly. Panics if the method did not converge.
|
||||||
pub fn new(m: MatrixN<N, D>) -> Self {
|
pub fn new(m: OMatrix<T, D, D>) -> Self {
|
||||||
let (vals, vecs) =
|
let (vals, vecs) =
|
||||||
Self::do_decompose(m, true).expect("SymmetricEigen: convergence failure.");
|
Self::do_decompose(m, true).expect("SymmetricEigen: convergence failure.");
|
||||||
Self {
|
Self {
|
||||||
|
@ -71,7 +71,7 @@ where
|
||||||
///
|
///
|
||||||
/// Only the lower-triangular part of `m` is read. If `eigenvectors` is `false` then, the
|
/// Only the lower-triangular part of `m` is read. If `eigenvectors` is `false` then, the
|
||||||
/// eigenvectors are not computed explicitly. Returns `None` if the method did not converge.
|
/// eigenvectors are not computed explicitly. Returns `None` if the method did not converge.
|
||||||
pub fn try_new(m: MatrixN<N, D>) -> Option<Self> {
|
pub fn try_new(m: OMatrix<T, D, D>) -> Option<Self> {
|
||||||
Self::do_decompose(m, true).map(|(vals, vecs)| SymmetricEigen {
|
Self::do_decompose(m, true).map(|(vals, vecs)| SymmetricEigen {
|
||||||
eigenvalues: vals,
|
eigenvalues: vals,
|
||||||
eigenvectors: vecs.unwrap(),
|
eigenvectors: vecs.unwrap(),
|
||||||
|
@ -79,30 +79,31 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_decompose(
|
fn do_decompose(
|
||||||
mut m: MatrixN<N, D>,
|
mut m: OMatrix<T, D, D>,
|
||||||
eigenvectors: bool,
|
eigenvectors: bool,
|
||||||
) -> Option<(VectorN<N, D>, Option<MatrixN<N, D>>)> {
|
) -> Option<(OVector<T, D>, Option<OMatrix<T, D, D>>)> {
|
||||||
assert!(
|
assert!(
|
||||||
m.is_square(),
|
m.is_square(),
|
||||||
"Unable to compute the eigenvalue decomposition of a non-square matrix."
|
"Unable to compute the eigenvalue decomposition of a non-square matrix."
|
||||||
);
|
);
|
||||||
|
|
||||||
let jobz = if eigenvectors { b'V' } else { b'N' };
|
let jobz = if eigenvectors { b'V' } else { b'T' };
|
||||||
|
|
||||||
let nrows = m.data.shape().0;
|
let nrows = m.data.shape().0;
|
||||||
let n = nrows.value();
|
let n = nrows.value();
|
||||||
|
|
||||||
let lda = n as i32;
|
let lda = n as i32;
|
||||||
|
|
||||||
let mut values = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() };
|
let mut values =
|
||||||
|
unsafe { Matrix::new_uninitialized_generic(nrows, Const::<1>).assume_init() };
|
||||||
let mut info = 0;
|
let mut info = 0;
|
||||||
|
|
||||||
let lwork = N::xsyev_work_size(jobz, b'L', n as i32, m.as_mut_slice(), lda, &mut info);
|
let lwork = T::xsyev_work_size(jobz, b'L', n as i32, m.as_mut_slice(), lda, &mut info);
|
||||||
lapack_check!(info);
|
lapack_check!(info);
|
||||||
|
|
||||||
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
|
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
|
||||||
|
|
||||||
N::xsyev(
|
T::xsyev(
|
||||||
jobz,
|
jobz,
|
||||||
b'L',
|
b'L',
|
||||||
n as i32,
|
n as i32,
|
||||||
|
@ -122,7 +123,7 @@ where
|
||||||
/// Computes only the eigenvalues of the input matrix.
|
/// Computes only the eigenvalues of the input matrix.
|
||||||
///
|
///
|
||||||
/// Panics if the method does not converge.
|
/// Panics if the method does not converge.
|
||||||
pub fn eigenvalues(m: MatrixN<N, D>) -> VectorN<N, D> {
|
pub fn eigenvalues(m: OMatrix<T, D, D>) -> OVector<T, D> {
|
||||||
Self::do_decompose(m, false)
|
Self::do_decompose(m, false)
|
||||||
.expect("SymmetricEigen eigenvalues: convergence failure.")
|
.expect("SymmetricEigen eigenvalues: convergence failure.")
|
||||||
.0
|
.0
|
||||||
|
@ -131,14 +132,14 @@ where
|
||||||
/// Computes only the eigenvalues of the input matrix.
|
/// Computes only the eigenvalues of the input matrix.
|
||||||
///
|
///
|
||||||
/// Returns `None` if the method does not converge.
|
/// Returns `None` if the method does not converge.
|
||||||
pub fn try_eigenvalues(m: MatrixN<N, D>) -> Option<VectorN<N, D>> {
|
pub fn try_eigenvalues(m: OMatrix<T, D, D>) -> Option<OVector<T, D>> {
|
||||||
Self::do_decompose(m, false).map(|res| res.0)
|
Self::do_decompose(m, false).map(|res| res.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The determinant of the decomposed matrix.
|
/// The determinant of the decomposed matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn determinant(&self) -> N {
|
pub fn determinant(&self) -> T {
|
||||||
let mut det = N::one();
|
let mut det = T::one();
|
||||||
for e in self.eigenvalues.iter() {
|
for e in self.eigenvalues.iter() {
|
||||||
det *= *e;
|
det *= *e;
|
||||||
}
|
}
|
||||||
|
@ -149,7 +150,7 @@ where
|
||||||
/// Rebuild the original matrix.
|
/// Rebuild the original matrix.
|
||||||
///
|
///
|
||||||
/// This is useful if some of the eigenvalues have been manually modified.
|
/// This is useful if some of the eigenvalues have been manually modified.
|
||||||
pub fn recompose(&self) -> MatrixN<N, D> {
|
pub fn recompose(&self) -> OMatrix<T, D, D> {
|
||||||
let mut u_t = self.eigenvectors.clone();
|
let mut u_t = self.eigenvectors.clone();
|
||||||
for i in 0..self.eigenvalues.len() {
|
for i in 0..self.eigenvalues.len() {
|
||||||
let val = self.eigenvalues[i];
|
let val = self.eigenvalues[i];
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "nalgebra-sparse"
|
name = "nalgebra-sparse"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
authors = [ "Andreas Longva", "Sébastien Crozet <developer@crozet.re>" ]
|
authors = [ "Andreas Longva", "Sébastien Crozet <developer@crozet.re>" ]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "Sparse matrix computation based on nalgebra."
|
description = "Sparse matrix computation based on nalgebra."
|
||||||
|
@ -20,7 +20,7 @@ compare = [ "matrixcompare-core" ]
|
||||||
slow-tests = []
|
slow-tests = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nalgebra = { version="0.25", path = "../" }
|
nalgebra = { version="0.26", path = "../" }
|
||||||
num-traits = { version = "0.2", default-features = false }
|
num-traits = { version = "0.2", default-features = false }
|
||||||
proptest = { version = "1.0", optional = true }
|
proptest = { version = "1.0", optional = true }
|
||||||
matrixcompare-core = { version = "0.1.0", optional = true }
|
matrixcompare-core = { version = "0.1.0", optional = true }
|
||||||
|
@ -28,7 +28,7 @@ matrixcompare-core = { version = "0.1.0", optional = true }
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
itertools = "0.10"
|
itertools = "0.10"
|
||||||
matrixcompare = { version = "0.2.0", features = [ "proptest-support" ] }
|
matrixcompare = { version = "0.2.0", features = [ "proptest-support" ] }
|
||||||
nalgebra = { version="0.25", path = "../", features = ["compare"] }
|
nalgebra = { version="0.26", path = "../", features = ["compare"] }
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
# Enable certain features when building docs for docs.rs
|
# Enable certain features when building docs for docs.rs
|
||||||
|
|
|
@ -10,7 +10,7 @@ use nalgebra::allocator::Allocator;
|
||||||
use nalgebra::base::storage::Storage;
|
use nalgebra::base::storage::Storage;
|
||||||
use nalgebra::constraint::{DimEq, ShapeConstraint};
|
use nalgebra::constraint::{DimEq, ShapeConstraint};
|
||||||
use nalgebra::{
|
use nalgebra::{
|
||||||
ClosedAdd, ClosedDiv, ClosedMul, ClosedSub, DefaultAllocator, Dim, Dynamic, Matrix, MatrixMN,
|
ClosedAdd, ClosedDiv, ClosedMul, ClosedSub, DefaultAllocator, Dim, Dynamic, Matrix, OMatrix,
|
||||||
Scalar, U1,
|
Scalar, U1,
|
||||||
};
|
};
|
||||||
use num_traits::{One, Zero};
|
use num_traits::{One, Zero};
|
||||||
|
@ -274,7 +274,7 @@ macro_rules! impl_spmm_cs_dense {
|
||||||
impl_spmm_cs_dense!(&'a $matrix_type_name<T>, &'a Matrix<T, R, C, S>, $spmm_fn, |lhs, rhs| {
|
impl_spmm_cs_dense!(&'a $matrix_type_name<T>, &'a Matrix<T, R, C, S>, $spmm_fn, |lhs, rhs| {
|
||||||
let (_, ncols) = rhs.data.shape();
|
let (_, ncols) = rhs.data.shape();
|
||||||
let nrows = Dynamic::new(lhs.nrows());
|
let nrows = Dynamic::new(lhs.nrows());
|
||||||
let mut result = MatrixMN::<T, Dynamic, C>::zeros_generic(nrows, ncols);
|
let mut result = OMatrix::<T, Dynamic, C>::zeros_generic(nrows, ncols);
|
||||||
$spmm_fn(T::zero(), &mut result, T::one(), Op::NoOp(lhs), Op::NoOp(rhs));
|
$spmm_fn(T::zero(), &mut result, T::one(), Op::NoOp(lhs), Op::NoOp(rhs));
|
||||||
result
|
result
|
||||||
});
|
});
|
||||||
|
@ -305,7 +305,7 @@ macro_rules! impl_spmm_cs_dense {
|
||||||
DefaultAllocator: Allocator<T, Dynamic, C>,
|
DefaultAllocator: Allocator<T, Dynamic, C>,
|
||||||
// TODO: Is it possible to simplify these bounds?
|
// TODO: Is it possible to simplify these bounds?
|
||||||
ShapeConstraint:
|
ShapeConstraint:
|
||||||
// Bounds so that we can turn MatrixMN<T, Dynamic, C> into a DMatrixSliceMut
|
// Bounds so that we can turn OMatrix<T, Dynamic, C> into a DMatrixSliceMut
|
||||||
DimEq<U1, <<DefaultAllocator as Allocator<T, Dynamic, C>>::Buffer as Storage<T, Dynamic, C>>::RStride>
|
DimEq<U1, <<DefaultAllocator as Allocator<T, Dynamic, C>>::Buffer as Storage<T, Dynamic, C>>::RStride>
|
||||||
+ DimEq<C, Dynamic>
|
+ DimEq<C, Dynamic>
|
||||||
+ DimEq<Dynamic, <<DefaultAllocator as Allocator<T, Dynamic, C>>::Buffer as Storage<T, Dynamic, C>>::CStride>
|
+ DimEq<Dynamic, <<DefaultAllocator as Allocator<T, Dynamic, C>>::Buffer as Storage<T, Dynamic, C>>::CStride>
|
||||||
|
@ -316,7 +316,7 @@ macro_rules! impl_spmm_cs_dense {
|
||||||
{
|
{
|
||||||
// We need the column dimension to be generic, so that if RHS is a vector, then
|
// We need the column dimension to be generic, so that if RHS is a vector, then
|
||||||
// we also get a vector (and not a matrix)
|
// we also get a vector (and not a matrix)
|
||||||
type Output = MatrixMN<T, Dynamic, C>;
|
type Output = OMatrix<T, Dynamic, C>;
|
||||||
|
|
||||||
fn mul(self, rhs: $dense_matrix_type) -> Self::Output {
|
fn mul(self, rhs: $dense_matrix_type) -> Self::Output {
|
||||||
let $lhs = self;
|
let $lhs = self;
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::base::dimension::{U1, U2, U3, U4, U5, U6};
|
||||||
use crate::base::storage::Owned;
|
use crate::base::storage::Owned;
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
use crate::base::vec_storage::VecStorage;
|
use crate::base::vec_storage::VecStorage;
|
||||||
use crate::base::Matrix;
|
use crate::base::{ArrayStorage, Const, Matrix, Unit};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
@ -13,244 +13,254 @@ use crate::base::Matrix;
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/// A statically sized column-major matrix with `R` rows and `C` columns.
|
|
||||||
|
/// An owned matrix column-major matrix with `R` rows and `C` columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[deprecated(note = "This matrix name contains a typo. Use MatrixMN instead.")]
|
pub type OMatrix<T, R, C> = Matrix<T, R, C, Owned<T, R, C>>;
|
||||||
pub type MatrixNM<N, R, C> = Matrix<N, R, C, Owned<N, R, C>>;
|
|
||||||
|
/// An owned matrix column-major matrix 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(
|
||||||
|
note = "use SMatrix for a statically-sized matrix using integer dimensions, or OMatrix for an owned matrix using types as dimensions."
|
||||||
|
)]
|
||||||
|
pub type MatrixMN<T, R, C> = Matrix<T, R, C, Owned<T, R, C>>;
|
||||||
|
|
||||||
|
/// An owned matrix column-major matrix with `D` columns.
|
||||||
|
///
|
||||||
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
#[deprecated(note = "use OMatrix<T, D, D> or SMatrix<T, D, D> instead.")]
|
||||||
|
pub type MatrixN<T, D> = Matrix<T, D, D, Owned<T, D, D>>;
|
||||||
|
|
||||||
/// A statically sized column-major matrix with `R` rows and `C` columns.
|
/// A statically sized column-major matrix with `R` rows and `C` columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixMN<N, R, C> = Matrix<N, R, C, Owned<N, R, C>>;
|
pub type SMatrix<T, const R: usize, const C: usize> =
|
||||||
|
Matrix<T, Const<R>, Const<C>, ArrayStorage<T, R, C>>;
|
||||||
/// A statically sized column-major square matrix 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.**
|
|
||||||
pub type MatrixN<N, D> = Matrix<N, D, D, Owned<N, D, D>>;
|
|
||||||
|
|
||||||
/// A dynamically sized column-major matrix.
|
/// A dynamically sized column-major matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type DMatrix<N> = Matrix<N, Dynamic, Dynamic, Owned<N, Dynamic, Dynamic>>;
|
pub type DMatrix<T> = Matrix<T, Dynamic, Dynamic, VecStorage<T, Dynamic, Dynamic>>;
|
||||||
|
|
||||||
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 1 columns.
|
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 1 columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type MatrixXx1<N> = Matrix<N, Dynamic, U1, Owned<N, Dynamic, U1>>;
|
pub type MatrixXx1<T> = Matrix<T, Dynamic, U1, VecStorage<T, Dynamic, U1>>;
|
||||||
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 2 columns.
|
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 2 columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type MatrixXx2<N> = Matrix<N, Dynamic, U2, Owned<N, Dynamic, U2>>;
|
pub type MatrixXx2<T> = Matrix<T, Dynamic, U2, VecStorage<T, Dynamic, U2>>;
|
||||||
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 3 columns.
|
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 3 columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type MatrixXx3<N> = Matrix<N, Dynamic, U3, Owned<N, Dynamic, U3>>;
|
pub type MatrixXx3<T> = Matrix<T, Dynamic, U3, VecStorage<T, Dynamic, U3>>;
|
||||||
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 4 columns.
|
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 4 columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type MatrixXx4<N> = Matrix<N, Dynamic, U4, Owned<N, Dynamic, U4>>;
|
pub type MatrixXx4<T> = Matrix<T, Dynamic, U4, VecStorage<T, Dynamic, U4>>;
|
||||||
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 5 columns.
|
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 5 columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type MatrixXx5<N> = Matrix<N, Dynamic, U5, Owned<N, Dynamic, U5>>;
|
pub type MatrixXx5<T> = Matrix<T, Dynamic, U5, VecStorage<T, Dynamic, U5>>;
|
||||||
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 6 columns.
|
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 6 columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type MatrixXx6<N> = Matrix<N, Dynamic, U6, Owned<N, Dynamic, U6>>;
|
pub type MatrixXx6<T> = Matrix<T, Dynamic, U6, VecStorage<T, Dynamic, U6>>;
|
||||||
|
|
||||||
/// A heap-allocated, row-major, matrix with 1 rows and a dynamic number of columns.
|
/// A heap-allocated, row-major, matrix with 1 rows and a dynamic number of columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type Matrix1xX<N> = Matrix<N, U1, Dynamic, Owned<N, U1, Dynamic>>;
|
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.
|
/// A heap-allocated, row-major, matrix with 2 rows and a dynamic number of columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type Matrix2xX<N> = Matrix<N, U2, Dynamic, Owned<N, U2, Dynamic>>;
|
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.
|
/// A heap-allocated, row-major, matrix with 3 rows and a dynamic number of columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type Matrix3xX<N> = Matrix<N, U3, Dynamic, Owned<N, U3, Dynamic>>;
|
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.
|
/// A heap-allocated, row-major, matrix with 4 rows and a dynamic number of columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type Matrix4xX<N> = Matrix<N, U4, Dynamic, Owned<N, U4, Dynamic>>;
|
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.
|
/// A heap-allocated, row-major, matrix with 5 rows and a dynamic number of columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type Matrix5xX<N> = Matrix<N, U5, Dynamic, Owned<N, U5, Dynamic>>;
|
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.
|
/// A heap-allocated, row-major, matrix with 6 rows and a dynamic number of columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type Matrix6xX<N> = Matrix<N, U6, Dynamic, Owned<N, U6, Dynamic>>;
|
pub type Matrix6xX<T> = Matrix<T, U6, Dynamic, VecStorage<T, U6, Dynamic>>;
|
||||||
|
|
||||||
/// A stack-allocated, column-major, 1x1 square matrix.
|
/// A stack-allocated, column-major, 1x1 square matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix1<N> = Matrix<N, U1, U1, Owned<N, U1, U1>>;
|
pub type Matrix1<T> = Matrix<T, U1, U1, ArrayStorage<T, 1, 1>>;
|
||||||
/// A stack-allocated, column-major, 2x2 square matrix.
|
/// A stack-allocated, column-major, 2x2 square matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix2<N> = Matrix<N, U2, U2, Owned<N, U2, U2>>;
|
pub type Matrix2<T> = Matrix<T, U2, U2, ArrayStorage<T, 2, 2>>;
|
||||||
/// A stack-allocated, column-major, 3x3 square matrix.
|
/// A stack-allocated, column-major, 3x3 square matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix3<N> = Matrix<N, U3, U3, Owned<N, U3, U3>>;
|
pub type Matrix3<T> = Matrix<T, U3, U3, ArrayStorage<T, 3, 3>>;
|
||||||
/// A stack-allocated, column-major, 4x4 square matrix.
|
/// A stack-allocated, column-major, 4x4 square matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix4<N> = Matrix<N, U4, U4, Owned<N, U4, U4>>;
|
pub type Matrix4<T> = Matrix<T, U4, U4, ArrayStorage<T, 4, 4>>;
|
||||||
/// A stack-allocated, column-major, 5x5 square matrix.
|
/// A stack-allocated, column-major, 5x5 square matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix5<N> = Matrix<N, U5, U5, Owned<N, U5, U5>>;
|
pub type Matrix5<T> = Matrix<T, U5, U5, ArrayStorage<T, 5, 5>>;
|
||||||
/// A stack-allocated, column-major, 6x6 square matrix.
|
/// A stack-allocated, column-major, 6x6 square matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix6<N> = Matrix<N, U6, U6, Owned<N, U6, U6>>;
|
pub type Matrix6<T> = Matrix<T, U6, U6, ArrayStorage<T, 6, 6>>;
|
||||||
|
|
||||||
/// A stack-allocated, column-major, 1x2 matrix.
|
/// A stack-allocated, column-major, 1x2 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix1x2<N> = Matrix<N, U1, U2, Owned<N, U1, U2>>;
|
pub type Matrix1x2<T> = Matrix<T, U1, U2, ArrayStorage<T, 1, 2>>;
|
||||||
/// A stack-allocated, column-major, 1x3 matrix.
|
/// A stack-allocated, column-major, 1x3 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix1x3<N> = Matrix<N, U1, U3, Owned<N, U1, U3>>;
|
pub type Matrix1x3<T> = Matrix<T, U1, U3, ArrayStorage<T, 1, 3>>;
|
||||||
/// A stack-allocated, column-major, 1x4 matrix.
|
/// A stack-allocated, column-major, 1x4 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix1x4<N> = Matrix<N, U1, U4, Owned<N, U1, U4>>;
|
pub type Matrix1x4<T> = Matrix<T, U1, U4, ArrayStorage<T, 1, 4>>;
|
||||||
/// A stack-allocated, column-major, 1x5 matrix.
|
/// A stack-allocated, column-major, 1x5 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix1x5<N> = Matrix<N, U1, U5, Owned<N, U1, U5>>;
|
pub type Matrix1x5<T> = Matrix<T, U1, U5, ArrayStorage<T, 1, 5>>;
|
||||||
/// A stack-allocated, column-major, 1x6 matrix.
|
/// A stack-allocated, column-major, 1x6 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix1x6<N> = Matrix<N, U1, U6, Owned<N, U1, U6>>;
|
pub type Matrix1x6<T> = Matrix<T, U1, U6, ArrayStorage<T, 1, 6>>;
|
||||||
|
|
||||||
/// A stack-allocated, column-major, 2x3 matrix.
|
/// A stack-allocated, column-major, 2x3 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix2x3<N> = Matrix<N, U2, U3, Owned<N, U2, U3>>;
|
pub type Matrix2x3<T> = Matrix<T, U2, U3, ArrayStorage<T, 2, 3>>;
|
||||||
/// A stack-allocated, column-major, 2x4 matrix.
|
/// A stack-allocated, column-major, 2x4 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix2x4<N> = Matrix<N, U2, U4, Owned<N, U2, U4>>;
|
pub type Matrix2x4<T> = Matrix<T, U2, U4, ArrayStorage<T, 2, 4>>;
|
||||||
/// A stack-allocated, column-major, 2x5 matrix.
|
/// A stack-allocated, column-major, 2x5 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix2x5<N> = Matrix<N, U2, U5, Owned<N, U2, U5>>;
|
pub type Matrix2x5<T> = Matrix<T, U2, U5, ArrayStorage<T, 2, 5>>;
|
||||||
/// A stack-allocated, column-major, 2x6 matrix.
|
/// A stack-allocated, column-major, 2x6 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix2x6<N> = Matrix<N, U2, U6, Owned<N, U2, U6>>;
|
pub type Matrix2x6<T> = Matrix<T, U2, U6, ArrayStorage<T, 2, 6>>;
|
||||||
|
|
||||||
/// A stack-allocated, column-major, 3x4 matrix.
|
/// A stack-allocated, column-major, 3x4 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix3x4<N> = Matrix<N, U3, U4, Owned<N, U3, U4>>;
|
pub type Matrix3x4<T> = Matrix<T, U3, U4, ArrayStorage<T, 3, 4>>;
|
||||||
/// A stack-allocated, column-major, 3x5 matrix.
|
/// A stack-allocated, column-major, 3x5 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix3x5<N> = Matrix<N, U3, U5, Owned<N, U3, U5>>;
|
pub type Matrix3x5<T> = Matrix<T, U3, U5, ArrayStorage<T, 3, 5>>;
|
||||||
/// A stack-allocated, column-major, 3x6 matrix.
|
/// A stack-allocated, column-major, 3x6 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix3x6<N> = Matrix<N, U3, U6, Owned<N, U3, U6>>;
|
pub type Matrix3x6<T> = Matrix<T, U3, U6, ArrayStorage<T, 3, 6>>;
|
||||||
|
|
||||||
/// A stack-allocated, column-major, 4x5 matrix.
|
/// A stack-allocated, column-major, 4x5 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix4x5<N> = Matrix<N, U4, U5, Owned<N, U4, U5>>;
|
pub type Matrix4x5<T> = Matrix<T, U4, U5, ArrayStorage<T, 4, 5>>;
|
||||||
/// A stack-allocated, column-major, 4x6 matrix.
|
/// A stack-allocated, column-major, 4x6 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix4x6<N> = Matrix<N, U4, U6, Owned<N, U4, U6>>;
|
pub type Matrix4x6<T> = Matrix<T, U4, U6, ArrayStorage<T, 4, 6>>;
|
||||||
|
|
||||||
/// A stack-allocated, column-major, 5x6 matrix.
|
/// A stack-allocated, column-major, 5x6 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix5x6<N> = Matrix<N, U5, U6, Owned<N, U5, U6>>;
|
pub type Matrix5x6<T> = Matrix<T, U5, U6, ArrayStorage<T, 5, 6>>;
|
||||||
|
|
||||||
/// A stack-allocated, column-major, 2x1 matrix.
|
/// A stack-allocated, column-major, 2x1 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix2x1<N> = Matrix<N, U2, U1, Owned<N, U2, U1>>;
|
pub type Matrix2x1<T> = Matrix<T, U2, U1, ArrayStorage<T, 2, 1>>;
|
||||||
/// A stack-allocated, column-major, 3x1 matrix.
|
/// A stack-allocated, column-major, 3x1 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix3x1<N> = Matrix<N, U3, U1, Owned<N, U3, U1>>;
|
pub type Matrix3x1<T> = Matrix<T, U3, U1, ArrayStorage<T, 3, 1>>;
|
||||||
/// A stack-allocated, column-major, 4x1 matrix.
|
/// A stack-allocated, column-major, 4x1 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix4x1<N> = Matrix<N, U4, U1, Owned<N, U4, U1>>;
|
pub type Matrix4x1<T> = Matrix<T, U4, U1, ArrayStorage<T, 4, 1>>;
|
||||||
/// A stack-allocated, column-major, 5x1 matrix.
|
/// A stack-allocated, column-major, 5x1 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix5x1<N> = Matrix<N, U5, U1, Owned<N, U5, U1>>;
|
pub type Matrix5x1<T> = Matrix<T, U5, U1, ArrayStorage<T, 5, 1>>;
|
||||||
/// A stack-allocated, column-major, 6x1 matrix.
|
/// A stack-allocated, column-major, 6x1 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix6x1<N> = Matrix<N, U6, U1, Owned<N, U6, U1>>;
|
pub type Matrix6x1<T> = Matrix<T, U6, U1, ArrayStorage<T, 6, 1>>;
|
||||||
|
|
||||||
/// A stack-allocated, column-major, 3x2 matrix.
|
/// A stack-allocated, column-major, 3x2 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix3x2<N> = Matrix<N, U3, U2, Owned<N, U3, U2>>;
|
pub type Matrix3x2<T> = Matrix<T, U3, U2, ArrayStorage<T, 3, 2>>;
|
||||||
/// A stack-allocated, column-major, 4x2 matrix.
|
/// A stack-allocated, column-major, 4x2 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix4x2<N> = Matrix<N, U4, U2, Owned<N, U4, U2>>;
|
pub type Matrix4x2<T> = Matrix<T, U4, U2, ArrayStorage<T, 4, 2>>;
|
||||||
/// A stack-allocated, column-major, 5x2 matrix.
|
/// A stack-allocated, column-major, 5x2 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix5x2<N> = Matrix<N, U5, U2, Owned<N, U5, U2>>;
|
pub type Matrix5x2<T> = Matrix<T, U5, U2, ArrayStorage<T, 5, 2>>;
|
||||||
/// A stack-allocated, column-major, 6x2 matrix.
|
/// A stack-allocated, column-major, 6x2 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix6x2<N> = Matrix<N, U6, U2, Owned<N, U6, U2>>;
|
pub type Matrix6x2<T> = Matrix<T, U6, U2, ArrayStorage<T, 6, 2>>;
|
||||||
|
|
||||||
/// A stack-allocated, column-major, 4x3 matrix.
|
/// A stack-allocated, column-major, 4x3 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix4x3<N> = Matrix<N, U4, U3, Owned<N, U4, U3>>;
|
pub type Matrix4x3<T> = Matrix<T, U4, U3, ArrayStorage<T, 4, 3>>;
|
||||||
/// A stack-allocated, column-major, 5x3 matrix.
|
/// A stack-allocated, column-major, 5x3 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix5x3<N> = Matrix<N, U5, U3, Owned<N, U5, U3>>;
|
pub type Matrix5x3<T> = Matrix<T, U5, U3, ArrayStorage<T, 5, 3>>;
|
||||||
/// A stack-allocated, column-major, 6x3 matrix.
|
/// A stack-allocated, column-major, 6x3 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix6x3<N> = Matrix<N, U6, U3, Owned<N, U6, U3>>;
|
pub type Matrix6x3<T> = Matrix<T, U6, U3, ArrayStorage<T, 6, 3>>;
|
||||||
|
|
||||||
/// A stack-allocated, column-major, 5x4 matrix.
|
/// A stack-allocated, column-major, 5x4 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix5x4<N> = Matrix<N, U5, U4, Owned<N, U5, U4>>;
|
pub type Matrix5x4<T> = Matrix<T, U5, U4, ArrayStorage<T, 5, 4>>;
|
||||||
/// A stack-allocated, column-major, 6x4 matrix.
|
/// A stack-allocated, column-major, 6x4 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix6x4<N> = Matrix<N, U6, U4, Owned<N, U6, U4>>;
|
pub type Matrix6x4<T> = Matrix<T, U6, U4, ArrayStorage<T, 6, 4>>;
|
||||||
|
|
||||||
/// A stack-allocated, column-major, 6x5 matrix.
|
/// A stack-allocated, column-major, 6x5 matrix.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type Matrix6x5<N> = Matrix<N, U6, U5, Owned<N, U6, U5>>;
|
pub type Matrix6x5<T> = Matrix<T, U6, U5, ArrayStorage<T, 6, 5>>;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
@ -261,23 +271,33 @@ pub type Matrix6x5<N> = Matrix<N, U6, U5, Owned<N, U6, U5>>;
|
||||||
*/
|
*/
|
||||||
/// A dynamically sized column vector.
|
/// A dynamically sized column vector.
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type DVector<N> = Matrix<N, Dynamic, U1, VecStorage<N, Dynamic, U1>>;
|
pub type DVector<T> = Matrix<T, Dynamic, U1, VecStorage<T, Dynamic, U1>>;
|
||||||
|
|
||||||
|
/// An owned D-dimensional column vector.
|
||||||
|
pub type OVector<T, D> = Matrix<T, D, U1, Owned<T, D, U1>>;
|
||||||
/// A statically sized D-dimensional column vector.
|
/// A statically sized D-dimensional column vector.
|
||||||
pub type VectorN<N, D> = Matrix<N, D, U1, Owned<N, D, U1>>;
|
pub type SVector<T, const D: usize> = Matrix<T, Const<D>, U1, ArrayStorage<T, D, 1>>; // Owned<T, Const<D>, U1>>;
|
||||||
|
|
||||||
|
/// An owned matrix column-major matrix 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(
|
||||||
|
note = "use SVector for a statically-sized matrix using integer dimensions, or OVector for an owned matrix using types as dimensions."
|
||||||
|
)]
|
||||||
|
pub type VectorN<T, D> = Matrix<T, D, U1, Owned<T, D, U1>>;
|
||||||
|
|
||||||
/// A stack-allocated, 1-dimensional column vector.
|
/// A stack-allocated, 1-dimensional column vector.
|
||||||
pub type Vector1<N> = Matrix<N, U1, U1, Owned<N, U1, U1>>;
|
pub type Vector1<T> = Matrix<T, U1, U1, ArrayStorage<T, 1, 1>>;
|
||||||
/// A stack-allocated, 2-dimensional column vector.
|
/// A stack-allocated, 2-dimensional column vector.
|
||||||
pub type Vector2<N> = Matrix<N, U2, U1, Owned<N, U2, U1>>;
|
pub type Vector2<T> = Matrix<T, U2, U1, ArrayStorage<T, 2, 1>>;
|
||||||
/// A stack-allocated, 3-dimensional column vector.
|
/// A stack-allocated, 3-dimensional column vector.
|
||||||
pub type Vector3<N> = Matrix<N, U3, U1, Owned<N, U3, U1>>;
|
pub type Vector3<T> = Matrix<T, U3, U1, ArrayStorage<T, 3, 1>>;
|
||||||
/// A stack-allocated, 4-dimensional column vector.
|
/// A stack-allocated, 4-dimensional column vector.
|
||||||
pub type Vector4<N> = Matrix<N, U4, U1, Owned<N, U4, U1>>;
|
pub type Vector4<T> = Matrix<T, U4, U1, ArrayStorage<T, 4, 1>>;
|
||||||
/// A stack-allocated, 5-dimensional column vector.
|
/// A stack-allocated, 5-dimensional column vector.
|
||||||
pub type Vector5<N> = Matrix<N, U5, U1, Owned<N, U5, U1>>;
|
pub type Vector5<T> = Matrix<T, U5, U1, ArrayStorage<T, 5, 1>>;
|
||||||
/// A stack-allocated, 6-dimensional column vector.
|
/// A stack-allocated, 6-dimensional column vector.
|
||||||
pub type Vector6<N> = Matrix<N, U6, U1, Owned<N, U6, U1>>;
|
pub type Vector6<T> = Matrix<T, U6, U1, ArrayStorage<T, 6, 1>>;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
@ -288,20 +308,43 @@ pub type Vector6<N> = Matrix<N, U6, U1, Owned<N, U6, U1>>;
|
||||||
*/
|
*/
|
||||||
/// A dynamically sized row vector.
|
/// A dynamically sized row vector.
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub type RowDVector<N> = Matrix<N, U1, Dynamic, VecStorage<N, U1, Dynamic>>;
|
pub type RowDVector<T> = Matrix<T, U1, Dynamic, VecStorage<T, U1, Dynamic>>;
|
||||||
|
|
||||||
|
/// An owned D-dimensional row vector.
|
||||||
|
pub type RowOVector<T, D> = Matrix<T, U1, D, Owned<T, U1, D>>;
|
||||||
|
|
||||||
/// A statically sized D-dimensional row vector.
|
/// A statically sized D-dimensional row vector.
|
||||||
pub type RowVectorN<N, D> = Matrix<N, U1, D, Owned<N, U1, D>>;
|
pub type RowSVector<T, const D: usize> = Matrix<T, U1, Const<D>, ArrayStorage<T, 1, D>>;
|
||||||
|
|
||||||
/// A stack-allocated, 1-dimensional row vector.
|
/// A stack-allocated, 1-dimensional row vector.
|
||||||
pub type RowVector1<N> = Matrix<N, U1, U1, Owned<N, U1, U1>>;
|
pub type RowVector1<T> = Matrix<T, U1, U1, ArrayStorage<T, 1, 1>>;
|
||||||
/// A stack-allocated, 2-dimensional row vector.
|
/// A stack-allocated, 2-dimensional row vector.
|
||||||
pub type RowVector2<N> = Matrix<N, U1, U2, Owned<N, U1, U2>>;
|
pub type RowVector2<T> = Matrix<T, U1, U2, ArrayStorage<T, 1, 2>>;
|
||||||
/// A stack-allocated, 3-dimensional row vector.
|
/// A stack-allocated, 3-dimensional row vector.
|
||||||
pub type RowVector3<N> = Matrix<N, U1, U3, Owned<N, U1, U3>>;
|
pub type RowVector3<T> = Matrix<T, U1, U3, ArrayStorage<T, 1, 3>>;
|
||||||
/// A stack-allocated, 4-dimensional row vector.
|
/// A stack-allocated, 4-dimensional row vector.
|
||||||
pub type RowVector4<N> = Matrix<N, U1, U4, Owned<N, U1, U4>>;
|
pub type RowVector4<T> = Matrix<T, U1, U4, ArrayStorage<T, 1, 4>>;
|
||||||
/// A stack-allocated, 5-dimensional row vector.
|
/// A stack-allocated, 5-dimensional row vector.
|
||||||
pub type RowVector5<N> = Matrix<N, U1, U5, Owned<N, U1, U5>>;
|
pub type RowVector5<T> = Matrix<T, U1, U5, ArrayStorage<T, 1, 5>>;
|
||||||
/// A stack-allocated, 6-dimensional row vector.
|
/// A stack-allocated, 6-dimensional row vector.
|
||||||
pub type RowVector6<N> = Matrix<N, U1, U6, Owned<N, U1, U6>>;
|
pub type RowVector6<T> = Matrix<T, U1, U6, ArrayStorage<T, 1, 6>>;
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Unit Vector.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/// A stack-allocated, 1-dimensional unit vector.
|
||||||
|
pub type UnitVector1<T> = Unit<Matrix<T, U1, U1, ArrayStorage<T, 1, 1>>>;
|
||||||
|
/// A stack-allocated, 2-dimensional unit vector.
|
||||||
|
pub type UnitVector2<T> = Unit<Matrix<T, U2, U1, ArrayStorage<T, 2, 1>>>;
|
||||||
|
/// A stack-allocated, 3-dimensional unit vector.
|
||||||
|
pub type UnitVector3<T> = Unit<Matrix<T, U3, U1, ArrayStorage<T, 3, 1>>>;
|
||||||
|
/// A stack-allocated, 4-dimensional unit vector.
|
||||||
|
pub type UnitVector4<T> = Unit<Matrix<T, U4, U1, ArrayStorage<T, 4, 1>>>;
|
||||||
|
/// A stack-allocated, 5-dimensional unit vector.
|
||||||
|
pub type UnitVector5<T> = Unit<Matrix<T, U5, U1, ArrayStorage<T, 5, 1>>>;
|
||||||
|
/// A stack-allocated, 6-dimensional unit vector.
|
||||||
|
pub type UnitVector6<T> = Unit<Matrix<T, U6, U1, ArrayStorage<T, 6, 1>>>;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::base::dimension::{Dynamic, U1, U2, U3, U4, U5, U6};
|
use crate::base::dimension::{Dynamic, U1, U2, U3, U4, U5, U6};
|
||||||
use crate::base::matrix_slice::{SliceStorage, SliceStorageMut};
|
use crate::base::matrix_slice::{SliceStorage, SliceStorageMut};
|
||||||
use crate::base::Matrix;
|
use crate::base::{Const, Matrix};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
@ -9,287 +9,290 @@ use crate::base::Matrix;
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/// A column-major matrix slice with `R` rows and `C` columns.
|
// NOTE: we can't provide defaults for the strides because it's not supported yet by min_const_generics.
|
||||||
|
/// A column-major matrix slice with dimensions known at compile-time.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMN<'a, N, R, C, RStride = U1, CStride = R> =
|
pub type SMatrixSlice<'a, T, const R: usize, const C: usize> =
|
||||||
Matrix<N, R, C, SliceStorage<'a, N, R, C, RStride, CStride>>;
|
Matrix<T, Const<R>, Const<C>, SliceStorage<'a, T, Const<R>, Const<C>, Const<1>, Const<R>>>;
|
||||||
|
|
||||||
/// 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.**
|
|
||||||
pub type MatrixSliceN<'a, N, D, RStride = U1, CStride = D> =
|
|
||||||
Matrix<N, D, D, SliceStorage<'a, N, D, D, RStride, CStride>>;
|
|
||||||
|
|
||||||
/// A column-major matrix slice dynamic numbers of rows and columns.
|
/// A column-major matrix slice dynamic numbers of rows and columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type DMatrixSlice<'a, N, RStride = U1, CStride = Dynamic> =
|
pub type DMatrixSlice<'a, T, RStride = U1, CStride = Dynamic> =
|
||||||
Matrix<N, Dynamic, Dynamic, SliceStorage<'a, N, Dynamic, Dynamic, RStride, CStride>>;
|
Matrix<T, Dynamic, Dynamic, SliceStorage<'a, T, Dynamic, Dynamic, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 1x1 matrix slice.
|
/// A column-major 1x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice1<'a, N, RStride = U1, CStride = U1> =
|
pub type MatrixSlice1<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<N, U1, U1, SliceStorage<'a, N, U1, U1, RStride, CStride>>;
|
Matrix<T, U1, U1, SliceStorage<'a, T, U1, U1, RStride, CStride>>;
|
||||||
/// A column-major 2x2 matrix slice.
|
/// A column-major 2x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice2<'a, N, RStride = U1, CStride = U2> =
|
pub type MatrixSlice2<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<N, U2, U2, SliceStorage<'a, N, U2, U2, RStride, CStride>>;
|
Matrix<T, U2, U2, SliceStorage<'a, T, U2, U2, RStride, CStride>>;
|
||||||
/// A column-major 3x3 matrix slice.
|
/// A column-major 3x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice3<'a, N, RStride = U1, CStride = U3> =
|
pub type MatrixSlice3<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<N, U3, U3, SliceStorage<'a, N, U3, U3, RStride, CStride>>;
|
Matrix<T, U3, U3, SliceStorage<'a, T, U3, U3, RStride, CStride>>;
|
||||||
/// A column-major 4x4 matrix slice.
|
/// A column-major 4x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice4<'a, N, RStride = U1, CStride = U4> =
|
pub type MatrixSlice4<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<N, U4, U4, SliceStorage<'a, N, U4, U4, RStride, CStride>>;
|
Matrix<T, U4, U4, SliceStorage<'a, T, U4, U4, RStride, CStride>>;
|
||||||
/// A column-major 5x5 matrix slice.
|
/// A column-major 5x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice5<'a, N, RStride = U1, CStride = U5> =
|
pub type MatrixSlice5<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<N, U5, U5, SliceStorage<'a, N, U5, U5, RStride, CStride>>;
|
Matrix<T, U5, U5, SliceStorage<'a, T, U5, U5, RStride, CStride>>;
|
||||||
/// A column-major 6x6 matrix slice.
|
/// A column-major 6x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice6<'a, N, RStride = U1, CStride = U6> =
|
pub type MatrixSlice6<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<N, U6, U6, SliceStorage<'a, N, U6, U6, RStride, CStride>>;
|
Matrix<T, U6, U6, SliceStorage<'a, T, U6, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 1x2 matrix slice.
|
/// A column-major 1x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice1x2<'a, N, RStride = U1, CStride = U1> =
|
pub type MatrixSlice1x2<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<N, U1, U2, SliceStorage<'a, N, U1, U2, RStride, CStride>>;
|
Matrix<T, U1, U2, SliceStorage<'a, T, U1, U2, RStride, CStride>>;
|
||||||
/// A column-major 1x3 matrix slice.
|
/// A column-major 1x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice1x3<'a, N, RStride = U1, CStride = U1> =
|
pub type MatrixSlice1x3<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<N, U1, U3, SliceStorage<'a, N, U1, U3, RStride, CStride>>;
|
Matrix<T, U1, U3, SliceStorage<'a, T, U1, U3, RStride, CStride>>;
|
||||||
/// A column-major 1x4 matrix slice.
|
/// A column-major 1x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice1x4<'a, N, RStride = U1, CStride = U1> =
|
pub type MatrixSlice1x4<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<N, U1, U4, SliceStorage<'a, N, U1, U4, RStride, CStride>>;
|
Matrix<T, U1, U4, SliceStorage<'a, T, U1, U4, RStride, CStride>>;
|
||||||
/// A column-major 1x5 matrix slice.
|
/// A column-major 1x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice1x5<'a, N, RStride = U1, CStride = U1> =
|
pub type MatrixSlice1x5<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<N, U1, U5, SliceStorage<'a, N, U1, U5, RStride, CStride>>;
|
Matrix<T, U1, U5, SliceStorage<'a, T, U1, U5, RStride, CStride>>;
|
||||||
/// A column-major 1x6 matrix slice.
|
/// A column-major 1x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice1x6<'a, N, RStride = U1, CStride = U1> =
|
pub type MatrixSlice1x6<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<N, U1, U6, SliceStorage<'a, N, U1, U6, RStride, CStride>>;
|
Matrix<T, U1, U6, SliceStorage<'a, T, U1, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 2x1 matrix slice.
|
/// A column-major 2x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice2x1<'a, N, RStride = U1, CStride = U2> =
|
pub type MatrixSlice2x1<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<N, U2, U1, SliceStorage<'a, N, U2, U1, RStride, CStride>>;
|
Matrix<T, U2, U1, SliceStorage<'a, T, U2, U1, RStride, CStride>>;
|
||||||
/// A column-major 2x3 matrix slice.
|
/// A column-major 2x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice2x3<'a, N, RStride = U1, CStride = U2> =
|
pub type MatrixSlice2x3<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<N, U2, U3, SliceStorage<'a, N, U2, U3, RStride, CStride>>;
|
Matrix<T, U2, U3, SliceStorage<'a, T, U2, U3, RStride, CStride>>;
|
||||||
/// A column-major 2x4 matrix slice.
|
/// A column-major 2x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice2x4<'a, N, RStride = U1, CStride = U2> =
|
pub type MatrixSlice2x4<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<N, U2, U4, SliceStorage<'a, N, U2, U4, RStride, CStride>>;
|
Matrix<T, U2, U4, SliceStorage<'a, T, U2, U4, RStride, CStride>>;
|
||||||
/// A column-major 2x5 matrix slice.
|
/// A column-major 2x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice2x5<'a, N, RStride = U1, CStride = U2> =
|
pub type MatrixSlice2x5<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<N, U2, U5, SliceStorage<'a, N, U2, U5, RStride, CStride>>;
|
Matrix<T, U2, U5, SliceStorage<'a, T, U2, U5, RStride, CStride>>;
|
||||||
/// A column-major 2x6 matrix slice.
|
/// A column-major 2x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice2x6<'a, N, RStride = U1, CStride = U2> =
|
pub type MatrixSlice2x6<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<N, U2, U6, SliceStorage<'a, N, U2, U6, RStride, CStride>>;
|
Matrix<T, U2, U6, SliceStorage<'a, T, U2, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 3x1 matrix slice.
|
/// A column-major 3x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice3x1<'a, N, RStride = U1, CStride = U3> =
|
pub type MatrixSlice3x1<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<N, U3, U1, SliceStorage<'a, N, U3, U1, RStride, CStride>>;
|
Matrix<T, U3, U1, SliceStorage<'a, T, U3, U1, RStride, CStride>>;
|
||||||
/// A column-major 3x2 matrix slice.
|
/// A column-major 3x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice3x2<'a, N, RStride = U1, CStride = U3> =
|
pub type MatrixSlice3x2<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<N, U3, U2, SliceStorage<'a, N, U3, U2, RStride, CStride>>;
|
Matrix<T, U3, U2, SliceStorage<'a, T, U3, U2, RStride, CStride>>;
|
||||||
/// A column-major 3x4 matrix slice.
|
/// A column-major 3x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice3x4<'a, N, RStride = U1, CStride = U3> =
|
pub type MatrixSlice3x4<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<N, U3, U4, SliceStorage<'a, N, U3, U4, RStride, CStride>>;
|
Matrix<T, U3, U4, SliceStorage<'a, T, U3, U4, RStride, CStride>>;
|
||||||
/// A column-major 3x5 matrix slice.
|
/// A column-major 3x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice3x5<'a, N, RStride = U1, CStride = U3> =
|
pub type MatrixSlice3x5<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<N, U3, U5, SliceStorage<'a, N, U3, U5, RStride, CStride>>;
|
Matrix<T, U3, U5, SliceStorage<'a, T, U3, U5, RStride, CStride>>;
|
||||||
/// A column-major 3x6 matrix slice.
|
/// A column-major 3x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice3x6<'a, N, RStride = U1, CStride = U3> =
|
pub type MatrixSlice3x6<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<N, U3, U6, SliceStorage<'a, N, U3, U6, RStride, CStride>>;
|
Matrix<T, U3, U6, SliceStorage<'a, T, U3, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 4x1 matrix slice.
|
/// A column-major 4x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice4x1<'a, N, RStride = U1, CStride = U4> =
|
pub type MatrixSlice4x1<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<N, U4, U1, SliceStorage<'a, N, U4, U1, RStride, CStride>>;
|
Matrix<T, U4, U1, SliceStorage<'a, T, U4, U1, RStride, CStride>>;
|
||||||
/// A column-major 4x2 matrix slice.
|
/// A column-major 4x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice4x2<'a, N, RStride = U1, CStride = U4> =
|
pub type MatrixSlice4x2<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<N, U4, U2, SliceStorage<'a, N, U4, U2, RStride, CStride>>;
|
Matrix<T, U4, U2, SliceStorage<'a, T, U4, U2, RStride, CStride>>;
|
||||||
/// A column-major 4x3 matrix slice.
|
/// A column-major 4x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice4x3<'a, N, RStride = U1, CStride = U4> =
|
pub type MatrixSlice4x3<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<N, U4, U3, SliceStorage<'a, N, U4, U3, RStride, CStride>>;
|
Matrix<T, U4, U3, SliceStorage<'a, T, U4, U3, RStride, CStride>>;
|
||||||
/// A column-major 4x5 matrix slice.
|
/// A column-major 4x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice4x5<'a, N, RStride = U1, CStride = U4> =
|
pub type MatrixSlice4x5<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<N, U4, U5, SliceStorage<'a, N, U4, U5, RStride, CStride>>;
|
Matrix<T, U4, U5, SliceStorage<'a, T, U4, U5, RStride, CStride>>;
|
||||||
/// A column-major 4x6 matrix slice.
|
/// A column-major 4x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice4x6<'a, N, RStride = U1, CStride = U4> =
|
pub type MatrixSlice4x6<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<N, U4, U6, SliceStorage<'a, N, U4, U6, RStride, CStride>>;
|
Matrix<T, U4, U6, SliceStorage<'a, T, U4, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 5x1 matrix slice.
|
/// A column-major 5x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice5x1<'a, N, RStride = U1, CStride = U5> =
|
pub type MatrixSlice5x1<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<N, U5, U1, SliceStorage<'a, N, U5, U1, RStride, CStride>>;
|
Matrix<T, U5, U1, SliceStorage<'a, T, U5, U1, RStride, CStride>>;
|
||||||
/// A column-major 5x2 matrix slice.
|
/// A column-major 5x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice5x2<'a, N, RStride = U1, CStride = U5> =
|
pub type MatrixSlice5x2<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<N, U5, U2, SliceStorage<'a, N, U5, U2, RStride, CStride>>;
|
Matrix<T, U5, U2, SliceStorage<'a, T, U5, U2, RStride, CStride>>;
|
||||||
/// A column-major 5x3 matrix slice.
|
/// A column-major 5x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice5x3<'a, N, RStride = U1, CStride = U5> =
|
pub type MatrixSlice5x3<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<N, U5, U3, SliceStorage<'a, N, U5, U3, RStride, CStride>>;
|
Matrix<T, U5, U3, SliceStorage<'a, T, U5, U3, RStride, CStride>>;
|
||||||
/// A column-major 5x4 matrix slice.
|
/// A column-major 5x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice5x4<'a, N, RStride = U1, CStride = U5> =
|
pub type MatrixSlice5x4<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<N, U5, U4, SliceStorage<'a, N, U5, U4, RStride, CStride>>;
|
Matrix<T, U5, U4, SliceStorage<'a, T, U5, U4, RStride, CStride>>;
|
||||||
/// A column-major 5x6 matrix slice.
|
/// A column-major 5x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice5x6<'a, N, RStride = U1, CStride = U5> =
|
pub type MatrixSlice5x6<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<N, U5, U6, SliceStorage<'a, N, U5, U6, RStride, CStride>>;
|
Matrix<T, U5, U6, SliceStorage<'a, T, U5, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 6x1 matrix slice.
|
/// A column-major 6x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice6x1<'a, N, RStride = U1, CStride = U6> =
|
pub type MatrixSlice6x1<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<N, U6, U1, SliceStorage<'a, N, U6, U1, RStride, CStride>>;
|
Matrix<T, U6, U1, SliceStorage<'a, T, U6, U1, RStride, CStride>>;
|
||||||
/// A column-major 6x2 matrix slice.
|
/// A column-major 6x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice6x2<'a, N, RStride = U1, CStride = U6> =
|
pub type MatrixSlice6x2<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<N, U6, U2, SliceStorage<'a, N, U6, U2, RStride, CStride>>;
|
Matrix<T, U6, U2, SliceStorage<'a, T, U6, U2, RStride, CStride>>;
|
||||||
/// A column-major 6x3 matrix slice.
|
/// A column-major 6x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice6x3<'a, N, RStride = U1, CStride = U6> =
|
pub type MatrixSlice6x3<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<N, U6, U3, SliceStorage<'a, N, U6, U3, RStride, CStride>>;
|
Matrix<T, U6, U3, SliceStorage<'a, T, U6, U3, RStride, CStride>>;
|
||||||
/// A column-major 6x4 matrix slice.
|
/// A column-major 6x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice6x4<'a, N, RStride = U1, CStride = U6> =
|
pub type MatrixSlice6x4<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<N, U6, U4, SliceStorage<'a, N, U6, U4, RStride, CStride>>;
|
Matrix<T, U6, U4, SliceStorage<'a, T, U6, U4, RStride, CStride>>;
|
||||||
/// A column-major 6x5 matrix slice.
|
/// A column-major 6x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSlice6x5<'a, N, RStride = U1, CStride = U6> =
|
pub type MatrixSlice6x5<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<N, U6, U5, SliceStorage<'a, N, U6, U5, RStride, CStride>>;
|
Matrix<T, U6, U5, SliceStorage<'a, T, U6, U5, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major matrix slice with 1 row and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 1 row and a number of columns chosen at runtime.
|
||||||
pub type MatrixSlice1xX<'a, N, RStride = U1, CStride = U1> =
|
pub type MatrixSlice1xX<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<N, U1, Dynamic, SliceStorage<'a, N, U1, Dynamic, RStride, CStride>>;
|
Matrix<T, U1, Dynamic, SliceStorage<'a, T, U1, Dynamic, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with 2 rows and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 2 rows and a number of columns chosen at runtime.
|
||||||
pub type MatrixSlice2xX<'a, N, RStride = U1, CStride = U2> =
|
pub type MatrixSlice2xX<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<N, U2, Dynamic, SliceStorage<'a, N, U2, Dynamic, RStride, CStride>>;
|
Matrix<T, U2, Dynamic, SliceStorage<'a, T, U2, Dynamic, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with 3 rows and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 3 rows and a number of columns chosen at runtime.
|
||||||
pub type MatrixSlice3xX<'a, N, RStride = U1, CStride = U3> =
|
pub type MatrixSlice3xX<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<N, U3, Dynamic, SliceStorage<'a, N, U3, Dynamic, RStride, CStride>>;
|
Matrix<T, U3, Dynamic, SliceStorage<'a, T, U3, Dynamic, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with 4 rows and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 4 rows and a number of columns chosen at runtime.
|
||||||
pub type MatrixSlice4xX<'a, N, RStride = U1, CStride = U4> =
|
pub type MatrixSlice4xX<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<N, U4, Dynamic, SliceStorage<'a, N, U4, Dynamic, RStride, CStride>>;
|
Matrix<T, U4, Dynamic, SliceStorage<'a, T, U4, Dynamic, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with 5 rows and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 5 rows and a number of columns chosen at runtime.
|
||||||
pub type MatrixSlice5xX<'a, N, RStride = U1, CStride = U5> =
|
pub type MatrixSlice5xX<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<N, U5, Dynamic, SliceStorage<'a, N, U5, Dynamic, RStride, CStride>>;
|
Matrix<T, U5, Dynamic, SliceStorage<'a, T, U5, Dynamic, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with 6 rows and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 6 rows and a number of columns chosen at runtime.
|
||||||
pub type MatrixSlice6xX<'a, N, RStride = U1, CStride = U6> =
|
pub type MatrixSlice6xX<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<N, U6, Dynamic, SliceStorage<'a, N, U6, Dynamic, RStride, CStride>>;
|
Matrix<T, U6, Dynamic, SliceStorage<'a, T, U6, Dynamic, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 1 column.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 1 column.
|
||||||
pub type MatrixSliceXx1<'a, N, RStride = U1, CStride = Dynamic> =
|
pub type MatrixSliceXx1<'a, T, RStride = U1, CStride = Dynamic> =
|
||||||
Matrix<N, Dynamic, U1, SliceStorage<'a, N, Dynamic, U1, RStride, CStride>>;
|
Matrix<T, Dynamic, U1, SliceStorage<'a, T, Dynamic, U1, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 2 columns.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 2 columns.
|
||||||
pub type MatrixSliceXx2<'a, N, RStride = U1, CStride = Dynamic> =
|
pub type MatrixSliceXx2<'a, T, RStride = U1, CStride = Dynamic> =
|
||||||
Matrix<N, Dynamic, U2, SliceStorage<'a, N, Dynamic, U2, RStride, CStride>>;
|
Matrix<T, Dynamic, U2, SliceStorage<'a, T, Dynamic, U2, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 3 columns.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 3 columns.
|
||||||
pub type MatrixSliceXx3<'a, N, RStride = U1, CStride = Dynamic> =
|
pub type MatrixSliceXx3<'a, T, RStride = U1, CStride = Dynamic> =
|
||||||
Matrix<N, Dynamic, U3, SliceStorage<'a, N, Dynamic, U3, RStride, CStride>>;
|
Matrix<T, Dynamic, U3, SliceStorage<'a, T, Dynamic, U3, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 4 columns.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 4 columns.
|
||||||
pub type MatrixSliceXx4<'a, N, RStride = U1, CStride = Dynamic> =
|
pub type MatrixSliceXx4<'a, T, RStride = U1, CStride = Dynamic> =
|
||||||
Matrix<N, Dynamic, U4, SliceStorage<'a, N, Dynamic, U4, RStride, CStride>>;
|
Matrix<T, Dynamic, U4, SliceStorage<'a, T, Dynamic, U4, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 5 columns.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 5 columns.
|
||||||
pub type MatrixSliceXx5<'a, N, RStride = U1, CStride = Dynamic> =
|
pub type MatrixSliceXx5<'a, T, RStride = U1, CStride = Dynamic> =
|
||||||
Matrix<N, Dynamic, U5, SliceStorage<'a, N, Dynamic, U5, RStride, CStride>>;
|
Matrix<T, Dynamic, U5, SliceStorage<'a, T, Dynamic, U5, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 6 columns.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 6 columns.
|
||||||
pub type MatrixSliceXx6<'a, N, RStride = U1, CStride = Dynamic> =
|
pub type MatrixSliceXx6<'a, T, RStride = U1, CStride = Dynamic> =
|
||||||
Matrix<N, Dynamic, U6, SliceStorage<'a, N, Dynamic, U6, RStride, CStride>>;
|
Matrix<T, Dynamic, U6, SliceStorage<'a, T, Dynamic, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column vector slice with `D` rows.
|
/// A column vector slice with dimensions known at compile-time.
|
||||||
pub type VectorSliceN<'a, N, D, RStride = U1, CStride = D> =
|
///
|
||||||
Matrix<N, D, U1, SliceStorage<'a, N, D, U1, RStride, CStride>>;
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
pub type VectorSlice<'a, T, D, RStride = U1, CStride = D> =
|
||||||
|
Matrix<T, D, U1, SliceStorage<'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.**
|
||||||
|
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>>>;
|
||||||
|
|
||||||
/// A column vector slice dynamic numbers of rows and columns.
|
/// A column vector slice dynamic numbers of rows and columns.
|
||||||
pub type DVectorSlice<'a, N, RStride = U1, CStride = Dynamic> =
|
pub type DVectorSlice<'a, T, RStride = U1, CStride = Dynamic> =
|
||||||
Matrix<N, Dynamic, U1, SliceStorage<'a, N, Dynamic, U1, RStride, CStride>>;
|
Matrix<T, Dynamic, U1, SliceStorage<'a, T, Dynamic, U1, RStride, CStride>>;
|
||||||
|
|
||||||
/// A 1D column vector slice.
|
/// A 1D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type VectorSlice1<'a, N, RStride = U1, CStride = U1> =
|
pub type VectorSlice1<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<N, U1, U1, SliceStorage<'a, N, U1, U1, RStride, CStride>>;
|
Matrix<T, U1, U1, SliceStorage<'a, T, U1, U1, RStride, CStride>>;
|
||||||
/// A 2D column vector slice.
|
/// A 2D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type VectorSlice2<'a, N, RStride = U1, CStride = U2> =
|
pub type VectorSlice2<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<N, U2, U1, SliceStorage<'a, N, U2, U1, RStride, CStride>>;
|
Matrix<T, U2, U1, SliceStorage<'a, T, U2, U1, RStride, CStride>>;
|
||||||
/// A 3D column vector slice.
|
/// A 3D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type VectorSlice3<'a, N, RStride = U1, CStride = U3> =
|
pub type VectorSlice3<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<N, U3, U1, SliceStorage<'a, N, U3, U1, RStride, CStride>>;
|
Matrix<T, U3, U1, SliceStorage<'a, T, U3, U1, RStride, CStride>>;
|
||||||
/// A 4D column vector slice.
|
/// A 4D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type VectorSlice4<'a, N, RStride = U1, CStride = U4> =
|
pub type VectorSlice4<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<N, U4, U1, SliceStorage<'a, N, U4, U1, RStride, CStride>>;
|
Matrix<T, U4, U1, SliceStorage<'a, T, U4, U1, RStride, CStride>>;
|
||||||
/// A 5D column vector slice.
|
/// A 5D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type VectorSlice5<'a, N, RStride = U1, CStride = U5> =
|
pub type VectorSlice5<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<N, U5, U1, SliceStorage<'a, N, U5, U1, RStride, CStride>>;
|
Matrix<T, U5, U1, SliceStorage<'a, T, U5, U1, RStride, CStride>>;
|
||||||
/// A 6D column vector slice.
|
/// A 6D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type VectorSlice6<'a, N, RStride = U1, CStride = U6> =
|
pub type VectorSlice6<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<N, U6, U1, SliceStorage<'a, N, U6, U1, RStride, CStride>>;
|
Matrix<T, U6, U1, SliceStorage<'a, T, U6, U1, RStride, CStride>>;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
@ -301,281 +304,297 @@ pub type VectorSlice6<'a, N, RStride = U1, CStride = U6> =
|
||||||
/// A column-major matrix slice with `R` rows and `C` columns.
|
/// A column-major matrix slice with `R` rows and `C` columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMutMN<'a, N, R, C, RStride = U1, CStride = R> =
|
pub type MatrixSliceMutMN<'a, T, R, C, RStride = U1, CStride = R> =
|
||||||
Matrix<N, R, C, SliceStorageMut<'a, N, R, C, RStride, CStride>>;
|
Matrix<T, R, C, SliceStorageMut<'a, T, R, C, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major matrix slice with `D` rows and columns.
|
/// A column-major matrix slice with `D` rows and columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMutN<'a, N, D, RStride = U1, CStride = D> =
|
pub type MatrixSliceMutN<'a, T, D, RStride = U1, CStride = D> =
|
||||||
Matrix<N, D, D, SliceStorageMut<'a, N, D, D, RStride, CStride>>;
|
Matrix<T, D, D, SliceStorageMut<'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.**
|
||||||
|
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>>>;
|
||||||
|
|
||||||
/// A column-major matrix slice dynamic numbers of rows and columns.
|
/// A column-major matrix slice dynamic numbers of rows and columns.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type DMatrixSliceMut<'a, N, RStride = U1, CStride = Dynamic> =
|
pub type DMatrixSliceMut<'a, T, RStride = U1, CStride = Dynamic> =
|
||||||
Matrix<N, Dynamic, Dynamic, SliceStorageMut<'a, N, Dynamic, Dynamic, RStride, CStride>>;
|
Matrix<T, Dynamic, Dynamic, SliceStorageMut<'a, T, Dynamic, Dynamic, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 1x1 matrix slice.
|
/// A column-major 1x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut1<'a, N, RStride = U1, CStride = U1> =
|
pub type MatrixSliceMut1<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<N, U1, U1, SliceStorageMut<'a, N, U1, U1, RStride, CStride>>;
|
Matrix<T, U1, U1, SliceStorageMut<'a, T, U1, U1, RStride, CStride>>;
|
||||||
/// A column-major 2x2 matrix slice.
|
/// A column-major 2x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut2<'a, N, RStride = U1, CStride = U2> =
|
pub type MatrixSliceMut2<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<N, U2, U2, SliceStorageMut<'a, N, U2, U2, RStride, CStride>>;
|
Matrix<T, U2, U2, SliceStorageMut<'a, T, U2, U2, RStride, CStride>>;
|
||||||
/// A column-major 3x3 matrix slice.
|
/// A column-major 3x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut3<'a, N, RStride = U1, CStride = U3> =
|
pub type MatrixSliceMut3<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<N, U3, U3, SliceStorageMut<'a, N, U3, U3, RStride, CStride>>;
|
Matrix<T, U3, U3, SliceStorageMut<'a, T, U3, U3, RStride, CStride>>;
|
||||||
/// A column-major 4x4 matrix slice.
|
/// A column-major 4x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut4<'a, N, RStride = U1, CStride = U4> =
|
pub type MatrixSliceMut4<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<N, U4, U4, SliceStorageMut<'a, N, U4, U4, RStride, CStride>>;
|
Matrix<T, U4, U4, SliceStorageMut<'a, T, U4, U4, RStride, CStride>>;
|
||||||
/// A column-major 5x5 matrix slice.
|
/// A column-major 5x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut5<'a, N, RStride = U1, CStride = U5> =
|
pub type MatrixSliceMut5<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<N, U5, U5, SliceStorageMut<'a, N, U5, U5, RStride, CStride>>;
|
Matrix<T, U5, U5, SliceStorageMut<'a, T, U5, U5, RStride, CStride>>;
|
||||||
/// A column-major 6x6 matrix slice.
|
/// A column-major 6x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut6<'a, N, RStride = U1, CStride = U6> =
|
pub type MatrixSliceMut6<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<N, U6, U6, SliceStorageMut<'a, N, U6, U6, RStride, CStride>>;
|
Matrix<T, U6, U6, SliceStorageMut<'a, T, U6, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 1x2 matrix slice.
|
/// A column-major 1x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut1x2<'a, N, RStride = U1, CStride = U1> =
|
pub type MatrixSliceMut1x2<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<N, U1, U2, SliceStorageMut<'a, N, U1, U2, RStride, CStride>>;
|
Matrix<T, U1, U2, SliceStorageMut<'a, T, U1, U2, RStride, CStride>>;
|
||||||
/// A column-major 1x3 matrix slice.
|
/// A column-major 1x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut1x3<'a, N, RStride = U1, CStride = U1> =
|
pub type MatrixSliceMut1x3<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<N, U1, U3, SliceStorageMut<'a, N, U1, U3, RStride, CStride>>;
|
Matrix<T, U1, U3, SliceStorageMut<'a, T, U1, U3, RStride, CStride>>;
|
||||||
/// A column-major 1x4 matrix slice.
|
/// A column-major 1x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut1x4<'a, N, RStride = U1, CStride = U1> =
|
pub type MatrixSliceMut1x4<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<N, U1, U4, SliceStorageMut<'a, N, U1, U4, RStride, CStride>>;
|
Matrix<T, U1, U4, SliceStorageMut<'a, T, U1, U4, RStride, CStride>>;
|
||||||
/// A column-major 1x5 matrix slice.
|
/// A column-major 1x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut1x5<'a, N, RStride = U1, CStride = U1> =
|
pub type MatrixSliceMut1x5<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<N, U1, U5, SliceStorageMut<'a, N, U1, U5, RStride, CStride>>;
|
Matrix<T, U1, U5, SliceStorageMut<'a, T, U1, U5, RStride, CStride>>;
|
||||||
/// A column-major 1x6 matrix slice.
|
/// A column-major 1x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut1x6<'a, N, RStride = U1, CStride = U1> =
|
pub type MatrixSliceMut1x6<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<N, U1, U6, SliceStorageMut<'a, N, U1, U6, RStride, CStride>>;
|
Matrix<T, U1, U6, SliceStorageMut<'a, T, U1, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 2x1 matrix slice.
|
/// A column-major 2x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut2x1<'a, N, RStride = U1, CStride = U2> =
|
pub type MatrixSliceMut2x1<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<N, U2, U1, SliceStorageMut<'a, N, U2, U1, RStride, CStride>>;
|
Matrix<T, U2, U1, SliceStorageMut<'a, T, U2, U1, RStride, CStride>>;
|
||||||
/// A column-major 2x3 matrix slice.
|
/// A column-major 2x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut2x3<'a, N, RStride = U1, CStride = U2> =
|
pub type MatrixSliceMut2x3<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<N, U2, U3, SliceStorageMut<'a, N, U2, U3, RStride, CStride>>;
|
Matrix<T, U2, U3, SliceStorageMut<'a, T, U2, U3, RStride, CStride>>;
|
||||||
/// A column-major 2x4 matrix slice.
|
/// A column-major 2x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut2x4<'a, N, RStride = U1, CStride = U2> =
|
pub type MatrixSliceMut2x4<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<N, U2, U4, SliceStorageMut<'a, N, U2, U4, RStride, CStride>>;
|
Matrix<T, U2, U4, SliceStorageMut<'a, T, U2, U4, RStride, CStride>>;
|
||||||
/// A column-major 2x5 matrix slice.
|
/// A column-major 2x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut2x5<'a, N, RStride = U1, CStride = U2> =
|
pub type MatrixSliceMut2x5<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<N, U2, U5, SliceStorageMut<'a, N, U2, U5, RStride, CStride>>;
|
Matrix<T, U2, U5, SliceStorageMut<'a, T, U2, U5, RStride, CStride>>;
|
||||||
/// A column-major 2x6 matrix slice.
|
/// A column-major 2x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut2x6<'a, N, RStride = U1, CStride = U2> =
|
pub type MatrixSliceMut2x6<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<N, U2, U6, SliceStorageMut<'a, N, U2, U6, RStride, CStride>>;
|
Matrix<T, U2, U6, SliceStorageMut<'a, T, U2, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 3x1 matrix slice.
|
/// A column-major 3x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut3x1<'a, N, RStride = U1, CStride = U3> =
|
pub type MatrixSliceMut3x1<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<N, U3, U1, SliceStorageMut<'a, N, U3, U1, RStride, CStride>>;
|
Matrix<T, U3, U1, SliceStorageMut<'a, T, U3, U1, RStride, CStride>>;
|
||||||
/// A column-major 3x2 matrix slice.
|
/// A column-major 3x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut3x2<'a, N, RStride = U1, CStride = U3> =
|
pub type MatrixSliceMut3x2<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<N, U3, U2, SliceStorageMut<'a, N, U3, U2, RStride, CStride>>;
|
Matrix<T, U3, U2, SliceStorageMut<'a, T, U3, U2, RStride, CStride>>;
|
||||||
/// A column-major 3x4 matrix slice.
|
/// A column-major 3x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut3x4<'a, N, RStride = U1, CStride = U3> =
|
pub type MatrixSliceMut3x4<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<N, U3, U4, SliceStorageMut<'a, N, U3, U4, RStride, CStride>>;
|
Matrix<T, U3, U4, SliceStorageMut<'a, T, U3, U4, RStride, CStride>>;
|
||||||
/// A column-major 3x5 matrix slice.
|
/// A column-major 3x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut3x5<'a, N, RStride = U1, CStride = U3> =
|
pub type MatrixSliceMut3x5<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<N, U3, U5, SliceStorageMut<'a, N, U3, U5, RStride, CStride>>;
|
Matrix<T, U3, U5, SliceStorageMut<'a, T, U3, U5, RStride, CStride>>;
|
||||||
/// A column-major 3x6 matrix slice.
|
/// A column-major 3x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut3x6<'a, N, RStride = U1, CStride = U3> =
|
pub type MatrixSliceMut3x6<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<N, U3, U6, SliceStorageMut<'a, N, U3, U6, RStride, CStride>>;
|
Matrix<T, U3, U6, SliceStorageMut<'a, T, U3, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 4x1 matrix slice.
|
/// A column-major 4x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut4x1<'a, N, RStride = U1, CStride = U4> =
|
pub type MatrixSliceMut4x1<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<N, U4, U1, SliceStorageMut<'a, N, U4, U1, RStride, CStride>>;
|
Matrix<T, U4, U1, SliceStorageMut<'a, T, U4, U1, RStride, CStride>>;
|
||||||
/// A column-major 4x2 matrix slice.
|
/// A column-major 4x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut4x2<'a, N, RStride = U1, CStride = U4> =
|
pub type MatrixSliceMut4x2<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<N, U4, U2, SliceStorageMut<'a, N, U4, U2, RStride, CStride>>;
|
Matrix<T, U4, U2, SliceStorageMut<'a, T, U4, U2, RStride, CStride>>;
|
||||||
/// A column-major 4x3 matrix slice.
|
/// A column-major 4x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut4x3<'a, N, RStride = U1, CStride = U4> =
|
pub type MatrixSliceMut4x3<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<N, U4, U3, SliceStorageMut<'a, N, U4, U3, RStride, CStride>>;
|
Matrix<T, U4, U3, SliceStorageMut<'a, T, U4, U3, RStride, CStride>>;
|
||||||
/// A column-major 4x5 matrix slice.
|
/// A column-major 4x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut4x5<'a, N, RStride = U1, CStride = U4> =
|
pub type MatrixSliceMut4x5<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<N, U4, U5, SliceStorageMut<'a, N, U4, U5, RStride, CStride>>;
|
Matrix<T, U4, U5, SliceStorageMut<'a, T, U4, U5, RStride, CStride>>;
|
||||||
/// A column-major 4x6 matrix slice.
|
/// A column-major 4x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut4x6<'a, N, RStride = U1, CStride = U4> =
|
pub type MatrixSliceMut4x6<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<N, U4, U6, SliceStorageMut<'a, N, U4, U6, RStride, CStride>>;
|
Matrix<T, U4, U6, SliceStorageMut<'a, T, U4, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 5x1 matrix slice.
|
/// A column-major 5x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut5x1<'a, N, RStride = U1, CStride = U5> =
|
pub type MatrixSliceMut5x1<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<N, U5, U1, SliceStorageMut<'a, N, U5, U1, RStride, CStride>>;
|
Matrix<T, U5, U1, SliceStorageMut<'a, T, U5, U1, RStride, CStride>>;
|
||||||
/// A column-major 5x2 matrix slice.
|
/// A column-major 5x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut5x2<'a, N, RStride = U1, CStride = U5> =
|
pub type MatrixSliceMut5x2<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<N, U5, U2, SliceStorageMut<'a, N, U5, U2, RStride, CStride>>;
|
Matrix<T, U5, U2, SliceStorageMut<'a, T, U5, U2, RStride, CStride>>;
|
||||||
/// A column-major 5x3 matrix slice.
|
/// A column-major 5x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut5x3<'a, N, RStride = U1, CStride = U5> =
|
pub type MatrixSliceMut5x3<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<N, U5, U3, SliceStorageMut<'a, N, U5, U3, RStride, CStride>>;
|
Matrix<T, U5, U3, SliceStorageMut<'a, T, U5, U3, RStride, CStride>>;
|
||||||
/// A column-major 5x4 matrix slice.
|
/// A column-major 5x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut5x4<'a, N, RStride = U1, CStride = U5> =
|
pub type MatrixSliceMut5x4<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<N, U5, U4, SliceStorageMut<'a, N, U5, U4, RStride, CStride>>;
|
Matrix<T, U5, U4, SliceStorageMut<'a, T, U5, U4, RStride, CStride>>;
|
||||||
/// A column-major 5x6 matrix slice.
|
/// A column-major 5x6 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut5x6<'a, N, RStride = U1, CStride = U5> =
|
pub type MatrixSliceMut5x6<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<N, U5, U6, SliceStorageMut<'a, N, U5, U6, RStride, CStride>>;
|
Matrix<T, U5, U6, SliceStorageMut<'a, T, U5, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major 6x1 matrix slice.
|
/// A column-major 6x1 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut6x1<'a, N, RStride = U1, CStride = U6> =
|
pub type MatrixSliceMut6x1<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<N, U6, U1, SliceStorageMut<'a, N, U6, U1, RStride, CStride>>;
|
Matrix<T, U6, U1, SliceStorageMut<'a, T, U6, U1, RStride, CStride>>;
|
||||||
/// A column-major 6x2 matrix slice.
|
/// A column-major 6x2 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut6x2<'a, N, RStride = U1, CStride = U6> =
|
pub type MatrixSliceMut6x2<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<N, U6, U2, SliceStorageMut<'a, N, U6, U2, RStride, CStride>>;
|
Matrix<T, U6, U2, SliceStorageMut<'a, T, U6, U2, RStride, CStride>>;
|
||||||
/// A column-major 6x3 matrix slice.
|
/// A column-major 6x3 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut6x3<'a, N, RStride = U1, CStride = U6> =
|
pub type MatrixSliceMut6x3<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<N, U6, U3, SliceStorageMut<'a, N, U6, U3, RStride, CStride>>;
|
Matrix<T, U6, U3, SliceStorageMut<'a, T, U6, U3, RStride, CStride>>;
|
||||||
/// A column-major 6x4 matrix slice.
|
/// A column-major 6x4 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut6x4<'a, N, RStride = U1, CStride = U6> =
|
pub type MatrixSliceMut6x4<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<N, U6, U4, SliceStorageMut<'a, N, U6, U4, RStride, CStride>>;
|
Matrix<T, U6, U4, SliceStorageMut<'a, T, U6, U4, RStride, CStride>>;
|
||||||
/// A column-major 6x5 matrix slice.
|
/// A column-major 6x5 matrix slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type MatrixSliceMut6x5<'a, N, RStride = U1, CStride = U6> =
|
pub type MatrixSliceMut6x5<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<N, U6, U5, SliceStorageMut<'a, N, U6, U5, RStride, CStride>>;
|
Matrix<T, U6, U5, SliceStorageMut<'a, T, U6, U5, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major matrix slice with 1 row and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 1 row and a number of columns chosen at runtime.
|
||||||
pub type MatrixSliceMut1xX<'a, N, RStride = U1, CStride = U1> =
|
pub type MatrixSliceMut1xX<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<N, U1, Dynamic, SliceStorageMut<'a, N, U1, Dynamic, RStride, CStride>>;
|
Matrix<T, U1, Dynamic, SliceStorageMut<'a, T, U1, Dynamic, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with 2 rows and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 2 rows and a number of columns chosen at runtime.
|
||||||
pub type MatrixSliceMut2xX<'a, N, RStride = U1, CStride = U2> =
|
pub type MatrixSliceMut2xX<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<N, U2, Dynamic, SliceStorageMut<'a, N, U2, Dynamic, RStride, CStride>>;
|
Matrix<T, U2, Dynamic, SliceStorageMut<'a, T, U2, Dynamic, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with 3 rows and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 3 rows and a number of columns chosen at runtime.
|
||||||
pub type MatrixSliceMut3xX<'a, N, RStride = U1, CStride = U3> =
|
pub type MatrixSliceMut3xX<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<N, U3, Dynamic, SliceStorageMut<'a, N, U3, Dynamic, RStride, CStride>>;
|
Matrix<T, U3, Dynamic, SliceStorageMut<'a, T, U3, Dynamic, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with 4 rows and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 4 rows and a number of columns chosen at runtime.
|
||||||
pub type MatrixSliceMut4xX<'a, N, RStride = U1, CStride = U4> =
|
pub type MatrixSliceMut4xX<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<N, U4, Dynamic, SliceStorageMut<'a, N, U4, Dynamic, RStride, CStride>>;
|
Matrix<T, U4, Dynamic, SliceStorageMut<'a, T, U4, Dynamic, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with 5 rows and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 5 rows and a number of columns chosen at runtime.
|
||||||
pub type MatrixSliceMut5xX<'a, N, RStride = U1, CStride = U5> =
|
pub type MatrixSliceMut5xX<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<N, U5, Dynamic, SliceStorageMut<'a, N, U5, Dynamic, RStride, CStride>>;
|
Matrix<T, U5, Dynamic, SliceStorageMut<'a, T, U5, Dynamic, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with 6 rows and a number of columns chosen at runtime.
|
/// A column-major matrix slice with 6 rows and a number of columns chosen at runtime.
|
||||||
pub type MatrixSliceMut6xX<'a, N, RStride = U1, CStride = U6> =
|
pub type MatrixSliceMut6xX<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<N, U6, Dynamic, SliceStorageMut<'a, N, U6, Dynamic, RStride, CStride>>;
|
Matrix<T, U6, Dynamic, SliceStorageMut<'a, T, U6, Dynamic, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 1 column.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 1 column.
|
||||||
pub type MatrixSliceMutXx1<'a, N, RStride = U1, CStride = Dynamic> =
|
pub type MatrixSliceMutXx1<'a, T, RStride = U1, CStride = Dynamic> =
|
||||||
Matrix<N, Dynamic, U1, SliceStorageMut<'a, N, Dynamic, U1, RStride, CStride>>;
|
Matrix<T, Dynamic, U1, SliceStorageMut<'a, T, Dynamic, U1, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 2 columns.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 2 columns.
|
||||||
pub type MatrixSliceMutXx2<'a, N, RStride = U1, CStride = Dynamic> =
|
pub type MatrixSliceMutXx2<'a, T, RStride = U1, CStride = Dynamic> =
|
||||||
Matrix<N, Dynamic, U2, SliceStorageMut<'a, N, Dynamic, U2, RStride, CStride>>;
|
Matrix<T, Dynamic, U2, SliceStorageMut<'a, T, Dynamic, U2, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 3 columns.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 3 columns.
|
||||||
pub type MatrixSliceMutXx3<'a, N, RStride = U1, CStride = Dynamic> =
|
pub type MatrixSliceMutXx3<'a, T, RStride = U1, CStride = Dynamic> =
|
||||||
Matrix<N, Dynamic, U3, SliceStorageMut<'a, N, Dynamic, U3, RStride, CStride>>;
|
Matrix<T, Dynamic, U3, SliceStorageMut<'a, T, Dynamic, U3, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 4 columns.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 4 columns.
|
||||||
pub type MatrixSliceMutXx4<'a, N, RStride = U1, CStride = Dynamic> =
|
pub type MatrixSliceMutXx4<'a, T, RStride = U1, CStride = Dynamic> =
|
||||||
Matrix<N, Dynamic, U4, SliceStorageMut<'a, N, Dynamic, U4, RStride, CStride>>;
|
Matrix<T, Dynamic, U4, SliceStorageMut<'a, T, Dynamic, U4, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 5 columns.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 5 columns.
|
||||||
pub type MatrixSliceMutXx5<'a, N, RStride = U1, CStride = Dynamic> =
|
pub type MatrixSliceMutXx5<'a, T, RStride = U1, CStride = Dynamic> =
|
||||||
Matrix<N, Dynamic, U5, SliceStorageMut<'a, N, Dynamic, U5, RStride, CStride>>;
|
Matrix<T, Dynamic, U5, SliceStorageMut<'a, T, Dynamic, U5, RStride, CStride>>;
|
||||||
/// A column-major matrix slice with a number of rows chosen at runtime and 6 columns.
|
/// A column-major matrix slice with a number of rows chosen at runtime and 6 columns.
|
||||||
pub type MatrixSliceMutXx6<'a, N, RStride = U1, CStride = Dynamic> =
|
pub type MatrixSliceMutXx6<'a, T, RStride = U1, CStride = Dynamic> =
|
||||||
Matrix<N, Dynamic, U6, SliceStorageMut<'a, N, Dynamic, U6, RStride, CStride>>;
|
Matrix<T, Dynamic, U6, SliceStorageMut<'a, T, Dynamic, U6, RStride, CStride>>;
|
||||||
|
|
||||||
/// A column vector slice with `D` rows.
|
/// A column vector slice with dimensions known at compile-time.
|
||||||
pub type VectorSliceMutN<'a, N, D, RStride = U1, CStride = D> =
|
///
|
||||||
Matrix<N, D, U1, SliceStorageMut<'a, N, D, U1, RStride, CStride>>;
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
|
pub type VectorSliceMut<'a, T, D, RStride = U1, CStride = D> =
|
||||||
|
Matrix<T, D, U1, SliceStorageMut<'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.**
|
||||||
|
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>>>;
|
||||||
|
|
||||||
/// A column vector slice dynamic numbers of rows and columns.
|
/// A column vector slice dynamic numbers of rows and columns.
|
||||||
pub type DVectorSliceMut<'a, N, RStride = U1, CStride = Dynamic> =
|
///
|
||||||
Matrix<N, Dynamic, U1, SliceStorageMut<'a, N, Dynamic, U1, RStride, CStride>>;
|
/// **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>>;
|
||||||
|
|
||||||
/// A 1D column vector slice.
|
/// A 1D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type VectorSliceMut1<'a, N, RStride = U1, CStride = U1> =
|
pub type VectorSliceMut1<'a, T, RStride = U1, CStride = U1> =
|
||||||
Matrix<N, U1, U1, SliceStorageMut<'a, N, U1, U1, RStride, CStride>>;
|
Matrix<T, U1, U1, SliceStorageMut<'a, T, U1, U1, RStride, CStride>>;
|
||||||
/// A 2D column vector slice.
|
/// A 2D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type VectorSliceMut2<'a, N, RStride = U1, CStride = U2> =
|
pub type VectorSliceMut2<'a, T, RStride = U1, CStride = U2> =
|
||||||
Matrix<N, U2, U1, SliceStorageMut<'a, N, U2, U1, RStride, CStride>>;
|
Matrix<T, U2, U1, SliceStorageMut<'a, T, U2, U1, RStride, CStride>>;
|
||||||
/// A 3D column vector slice.
|
/// A 3D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type VectorSliceMut3<'a, N, RStride = U1, CStride = U3> =
|
pub type VectorSliceMut3<'a, T, RStride = U1, CStride = U3> =
|
||||||
Matrix<N, U3, U1, SliceStorageMut<'a, N, U3, U1, RStride, CStride>>;
|
Matrix<T, U3, U1, SliceStorageMut<'a, T, U3, U1, RStride, CStride>>;
|
||||||
/// A 4D column vector slice.
|
/// A 4D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type VectorSliceMut4<'a, N, RStride = U1, CStride = U4> =
|
pub type VectorSliceMut4<'a, T, RStride = U1, CStride = U4> =
|
||||||
Matrix<N, U4, U1, SliceStorageMut<'a, N, U4, U1, RStride, CStride>>;
|
Matrix<T, U4, U1, SliceStorageMut<'a, T, U4, U1, RStride, CStride>>;
|
||||||
/// A 5D column vector slice.
|
/// A 5D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type VectorSliceMut5<'a, N, RStride = U1, CStride = U5> =
|
pub type VectorSliceMut5<'a, T, RStride = U1, CStride = U5> =
|
||||||
Matrix<N, U5, U1, SliceStorageMut<'a, N, U5, U1, RStride, CStride>>;
|
Matrix<T, U5, U1, SliceStorageMut<'a, T, U5, U1, RStride, CStride>>;
|
||||||
/// A 6D column vector slice.
|
/// A 6D column vector slice.
|
||||||
///
|
///
|
||||||
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
|
||||||
pub type VectorSliceMut6<'a, N, RStride = U1, CStride = U6> =
|
pub type VectorSliceMut6<'a, T, RStride = U1, CStride = U6> =
|
||||||
Matrix<N, U6, U1, SliceStorageMut<'a, N, U6, U1, RStride, CStride>>;
|
Matrix<T, U6, U1, SliceStorageMut<'a, T, U6, U1, RStride, CStride>>;
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::base::storage::ContiguousStorageMut;
|
||||||
use crate::base::{DefaultAllocator, Scalar};
|
use crate::base::{DefaultAllocator, Scalar};
|
||||||
|
|
||||||
/// A matrix allocator of a memory buffer that may contain `R::to_usize() * C::to_usize()`
|
/// A matrix allocator of a memory buffer that may contain `R::to_usize() * C::to_usize()`
|
||||||
/// elements of type `N`.
|
/// elements of type `T`.
|
||||||
///
|
///
|
||||||
/// An allocator is said to be:
|
/// An allocator is said to be:
|
||||||
/// − static: if `R` and `C` both implement `DimName`.
|
/// − static: if `R` and `C` both implement `DimName`.
|
||||||
|
@ -17,15 +17,15 @@ use crate::base::{DefaultAllocator, Scalar};
|
||||||
///
|
///
|
||||||
/// Every allocator must be both static and dynamic. Though not all implementations may share the
|
/// Every allocator must be both static and dynamic. Though not all implementations may share the
|
||||||
/// same `Buffer` type.
|
/// same `Buffer` type.
|
||||||
pub trait Allocator<N: Scalar, R: Dim, C: Dim = U1>: Any + Sized {
|
pub trait Allocator<T: Scalar, R: Dim, C: Dim = U1>: Any + Sized {
|
||||||
/// The type of buffer this allocator can instanciate.
|
/// The type of buffer this allocator can instanciate.
|
||||||
type Buffer: ContiguousStorageMut<N, R, C> + Clone;
|
type Buffer: ContiguousStorageMut<T, R, C> + Clone;
|
||||||
|
|
||||||
/// Allocates a buffer with the given number of rows and columns without initializing its content.
|
/// Allocates a buffer with the given number of rows and columns without initializing its content.
|
||||||
unsafe fn allocate_uninitialized(nrows: R, ncols: C) -> mem::MaybeUninit<Self::Buffer>;
|
unsafe fn allocate_uninitialized(nrows: R, ncols: C) -> mem::MaybeUninit<Self::Buffer>;
|
||||||
|
|
||||||
/// Allocates a buffer initialized with the content of the given iterator.
|
/// Allocates a buffer initialized with the content of the given iterator.
|
||||||
fn allocate_from_iterator<I: IntoIterator<Item = N>>(
|
fn allocate_from_iterator<I: IntoIterator<Item = T>>(
|
||||||
nrows: R,
|
nrows: R,
|
||||||
ncols: C,
|
ncols: C,
|
||||||
iter: I,
|
iter: I,
|
||||||
|
@ -34,8 +34,8 @@ pub trait Allocator<N: Scalar, R: Dim, C: Dim = U1>: Any + Sized {
|
||||||
|
|
||||||
/// A matrix reallocator. Changes the size of the memory buffer that initially contains (RFrom ×
|
/// A matrix reallocator. Changes the size of the memory buffer that initially contains (RFrom ×
|
||||||
/// CFrom) elements to a smaller or larger size (RTo, CTo).
|
/// CFrom) elements to a smaller or larger size (RTo, CTo).
|
||||||
pub trait Reallocator<N: Scalar, RFrom: Dim, CFrom: Dim, RTo: Dim, CTo: Dim>:
|
pub trait Reallocator<T: Scalar, RFrom: Dim, CFrom: Dim, RTo: Dim, CTo: Dim>:
|
||||||
Allocator<N, RFrom, CFrom> + Allocator<N, RTo, CTo>
|
Allocator<T, RFrom, CFrom> + Allocator<T, RTo, CTo>
|
||||||
{
|
{
|
||||||
/// Reallocates a buffer of shape `(RTo, CTo)`, possibly reusing a previously allocated buffer
|
/// Reallocates a buffer of shape `(RTo, CTo)`, possibly reusing a previously allocated buffer
|
||||||
/// `buf`. Data stored by `buf` are linearly copied to the output:
|
/// `buf`. Data stored by `buf` are linearly copied to the output:
|
||||||
|
@ -47,8 +47,8 @@ pub trait Reallocator<N: Scalar, RFrom: Dim, CFrom: Dim, RTo: Dim, CTo: Dim>:
|
||||||
unsafe fn reallocate_copy(
|
unsafe fn reallocate_copy(
|
||||||
nrows: RTo,
|
nrows: RTo,
|
||||||
ncols: CTo,
|
ncols: CTo,
|
||||||
buf: <Self as Allocator<N, RFrom, CFrom>>::Buffer,
|
buf: <Self as Allocator<T, RFrom, CFrom>>::Buffer,
|
||||||
) -> <Self as Allocator<N, RTo, CTo>>::Buffer;
|
) -> <Self as Allocator<T, RTo, CTo>>::Buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The number of rows of the result of a componentwise operation on two matrices.
|
/// The number of rows of the result of a componentwise operation on two matrices.
|
||||||
|
@ -59,48 +59,48 @@ pub type SameShapeC<C1, C2> = <ShapeConstraint as SameNumberOfColumns<C1, C2>>::
|
||||||
|
|
||||||
// TODO: Bad name.
|
// TODO: Bad name.
|
||||||
/// Restricts the given number of rows and columns to be respectively the same.
|
/// Restricts the given number of rows and columns to be respectively the same.
|
||||||
pub trait SameShapeAllocator<N, R1, C1, R2, C2>:
|
pub trait SameShapeAllocator<T, R1, C1, R2, C2>:
|
||||||
Allocator<N, R1, C1> + Allocator<N, SameShapeR<R1, R2>, SameShapeC<C1, C2>>
|
Allocator<T, R1, C1> + Allocator<T, SameShapeR<R1, R2>, SameShapeC<C1, C2>>
|
||||||
where
|
where
|
||||||
R1: Dim,
|
R1: Dim,
|
||||||
R2: Dim,
|
R2: Dim,
|
||||||
C1: Dim,
|
C1: Dim,
|
||||||
C2: Dim,
|
C2: Dim,
|
||||||
N: Scalar,
|
T: Scalar,
|
||||||
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>,
|
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, R1, R2, C1, C2> SameShapeAllocator<N, R1, C1, R2, C2> for DefaultAllocator
|
impl<T, R1, R2, C1, C2> SameShapeAllocator<T, R1, C1, R2, C2> for DefaultAllocator
|
||||||
where
|
where
|
||||||
R1: Dim,
|
R1: Dim,
|
||||||
R2: Dim,
|
R2: Dim,
|
||||||
C1: Dim,
|
C1: Dim,
|
||||||
C2: Dim,
|
C2: Dim,
|
||||||
N: Scalar,
|
T: Scalar,
|
||||||
DefaultAllocator: Allocator<N, R1, C1> + Allocator<N, SameShapeR<R1, R2>, SameShapeC<C1, C2>>,
|
DefaultAllocator: Allocator<T, R1, C1> + Allocator<T, SameShapeR<R1, R2>, SameShapeC<C1, C2>>,
|
||||||
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>,
|
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX: Bad name.
|
// XXX: Bad name.
|
||||||
/// Restricts the given number of rows to be equal.
|
/// Restricts the given number of rows to be equal.
|
||||||
pub trait SameShapeVectorAllocator<N, R1, R2>:
|
pub trait SameShapeVectorAllocator<T, R1, R2>:
|
||||||
Allocator<N, R1> + Allocator<N, SameShapeR<R1, R2>> + SameShapeAllocator<N, R1, U1, R2, U1>
|
Allocator<T, R1> + Allocator<T, SameShapeR<R1, R2>> + SameShapeAllocator<T, R1, U1, R2, U1>
|
||||||
where
|
where
|
||||||
R1: Dim,
|
R1: Dim,
|
||||||
R2: Dim,
|
R2: Dim,
|
||||||
N: Scalar,
|
T: Scalar,
|
||||||
ShapeConstraint: SameNumberOfRows<R1, R2>,
|
ShapeConstraint: SameNumberOfRows<R1, R2>,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, R1, R2> SameShapeVectorAllocator<N, R1, R2> for DefaultAllocator
|
impl<T, R1, R2> SameShapeVectorAllocator<T, R1, R2> for DefaultAllocator
|
||||||
where
|
where
|
||||||
R1: Dim,
|
R1: Dim,
|
||||||
R2: Dim,
|
R2: Dim,
|
||||||
N: Scalar,
|
T: Scalar,
|
||||||
DefaultAllocator: Allocator<N, R1, U1> + Allocator<N, SameShapeR<R1, R2>>,
|
DefaultAllocator: Allocator<T, R1, U1> + Allocator<T, SameShapeR<R1, R2>>,
|
||||||
ShapeConstraint: SameNumberOfRows<R1, R2>,
|
ShapeConstraint: SameNumberOfRows<R1, R2>,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,26 @@
|
||||||
use std::fmt::{self, Debug, Formatter};
|
use std::fmt::{self, Debug, Formatter};
|
||||||
use std::hash::{Hash, Hasher};
|
// use std::hash::{Hash, Hasher};
|
||||||
#[cfg(feature = "abomonation-serialize")]
|
#[cfg(feature = "abomonation-serialize")]
|
||||||
use std::io::{Result as IOResult, Write};
|
use std::io::{Result as IOResult, Write};
|
||||||
use std::ops::{Deref, DerefMut, Mul};
|
use std::ops::Mul;
|
||||||
|
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize-no-std")]
|
||||||
use serde::de::{Error, SeqAccess, Visitor};
|
use serde::de::{Error, SeqAccess, Visitor};
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize-no-std")]
|
||||||
use serde::ser::SerializeSeq;
|
use serde::ser::SerializeSeq;
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize-no-std")]
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize-no-std")]
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize-no-std")]
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
#[cfg(feature = "abomonation-serialize")]
|
#[cfg(feature = "abomonation-serialize")]
|
||||||
use abomonation::Abomonation;
|
use abomonation::Abomonation;
|
||||||
|
|
||||||
use generic_array::{ArrayLength, GenericArray};
|
|
||||||
use typenum::Prod;
|
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use crate::base::default_allocator::DefaultAllocator;
|
use crate::base::default_allocator::DefaultAllocator;
|
||||||
use crate::base::dimension::{DimName, U1};
|
use crate::base::dimension::{Const, ToTypenum};
|
||||||
use crate::base::storage::{
|
use crate::base::storage::{
|
||||||
ContiguousStorage, ContiguousStorageMut, Owned, ReshapableStorage, Storage, StorageMut,
|
ContiguousStorage, ContiguousStorageMut, Owned, ReshapableStorage, Storage, StorageMut,
|
||||||
};
|
};
|
||||||
|
@ -36,166 +33,49 @@ use crate::base::Scalar;
|
||||||
*/
|
*/
|
||||||
/// A array-based statically sized matrix data storage.
|
/// A array-based statically sized matrix data storage.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct ArrayStorage<N, R, C>
|
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
where
|
pub struct ArrayStorage<T, const R: usize, const C: usize>(pub [[T; R]; C]);
|
||||||
R: DimName,
|
|
||||||
C: DimName,
|
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
{
|
|
||||||
data: GenericArray<N, Prod<R::Value, C::Value>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[deprecated(note = "renamed to `ArrayStorage`")]
|
// TODO: remove this once the stdlib implements Default for arrays.
|
||||||
/// Renamed to [ArrayStorage].
|
impl<T: Default, const R: usize, const C: usize> Default for ArrayStorage<T, R, C>
|
||||||
pub type MatrixArray<N, R, C> = ArrayStorage<N, R, C>;
|
|
||||||
|
|
||||||
impl<N, R, C> Default for ArrayStorage<N, R, C>
|
|
||||||
where
|
where
|
||||||
R: DimName,
|
[[T; R]; C]: Default,
|
||||||
C: DimName,
|
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
N: Default,
|
|
||||||
{
|
{
|
||||||
|
#[inline]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
ArrayStorage {
|
Self(Default::default())
|
||||||
data: Default::default(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, R, C> Hash for ArrayStorage<N, R, C>
|
impl<T: Debug, const R: usize, const C: usize> Debug for ArrayStorage<T, R, C> {
|
||||||
where
|
|
||||||
N: Hash,
|
|
||||||
R: DimName,
|
|
||||||
C: DimName,
|
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
{
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
||||||
self.data[..].hash(state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N, R, C> Deref for ArrayStorage<N, R, C>
|
|
||||||
where
|
|
||||||
R: DimName,
|
|
||||||
C: DimName,
|
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
{
|
|
||||||
type Target = GenericArray<N, Prod<R::Value, C::Value>>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
&self.data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N, R, C> DerefMut for ArrayStorage<N, R, C>
|
|
||||||
where
|
|
||||||
R: DimName,
|
|
||||||
C: DimName,
|
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
||||||
&mut self.data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N, R, C> Debug for ArrayStorage<N, R, C>
|
|
||||||
where
|
|
||||||
N: Debug,
|
|
||||||
R: DimName,
|
|
||||||
C: DimName,
|
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
{
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
|
||||||
self.data.fmt(fmt)
|
self.0.fmt(fmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, R, C> Copy for ArrayStorage<N, R, C>
|
unsafe impl<T, const R: usize, const C: usize> Storage<T, Const<R>, Const<C>>
|
||||||
|
for ArrayStorage<T, R, C>
|
||||||
where
|
where
|
||||||
N: Copy,
|
T: Scalar,
|
||||||
R: DimName,
|
DefaultAllocator: Allocator<T, Const<R>, Const<C>, Buffer = Self>,
|
||||||
C: DimName,
|
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
GenericArray<N, Prod<R::Value, C::Value>>: Copy,
|
|
||||||
{
|
{
|
||||||
}
|
type RStride = Const<1>;
|
||||||
|
type CStride = Const<R>;
|
||||||
impl<N, R, C> Clone for ArrayStorage<N, R, C>
|
|
||||||
where
|
|
||||||
N: Clone,
|
|
||||||
R: DimName,
|
|
||||||
C: DimName,
|
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
ArrayStorage {
|
|
||||||
data: self.data.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N, R, C> Eq for ArrayStorage<N, R, C>
|
|
||||||
where
|
|
||||||
N: Eq,
|
|
||||||
R: DimName,
|
|
||||||
C: DimName,
|
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N, R, C> PartialEq for ArrayStorage<N, R, C>
|
|
||||||
where
|
|
||||||
N: PartialEq,
|
|
||||||
R: DimName,
|
|
||||||
C: DimName,
|
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn eq(&self, right: &Self) -> bool {
|
|
||||||
self.data == right.data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<N, R, C> Storage<N, R, C> for ArrayStorage<N, R, C>
|
|
||||||
where
|
|
||||||
N: Scalar,
|
|
||||||
R: DimName,
|
|
||||||
C: DimName,
|
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
DefaultAllocator: Allocator<N, R, C, Buffer = Self>,
|
|
||||||
{
|
|
||||||
type RStride = U1;
|
|
||||||
type CStride = R;
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ptr(&self) -> *const N {
|
fn ptr(&self) -> *const T {
|
||||||
self[..].as_ptr()
|
self.0.as_ptr() as *const T
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn shape(&self) -> (R, C) {
|
fn shape(&self) -> (Const<R>, Const<C>) {
|
||||||
(R::name(), C::name())
|
(Const, Const)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn strides(&self) -> (Self::RStride, Self::CStride) {
|
fn strides(&self) -> (Self::RStride, Self::CStride) {
|
||||||
(Self::RStride::name(), Self::CStride::name())
|
(Const, Const)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -204,112 +84,107 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into_owned(self) -> Owned<N, R, C>
|
fn into_owned(self) -> Owned<T, Const<R>, Const<C>>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, R, C>,
|
DefaultAllocator: Allocator<T, Const<R>, Const<C>>,
|
||||||
{
|
{
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone_owned(&self) -> Owned<N, R, C>
|
fn clone_owned(&self) -> Owned<T, Const<R>, Const<C>>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, R, C>,
|
DefaultAllocator: Allocator<T, Const<R>, Const<C>>,
|
||||||
{
|
{
|
||||||
let it = self.iter().cloned();
|
let it = self.as_slice().iter().cloned();
|
||||||
|
|
||||||
DefaultAllocator::allocate_from_iterator(self.shape().0, self.shape().1, it)
|
DefaultAllocator::allocate_from_iterator(self.shape().0, self.shape().1, it)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_slice(&self) -> &[N] {
|
fn as_slice(&self) -> &[T] {
|
||||||
&self[..]
|
unsafe { std::slice::from_raw_parts(self.ptr(), R * C) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<N, R, C> StorageMut<N, R, C> for ArrayStorage<N, R, C>
|
unsafe impl<T, const R: usize, const C: usize> StorageMut<T, Const<R>, Const<C>>
|
||||||
|
for ArrayStorage<T, R, C>
|
||||||
where
|
where
|
||||||
N: Scalar,
|
T: Scalar,
|
||||||
R: DimName,
|
DefaultAllocator: Allocator<T, Const<R>, Const<C>, Buffer = Self>,
|
||||||
C: DimName,
|
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
DefaultAllocator: Allocator<N, R, C, Buffer = Self>,
|
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ptr_mut(&mut self) -> *mut N {
|
fn ptr_mut(&mut self) -> *mut T {
|
||||||
self[..].as_mut_ptr()
|
self.0.as_mut_ptr() as *mut T
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_mut_slice(&mut self) -> &mut [N] {
|
fn as_mut_slice(&mut self) -> &mut [T] {
|
||||||
&mut self[..]
|
unsafe { std::slice::from_raw_parts_mut(self.ptr_mut(), R * C) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<N, R, C> ContiguousStorage<N, R, C> for ArrayStorage<N, R, C>
|
unsafe impl<T, const R: usize, const C: usize> ContiguousStorage<T, Const<R>, Const<C>>
|
||||||
|
for ArrayStorage<T, R, C>
|
||||||
where
|
where
|
||||||
N: Scalar,
|
T: Scalar,
|
||||||
R: DimName,
|
DefaultAllocator: Allocator<T, Const<R>, Const<C>, Buffer = Self>,
|
||||||
C: DimName,
|
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
DefaultAllocator: Allocator<N, R, C, Buffer = Self>,
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<N, R, C> ContiguousStorageMut<N, R, C> for ArrayStorage<N, R, C>
|
unsafe impl<T, const R: usize, const C: usize> ContiguousStorageMut<T, Const<R>, Const<C>>
|
||||||
|
for ArrayStorage<T, R, C>
|
||||||
where
|
where
|
||||||
N: Scalar,
|
T: Scalar,
|
||||||
R: DimName,
|
DefaultAllocator: Allocator<T, Const<R>, Const<C>, Buffer = Self>,
|
||||||
C: DimName,
|
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
DefaultAllocator: Allocator<N, R, C, Buffer = Self>,
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, R1, C1, R2, C2> ReshapableStorage<N, R1, C1, R2, C2> for ArrayStorage<N, R1, C1>
|
impl<T, const R1: usize, const C1: usize, const R2: usize, const C2: usize>
|
||||||
|
ReshapableStorage<T, Const<R1>, Const<C1>, Const<R2>, Const<C2>> for ArrayStorage<T, R1, C1>
|
||||||
where
|
where
|
||||||
N: Scalar,
|
T: Scalar,
|
||||||
R1: DimName,
|
Const<R1>: ToTypenum,
|
||||||
C1: DimName,
|
Const<C1>: ToTypenum,
|
||||||
R1::Value: Mul<C1::Value>,
|
Const<R2>: ToTypenum,
|
||||||
Prod<R1::Value, C1::Value>: ArrayLength<N>,
|
Const<C2>: ToTypenum,
|
||||||
R2: DimName,
|
<Const<R1> as ToTypenum>::Typenum: Mul<<Const<C1> as ToTypenum>::Typenum>,
|
||||||
C2: DimName,
|
<Const<R2> as ToTypenum>::Typenum: Mul<
|
||||||
R2::Value: Mul<C2::Value, Output = Prod<R1::Value, C1::Value>>,
|
<Const<C2> as ToTypenum>::Typenum,
|
||||||
Prod<R2::Value, C2::Value>: ArrayLength<N>,
|
Output = typenum::Prod<
|
||||||
|
<Const<R1> as ToTypenum>::Typenum,
|
||||||
|
<Const<C1> as ToTypenum>::Typenum,
|
||||||
|
>,
|
||||||
|
>,
|
||||||
{
|
{
|
||||||
type Output = ArrayStorage<N, R2, C2>;
|
type Output = ArrayStorage<T, R2, C2>;
|
||||||
|
|
||||||
fn reshape_generic(self, _: R2, _: C2) -> Self::Output {
|
fn reshape_generic(self, _: Const<R2>, _: Const<C2>) -> Self::Output {
|
||||||
ArrayStorage { data: self.data }
|
unsafe {
|
||||||
|
let data: [[T; R2]; C2] = std::mem::transmute_copy(&self.0);
|
||||||
|
std::mem::forget(self.0);
|
||||||
|
ArrayStorage(data)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Allocation-less serde impls.
|
* Serialization.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
// XXX: open an issue for GenericArray so that it implements serde traits?
|
// XXX: open an issue for serde so that it allows the serialization/deserialization of all arrays?
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize-no-std")]
|
||||||
impl<N, R, C> Serialize for ArrayStorage<N, R, C>
|
impl<T, const R: usize, const C: usize> Serialize for ArrayStorage<T, R, C>
|
||||||
where
|
where
|
||||||
N: Scalar + Serialize,
|
T: Scalar + Serialize,
|
||||||
R: DimName,
|
|
||||||
C: DimName,
|
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
{
|
{
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
let mut serializer = serializer.serialize_seq(Some(R::dim() * C::dim()))?;
|
let mut serializer = serializer.serialize_seq(Some(R * C))?;
|
||||||
|
|
||||||
for e in self.iter() {
|
for e in self.as_slice().iter() {
|
||||||
serializer.serialize_element(e)?;
|
serializer.serialize_element(e)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,14 +192,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize-no-std")]
|
||||||
impl<'a, N, R, C> Deserialize<'a> for ArrayStorage<N, R, C>
|
impl<'a, T, const R: usize, const C: usize> Deserialize<'a> for ArrayStorage<T, R, C>
|
||||||
where
|
where
|
||||||
N: Scalar + Deserialize<'a>,
|
T: Scalar + Deserialize<'a>,
|
||||||
R: DimName,
|
|
||||||
C: DimName,
|
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
{
|
{
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
|
@ -334,20 +205,16 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize-no-std")]
|
||||||
/// A visitor that produces a matrix array.
|
/// A visitor that produces a matrix array.
|
||||||
struct ArrayStorageVisitor<N, R, C> {
|
struct ArrayStorageVisitor<T, const R: usize, const C: usize> {
|
||||||
marker: PhantomData<(N, R, C)>,
|
marker: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize-no-std")]
|
||||||
impl<N, R, C> ArrayStorageVisitor<N, R, C>
|
impl<T, const R: usize, const C: usize> ArrayStorageVisitor<T, R, C>
|
||||||
where
|
where
|
||||||
N: Scalar,
|
T: Scalar,
|
||||||
R: DimName,
|
|
||||||
C: DimName,
|
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
{
|
{
|
||||||
/// Construct a new sequence visitor.
|
/// Construct a new sequence visitor.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
@ -357,23 +224,19 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize-no-std")]
|
||||||
impl<'a, N, R, C> Visitor<'a> for ArrayStorageVisitor<N, R, C>
|
impl<'a, T, const R: usize, const C: usize> Visitor<'a> for ArrayStorageVisitor<T, R, C>
|
||||||
where
|
where
|
||||||
N: Scalar + Deserialize<'a>,
|
T: Scalar + Deserialize<'a>,
|
||||||
R: DimName,
|
|
||||||
C: DimName,
|
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
{
|
{
|
||||||
type Value = ArrayStorage<N, R, C>;
|
type Value = ArrayStorage<T, R, C>;
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
|
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
|
||||||
formatter.write_str("a matrix array")
|
formatter.write_str("a matrix array")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit_seq<V>(self, mut visitor: V) -> Result<ArrayStorage<N, R, C>, V::Error>
|
fn visit_seq<V>(self, mut visitor: V) -> Result<ArrayStorage<T, R, C>, V::Error>
|
||||||
where
|
where
|
||||||
V: SeqAccess<'a>,
|
V: SeqAccess<'a>,
|
||||||
{
|
{
|
||||||
|
@ -381,12 +244,13 @@ where
|
||||||
let mut curr = 0;
|
let mut curr = 0;
|
||||||
|
|
||||||
while let Some(value) = visitor.next_element()? {
|
while let Some(value) = visitor.next_element()? {
|
||||||
*out.get_mut(curr)
|
*out.as_mut_slice()
|
||||||
|
.get_mut(curr)
|
||||||
.ok_or_else(|| V::Error::invalid_length(curr, &self))? = value;
|
.ok_or_else(|| V::Error::invalid_length(curr, &self))? = value;
|
||||||
curr += 1;
|
curr += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if curr == R::dim() * C::dim() {
|
if curr == R * C {
|
||||||
Ok(out)
|
Ok(out)
|
||||||
} else {
|
} else {
|
||||||
Err(V::Error::invalid_length(curr, &self))
|
Err(V::Error::invalid_length(curr, &self))
|
||||||
|
@ -395,36 +259,24 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bytemuck")]
|
#[cfg(feature = "bytemuck")]
|
||||||
unsafe impl<N: Scalar + bytemuck::Zeroable, R: DimName, C: DimName> bytemuck::Zeroable
|
unsafe impl<T: Scalar + Copy + bytemuck::Zeroable, const R: usize, const C: usize>
|
||||||
for ArrayStorage<N, R, C>
|
bytemuck::Zeroable for ArrayStorage<T, R, C>
|
||||||
where
|
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
Self: Copy,
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bytemuck")]
|
#[cfg(feature = "bytemuck")]
|
||||||
unsafe impl<N: Scalar + bytemuck::Pod, R: DimName, C: DimName> bytemuck::Pod
|
unsafe impl<T: Scalar + Copy + bytemuck::Pod, const R: usize, const C: usize> bytemuck::Pod
|
||||||
for ArrayStorage<N, R, C>
|
for ArrayStorage<T, R, C>
|
||||||
where
|
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
Self: Copy,
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "abomonation-serialize")]
|
#[cfg(feature = "abomonation-serialize")]
|
||||||
impl<N, R, C> Abomonation for ArrayStorage<N, R, C>
|
impl<T, const R: usize, const C: usize> Abomonation for ArrayStorage<T, R, C>
|
||||||
where
|
where
|
||||||
R: DimName,
|
T: Scalar + Abomonation,
|
||||||
C: DimName,
|
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
N: Abomonation,
|
|
||||||
{
|
{
|
||||||
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
|
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
|
||||||
for element in self.data.as_slice() {
|
for element in self.as_slice() {
|
||||||
element.entomb(writer)?;
|
element.entomb(writer)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,7 +284,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn exhume<'a, 'b>(&'a mut self, mut bytes: &'b mut [u8]) -> Option<&'b mut [u8]> {
|
unsafe fn exhume<'a, 'b>(&'a mut self, mut bytes: &'b mut [u8]) -> Option<&'b mut [u8]> {
|
||||||
for element in self.data.as_mut_slice() {
|
for element in self.as_mut_slice() {
|
||||||
let temp = bytes;
|
let temp = bytes;
|
||||||
bytes = if let Some(remainder) = element.exhume(temp) {
|
bytes = if let Some(remainder) = element.exhume(temp) {
|
||||||
remainder
|
remainder
|
||||||
|
@ -444,9 +296,6 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extent(&self) -> usize {
|
fn extent(&self) -> usize {
|
||||||
self.data
|
self.as_slice().iter().fold(0, |acc, e| acc + e.extent())
|
||||||
.as_slice()
|
|
||||||
.iter()
|
|
||||||
.fold(0, |acc, e| acc + e.extent())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
458
src/base/blas.rs
458
src/base/blas.rs
|
@ -10,25 +10,25 @@ use crate::base::allocator::Allocator;
|
||||||
use crate::base::constraint::{
|
use crate::base::constraint::{
|
||||||
AreMultipliable, DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint,
|
AreMultipliable, DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint,
|
||||||
};
|
};
|
||||||
use crate::base::dimension::{Dim, Dynamic, U1, U2, U3, U4};
|
use crate::base::dimension::{Const, Dim, Dynamic, U1, U2, U3, U4};
|
||||||
use crate::base::storage::{Storage, StorageMut};
|
use crate::base::storage::{Storage, StorageMut};
|
||||||
use crate::base::{
|
use crate::base::{
|
||||||
DVectorSlice, DefaultAllocator, Matrix, Scalar, SquareMatrix, Vector, VectorSliceN,
|
DVectorSlice, DefaultAllocator, Matrix, Scalar, SquareMatrix, Vector, VectorSlice,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// # Dot/scalar product
|
/// # Dot/scalar product
|
||||||
impl<N, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S>
|
impl<T, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S>
|
||||||
where
|
where
|
||||||
N: Scalar + Zero + ClosedAdd + ClosedMul,
|
T: Scalar + Zero + ClosedAdd + ClosedMul,
|
||||||
{
|
{
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn dotx<R2: Dim, C2: Dim, SB>(
|
fn dotx<R2: Dim, C2: Dim, SB>(
|
||||||
&self,
|
&self,
|
||||||
rhs: &Matrix<N, R2, C2, SB>,
|
rhs: &Matrix<T, R2, C2, SB>,
|
||||||
conjugate: impl Fn(N) -> N,
|
conjugate: impl Fn(T) -> T,
|
||||||
) -> N
|
) -> T
|
||||||
where
|
where
|
||||||
SB: Storage<N, R2, C2>,
|
SB: Storage<T, R2, C2>,
|
||||||
ShapeConstraint: DimEq<R, R2> + DimEq<C, C2>,
|
ShapeConstraint: DimEq<R, R2> + DimEq<C, C2>,
|
||||||
{
|
{
|
||||||
assert!(
|
assert!(
|
||||||
|
@ -92,7 +92,7 @@ where
|
||||||
//
|
//
|
||||||
// And this comment from bluss:
|
// And this comment from bluss:
|
||||||
// https://users.rust-lang.org/t/how-to-zip-two-slices-efficiently/2048/12
|
// https://users.rust-lang.org/t/how-to-zip-two-slices-efficiently/2048/12
|
||||||
let mut res = N::zero();
|
let mut res = T::zero();
|
||||||
|
|
||||||
// We have to define them outside of the loop (and not inside at first assignment)
|
// We have to define them outside of the loop (and not inside at first assignment)
|
||||||
// otherwise vectorization won't kick in for some reason.
|
// otherwise vectorization won't kick in for some reason.
|
||||||
|
@ -108,14 +108,14 @@ where
|
||||||
for j in 0..self.ncols() {
|
for j in 0..self.ncols() {
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
|
|
||||||
acc0 = N::zero();
|
acc0 = T::zero();
|
||||||
acc1 = N::zero();
|
acc1 = T::zero();
|
||||||
acc2 = N::zero();
|
acc2 = T::zero();
|
||||||
acc3 = N::zero();
|
acc3 = T::zero();
|
||||||
acc4 = N::zero();
|
acc4 = T::zero();
|
||||||
acc5 = N::zero();
|
acc5 = T::zero();
|
||||||
acc6 = N::zero();
|
acc6 = T::zero();
|
||||||
acc7 = N::zero();
|
acc7 = T::zero();
|
||||||
|
|
||||||
while self.nrows() - i >= 8 {
|
while self.nrows() - i >= 8 {
|
||||||
acc0 += unsafe {
|
acc0 += unsafe {
|
||||||
|
@ -193,9 +193,9 @@ where
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn dot<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> N
|
pub fn dot<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> T
|
||||||
where
|
where
|
||||||
SB: Storage<N, R2, C2>,
|
SB: Storage<T, R2, C2>,
|
||||||
ShapeConstraint: DimEq<R, R2> + DimEq<C, C2>,
|
ShapeConstraint: DimEq<R, R2> + DimEq<C, C2>,
|
||||||
{
|
{
|
||||||
self.dotx(rhs, |e| e)
|
self.dotx(rhs, |e| e)
|
||||||
|
@ -221,13 +221,13 @@ where
|
||||||
/// assert_ne!(vec1.dotc(&vec2), vec1.dot(&vec2));
|
/// assert_ne!(vec1.dotc(&vec2), vec1.dot(&vec2));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn dotc<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> N
|
pub fn dotc<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> T
|
||||||
where
|
where
|
||||||
N: SimdComplexField,
|
T: SimdComplexField,
|
||||||
SB: Storage<N, R2, C2>,
|
SB: Storage<T, R2, C2>,
|
||||||
ShapeConstraint: DimEq<R, R2> + DimEq<C, C2>,
|
ShapeConstraint: DimEq<R, R2> + DimEq<C, C2>,
|
||||||
{
|
{
|
||||||
self.dotx(rhs, N::simd_conjugate)
|
self.dotx(rhs, T::simd_conjugate)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The dot product between the transpose of `self` and `rhs`.
|
/// The dot product between the transpose of `self` and `rhs`.
|
||||||
|
@ -248,9 +248,9 @@ where
|
||||||
/// assert_eq!(mat1.tr_dot(&mat2), 9.1);
|
/// assert_eq!(mat1.tr_dot(&mat2), 9.1);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn tr_dot<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> N
|
pub fn tr_dot<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> T
|
||||||
where
|
where
|
||||||
SB: Storage<N, R2, C2>,
|
SB: Storage<T, R2, C2>,
|
||||||
ShapeConstraint: DimEq<C, R2> + DimEq<R, C2>,
|
ShapeConstraint: DimEq<C, R2> + DimEq<R, C2>,
|
||||||
{
|
{
|
||||||
let (nrows, ncols) = self.shape();
|
let (nrows, ncols) = self.shape();
|
||||||
|
@ -260,7 +260,7 @@ where
|
||||||
"Transposed dot product dimension mismatch."
|
"Transposed dot product dimension mismatch."
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut res = N::zero();
|
let mut res = T::zero();
|
||||||
|
|
||||||
for j in 0..self.nrows() {
|
for j in 0..self.nrows() {
|
||||||
for i in 0..self.ncols() {
|
for i in 0..self.ncols() {
|
||||||
|
@ -275,17 +275,17 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn array_axcpy<N>(
|
fn array_axcpy<T>(
|
||||||
y: &mut [N],
|
y: &mut [T],
|
||||||
a: N,
|
a: T,
|
||||||
x: &[N],
|
x: &[T],
|
||||||
c: N,
|
c: T,
|
||||||
beta: N,
|
beta: T,
|
||||||
stride1: usize,
|
stride1: usize,
|
||||||
stride2: usize,
|
stride2: usize,
|
||||||
len: usize,
|
len: usize,
|
||||||
) where
|
) where
|
||||||
N: Scalar + Zero + ClosedAdd + ClosedMul,
|
T: Scalar + Zero + ClosedAdd + ClosedMul,
|
||||||
{
|
{
|
||||||
for i in 0..len {
|
for i in 0..len {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -298,9 +298,9 @@ fn array_axcpy<N>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn array_axc<N>(y: &mut [N], a: N, x: &[N], c: N, stride1: usize, stride2: usize, len: usize)
|
fn array_axc<T>(y: &mut [T], a: T, x: &[T], c: T, stride1: usize, stride2: usize, len: usize)
|
||||||
where
|
where
|
||||||
N: Scalar + Zero + ClosedAdd + ClosedMul,
|
T: Scalar + Zero + ClosedAdd + ClosedMul,
|
||||||
{
|
{
|
||||||
for i in 0..len {
|
for i in 0..len {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -312,10 +312,10 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # BLAS functions
|
/// # BLAS functions
|
||||||
impl<N, D: Dim, S> Vector<N, D, S>
|
impl<T, D: Dim, S> Vector<T, D, S>
|
||||||
where
|
where
|
||||||
N: Scalar + Zero + ClosedAdd + ClosedMul,
|
T: Scalar + Zero + ClosedAdd + ClosedMul,
|
||||||
S: StorageMut<N, D>,
|
S: StorageMut<T, D>,
|
||||||
{
|
{
|
||||||
/// Computes `self = a * x * c + b * self`.
|
/// Computes `self = a * x * c + b * self`.
|
||||||
///
|
///
|
||||||
|
@ -331,9 +331,9 @@ where
|
||||||
/// assert_eq!(vec1, Vector3::new(6.0, 12.0, 18.0));
|
/// assert_eq!(vec1, Vector3::new(6.0, 12.0, 18.0));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn axcpy<D2: Dim, SB>(&mut self, a: N, x: &Vector<N, D2, SB>, c: N, b: N)
|
pub fn axcpy<D2: Dim, SB>(&mut self, a: T, x: &Vector<T, D2, SB>, c: T, b: T)
|
||||||
where
|
where
|
||||||
SB: Storage<N, D2>,
|
SB: Storage<T, D2>,
|
||||||
ShapeConstraint: DimEq<D, D2>,
|
ShapeConstraint: DimEq<D, D2>,
|
||||||
{
|
{
|
||||||
assert_eq!(self.nrows(), x.nrows(), "Axcpy: mismatched vector shapes.");
|
assert_eq!(self.nrows(), x.nrows(), "Axcpy: mismatched vector shapes.");
|
||||||
|
@ -365,14 +365,14 @@ where
|
||||||
/// assert_eq!(vec1, Vector3::new(6.0, 12.0, 18.0));
|
/// assert_eq!(vec1, Vector3::new(6.0, 12.0, 18.0));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn axpy<D2: Dim, SB>(&mut self, a: N, x: &Vector<N, D2, SB>, b: N)
|
pub fn axpy<D2: Dim, SB>(&mut self, a: T, x: &Vector<T, D2, SB>, b: T)
|
||||||
where
|
where
|
||||||
N: One,
|
T: One,
|
||||||
SB: Storage<N, D2>,
|
SB: Storage<T, D2>,
|
||||||
ShapeConstraint: DimEq<D, D2>,
|
ShapeConstraint: DimEq<D, D2>,
|
||||||
{
|
{
|
||||||
assert_eq!(self.nrows(), x.nrows(), "Axpy: mismatched vector shapes.");
|
assert_eq!(self.nrows(), x.nrows(), "Axpy: mismatched vector shapes.");
|
||||||
self.axcpy(a, x, N::one(), b)
|
self.axcpy(a, x, T::one(), b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes `self = alpha * a * x + beta * self`, where `a` is a matrix, `x` a vector, and
|
/// Computes `self = alpha * a * x + beta * self`, where `a` is a matrix, `x` a vector, and
|
||||||
|
@ -394,14 +394,14 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn gemv<R2: Dim, C2: Dim, D3: Dim, SB, SC>(
|
pub fn gemv<R2: Dim, C2: Dim, D3: Dim, SB, SC>(
|
||||||
&mut self,
|
&mut self,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
a: &Matrix<N, R2, C2, SB>,
|
a: &Matrix<T, R2, C2, SB>,
|
||||||
x: &Vector<N, D3, SC>,
|
x: &Vector<T, D3, SC>,
|
||||||
beta: N,
|
beta: T,
|
||||||
) where
|
) where
|
||||||
N: One,
|
T: One,
|
||||||
SB: Storage<N, R2, C2>,
|
SB: Storage<T, R2, C2>,
|
||||||
SC: Storage<N, D3>,
|
SC: Storage<T, D3>,
|
||||||
ShapeConstraint: DimEq<D, R2> + AreMultipliable<R2, C2, D3, U1>,
|
ShapeConstraint: DimEq<D, R2> + AreMultipliable<R2, C2, D3, U1>,
|
||||||
{
|
{
|
||||||
let dim1 = self.nrows();
|
let dim1 = self.nrows();
|
||||||
|
@ -418,7 +418,7 @@ where
|
||||||
// because we documented the guaranty that `self` is
|
// because we documented the guaranty that `self` is
|
||||||
// never read if `beta` is zero.
|
// never read if `beta` is zero.
|
||||||
if beta.is_zero() {
|
if beta.is_zero() {
|
||||||
self.fill(N::zero());
|
self.fill(T::zero());
|
||||||
} else {
|
} else {
|
||||||
*self *= beta;
|
*self *= beta;
|
||||||
}
|
}
|
||||||
|
@ -434,25 +434,25 @@ where
|
||||||
let col2 = a.column(j);
|
let col2 = a.column(j);
|
||||||
let val = unsafe { x.vget_unchecked(j).inlined_clone() };
|
let val = unsafe { x.vget_unchecked(j).inlined_clone() };
|
||||||
|
|
||||||
self.axcpy(alpha.inlined_clone(), &col2, val, N::one());
|
self.axcpy(alpha.inlined_clone(), &col2, val, T::one());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn xxgemv<D2: Dim, D3: Dim, SB, SC>(
|
fn xxgemv<D2: Dim, D3: Dim, SB, SC>(
|
||||||
&mut self,
|
&mut self,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
a: &SquareMatrix<N, D2, SB>,
|
a: &SquareMatrix<T, D2, SB>,
|
||||||
x: &Vector<N, D3, SC>,
|
x: &Vector<T, D3, SC>,
|
||||||
beta: N,
|
beta: T,
|
||||||
dot: impl Fn(
|
dot: impl Fn(
|
||||||
&DVectorSlice<N, SB::RStride, SB::CStride>,
|
&DVectorSlice<T, SB::RStride, SB::CStride>,
|
||||||
&DVectorSlice<N, SC::RStride, SC::CStride>,
|
&DVectorSlice<T, SC::RStride, SC::CStride>,
|
||||||
) -> N,
|
) -> T,
|
||||||
) where
|
) where
|
||||||
N: One,
|
T: One,
|
||||||
SB: Storage<N, D2, D2>,
|
SB: Storage<T, D2, D2>,
|
||||||
SC: Storage<N, D3>,
|
SC: Storage<T, D3>,
|
||||||
ShapeConstraint: DimEq<D, D2> + AreMultipliable<D2, D2, D3, U1>,
|
ShapeConstraint: DimEq<D, D2> + AreMultipliable<D2, D2, D3, U1>,
|
||||||
{
|
{
|
||||||
let dim1 = self.nrows();
|
let dim1 = self.nrows();
|
||||||
|
@ -490,7 +490,7 @@ where
|
||||||
self.rows_range_mut(j + 1..).axpy(
|
self.rows_range_mut(j + 1..).axpy(
|
||||||
alpha.inlined_clone() * val,
|
alpha.inlined_clone() * val,
|
||||||
&col2.rows_range(j + 1..),
|
&col2.rows_range(j + 1..),
|
||||||
N::one(),
|
T::one(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -501,14 +501,14 @@ where
|
||||||
#[deprecated(note = "This is renamed `sygemv` to match the original BLAS terminology.")]
|
#[deprecated(note = "This is renamed `sygemv` to match the original BLAS terminology.")]
|
||||||
pub fn gemv_symm<D2: Dim, D3: Dim, SB, SC>(
|
pub fn gemv_symm<D2: Dim, D3: Dim, SB, SC>(
|
||||||
&mut self,
|
&mut self,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
a: &SquareMatrix<N, D2, SB>,
|
a: &SquareMatrix<T, D2, SB>,
|
||||||
x: &Vector<N, D3, SC>,
|
x: &Vector<T, D3, SC>,
|
||||||
beta: N,
|
beta: T,
|
||||||
) where
|
) where
|
||||||
N: One,
|
T: One,
|
||||||
SB: Storage<N, D2, D2>,
|
SB: Storage<T, D2, D2>,
|
||||||
SC: Storage<N, D3>,
|
SC: Storage<T, D3>,
|
||||||
ShapeConstraint: DimEq<D, D2> + AreMultipliable<D2, D2, D3, U1>,
|
ShapeConstraint: DimEq<D, D2> + AreMultipliable<D2, D2, D3, U1>,
|
||||||
{
|
{
|
||||||
self.sygemv(alpha, a, x, beta)
|
self.sygemv(alpha, a, x, beta)
|
||||||
|
@ -545,14 +545,14 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn sygemv<D2: Dim, D3: Dim, SB, SC>(
|
pub fn sygemv<D2: Dim, D3: Dim, SB, SC>(
|
||||||
&mut self,
|
&mut self,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
a: &SquareMatrix<N, D2, SB>,
|
a: &SquareMatrix<T, D2, SB>,
|
||||||
x: &Vector<N, D3, SC>,
|
x: &Vector<T, D3, SC>,
|
||||||
beta: N,
|
beta: T,
|
||||||
) where
|
) where
|
||||||
N: One,
|
T: One,
|
||||||
SB: Storage<N, D2, D2>,
|
SB: Storage<T, D2, D2>,
|
||||||
SC: Storage<N, D3>,
|
SC: Storage<T, D3>,
|
||||||
ShapeConstraint: DimEq<D, D2> + AreMultipliable<D2, D2, D3, U1>,
|
ShapeConstraint: DimEq<D, D2> + AreMultipliable<D2, D2, D3, U1>,
|
||||||
{
|
{
|
||||||
self.xxgemv(alpha, a, x, beta, |a, b| a.dot(b))
|
self.xxgemv(alpha, a, x, beta, |a, b| a.dot(b))
|
||||||
|
@ -590,14 +590,14 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn hegemv<D2: Dim, D3: Dim, SB, SC>(
|
pub fn hegemv<D2: Dim, D3: Dim, SB, SC>(
|
||||||
&mut self,
|
&mut self,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
a: &SquareMatrix<N, D2, SB>,
|
a: &SquareMatrix<T, D2, SB>,
|
||||||
x: &Vector<N, D3, SC>,
|
x: &Vector<T, D3, SC>,
|
||||||
beta: N,
|
beta: T,
|
||||||
) where
|
) where
|
||||||
N: SimdComplexField,
|
T: SimdComplexField,
|
||||||
SB: Storage<N, D2, D2>,
|
SB: Storage<T, D2, D2>,
|
||||||
SC: Storage<N, D3>,
|
SC: Storage<T, D3>,
|
||||||
ShapeConstraint: DimEq<D, D2> + AreMultipliable<D2, D2, D3, U1>,
|
ShapeConstraint: DimEq<D, D2> + AreMultipliable<D2, D2, D3, U1>,
|
||||||
{
|
{
|
||||||
self.xxgemv(alpha, a, x, beta, |a, b| a.dotc(b))
|
self.xxgemv(alpha, a, x, beta, |a, b| a.dotc(b))
|
||||||
|
@ -606,15 +606,15 @@ where
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn gemv_xx<R2: Dim, C2: Dim, D3: Dim, SB, SC>(
|
fn gemv_xx<R2: Dim, C2: Dim, D3: Dim, SB, SC>(
|
||||||
&mut self,
|
&mut self,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
a: &Matrix<N, R2, C2, SB>,
|
a: &Matrix<T, R2, C2, SB>,
|
||||||
x: &Vector<N, D3, SC>,
|
x: &Vector<T, D3, SC>,
|
||||||
beta: N,
|
beta: T,
|
||||||
dot: impl Fn(&VectorSliceN<N, R2, SB::RStride, SB::CStride>, &Vector<N, D3, SC>) -> N,
|
dot: impl Fn(&VectorSlice<T, R2, SB::RStride, SB::CStride>, &Vector<T, D3, SC>) -> T,
|
||||||
) where
|
) where
|
||||||
N: One,
|
T: One,
|
||||||
SB: Storage<N, R2, C2>,
|
SB: Storage<T, R2, C2>,
|
||||||
SC: Storage<N, D3>,
|
SC: Storage<T, D3>,
|
||||||
ShapeConstraint: DimEq<D, C2> + AreMultipliable<C2, R2, D3, U1>,
|
ShapeConstraint: DimEq<D, C2> + AreMultipliable<C2, R2, D3, U1>,
|
||||||
{
|
{
|
||||||
let dim1 = self.nrows();
|
let dim1 = self.nrows();
|
||||||
|
@ -665,14 +665,14 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn gemv_tr<R2: Dim, C2: Dim, D3: Dim, SB, SC>(
|
pub fn gemv_tr<R2: Dim, C2: Dim, D3: Dim, SB, SC>(
|
||||||
&mut self,
|
&mut self,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
a: &Matrix<N, R2, C2, SB>,
|
a: &Matrix<T, R2, C2, SB>,
|
||||||
x: &Vector<N, D3, SC>,
|
x: &Vector<T, D3, SC>,
|
||||||
beta: N,
|
beta: T,
|
||||||
) where
|
) where
|
||||||
N: One,
|
T: One,
|
||||||
SB: Storage<N, R2, C2>,
|
SB: Storage<T, R2, C2>,
|
||||||
SC: Storage<N, D3>,
|
SC: Storage<T, D3>,
|
||||||
ShapeConstraint: DimEq<D, C2> + AreMultipliable<C2, R2, D3, U1>,
|
ShapeConstraint: DimEq<D, C2> + AreMultipliable<C2, R2, D3, U1>,
|
||||||
{
|
{
|
||||||
self.gemv_xx(alpha, a, x, beta, |a, b| a.dot(b))
|
self.gemv_xx(alpha, a, x, beta, |a, b| a.dot(b))
|
||||||
|
@ -700,36 +700,36 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn gemv_ad<R2: Dim, C2: Dim, D3: Dim, SB, SC>(
|
pub fn gemv_ad<R2: Dim, C2: Dim, D3: Dim, SB, SC>(
|
||||||
&mut self,
|
&mut self,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
a: &Matrix<N, R2, C2, SB>,
|
a: &Matrix<T, R2, C2, SB>,
|
||||||
x: &Vector<N, D3, SC>,
|
x: &Vector<T, D3, SC>,
|
||||||
beta: N,
|
beta: T,
|
||||||
) where
|
) where
|
||||||
N: SimdComplexField,
|
T: SimdComplexField,
|
||||||
SB: Storage<N, R2, C2>,
|
SB: Storage<T, R2, C2>,
|
||||||
SC: Storage<N, D3>,
|
SC: Storage<T, D3>,
|
||||||
ShapeConstraint: DimEq<D, C2> + AreMultipliable<C2, R2, D3, U1>,
|
ShapeConstraint: DimEq<D, C2> + AreMultipliable<C2, R2, D3, U1>,
|
||||||
{
|
{
|
||||||
self.gemv_xx(alpha, a, x, beta, |a, b| a.dotc(b))
|
self.gemv_xx(alpha, a, x, beta, |a, b| a.dotc(b))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, R1: Dim, C1: Dim, S: StorageMut<N, R1, C1>> Matrix<N, R1, C1, S>
|
impl<T, R1: Dim, C1: Dim, S: StorageMut<T, R1, C1>> Matrix<T, R1, C1, S>
|
||||||
where
|
where
|
||||||
N: Scalar + Zero + ClosedAdd + ClosedMul,
|
T: Scalar + Zero + ClosedAdd + ClosedMul,
|
||||||
{
|
{
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn gerx<D2: Dim, D3: Dim, SB, SC>(
|
fn gerx<D2: Dim, D3: Dim, SB, SC>(
|
||||||
&mut self,
|
&mut self,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
x: &Vector<N, D2, SB>,
|
x: &Vector<T, D2, SB>,
|
||||||
y: &Vector<N, D3, SC>,
|
y: &Vector<T, D3, SC>,
|
||||||
beta: N,
|
beta: T,
|
||||||
conjugate: impl Fn(N) -> N,
|
conjugate: impl Fn(T) -> T,
|
||||||
) where
|
) where
|
||||||
N: One,
|
T: One,
|
||||||
SB: Storage<N, D2>,
|
SB: Storage<T, D2>,
|
||||||
SC: Storage<N, D3>,
|
SC: Storage<T, D3>,
|
||||||
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
||||||
{
|
{
|
||||||
let (nrows1, ncols1) = self.shape();
|
let (nrows1, ncols1) = self.shape();
|
||||||
|
@ -768,14 +768,14 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn ger<D2: Dim, D3: Dim, SB, SC>(
|
pub fn ger<D2: Dim, D3: Dim, SB, SC>(
|
||||||
&mut self,
|
&mut self,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
x: &Vector<N, D2, SB>,
|
x: &Vector<T, D2, SB>,
|
||||||
y: &Vector<N, D3, SC>,
|
y: &Vector<T, D3, SC>,
|
||||||
beta: N,
|
beta: T,
|
||||||
) where
|
) where
|
||||||
N: One,
|
T: One,
|
||||||
SB: Storage<N, D2>,
|
SB: Storage<T, D2>,
|
||||||
SC: Storage<N, D3>,
|
SC: Storage<T, D3>,
|
||||||
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
||||||
{
|
{
|
||||||
self.gerx(alpha, x, y, beta, |e| e)
|
self.gerx(alpha, x, y, beta, |e| e)
|
||||||
|
@ -801,14 +801,14 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn gerc<D2: Dim, D3: Dim, SB, SC>(
|
pub fn gerc<D2: Dim, D3: Dim, SB, SC>(
|
||||||
&mut self,
|
&mut self,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
x: &Vector<N, D2, SB>,
|
x: &Vector<T, D2, SB>,
|
||||||
y: &Vector<N, D3, SC>,
|
y: &Vector<T, D3, SC>,
|
||||||
beta: N,
|
beta: T,
|
||||||
) where
|
) where
|
||||||
N: SimdComplexField,
|
T: SimdComplexField,
|
||||||
SB: Storage<N, D2>,
|
SB: Storage<T, D2>,
|
||||||
SC: Storage<N, D3>,
|
SC: Storage<T, D3>,
|
||||||
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
||||||
{
|
{
|
||||||
self.gerx(alpha, x, y, beta, SimdComplexField::simd_conjugate)
|
self.gerx(alpha, x, y, beta, SimdComplexField::simd_conjugate)
|
||||||
|
@ -838,14 +838,14 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn gemm<R2: Dim, C2: Dim, R3: Dim, C3: Dim, SB, SC>(
|
pub fn gemm<R2: Dim, C2: Dim, R3: Dim, C3: Dim, SB, SC>(
|
||||||
&mut self,
|
&mut self,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
a: &Matrix<N, R2, C2, SB>,
|
a: &Matrix<T, R2, C2, SB>,
|
||||||
b: &Matrix<N, R3, C3, SC>,
|
b: &Matrix<T, R3, C3, SC>,
|
||||||
beta: N,
|
beta: T,
|
||||||
) where
|
) where
|
||||||
N: One,
|
T: One,
|
||||||
SB: Storage<N, R2, C2>,
|
SB: Storage<T, R2, C2>,
|
||||||
SC: Storage<N, R3, C3>,
|
SC: Storage<T, R3, C3>,
|
||||||
ShapeConstraint: SameNumberOfRows<R1, R2>
|
ShapeConstraint: SameNumberOfRows<R1, R2>
|
||||||
+ SameNumberOfColumns<C1, C3>
|
+ SameNumberOfColumns<C1, C3>
|
||||||
+ AreMultipliable<R2, C2, R3, C3>,
|
+ AreMultipliable<R2, C2, R3, C3>,
|
||||||
|
@ -897,14 +897,14 @@ where
|
||||||
// because we documented the guaranty that `self` is
|
// because we documented the guaranty that `self` is
|
||||||
// never read if `beta` is zero.
|
// never read if `beta` is zero.
|
||||||
if beta.is_zero() {
|
if beta.is_zero() {
|
||||||
self.fill(N::zero());
|
self.fill(T::zero());
|
||||||
} else {
|
} else {
|
||||||
*self *= beta;
|
*self *= beta;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if N::is::<f32>() {
|
if T::is::<f32>() {
|
||||||
let (rsa, csa) = a.strides();
|
let (rsa, csa) = a.strides();
|
||||||
let (rsb, csb) = b.strides();
|
let (rsb, csb) = b.strides();
|
||||||
let (rsc, csc) = self.strides();
|
let (rsc, csc) = self.strides();
|
||||||
|
@ -928,7 +928,7 @@ where
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if N::is::<f64>() {
|
} else if T::is::<f64>() {
|
||||||
let (rsa, csa) = a.strides();
|
let (rsa, csa) = a.strides();
|
||||||
let (rsb, csb) = b.strides();
|
let (rsb, csb) = b.strides();
|
||||||
let (rsc, csc) = self.strides();
|
let (rsc, csc) = self.strides();
|
||||||
|
@ -993,14 +993,14 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn gemm_tr<R2: Dim, C2: Dim, R3: Dim, C3: Dim, SB, SC>(
|
pub fn gemm_tr<R2: Dim, C2: Dim, R3: Dim, C3: Dim, SB, SC>(
|
||||||
&mut self,
|
&mut self,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
a: &Matrix<N, R2, C2, SB>,
|
a: &Matrix<T, R2, C2, SB>,
|
||||||
b: &Matrix<N, R3, C3, SC>,
|
b: &Matrix<T, R3, C3, SC>,
|
||||||
beta: N,
|
beta: T,
|
||||||
) where
|
) where
|
||||||
N: One,
|
T: One,
|
||||||
SB: Storage<N, R2, C2>,
|
SB: Storage<T, R2, C2>,
|
||||||
SC: Storage<N, R3, C3>,
|
SC: Storage<T, R3, C3>,
|
||||||
ShapeConstraint: SameNumberOfRows<R1, C2>
|
ShapeConstraint: SameNumberOfRows<R1, C2>
|
||||||
+ SameNumberOfColumns<C1, C3>
|
+ SameNumberOfColumns<C1, C3>
|
||||||
+ AreMultipliable<C2, R2, R3, C3>,
|
+ AreMultipliable<C2, R2, R3, C3>,
|
||||||
|
@ -1055,14 +1055,14 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn gemm_ad<R2: Dim, C2: Dim, R3: Dim, C3: Dim, SB, SC>(
|
pub fn gemm_ad<R2: Dim, C2: Dim, R3: Dim, C3: Dim, SB, SC>(
|
||||||
&mut self,
|
&mut self,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
a: &Matrix<N, R2, C2, SB>,
|
a: &Matrix<T, R2, C2, SB>,
|
||||||
b: &Matrix<N, R3, C3, SC>,
|
b: &Matrix<T, R3, C3, SC>,
|
||||||
beta: N,
|
beta: T,
|
||||||
) where
|
) where
|
||||||
N: SimdComplexField,
|
T: SimdComplexField,
|
||||||
SB: Storage<N, R2, C2>,
|
SB: Storage<T, R2, C2>,
|
||||||
SC: Storage<N, R3, C3>,
|
SC: Storage<T, R3, C3>,
|
||||||
ShapeConstraint: SameNumberOfRows<R1, C2>
|
ShapeConstraint: SameNumberOfRows<R1, C2>
|
||||||
+ SameNumberOfColumns<C1, C3>
|
+ SameNumberOfColumns<C1, C3>
|
||||||
+ AreMultipliable<C2, R2, R3, C3>,
|
+ AreMultipliable<C2, R2, R3, C3>,
|
||||||
|
@ -1088,22 +1088,22 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, R1: Dim, C1: Dim, S: StorageMut<N, R1, C1>> Matrix<N, R1, C1, S>
|
impl<T, R1: Dim, C1: Dim, S: StorageMut<T, R1, C1>> Matrix<T, R1, C1, S>
|
||||||
where
|
where
|
||||||
N: Scalar + Zero + ClosedAdd + ClosedMul,
|
T: Scalar + Zero + ClosedAdd + ClosedMul,
|
||||||
{
|
{
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn xxgerx<D2: Dim, D3: Dim, SB, SC>(
|
fn xxgerx<D2: Dim, D3: Dim, SB, SC>(
|
||||||
&mut self,
|
&mut self,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
x: &Vector<N, D2, SB>,
|
x: &Vector<T, D2, SB>,
|
||||||
y: &Vector<N, D3, SC>,
|
y: &Vector<T, D3, SC>,
|
||||||
beta: N,
|
beta: T,
|
||||||
conjugate: impl Fn(N) -> N,
|
conjugate: impl Fn(T) -> T,
|
||||||
) where
|
) where
|
||||||
N: One,
|
T: One,
|
||||||
SB: Storage<N, D2>,
|
SB: Storage<T, D2>,
|
||||||
SC: Storage<N, D3>,
|
SC: Storage<T, D3>,
|
||||||
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
||||||
{
|
{
|
||||||
let dim1 = self.nrows();
|
let dim1 = self.nrows();
|
||||||
|
@ -1120,7 +1120,7 @@ where
|
||||||
let val = unsafe { conjugate(y.vget_unchecked(j).inlined_clone()) };
|
let val = unsafe { conjugate(y.vget_unchecked(j).inlined_clone()) };
|
||||||
let subdim = Dynamic::new(dim1 - j);
|
let subdim = Dynamic::new(dim1 - j);
|
||||||
// TODO: avoid bound checks.
|
// TODO: avoid bound checks.
|
||||||
self.generic_slice_mut((j, j), (subdim, U1)).axpy(
|
self.generic_slice_mut((j, j), (subdim, Const::<1>)).axpy(
|
||||||
alpha.inlined_clone() * val,
|
alpha.inlined_clone() * val,
|
||||||
&x.rows_range(j..),
|
&x.rows_range(j..),
|
||||||
beta.inlined_clone(),
|
beta.inlined_clone(),
|
||||||
|
@ -1151,14 +1151,14 @@ where
|
||||||
#[deprecated(note = "This is renamed `syger` to match the original BLAS terminology.")]
|
#[deprecated(note = "This is renamed `syger` to match the original BLAS terminology.")]
|
||||||
pub fn ger_symm<D2: Dim, D3: Dim, SB, SC>(
|
pub fn ger_symm<D2: Dim, D3: Dim, SB, SC>(
|
||||||
&mut self,
|
&mut self,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
x: &Vector<N, D2, SB>,
|
x: &Vector<T, D2, SB>,
|
||||||
y: &Vector<N, D3, SC>,
|
y: &Vector<T, D3, SC>,
|
||||||
beta: N,
|
beta: T,
|
||||||
) where
|
) where
|
||||||
N: One,
|
T: One,
|
||||||
SB: Storage<N, D2>,
|
SB: Storage<T, D2>,
|
||||||
SC: Storage<N, D3>,
|
SC: Storage<T, D3>,
|
||||||
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
||||||
{
|
{
|
||||||
self.syger(alpha, x, y, beta)
|
self.syger(alpha, x, y, beta)
|
||||||
|
@ -1187,14 +1187,14 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn syger<D2: Dim, D3: Dim, SB, SC>(
|
pub fn syger<D2: Dim, D3: Dim, SB, SC>(
|
||||||
&mut self,
|
&mut self,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
x: &Vector<N, D2, SB>,
|
x: &Vector<T, D2, SB>,
|
||||||
y: &Vector<N, D3, SC>,
|
y: &Vector<T, D3, SC>,
|
||||||
beta: N,
|
beta: T,
|
||||||
) where
|
) where
|
||||||
N: One,
|
T: One,
|
||||||
SB: Storage<N, D2>,
|
SB: Storage<T, D2>,
|
||||||
SC: Storage<N, D3>,
|
SC: Storage<T, D3>,
|
||||||
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
||||||
{
|
{
|
||||||
self.xxgerx(alpha, x, y, beta, |e| e)
|
self.xxgerx(alpha, x, y, beta, |e| e)
|
||||||
|
@ -1222,23 +1222,23 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn hegerc<D2: Dim, D3: Dim, SB, SC>(
|
pub fn hegerc<D2: Dim, D3: Dim, SB, SC>(
|
||||||
&mut self,
|
&mut self,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
x: &Vector<N, D2, SB>,
|
x: &Vector<T, D2, SB>,
|
||||||
y: &Vector<N, D3, SC>,
|
y: &Vector<T, D3, SC>,
|
||||||
beta: N,
|
beta: T,
|
||||||
) where
|
) where
|
||||||
N: SimdComplexField,
|
T: SimdComplexField,
|
||||||
SB: Storage<N, D2>,
|
SB: Storage<T, D2>,
|
||||||
SC: Storage<N, D3>,
|
SC: Storage<T, D3>,
|
||||||
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
||||||
{
|
{
|
||||||
self.xxgerx(alpha, x, y, beta, SimdComplexField::simd_conjugate)
|
self.xxgerx(alpha, x, y, beta, SimdComplexField::simd_conjugate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, D1: Dim, S: StorageMut<N, D1, D1>> SquareMatrix<N, D1, S>
|
impl<T, D1: Dim, S: StorageMut<T, D1, D1>> SquareMatrix<T, D1, S>
|
||||||
where
|
where
|
||||||
N: Scalar + Zero + One + ClosedAdd + ClosedMul,
|
T: Scalar + Zero + One + ClosedAdd + ClosedMul,
|
||||||
{
|
{
|
||||||
/// Computes the quadratic form `self = alpha * lhs * mid * lhs.transpose() + beta * self`.
|
/// Computes the quadratic form `self = alpha * lhs * mid * lhs.transpose() + beta * self`.
|
||||||
///
|
///
|
||||||
|
@ -1268,27 +1268,27 @@ where
|
||||||
/// assert_relative_eq!(mat, expected);
|
/// assert_relative_eq!(mat, expected);
|
||||||
pub fn quadform_tr_with_workspace<D2, S2, R3, C3, S3, D4, S4>(
|
pub fn quadform_tr_with_workspace<D2, S2, R3, C3, S3, D4, S4>(
|
||||||
&mut self,
|
&mut self,
|
||||||
work: &mut Vector<N, D2, S2>,
|
work: &mut Vector<T, D2, S2>,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
lhs: &Matrix<N, R3, C3, S3>,
|
lhs: &Matrix<T, R3, C3, S3>,
|
||||||
mid: &SquareMatrix<N, D4, S4>,
|
mid: &SquareMatrix<T, D4, S4>,
|
||||||
beta: N,
|
beta: T,
|
||||||
) where
|
) where
|
||||||
D2: Dim,
|
D2: Dim,
|
||||||
R3: Dim,
|
R3: Dim,
|
||||||
C3: Dim,
|
C3: Dim,
|
||||||
D4: Dim,
|
D4: Dim,
|
||||||
S2: StorageMut<N, D2>,
|
S2: StorageMut<T, D2>,
|
||||||
S3: Storage<N, R3, C3>,
|
S3: Storage<T, R3, C3>,
|
||||||
S4: Storage<N, D4, D4>,
|
S4: Storage<T, D4, D4>,
|
||||||
ShapeConstraint: DimEq<D1, D2> + DimEq<D1, R3> + DimEq<D2, R3> + DimEq<C3, D4>,
|
ShapeConstraint: DimEq<D1, D2> + DimEq<D1, R3> + DimEq<D2, R3> + DimEq<C3, D4>,
|
||||||
{
|
{
|
||||||
work.gemv(N::one(), lhs, &mid.column(0), N::zero());
|
work.gemv(T::one(), lhs, &mid.column(0), T::zero());
|
||||||
self.ger(alpha.inlined_clone(), work, &lhs.column(0), beta);
|
self.ger(alpha.inlined_clone(), work, &lhs.column(0), beta);
|
||||||
|
|
||||||
for j in 1..mid.ncols() {
|
for j in 1..mid.ncols() {
|
||||||
work.gemv(N::one(), lhs, &mid.column(j), N::zero());
|
work.gemv(T::one(), lhs, &mid.column(j), T::zero());
|
||||||
self.ger(alpha.inlined_clone(), work, &lhs.column(j), N::one());
|
self.ger(alpha.inlined_clone(), work, &lhs.column(j), T::one());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1315,21 +1315,22 @@ where
|
||||||
/// assert_relative_eq!(mat, expected);
|
/// assert_relative_eq!(mat, expected);
|
||||||
pub fn quadform_tr<R3, C3, S3, D4, S4>(
|
pub fn quadform_tr<R3, C3, S3, D4, S4>(
|
||||||
&mut self,
|
&mut self,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
lhs: &Matrix<N, R3, C3, S3>,
|
lhs: &Matrix<T, R3, C3, S3>,
|
||||||
mid: &SquareMatrix<N, D4, S4>,
|
mid: &SquareMatrix<T, D4, S4>,
|
||||||
beta: N,
|
beta: T,
|
||||||
) where
|
) where
|
||||||
R3: Dim,
|
R3: Dim,
|
||||||
C3: Dim,
|
C3: Dim,
|
||||||
D4: Dim,
|
D4: Dim,
|
||||||
S3: Storage<N, R3, C3>,
|
S3: Storage<T, R3, C3>,
|
||||||
S4: Storage<N, D4, D4>,
|
S4: Storage<T, D4, D4>,
|
||||||
ShapeConstraint: DimEq<D1, D1> + DimEq<D1, R3> + DimEq<C3, D4>,
|
ShapeConstraint: DimEq<D1, D1> + DimEq<D1, R3> + DimEq<C3, D4>,
|
||||||
DefaultAllocator: Allocator<N, D1>,
|
DefaultAllocator: Allocator<T, D1>,
|
||||||
{
|
{
|
||||||
let mut work =
|
let mut work = unsafe {
|
||||||
unsafe { crate::unimplemented_or_uninitialized_generic!(self.data.shape().0, U1) };
|
crate::unimplemented_or_uninitialized_generic!(self.data.shape().0, Const::<1>)
|
||||||
|
};
|
||||||
self.quadform_tr_with_workspace(&mut work, alpha, lhs, mid, beta)
|
self.quadform_tr_with_workspace(&mut work, alpha, lhs, mid, beta)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1360,28 +1361,28 @@ where
|
||||||
/// assert_relative_eq!(mat, expected);
|
/// assert_relative_eq!(mat, expected);
|
||||||
pub fn quadform_with_workspace<D2, S2, D3, S3, R4, C4, S4>(
|
pub fn quadform_with_workspace<D2, S2, D3, S3, R4, C4, S4>(
|
||||||
&mut self,
|
&mut self,
|
||||||
work: &mut Vector<N, D2, S2>,
|
work: &mut Vector<T, D2, S2>,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
mid: &SquareMatrix<N, D3, S3>,
|
mid: &SquareMatrix<T, D3, S3>,
|
||||||
rhs: &Matrix<N, R4, C4, S4>,
|
rhs: &Matrix<T, R4, C4, S4>,
|
||||||
beta: N,
|
beta: T,
|
||||||
) where
|
) where
|
||||||
D2: Dim,
|
D2: Dim,
|
||||||
D3: Dim,
|
D3: Dim,
|
||||||
R4: Dim,
|
R4: Dim,
|
||||||
C4: Dim,
|
C4: Dim,
|
||||||
S2: StorageMut<N, D2>,
|
S2: StorageMut<T, D2>,
|
||||||
S3: Storage<N, D3, D3>,
|
S3: Storage<T, D3, D3>,
|
||||||
S4: Storage<N, R4, C4>,
|
S4: Storage<T, R4, C4>,
|
||||||
ShapeConstraint:
|
ShapeConstraint:
|
||||||
DimEq<D3, R4> + DimEq<D1, C4> + DimEq<D2, D3> + AreMultipliable<C4, R4, D2, U1>,
|
DimEq<D3, R4> + DimEq<D1, C4> + DimEq<D2, D3> + AreMultipliable<C4, R4, D2, U1>,
|
||||||
{
|
{
|
||||||
work.gemv(N::one(), mid, &rhs.column(0), N::zero());
|
work.gemv(T::one(), mid, &rhs.column(0), T::zero());
|
||||||
self.column_mut(0)
|
self.column_mut(0)
|
||||||
.gemv_tr(alpha.inlined_clone(), &rhs, work, beta.inlined_clone());
|
.gemv_tr(alpha.inlined_clone(), &rhs, work, beta.inlined_clone());
|
||||||
|
|
||||||
for j in 1..rhs.ncols() {
|
for j in 1..rhs.ncols() {
|
||||||
work.gemv(N::one(), mid, &rhs.column(j), N::zero());
|
work.gemv(T::one(), mid, &rhs.column(j), T::zero());
|
||||||
self.column_mut(j)
|
self.column_mut(j)
|
||||||
.gemv_tr(alpha.inlined_clone(), &rhs, work, beta.inlined_clone());
|
.gemv_tr(alpha.inlined_clone(), &rhs, work, beta.inlined_clone());
|
||||||
}
|
}
|
||||||
|
@ -1409,21 +1410,22 @@ where
|
||||||
/// assert_relative_eq!(mat, expected);
|
/// assert_relative_eq!(mat, expected);
|
||||||
pub fn quadform<D2, S2, R3, C3, S3>(
|
pub fn quadform<D2, S2, R3, C3, S3>(
|
||||||
&mut self,
|
&mut self,
|
||||||
alpha: N,
|
alpha: T,
|
||||||
mid: &SquareMatrix<N, D2, S2>,
|
mid: &SquareMatrix<T, D2, S2>,
|
||||||
rhs: &Matrix<N, R3, C3, S3>,
|
rhs: &Matrix<T, R3, C3, S3>,
|
||||||
beta: N,
|
beta: T,
|
||||||
) where
|
) where
|
||||||
D2: Dim,
|
D2: Dim,
|
||||||
R3: Dim,
|
R3: Dim,
|
||||||
C3: Dim,
|
C3: Dim,
|
||||||
S2: Storage<N, D2, D2>,
|
S2: Storage<T, D2, D2>,
|
||||||
S3: Storage<N, R3, C3>,
|
S3: Storage<T, R3, C3>,
|
||||||
ShapeConstraint: DimEq<D2, R3> + DimEq<D1, C3> + AreMultipliable<C3, R3, D2, U1>,
|
ShapeConstraint: DimEq<D2, R3> + DimEq<D1, C3> + AreMultipliable<C3, R3, D2, U1>,
|
||||||
DefaultAllocator: Allocator<N, D2>,
|
DefaultAllocator: Allocator<T, D2>,
|
||||||
{
|
{
|
||||||
let mut work =
|
let mut work = unsafe {
|
||||||
unsafe { crate::unimplemented_or_uninitialized_generic!(mid.data.shape().0, U1) };
|
crate::unimplemented_or_uninitialized_generic!(mid.data.shape().0, Const::<1>)
|
||||||
|
};
|
||||||
self.quadform_with_workspace(&mut work, alpha, mid, rhs, beta)
|
self.quadform_with_workspace(&mut work, alpha, mid, rhs, beta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
225
src/base/cg.rs
225
src/base/cg.rs
|
@ -11,8 +11,8 @@ use crate::base::allocator::Allocator;
|
||||||
use crate::base::dimension::{DimName, DimNameDiff, DimNameSub, U1};
|
use crate::base::dimension::{DimName, DimNameDiff, DimNameSub, U1};
|
||||||
use crate::base::storage::{Storage, StorageMut};
|
use crate::base::storage::{Storage, StorageMut};
|
||||||
use crate::base::{
|
use crate::base::{
|
||||||
DefaultAllocator, Matrix3, Matrix4, MatrixN, Scalar, SquareMatrix, Unit, Vector, Vector2,
|
Const, DefaultAllocator, Matrix3, Matrix4, OMatrix, OVector, Scalar, SquareMatrix, Unit,
|
||||||
Vector3, VectorN,
|
Vector, Vector2, Vector3,
|
||||||
};
|
};
|
||||||
use crate::geometry::{
|
use crate::geometry::{
|
||||||
Isometry, IsometryMatrix3, Orthographic3, Perspective3, Point, Point2, Point3, Rotation2,
|
Isometry, IsometryMatrix3, Orthographic3, Perspective3, Point, Point2, Point3, Rotation2,
|
||||||
|
@ -22,26 +22,26 @@ use crate::geometry::{
|
||||||
use simba::scalar::{ClosedAdd, ClosedMul, RealField};
|
use simba::scalar::{ClosedAdd, ClosedMul, RealField};
|
||||||
|
|
||||||
/// # Translation and scaling in any dimension
|
/// # Translation and scaling in any dimension
|
||||||
impl<N, D: DimName> MatrixN<N, D>
|
impl<T, D: DimName> OMatrix<T, D, D>
|
||||||
where
|
where
|
||||||
N: Scalar + Zero + One,
|
T: Scalar + Zero + One,
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
DefaultAllocator: Allocator<T, D, D>,
|
||||||
{
|
{
|
||||||
/// Creates a new homogeneous matrix that applies the same scaling factor on each dimension.
|
/// Creates a new homogeneous matrix that applies the same scaling factor on each dimension.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_scaling(scaling: N) -> Self {
|
pub fn new_scaling(scaling: T) -> Self {
|
||||||
let mut res = Self::from_diagonal_element(scaling);
|
let mut res = Self::from_diagonal_element(scaling);
|
||||||
res[(D::dim() - 1, D::dim() - 1)] = N::one();
|
res[(D::dim() - 1, D::dim() - 1)] = T::one();
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new homogeneous matrix that applies a distinct scaling factor for each dimension.
|
/// Creates a new homogeneous matrix that applies a distinct scaling factor for each dimension.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_nonuniform_scaling<SB>(scaling: &Vector<N, DimNameDiff<D, U1>, SB>) -> Self
|
pub fn new_nonuniform_scaling<SB>(scaling: &Vector<T, DimNameDiff<D, U1>, SB>) -> Self
|
||||||
where
|
where
|
||||||
D: DimNameSub<U1>,
|
D: DimNameSub<U1>,
|
||||||
SB: Storage<N, DimNameDiff<D, U1>>,
|
SB: Storage<T, DimNameDiff<D, U1>>,
|
||||||
{
|
{
|
||||||
let mut res = Self::identity();
|
let mut res = Self::identity();
|
||||||
for i in 0..scaling.len() {
|
for i in 0..scaling.len() {
|
||||||
|
@ -53,13 +53,16 @@ where
|
||||||
|
|
||||||
/// Creates a new homogeneous matrix that applies a pure translation.
|
/// Creates a new homogeneous matrix that applies a pure translation.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_translation<SB>(translation: &Vector<N, DimNameDiff<D, U1>, SB>) -> Self
|
pub fn new_translation<SB>(translation: &Vector<T, DimNameDiff<D, U1>, SB>) -> Self
|
||||||
where
|
where
|
||||||
D: DimNameSub<U1>,
|
D: DimNameSub<U1>,
|
||||||
SB: Storage<N, DimNameDiff<D, U1>>,
|
SB: Storage<T, DimNameDiff<D, U1>>,
|
||||||
{
|
{
|
||||||
let mut res = Self::identity();
|
let mut res = Self::identity();
|
||||||
res.fixed_slice_mut::<DimNameDiff<D, U1>, U1>(0, D::dim() - 1)
|
res.generic_slice_mut(
|
||||||
|
(0, D::dim() - 1),
|
||||||
|
(DimNameDiff::<D, U1>::name(), Const::<1>),
|
||||||
|
)
|
||||||
.copy_from(translation);
|
.copy_from(translation);
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -67,10 +70,10 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # 2D transformations as a Matrix3
|
/// # 2D transformations as a Matrix3
|
||||||
impl<N: RealField> Matrix3<N> {
|
impl<T: RealField> Matrix3<T> {
|
||||||
/// Builds a 2 dimensional homogeneous rotation matrix from an angle in radian.
|
/// Builds a 2 dimensional homogeneous rotation matrix from an angle in radian.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_rotation(angle: N) -> Self {
|
pub fn new_rotation(angle: T) -> Self {
|
||||||
Rotation2::new(angle).to_homogeneous()
|
Rotation2::new(angle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,9 +81,9 @@ impl<N: RealField> Matrix3<N> {
|
||||||
///
|
///
|
||||||
/// Can be used to implement "zoom_to" functionality.
|
/// Can be used to implement "zoom_to" functionality.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_nonuniform_scaling_wrt_point(scaling: &Vector2<N>, pt: &Point2<N>) -> Self {
|
pub fn new_nonuniform_scaling_wrt_point(scaling: &Vector2<T>, pt: &Point2<T>) -> Self {
|
||||||
let zero = N::zero();
|
let zero = T::zero();
|
||||||
let one = N::one();
|
let one = T::one();
|
||||||
Matrix3::new(
|
Matrix3::new(
|
||||||
scaling.x,
|
scaling.x,
|
||||||
zero,
|
zero,
|
||||||
|
@ -96,12 +99,12 @@ impl<N: RealField> Matrix3<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # 3D transformations as a Matrix4
|
/// # 3D transformations as a Matrix4
|
||||||
impl<N: RealField> Matrix4<N> {
|
impl<T: RealField> Matrix4<T> {
|
||||||
/// Builds a 3D homogeneous rotation matrix from an axis and an angle (multiplied together).
|
/// Builds a 3D homogeneous rotation matrix from an axis and an angle (multiplied together).
|
||||||
///
|
///
|
||||||
/// Returns the identity matrix if the given argument is zero.
|
/// Returns the identity matrix if the given argument is zero.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_rotation(axisangle: Vector3<N>) -> Self {
|
pub fn new_rotation(axisangle: Vector3<T>) -> Self {
|
||||||
Rotation3::new(axisangle).to_homogeneous()
|
Rotation3::new(axisangle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +112,7 @@ impl<N: RealField> Matrix4<N> {
|
||||||
///
|
///
|
||||||
/// Returns the identity matrix if the given argument is zero.
|
/// Returns the identity matrix if the given argument is zero.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_rotation_wrt_point(axisangle: Vector3<N>, pt: Point3<N>) -> Self {
|
pub fn new_rotation_wrt_point(axisangle: Vector3<T>, pt: Point3<T>) -> Self {
|
||||||
let rot = Rotation3::from_scaled_axis(axisangle);
|
let rot = Rotation3::from_scaled_axis(axisangle);
|
||||||
Isometry::rotation_wrt_point(rot, pt).to_homogeneous()
|
Isometry::rotation_wrt_point(rot, pt).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
@ -118,9 +121,9 @@ impl<N: RealField> Matrix4<N> {
|
||||||
///
|
///
|
||||||
/// Can be used to implement "zoom_to" functionality.
|
/// Can be used to implement "zoom_to" functionality.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_nonuniform_scaling_wrt_point(scaling: &Vector3<N>, pt: &Point3<N>) -> Self {
|
pub fn new_nonuniform_scaling_wrt_point(scaling: &Vector3<T>, pt: &Point3<T>) -> Self {
|
||||||
let zero = N::zero();
|
let zero = T::zero();
|
||||||
let one = N::one();
|
let one = T::one();
|
||||||
Matrix4::new(
|
Matrix4::new(
|
||||||
scaling.x,
|
scaling.x,
|
||||||
zero,
|
zero,
|
||||||
|
@ -146,31 +149,31 @@ impl<N: RealField> Matrix4<N> {
|
||||||
/// Returns the identity matrix if the given argument is zero.
|
/// Returns the identity matrix if the given argument is zero.
|
||||||
/// This is identical to `Self::new_rotation`.
|
/// This is identical to `Self::new_rotation`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_scaled_axis(axisangle: Vector3<N>) -> Self {
|
pub fn from_scaled_axis(axisangle: Vector3<T>) -> Self {
|
||||||
Rotation3::from_scaled_axis(axisangle).to_homogeneous()
|
Rotation3::from_scaled_axis(axisangle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new rotation from Euler angles.
|
/// Creates a new rotation from Euler angles.
|
||||||
///
|
///
|
||||||
/// The primitive rotations are applied in order: 1 roll − 2 pitch − 3 yaw.
|
/// The primitive rotations are applied in order: 1 roll − 2 pitch − 3 yaw.
|
||||||
pub fn from_euler_angles(roll: N, pitch: N, yaw: N) -> Self {
|
pub fn from_euler_angles(roll: T, pitch: T, yaw: T) -> Self {
|
||||||
Rotation3::from_euler_angles(roll, pitch, yaw).to_homogeneous()
|
Rotation3::from_euler_angles(roll, pitch, yaw).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a 3D homogeneous rotation matrix from an axis and a rotation angle.
|
/// Builds a 3D homogeneous rotation matrix from an axis and a rotation angle.
|
||||||
pub fn from_axis_angle(axis: &Unit<Vector3<N>>, angle: N) -> Self {
|
pub fn from_axis_angle(axis: &Unit<Vector3<T>>, angle: T) -> Self {
|
||||||
Rotation3::from_axis_angle(axis, angle).to_homogeneous()
|
Rotation3::from_axis_angle(axis, angle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new homogeneous matrix for an orthographic projection.
|
/// Creates a new homogeneous matrix for an orthographic projection.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_orthographic(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> Self {
|
pub fn new_orthographic(left: T, right: T, bottom: T, top: T, znear: T, zfar: T) -> Self {
|
||||||
Orthographic3::new(left, right, bottom, top, znear, zfar).into_inner()
|
Orthographic3::new(left, right, bottom, top, znear, zfar).into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new homogeneous matrix for a perspective projection.
|
/// Creates a new homogeneous matrix for a perspective projection.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new_perspective(aspect: N, fovy: N, znear: N, zfar: N) -> Self {
|
pub fn new_perspective(aspect: T, fovy: T, znear: T, zfar: T) -> Self {
|
||||||
Perspective3::new(aspect, fovy, znear, zfar).into_inner()
|
Perspective3::new(aspect, fovy, znear, zfar).into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,40 +183,40 @@ impl<N: RealField> Matrix4<N> {
|
||||||
/// It maps the view direction `target - eye` to the positive `z` axis and the origin to the
|
/// It maps the view direction `target - eye` to the positive `z` axis and the origin to the
|
||||||
/// `eye`.
|
/// `eye`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn face_towards(eye: &Point3<N>, target: &Point3<N>, up: &Vector3<N>) -> Self {
|
pub fn face_towards(eye: &Point3<T>, target: &Point3<T>, up: &Vector3<T>) -> Self {
|
||||||
IsometryMatrix3::face_towards(eye, target, up).to_homogeneous()
|
IsometryMatrix3::face_towards(eye, target, up).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deprecated: Use [Matrix4::face_towards] instead.
|
/// Deprecated: Use [Matrix4::face_towards] instead.
|
||||||
#[deprecated(note = "renamed to `face_towards`")]
|
#[deprecated(note = "renamed to `face_towards`")]
|
||||||
pub fn new_observer_frame(eye: &Point3<N>, target: &Point3<N>, up: &Vector3<N>) -> Self {
|
pub fn new_observer_frame(eye: &Point3<T>, target: &Point3<T>, up: &Vector3<T>) -> Self {
|
||||||
Matrix4::face_towards(eye, target, up)
|
Matrix4::face_towards(eye, target, up)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a right-handed look-at view matrix.
|
/// Builds a right-handed look-at view matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn look_at_rh(eye: &Point3<N>, target: &Point3<N>, up: &Vector3<N>) -> Self {
|
pub fn look_at_rh(eye: &Point3<T>, target: &Point3<T>, up: &Vector3<T>) -> Self {
|
||||||
IsometryMatrix3::look_at_rh(eye, target, up).to_homogeneous()
|
IsometryMatrix3::look_at_rh(eye, target, up).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a left-handed look-at view matrix.
|
/// Builds a left-handed look-at view matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn look_at_lh(eye: &Point3<N>, target: &Point3<N>, up: &Vector3<N>) -> Self {
|
pub fn look_at_lh(eye: &Point3<T>, target: &Point3<T>, up: &Vector3<T>) -> Self {
|
||||||
IsometryMatrix3::look_at_lh(eye, target, up).to_homogeneous()
|
IsometryMatrix3::look_at_lh(eye, target, up).to_homogeneous()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Append/prepend translation and scaling
|
/// # Append/prepend translation and scaling
|
||||||
impl<N: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<N, D, D>>
|
impl<T: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<T, D, D>>
|
||||||
SquareMatrix<N, D, S>
|
SquareMatrix<T, D, S>
|
||||||
{
|
{
|
||||||
/// Computes the transformation equal to `self` followed by an uniform scaling factor.
|
/// Computes the transformation equal to `self` followed by an uniform scaling factor.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use = "Did you mean to use append_scaling_mut()?"]
|
#[must_use = "Did you mean to use append_scaling_mut()?"]
|
||||||
pub fn append_scaling(&self, scaling: N) -> MatrixN<N, D>
|
pub fn append_scaling(&self, scaling: T) -> OMatrix<T, D, D>
|
||||||
where
|
where
|
||||||
D: DimNameSub<U1>,
|
D: DimNameSub<U1>,
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
DefaultAllocator: Allocator<T, D, D>,
|
||||||
{
|
{
|
||||||
let mut res = self.clone_owned();
|
let mut res = self.clone_owned();
|
||||||
res.append_scaling_mut(scaling);
|
res.append_scaling_mut(scaling);
|
||||||
|
@ -223,10 +226,10 @@ impl<N: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<N, D
|
||||||
/// Computes the transformation equal to an uniform scaling factor followed by `self`.
|
/// Computes the transformation equal to an uniform scaling factor followed by `self`.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use = "Did you mean to use prepend_scaling_mut()?"]
|
#[must_use = "Did you mean to use prepend_scaling_mut()?"]
|
||||||
pub fn prepend_scaling(&self, scaling: N) -> MatrixN<N, D>
|
pub fn prepend_scaling(&self, scaling: T) -> OMatrix<T, D, D>
|
||||||
where
|
where
|
||||||
D: DimNameSub<U1>,
|
D: DimNameSub<U1>,
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
DefaultAllocator: Allocator<T, D, D>,
|
||||||
{
|
{
|
||||||
let mut res = self.clone_owned();
|
let mut res = self.clone_owned();
|
||||||
res.prepend_scaling_mut(scaling);
|
res.prepend_scaling_mut(scaling);
|
||||||
|
@ -238,12 +241,12 @@ impl<N: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<N, D
|
||||||
#[must_use = "Did you mean to use append_nonuniform_scaling_mut()?"]
|
#[must_use = "Did you mean to use append_nonuniform_scaling_mut()?"]
|
||||||
pub fn append_nonuniform_scaling<SB>(
|
pub fn append_nonuniform_scaling<SB>(
|
||||||
&self,
|
&self,
|
||||||
scaling: &Vector<N, DimNameDiff<D, U1>, SB>,
|
scaling: &Vector<T, DimNameDiff<D, U1>, SB>,
|
||||||
) -> MatrixN<N, D>
|
) -> OMatrix<T, D, D>
|
||||||
where
|
where
|
||||||
D: DimNameSub<U1>,
|
D: DimNameSub<U1>,
|
||||||
SB: Storage<N, DimNameDiff<D, U1>>,
|
SB: Storage<T, DimNameDiff<D, U1>>,
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
DefaultAllocator: Allocator<T, D, D>,
|
||||||
{
|
{
|
||||||
let mut res = self.clone_owned();
|
let mut res = self.clone_owned();
|
||||||
res.append_nonuniform_scaling_mut(scaling);
|
res.append_nonuniform_scaling_mut(scaling);
|
||||||
|
@ -255,12 +258,12 @@ impl<N: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<N, D
|
||||||
#[must_use = "Did you mean to use prepend_nonuniform_scaling_mut()?"]
|
#[must_use = "Did you mean to use prepend_nonuniform_scaling_mut()?"]
|
||||||
pub fn prepend_nonuniform_scaling<SB>(
|
pub fn prepend_nonuniform_scaling<SB>(
|
||||||
&self,
|
&self,
|
||||||
scaling: &Vector<N, DimNameDiff<D, U1>, SB>,
|
scaling: &Vector<T, DimNameDiff<D, U1>, SB>,
|
||||||
) -> MatrixN<N, D>
|
) -> OMatrix<T, D, D>
|
||||||
where
|
where
|
||||||
D: DimNameSub<U1>,
|
D: DimNameSub<U1>,
|
||||||
SB: Storage<N, DimNameDiff<D, U1>>,
|
SB: Storage<T, DimNameDiff<D, U1>>,
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
DefaultAllocator: Allocator<T, D, D>,
|
||||||
{
|
{
|
||||||
let mut res = self.clone_owned();
|
let mut res = self.clone_owned();
|
||||||
res.prepend_nonuniform_scaling_mut(scaling);
|
res.prepend_nonuniform_scaling_mut(scaling);
|
||||||
|
@ -270,11 +273,14 @@ impl<N: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<N, D
|
||||||
/// Computes the transformation equal to `self` followed by a translation.
|
/// Computes the transformation equal to `self` followed by a translation.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use = "Did you mean to use append_translation_mut()?"]
|
#[must_use = "Did you mean to use append_translation_mut()?"]
|
||||||
pub fn append_translation<SB>(&self, shift: &Vector<N, DimNameDiff<D, U1>, SB>) -> MatrixN<N, D>
|
pub fn append_translation<SB>(
|
||||||
|
&self,
|
||||||
|
shift: &Vector<T, DimNameDiff<D, U1>, SB>,
|
||||||
|
) -> OMatrix<T, D, D>
|
||||||
where
|
where
|
||||||
D: DimNameSub<U1>,
|
D: DimNameSub<U1>,
|
||||||
SB: Storage<N, DimNameDiff<D, U1>>,
|
SB: Storage<T, DimNameDiff<D, U1>>,
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
DefaultAllocator: Allocator<T, D, D>,
|
||||||
{
|
{
|
||||||
let mut res = self.clone_owned();
|
let mut res = self.clone_owned();
|
||||||
res.append_translation_mut(shift);
|
res.append_translation_mut(shift);
|
||||||
|
@ -286,12 +292,12 @@ impl<N: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<N, D
|
||||||
#[must_use = "Did you mean to use prepend_translation_mut()?"]
|
#[must_use = "Did you mean to use prepend_translation_mut()?"]
|
||||||
pub fn prepend_translation<SB>(
|
pub fn prepend_translation<SB>(
|
||||||
&self,
|
&self,
|
||||||
shift: &Vector<N, DimNameDiff<D, U1>, SB>,
|
shift: &Vector<T, DimNameDiff<D, U1>, SB>,
|
||||||
) -> MatrixN<N, D>
|
) -> OMatrix<T, D, D>
|
||||||
where
|
where
|
||||||
D: DimNameSub<U1>,
|
D: DimNameSub<U1>,
|
||||||
SB: Storage<N, DimNameDiff<D, U1>>,
|
SB: Storage<T, DimNameDiff<D, U1>>,
|
||||||
DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimNameDiff<D, U1>>,
|
DefaultAllocator: Allocator<T, D, D> + Allocator<T, DimNameDiff<D, U1>>,
|
||||||
{
|
{
|
||||||
let mut res = self.clone_owned();
|
let mut res = self.clone_owned();
|
||||||
res.prepend_translation_mut(shift);
|
res.prepend_translation_mut(shift);
|
||||||
|
@ -300,36 +306,36 @@ impl<N: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<N, D
|
||||||
|
|
||||||
/// Computes in-place the transformation equal to `self` followed by an uniform scaling factor.
|
/// Computes in-place the transformation equal to `self` followed by an uniform scaling factor.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn append_scaling_mut(&mut self, scaling: N)
|
pub fn append_scaling_mut(&mut self, scaling: T)
|
||||||
where
|
where
|
||||||
S: StorageMut<N, D, D>,
|
S: StorageMut<T, D, D>,
|
||||||
D: DimNameSub<U1>,
|
D: DimNameSub<U1>,
|
||||||
{
|
{
|
||||||
let mut to_scale = self.fixed_rows_mut::<DimNameDiff<D, U1>>(0);
|
let mut to_scale = self.rows_generic_mut(0, DimNameDiff::<D, U1>::name());
|
||||||
to_scale *= scaling;
|
to_scale *= scaling;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes in-place the transformation equal to an uniform scaling factor followed by `self`.
|
/// Computes in-place the transformation equal to an uniform scaling factor followed by `self`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn prepend_scaling_mut(&mut self, scaling: N)
|
pub fn prepend_scaling_mut(&mut self, scaling: T)
|
||||||
where
|
where
|
||||||
S: StorageMut<N, D, D>,
|
S: StorageMut<T, D, D>,
|
||||||
D: DimNameSub<U1>,
|
D: DimNameSub<U1>,
|
||||||
{
|
{
|
||||||
let mut to_scale = self.fixed_columns_mut::<DimNameDiff<D, U1>>(0);
|
let mut to_scale = self.columns_generic_mut(0, DimNameDiff::<D, U1>::name());
|
||||||
to_scale *= scaling;
|
to_scale *= scaling;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes in-place the transformation equal to `self` followed by a non-uniform scaling factor.
|
/// Computes in-place the transformation equal to `self` followed by a non-uniform scaling factor.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn append_nonuniform_scaling_mut<SB>(&mut self, scaling: &Vector<N, DimNameDiff<D, U1>, SB>)
|
pub fn append_nonuniform_scaling_mut<SB>(&mut self, scaling: &Vector<T, DimNameDiff<D, U1>, SB>)
|
||||||
where
|
where
|
||||||
S: StorageMut<N, D, D>,
|
S: StorageMut<T, D, D>,
|
||||||
D: DimNameSub<U1>,
|
D: DimNameSub<U1>,
|
||||||
SB: Storage<N, DimNameDiff<D, U1>>,
|
SB: Storage<T, DimNameDiff<D, U1>>,
|
||||||
{
|
{
|
||||||
for i in 0..scaling.len() {
|
for i in 0..scaling.len() {
|
||||||
let mut to_scale = self.fixed_rows_mut::<U1>(i);
|
let mut to_scale = self.fixed_rows_mut::<1>(i);
|
||||||
to_scale *= scaling[i].inlined_clone();
|
to_scale *= scaling[i].inlined_clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -338,25 +344,25 @@ impl<N: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<N, D
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn prepend_nonuniform_scaling_mut<SB>(
|
pub fn prepend_nonuniform_scaling_mut<SB>(
|
||||||
&mut self,
|
&mut self,
|
||||||
scaling: &Vector<N, DimNameDiff<D, U1>, SB>,
|
scaling: &Vector<T, DimNameDiff<D, U1>, SB>,
|
||||||
) where
|
) where
|
||||||
S: StorageMut<N, D, D>,
|
S: StorageMut<T, D, D>,
|
||||||
D: DimNameSub<U1>,
|
D: DimNameSub<U1>,
|
||||||
SB: Storage<N, DimNameDiff<D, U1>>,
|
SB: Storage<T, DimNameDiff<D, U1>>,
|
||||||
{
|
{
|
||||||
for i in 0..scaling.len() {
|
for i in 0..scaling.len() {
|
||||||
let mut to_scale = self.fixed_columns_mut::<U1>(i);
|
let mut to_scale = self.fixed_columns_mut::<1>(i);
|
||||||
to_scale *= scaling[i].inlined_clone();
|
to_scale *= scaling[i].inlined_clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the transformation equal to `self` followed by a translation.
|
/// Computes the transformation equal to `self` followed by a translation.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn append_translation_mut<SB>(&mut self, shift: &Vector<N, DimNameDiff<D, U1>, SB>)
|
pub fn append_translation_mut<SB>(&mut self, shift: &Vector<T, DimNameDiff<D, U1>, SB>)
|
||||||
where
|
where
|
||||||
S: StorageMut<N, D, D>,
|
S: StorageMut<T, D, D>,
|
||||||
D: DimNameSub<U1>,
|
D: DimNameSub<U1>,
|
||||||
SB: Storage<N, DimNameDiff<D, U1>>,
|
SB: Storage<T, DimNameDiff<D, U1>>,
|
||||||
{
|
{
|
||||||
for i in 0..D::dim() {
|
for i in 0..D::dim() {
|
||||||
for j in 0..D::dim() - 1 {
|
for j in 0..D::dim() - 1 {
|
||||||
|
@ -368,41 +374,55 @@ impl<N: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<N, D
|
||||||
|
|
||||||
/// Computes the transformation equal to a translation followed by `self`.
|
/// Computes the transformation equal to a translation followed by `self`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn prepend_translation_mut<SB>(&mut self, shift: &Vector<N, DimNameDiff<D, U1>, SB>)
|
pub fn prepend_translation_mut<SB>(&mut self, shift: &Vector<T, DimNameDiff<D, U1>, SB>)
|
||||||
where
|
where
|
||||||
D: DimNameSub<U1>,
|
D: DimNameSub<U1>,
|
||||||
S: StorageMut<N, D, D>,
|
S: StorageMut<T, D, D>,
|
||||||
SB: Storage<N, DimNameDiff<D, U1>>,
|
SB: Storage<T, DimNameDiff<D, U1>>,
|
||||||
DefaultAllocator: Allocator<N, DimNameDiff<D, U1>>,
|
DefaultAllocator: Allocator<T, DimNameDiff<D, U1>>,
|
||||||
{
|
{
|
||||||
let scale = self
|
let scale = self
|
||||||
.fixed_slice::<U1, DimNameDiff<D, U1>>(D::dim() - 1, 0)
|
.generic_slice(
|
||||||
|
(D::dim() - 1, 0),
|
||||||
|
(Const::<1>, DimNameDiff::<D, U1>::name()),
|
||||||
|
)
|
||||||
.tr_dot(&shift);
|
.tr_dot(&shift);
|
||||||
let post_translation =
|
let post_translation = self.generic_slice(
|
||||||
self.fixed_slice::<DimNameDiff<D, U1>, DimNameDiff<D, U1>>(0, 0) * shift;
|
(0, 0),
|
||||||
|
(DimNameDiff::<D, U1>::name(), DimNameDiff::<D, U1>::name()),
|
||||||
|
) * shift;
|
||||||
|
|
||||||
self[(D::dim() - 1, D::dim() - 1)] += scale;
|
self[(D::dim() - 1, D::dim() - 1)] += scale;
|
||||||
|
|
||||||
let mut translation = self.fixed_slice_mut::<DimNameDiff<D, U1>, U1>(0, D::dim() - 1);
|
let mut translation = self.generic_slice_mut(
|
||||||
|
(0, D::dim() - 1),
|
||||||
|
(DimNameDiff::<D, U1>::name(), Const::<1>),
|
||||||
|
);
|
||||||
translation += post_translation;
|
translation += post_translation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Transformation of vectors and points
|
/// # Transformation of vectors and points
|
||||||
impl<N: RealField, D: DimNameSub<U1>, S: Storage<N, D, D>> SquareMatrix<N, D, S>
|
impl<T: RealField, D: DimNameSub<U1>, S: Storage<T, D, D>> SquareMatrix<T, D, S>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D, D>
|
DefaultAllocator: Allocator<T, D, D>
|
||||||
+ Allocator<N, DimNameDiff<D, U1>>
|
+ Allocator<T, DimNameDiff<D, U1>>
|
||||||
+ Allocator<N, DimNameDiff<D, U1>, DimNameDiff<D, U1>>,
|
+ Allocator<T, DimNameDiff<D, U1>, DimNameDiff<D, U1>>,
|
||||||
{
|
{
|
||||||
/// Transforms the given vector, assuming the matrix `self` uses homogeneous coordinates.
|
/// Transforms the given vector, assuming the matrix `self` uses homogeneous coordinates.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn transform_vector(
|
pub fn transform_vector(
|
||||||
&self,
|
&self,
|
||||||
v: &VectorN<N, DimNameDiff<D, U1>>,
|
v: &OVector<T, DimNameDiff<D, U1>>,
|
||||||
) -> VectorN<N, DimNameDiff<D, U1>> {
|
) -> OVector<T, DimNameDiff<D, U1>> {
|
||||||
let transform = self.fixed_slice::<DimNameDiff<D, U1>, DimNameDiff<D, U1>>(0, 0);
|
let transform = self.generic_slice(
|
||||||
let normalizer = self.fixed_slice::<U1, DimNameDiff<D, U1>>(D::dim() - 1, 0);
|
(0, 0),
|
||||||
|
(DimNameDiff::<D, U1>::name(), DimNameDiff::<D, U1>::name()),
|
||||||
|
);
|
||||||
|
let normalizer = self.generic_slice(
|
||||||
|
(D::dim() - 1, 0),
|
||||||
|
(Const::<1>, DimNameDiff::<D, U1>::name()),
|
||||||
|
);
|
||||||
let n = normalizer.tr_dot(&v);
|
let n = normalizer.tr_dot(&v);
|
||||||
|
|
||||||
if !n.is_zero() {
|
if !n.is_zero() {
|
||||||
|
@ -411,18 +431,33 @@ where
|
||||||
|
|
||||||
transform * v
|
transform * v
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: RealField, S: Storage<T, Const<3>, Const<3>>> SquareMatrix<T, Const<3>, S> {
|
||||||
/// Transforms the given point, assuming the matrix `self` uses homogeneous coordinates.
|
/// Transforms the given point, assuming the matrix `self` uses homogeneous coordinates.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn transform_point(
|
pub fn transform_point(&self, pt: &Point<T, 2>) -> Point<T, 2> {
|
||||||
&self,
|
let transform = self.fixed_slice::<2, 2>(0, 0);
|
||||||
pt: &Point<N, DimNameDiff<D, U1>>,
|
let translation = self.fixed_slice::<2, 1>(0, 2);
|
||||||
) -> Point<N, DimNameDiff<D, U1>> {
|
let normalizer = self.fixed_slice::<1, 2>(2, 0);
|
||||||
let transform = self.fixed_slice::<DimNameDiff<D, U1>, DimNameDiff<D, U1>>(0, 0);
|
let n = normalizer.tr_dot(&pt.coords) + unsafe { *self.get_unchecked((2, 2)) };
|
||||||
let translation = self.fixed_slice::<DimNameDiff<D, U1>, U1>(0, D::dim() - 1);
|
|
||||||
let normalizer = self.fixed_slice::<U1, DimNameDiff<D, U1>>(D::dim() - 1, 0);
|
if !n.is_zero() {
|
||||||
let n = normalizer.tr_dot(&pt.coords)
|
(transform * pt + translation) / n
|
||||||
+ unsafe { *self.get_unchecked((D::dim() - 1, D::dim() - 1)) };
|
} else {
|
||||||
|
transform * pt + translation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: RealField, S: Storage<T, Const<4>, Const<4>>> SquareMatrix<T, Const<4>, S> {
|
||||||
|
/// 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 n = normalizer.tr_dot(&pt.coords) + unsafe { *self.get_unchecked((3, 3)) };
|
||||||
|
|
||||||
if !n.is_zero() {
|
if !n.is_zero() {
|
||||||
(transform * pt + translation) / n
|
(transform * pt + translation) / n
|
||||||
|
|
|
@ -10,13 +10,13 @@ use crate::base::allocator::{Allocator, SameShapeAllocator};
|
||||||
use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
|
use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
|
||||||
use crate::base::dimension::Dim;
|
use crate::base::dimension::Dim;
|
||||||
use crate::base::storage::{Storage, StorageMut};
|
use crate::base::storage::{Storage, StorageMut};
|
||||||
use crate::base::{DefaultAllocator, Matrix, MatrixMN, MatrixSum, Scalar};
|
use crate::base::{DefaultAllocator, Matrix, MatrixSum, OMatrix, Scalar};
|
||||||
use crate::ClosedAdd;
|
use crate::ClosedAdd;
|
||||||
|
|
||||||
/// The type of the result of a matrix component-wise operation.
|
/// The type of the result of a matrix component-wise operation.
|
||||||
pub type MatrixComponentOp<N, R1, C1, R2, C2> = MatrixSum<N, R1, C1, R2, C2>;
|
pub type MatrixComponentOp<T, R1, C1, R2, C2> = MatrixSum<T, R1, C1, R2, C2>;
|
||||||
|
|
||||||
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
|
||||||
/// Computes the component-wise absolute value.
|
/// Computes the component-wise absolute value.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
|
@ -28,10 +28,10 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||||
/// assert_eq!(a.abs(), Matrix2::new(0.0, 1.0, 2.0, 3.0))
|
/// assert_eq!(a.abs(), Matrix2::new(0.0, 1.0, 2.0, 3.0))
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn abs(&self) -> MatrixMN<N, R, C>
|
pub fn abs(&self) -> OMatrix<T, R, C>
|
||||||
where
|
where
|
||||||
N: Signed,
|
T: Signed,
|
||||||
DefaultAllocator: Allocator<N, R, C>,
|
DefaultAllocator: Allocator<T, R, C>,
|
||||||
{
|
{
|
||||||
let mut res = self.clone_owned();
|
let mut res = self.clone_owned();
|
||||||
|
|
||||||
|
@ -49,11 +49,11 @@ macro_rules! component_binop_impl(
|
||||||
($($binop: ident, $binop_mut: ident, $binop_assign: ident, $cmpy: ident, $Trait: ident . $op: ident . $op_assign: ident, $desc:expr, $desc_cmpy:expr, $desc_mut:expr);* $(;)*) => {$(
|
($($binop: ident, $binop_mut: ident, $binop_assign: ident, $cmpy: ident, $Trait: ident . $op: ident . $op_assign: ident, $desc:expr, $desc_cmpy:expr, $desc_mut:expr);* $(;)*) => {$(
|
||||||
#[doc = $desc]
|
#[doc = $desc]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn $binop<R2, C2, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> MatrixComponentOp<N, R1, C1, R2, C2>
|
pub fn $binop<R2, C2, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> MatrixComponentOp<T, R1, C1, R2, C2>
|
||||||
where N: $Trait,
|
where T: $Trait,
|
||||||
R2: Dim, C2: Dim,
|
R2: Dim, C2: Dim,
|
||||||
SB: Storage<N, R2, C2>,
|
SB: Storage<T, R2, C2>,
|
||||||
DefaultAllocator: SameShapeAllocator<N, R1, C1, R2, C2>,
|
DefaultAllocator: SameShapeAllocator<T, R1, C1, R2, C2>,
|
||||||
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> {
|
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> {
|
||||||
|
|
||||||
assert_eq!(self.shape(), rhs.shape(), "Componentwise mul/div: mismatched matrix dimensions.");
|
assert_eq!(self.shape(), rhs.shape(), "Componentwise mul/div: mismatched matrix dimensions.");
|
||||||
|
@ -73,13 +73,13 @@ macro_rules! component_binop_impl(
|
||||||
// componentwise binop plus Y.
|
// componentwise binop plus Y.
|
||||||
#[doc = $desc_cmpy]
|
#[doc = $desc_cmpy]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn $cmpy<R2, C2, SB, R3, C3, SC>(&mut self, alpha: N, a: &Matrix<N, R2, C2, SB>, b: &Matrix<N, R3, C3, SC>, beta: N)
|
pub fn $cmpy<R2, C2, SB, R3, C3, SC>(&mut self, alpha: T, a: &Matrix<T, R2, C2, SB>, b: &Matrix<T, R3, C3, SC>, beta: T)
|
||||||
where N: $Trait + Zero + Mul<N, Output = N> + Add<N, Output = N>,
|
where T: $Trait + Zero + Mul<T, Output = T> + Add<T, Output = T>,
|
||||||
R2: Dim, C2: Dim,
|
R2: Dim, C2: Dim,
|
||||||
R3: Dim, C3: Dim,
|
R3: Dim, C3: Dim,
|
||||||
SA: StorageMut<N, R1, C1>,
|
SA: StorageMut<T, R1, C1>,
|
||||||
SB: Storage<N, R2, C2>,
|
SB: Storage<T, R2, C2>,
|
||||||
SC: Storage<N, R3, C3>,
|
SC: Storage<T, R3, C3>,
|
||||||
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> +
|
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> +
|
||||||
SameNumberOfRows<R1, R3> + SameNumberOfColumns<C1, C3> {
|
SameNumberOfRows<R1, R3> + SameNumberOfColumns<C1, C3> {
|
||||||
assert_eq!(self.shape(), a.shape(), "Componentwise mul/div: mismatched matrix dimensions.");
|
assert_eq!(self.shape(), a.shape(), "Componentwise mul/div: mismatched matrix dimensions.");
|
||||||
|
@ -109,12 +109,12 @@ macro_rules! component_binop_impl(
|
||||||
|
|
||||||
#[doc = $desc_mut]
|
#[doc = $desc_mut]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn $binop_assign<R2, C2, SB>(&mut self, rhs: &Matrix<N, R2, C2, SB>)
|
pub fn $binop_assign<R2, C2, SB>(&mut self, rhs: &Matrix<T, R2, C2, SB>)
|
||||||
where N: $Trait,
|
where T: $Trait,
|
||||||
R2: Dim,
|
R2: Dim,
|
||||||
C2: Dim,
|
C2: Dim,
|
||||||
SA: StorageMut<N, R1, C1>,
|
SA: StorageMut<T, R1, C1>,
|
||||||
SB: Storage<N, R2, C2>,
|
SB: Storage<T, R2, C2>,
|
||||||
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> {
|
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> {
|
||||||
|
|
||||||
assert_eq!(self.shape(), rhs.shape(), "Componentwise mul/div: mismatched matrix dimensions.");
|
assert_eq!(self.shape(), rhs.shape(), "Componentwise mul/div: mismatched matrix dimensions.");
|
||||||
|
@ -131,12 +131,12 @@ macro_rules! component_binop_impl(
|
||||||
#[doc = $desc_mut]
|
#[doc = $desc_mut]
|
||||||
#[inline]
|
#[inline]
|
||||||
#[deprecated(note = "This is renamed using the `_assign` suffix instead of the `_mut` suffix.")]
|
#[deprecated(note = "This is renamed using the `_assign` suffix instead of the `_mut` suffix.")]
|
||||||
pub fn $binop_mut<R2, C2, SB>(&mut self, rhs: &Matrix<N, R2, C2, SB>)
|
pub fn $binop_mut<R2, C2, SB>(&mut self, rhs: &Matrix<T, R2, C2, SB>)
|
||||||
where N: $Trait,
|
where T: $Trait,
|
||||||
R2: Dim,
|
R2: Dim,
|
||||||
C2: Dim,
|
C2: Dim,
|
||||||
SA: StorageMut<N, R1, C1>,
|
SA: StorageMut<T, R1, C1>,
|
||||||
SB: Storage<N, R2, C2>,
|
SB: Storage<T, R2, C2>,
|
||||||
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> {
|
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> {
|
||||||
self.$binop_assign(rhs)
|
self.$binop_assign(rhs)
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ macro_rules! component_binop_impl(
|
||||||
);
|
);
|
||||||
|
|
||||||
/// # Componentwise operations
|
/// # Componentwise operations
|
||||||
impl<N: Scalar, R1: Dim, C1: Dim, SA: Storage<N, R1, C1>> Matrix<N, R1, C1, SA> {
|
impl<T: Scalar, R1: Dim, C1: Dim, SA: Storage<T, R1, C1>> Matrix<T, R1, C1, SA> {
|
||||||
component_binop_impl!(
|
component_binop_impl!(
|
||||||
component_mul, component_mul_mut, component_mul_assign, cmpy, ClosedMul.mul.mul_assign,
|
component_mul, component_mul_mut, component_mul_assign, cmpy, ClosedMul.mul.mul_assign,
|
||||||
r"
|
r"
|
||||||
|
@ -241,30 +241,30 @@ impl<N: Scalar, R1: Dim, C1: Dim, SA: Storage<N, R1, C1>> Matrix<N, R1, C1, SA>
|
||||||
|
|
||||||
/// Computes the infimum (aka. componentwise min) of two matrices/vectors.
|
/// Computes the infimum (aka. componentwise min) of two matrices/vectors.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn inf(&self, other: &Self) -> MatrixMN<N, R1, C1>
|
pub fn inf(&self, other: &Self) -> OMatrix<T, R1, C1>
|
||||||
where
|
where
|
||||||
N: SimdPartialOrd,
|
T: SimdPartialOrd,
|
||||||
DefaultAllocator: Allocator<N, R1, C1>,
|
DefaultAllocator: Allocator<T, R1, C1>,
|
||||||
{
|
{
|
||||||
self.zip_map(other, |a, b| a.simd_min(b))
|
self.zip_map(other, |a, b| a.simd_min(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the supremum (aka. componentwise max) of two matrices/vectors.
|
/// Computes the supremum (aka. componentwise max) of two matrices/vectors.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn sup(&self, other: &Self) -> MatrixMN<N, R1, C1>
|
pub fn sup(&self, other: &Self) -> OMatrix<T, R1, C1>
|
||||||
where
|
where
|
||||||
N: SimdPartialOrd,
|
T: SimdPartialOrd,
|
||||||
DefaultAllocator: Allocator<N, R1, C1>,
|
DefaultAllocator: Allocator<T, R1, C1>,
|
||||||
{
|
{
|
||||||
self.zip_map(other, |a, b| a.simd_max(b))
|
self.zip_map(other, |a, b| a.simd_max(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the (infimum, supremum) of two matrices/vectors.
|
/// Computes the (infimum, supremum) of two matrices/vectors.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn inf_sup(&self, other: &Self) -> (MatrixMN<N, R1, C1>, MatrixMN<N, R1, C1>)
|
pub fn inf_sup(&self, other: &Self) -> (OMatrix<T, R1, C1>, OMatrix<T, R1, C1>)
|
||||||
where
|
where
|
||||||
N: SimdPartialOrd,
|
T: SimdPartialOrd,
|
||||||
DefaultAllocator: Allocator<N, R1, C1>,
|
DefaultAllocator: Allocator<T, R1, C1>,
|
||||||
{
|
{
|
||||||
// TODO: can this be optimized?
|
// TODO: can this be optimized?
|
||||||
(self.inf(other), self.sup(other))
|
(self.inf(other), self.sup(other))
|
||||||
|
@ -273,10 +273,10 @@ impl<N: Scalar, R1: Dim, C1: Dim, SA: Storage<N, R1, C1>> Matrix<N, R1, C1, SA>
|
||||||
/// Adds a scalar to `self`.
|
/// Adds a scalar to `self`.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use = "Did you mean to use add_scalar_mut()?"]
|
#[must_use = "Did you mean to use add_scalar_mut()?"]
|
||||||
pub fn add_scalar(&self, rhs: N) -> MatrixMN<N, R1, C1>
|
pub fn add_scalar(&self, rhs: T) -> OMatrix<T, R1, C1>
|
||||||
where
|
where
|
||||||
N: ClosedAdd,
|
T: ClosedAdd,
|
||||||
DefaultAllocator: Allocator<N, R1, C1>,
|
DefaultAllocator: Allocator<T, R1, C1>,
|
||||||
{
|
{
|
||||||
let mut res = self.clone_owned();
|
let mut res = self.clone_owned();
|
||||||
res.add_scalar_mut(rhs);
|
res.add_scalar_mut(rhs);
|
||||||
|
@ -285,10 +285,10 @@ impl<N: Scalar, R1: Dim, C1: Dim, SA: Storage<N, R1, C1>> Matrix<N, R1, C1, SA>
|
||||||
|
|
||||||
/// Adds a scalar to `self` in-place.
|
/// Adds a scalar to `self` in-place.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn add_scalar_mut(&mut self, rhs: N)
|
pub fn add_scalar_mut(&mut self, rhs: T)
|
||||||
where
|
where
|
||||||
N: ClosedAdd,
|
T: ClosedAdd,
|
||||||
SA: StorageMut<N, R1, C1>,
|
SA: StorageMut<T, R1, C1>,
|
||||||
{
|
{
|
||||||
for e in self.iter_mut() {
|
for e in self.iter_mut() {
|
||||||
*e += rhs.inlined_clone()
|
*e += rhs.inlined_clone()
|
||||||
|
|
|
@ -20,9 +20,11 @@ use typenum::{self, Cmp, Greater};
|
||||||
use simba::scalar::{ClosedAdd, ClosedMul};
|
use simba::scalar::{ClosedAdd, ClosedMul};
|
||||||
|
|
||||||
use crate::base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use crate::base::dimension::{Dim, DimName, Dynamic, U1, U2, U3, U4, U5, U6};
|
use crate::base::dimension::{Dim, DimName, Dynamic, ToTypenum};
|
||||||
use crate::base::storage::Storage;
|
use crate::base::storage::Storage;
|
||||||
use crate::base::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Scalar, Unit, Vector, VectorN};
|
use crate::base::{
|
||||||
|
ArrayStorage, Const, DefaultAllocator, Matrix, OMatrix, OVector, Scalar, Unit, Vector,
|
||||||
|
};
|
||||||
|
|
||||||
/// When "no_unsound_assume_init" is enabled, expands to `unimplemented!()` instead of `new_uninitialized_generic().assume_init()`.
|
/// When "no_unsound_assume_init" is enabled, expands to `unimplemented!()` instead of `new_uninitialized_generic().assume_init()`.
|
||||||
/// Intended as a placeholder, each callsite should be refactored to use uninitialized memory soundly
|
/// Intended as a placeholder, each callsite should be refactored to use uninitialized memory soundly
|
||||||
|
@ -31,7 +33,7 @@ macro_rules! unimplemented_or_uninitialized_generic {
|
||||||
($nrows:expr, $ncols:expr) => {{
|
($nrows:expr, $ncols:expr) => {{
|
||||||
#[cfg(feature="no_unsound_assume_init")] {
|
#[cfg(feature="no_unsound_assume_init")] {
|
||||||
// Some of the call sites need the number of rows and columns from this to infer a type, so
|
// Some of the call sites need the number of rows and columns from this to infer a type, so
|
||||||
// uninitialized memory is used to infer the type, as `N: Zero` isn't available at all callsites.
|
// uninitialized memory is used to infer the type, as `T: Zero` isn't available at all callsites.
|
||||||
// This may technically still be UB even though the assume_init is dead code, but all callsites should be fixed before #556 is closed.
|
// This may technically still be UB even though the assume_init is dead code, but all callsites should be fixed before #556 is closed.
|
||||||
let typeinference_helper = crate::base::Matrix::new_uninitialized_generic($nrows, $ncols);
|
let typeinference_helper = crate::base::Matrix::new_uninitialized_generic($nrows, $ncols);
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
|
@ -47,9 +49,9 @@ macro_rules! unimplemented_or_uninitialized_generic {
|
||||||
/// the dimension as inputs.
|
/// the dimension as inputs.
|
||||||
///
|
///
|
||||||
/// These functions should only be used when working on dimension-generic code.
|
/// These functions should only be used when working on dimension-generic code.
|
||||||
impl<N: Scalar, R: Dim, C: Dim> MatrixMN<N, R, C>
|
impl<T: Scalar, R: Dim, C: Dim> OMatrix<T, R, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, R, C>,
|
DefaultAllocator: Allocator<T, R, C>,
|
||||||
{
|
{
|
||||||
/// Creates a new uninitialized matrix. If the matrix has a compile-time dimension, this panics
|
/// Creates a new uninitialized matrix. If the matrix has a compile-time dimension, this panics
|
||||||
/// if `nrows != R::to_usize()` or `ncols != C::to_usize()`.
|
/// if `nrows != R::to_usize()` or `ncols != C::to_usize()`.
|
||||||
|
@ -60,7 +62,7 @@ where
|
||||||
|
|
||||||
/// Creates a matrix with all its elements set to `elem`.
|
/// Creates a matrix with all its elements set to `elem`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_element_generic(nrows: R, ncols: C, elem: N) -> Self {
|
pub fn from_element_generic(nrows: R, ncols: C, elem: T) -> Self {
|
||||||
let len = nrows.value() * ncols.value();
|
let len = nrows.value() * ncols.value();
|
||||||
Self::from_iterator_generic(nrows, ncols, iter::repeat(elem).take(len))
|
Self::from_iterator_generic(nrows, ncols, iter::repeat(elem).take(len))
|
||||||
}
|
}
|
||||||
|
@ -69,7 +71,7 @@ where
|
||||||
///
|
///
|
||||||
/// Same as `from_element_generic`.
|
/// Same as `from_element_generic`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn repeat_generic(nrows: R, ncols: C, elem: N) -> Self {
|
pub fn repeat_generic(nrows: R, ncols: C, elem: T) -> Self {
|
||||||
let len = nrows.value() * ncols.value();
|
let len = nrows.value() * ncols.value();
|
||||||
Self::from_iterator_generic(nrows, ncols, iter::repeat(elem).take(len))
|
Self::from_iterator_generic(nrows, ncols, iter::repeat(elem).take(len))
|
||||||
}
|
}
|
||||||
|
@ -78,16 +80,16 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn zeros_generic(nrows: R, ncols: C) -> Self
|
pub fn zeros_generic(nrows: R, ncols: C) -> Self
|
||||||
where
|
where
|
||||||
N: Zero,
|
T: Zero,
|
||||||
{
|
{
|
||||||
Self::from_element_generic(nrows, ncols, N::zero())
|
Self::from_element_generic(nrows, ncols, T::zero())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a matrix with all its elements filled by an iterator.
|
/// Creates a matrix with all its elements filled by an iterator.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_iterator_generic<I>(nrows: R, ncols: C, iter: I) -> Self
|
pub fn from_iterator_generic<I>(nrows: R, ncols: C, iter: I) -> Self
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = N>,
|
I: IntoIterator<Item = T>,
|
||||||
{
|
{
|
||||||
Self::from_data(DefaultAllocator::allocate_from_iterator(nrows, ncols, iter))
|
Self::from_data(DefaultAllocator::allocate_from_iterator(nrows, ncols, iter))
|
||||||
}
|
}
|
||||||
|
@ -98,7 +100,7 @@ where
|
||||||
/// The order of elements in the slice must follow the usual mathematic writing, i.e.,
|
/// The order of elements in the slice must follow the usual mathematic writing, i.e.,
|
||||||
/// row-by-row.
|
/// row-by-row.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_row_slice_generic(nrows: R, ncols: C, slice: &[N]) -> Self {
|
pub fn from_row_slice_generic(nrows: R, ncols: C, slice: &[T]) -> Self {
|
||||||
assert!(
|
assert!(
|
||||||
slice.len() == nrows.value() * ncols.value(),
|
slice.len() == nrows.value() * ncols.value(),
|
||||||
"Matrix init. error: the slice did not contain the right number of elements."
|
"Matrix init. error: the slice did not contain the right number of elements."
|
||||||
|
@ -119,7 +121,7 @@ where
|
||||||
/// Creates a matrix with its elements filled with the components provided by a slice. The
|
/// Creates a matrix with its elements filled with the components provided by a slice. The
|
||||||
/// components must have the same layout as the matrix data storage (i.e. column-major).
|
/// components must have the same layout as the matrix data storage (i.e. column-major).
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_column_slice_generic(nrows: R, ncols: C, slice: &[N]) -> Self {
|
pub fn from_column_slice_generic(nrows: R, ncols: C, slice: &[T]) -> Self {
|
||||||
Self::from_iterator_generic(nrows, ncols, slice.iter().cloned())
|
Self::from_iterator_generic(nrows, ncols, slice.iter().cloned())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +130,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_fn_generic<F>(nrows: R, ncols: C, mut f: F) -> Self
|
pub fn from_fn_generic<F>(nrows: R, ncols: C, mut f: F) -> Self
|
||||||
where
|
where
|
||||||
F: FnMut(usize, usize) -> N,
|
F: FnMut(usize, usize) -> T,
|
||||||
{
|
{
|
||||||
let mut res: Self = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, ncols) };
|
let mut res: Self = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, ncols) };
|
||||||
|
|
||||||
|
@ -148,9 +150,9 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn identity_generic(nrows: R, ncols: C) -> Self
|
pub fn identity_generic(nrows: R, ncols: C) -> Self
|
||||||
where
|
where
|
||||||
N: Zero + One,
|
T: Zero + One,
|
||||||
{
|
{
|
||||||
Self::from_diagonal_element_generic(nrows, ncols, N::one())
|
Self::from_diagonal_element_generic(nrows, ncols, T::one())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new matrix with its diagonal filled with copies of `elt`.
|
/// Creates a new matrix with its diagonal filled with copies of `elt`.
|
||||||
|
@ -158,9 +160,9 @@ where
|
||||||
/// If the matrix is not square, the largest square submatrix starting at index `(0, 0)` is set
|
/// If the matrix is not square, the largest square submatrix starting at index `(0, 0)` is set
|
||||||
/// to the identity matrix. All other entries are set to zero.
|
/// to the identity matrix. All other entries are set to zero.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_diagonal_element_generic(nrows: R, ncols: C, elt: N) -> Self
|
pub fn from_diagonal_element_generic(nrows: R, ncols: C, elt: T) -> Self
|
||||||
where
|
where
|
||||||
N: Zero + One,
|
T: Zero + One,
|
||||||
{
|
{
|
||||||
let mut res = Self::zeros_generic(nrows, ncols);
|
let mut res = Self::zeros_generic(nrows, ncols);
|
||||||
|
|
||||||
|
@ -176,9 +178,9 @@ where
|
||||||
///
|
///
|
||||||
/// Panics if `elts.len()` is larger than the minimum among `nrows` and `ncols`.
|
/// Panics if `elts.len()` is larger than the minimum among `nrows` and `ncols`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_partial_diagonal_generic(nrows: R, ncols: C, elts: &[N]) -> Self
|
pub fn from_partial_diagonal_generic(nrows: R, ncols: C, elts: &[T]) -> Self
|
||||||
where
|
where
|
||||||
N: Zero,
|
T: Zero,
|
||||||
{
|
{
|
||||||
let mut res = Self::zeros_generic(nrows, ncols);
|
let mut res = Self::zeros_generic(nrows, ncols);
|
||||||
assert!(
|
assert!(
|
||||||
|
@ -210,9 +212,9 @@ where
|
||||||
/// m.m31 == 7.0 && m.m32 == 8.0 && m.m33 == 9.0);
|
/// m.m31 == 7.0 && m.m32 == 8.0 && m.m33 == 9.0);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_rows<SB>(rows: &[Matrix<N, U1, C, SB>]) -> Self
|
pub fn from_rows<SB>(rows: &[Matrix<T, Const<1>, C, SB>]) -> Self
|
||||||
where
|
where
|
||||||
SB: Storage<N, U1, C>,
|
SB: Storage<T, Const<1>, C>,
|
||||||
{
|
{
|
||||||
assert!(!rows.is_empty(), "At least one row must be given.");
|
assert!(!rows.is_empty(), "At least one row must be given.");
|
||||||
let nrows = R::try_to_usize().unwrap_or_else(|| rows.len());
|
let nrows = R::try_to_usize().unwrap_or_else(|| rows.len());
|
||||||
|
@ -252,9 +254,9 @@ where
|
||||||
/// m.m31 == 3.0 && m.m32 == 6.0 && m.m33 == 9.0);
|
/// m.m31 == 3.0 && m.m32 == 6.0 && m.m33 == 9.0);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_columns<SB>(columns: &[Vector<N, R, SB>]) -> Self
|
pub fn from_columns<SB>(columns: &[Vector<T, R, SB>]) -> Self
|
||||||
where
|
where
|
||||||
SB: Storage<N, R>,
|
SB: Storage<T, R>,
|
||||||
{
|
{
|
||||||
assert!(!columns.is_empty(), "At least one column must be given.");
|
assert!(!columns.is_empty(), "At least one column must be given.");
|
||||||
let ncols = C::try_to_usize().unwrap_or_else(|| columns.len());
|
let ncols = C::try_to_usize().unwrap_or_else(|| columns.len());
|
||||||
|
@ -282,15 +284,16 @@ where
|
||||||
#[cfg(feature = "rand")]
|
#[cfg(feature = "rand")]
|
||||||
pub fn new_random_generic(nrows: R, ncols: C) -> Self
|
pub fn new_random_generic(nrows: R, ncols: C) -> Self
|
||||||
where
|
where
|
||||||
Standard: Distribution<N>,
|
Standard: Distribution<T>,
|
||||||
{
|
{
|
||||||
Self::from_fn_generic(nrows, ncols, |_, _| rand::random())
|
let mut rng = rand::thread_rng();
|
||||||
|
Self::from_fn_generic(nrows, ncols, |_, _| rng.gen())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a matrix filled with random values from the given distribution.
|
/// Creates a matrix filled with random values from the given distribution.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(feature = "rand-no-std")]
|
#[cfg(feature = "rand-no-std")]
|
||||||
pub fn from_distribution_generic<Distr: Distribution<N> + ?Sized, G: Rng + ?Sized>(
|
pub fn from_distribution_generic<Distr: Distribution<T> + ?Sized, G: Rng + ?Sized>(
|
||||||
nrows: R,
|
nrows: R,
|
||||||
ncols: C,
|
ncols: C,
|
||||||
distribution: &Distr,
|
distribution: &Distr,
|
||||||
|
@ -305,12 +308,12 @@ where
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
/// ```
|
/// ```
|
||||||
/// # use nalgebra::{Dynamic, DMatrix, Matrix, U1};
|
/// # use nalgebra::{Dynamic, DMatrix, Matrix, Const};
|
||||||
///
|
///
|
||||||
/// let vec = vec![0, 1, 2, 3, 4, 5];
|
/// let vec = vec![0, 1, 2, 3, 4, 5];
|
||||||
/// let vec_ptr = vec.as_ptr();
|
/// let vec_ptr = vec.as_ptr();
|
||||||
///
|
///
|
||||||
/// let matrix = Matrix::from_vec_generic(Dynamic::new(vec.len()), U1, vec);
|
/// let matrix = Matrix::from_vec_generic(Dynamic::new(vec.len()), Const::<1>, vec);
|
||||||
/// let matrix_storage_ptr = matrix.data.as_vec().as_ptr();
|
/// let matrix_storage_ptr = matrix.data.as_vec().as_ptr();
|
||||||
///
|
///
|
||||||
/// // `matrix` is backed by exactly the same `Vec` as it was constructed from.
|
/// // `matrix` is backed by exactly the same `Vec` as it was constructed from.
|
||||||
|
@ -318,15 +321,15 @@ where
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub fn from_vec_generic(nrows: R, ncols: C, data: Vec<N>) -> Self {
|
pub fn from_vec_generic(nrows: R, ncols: C, data: Vec<T>) -> Self {
|
||||||
Self::from_iterator_generic(nrows, ncols, data)
|
Self::from_iterator_generic(nrows, ncols, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, D: Dim> MatrixN<N, D>
|
impl<T, D: Dim> OMatrix<T, D, D>
|
||||||
where
|
where
|
||||||
N: Scalar,
|
T: Scalar,
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
DefaultAllocator: Allocator<T, D, D>,
|
||||||
{
|
{
|
||||||
/// Creates a square matrix with its diagonal set to `diag` and all other entries set to 0.
|
/// Creates a square matrix with its diagonal set to `diag` and all other entries set to 0.
|
||||||
///
|
///
|
||||||
|
@ -347,9 +350,9 @@ where
|
||||||
/// dm[(2, 0)] == 0.0 && dm[(2, 1)] == 0.0 && dm[(2, 2)] == 3.0);
|
/// dm[(2, 0)] == 0.0 && dm[(2, 1)] == 0.0 && dm[(2, 2)] == 3.0);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_diagonal<SB: Storage<N, D>>(diag: &Vector<N, D, SB>) -> Self
|
pub fn from_diagonal<SB: Storage<T, D>>(diag: &Vector<T, D, SB>) -> Self
|
||||||
where
|
where
|
||||||
N: Zero,
|
T: Zero,
|
||||||
{
|
{
|
||||||
let (dim, _) = diag.data.shape();
|
let (dim, _) = diag.data.shape();
|
||||||
let mut res = Self::zeros_generic(dim, dim);
|
let mut res = Self::zeros_generic(dim, dim);
|
||||||
|
@ -398,7 +401,7 @@ macro_rules! impl_constructors(
|
||||||
/// dm[(1, 0)] == 2.0 && dm[(1, 1)] == 2.0 && dm[(1, 2)] == 2.0);
|
/// dm[(1, 0)] == 2.0 && dm[(1, 1)] == 2.0 && dm[(1, 2)] == 2.0);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_element($($args: usize,)* elem: N) -> Self {
|
pub fn from_element($($args: usize,)* elem: T) -> Self {
|
||||||
Self::from_element_generic($($gargs, )* elem)
|
Self::from_element_generic($($gargs, )* elem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,7 +428,7 @@ macro_rules! impl_constructors(
|
||||||
/// dm[(1, 0)] == 2.0 && dm[(1, 1)] == 2.0 && dm[(1, 2)] == 2.0);
|
/// dm[(1, 0)] == 2.0 && dm[(1, 1)] == 2.0 && dm[(1, 2)] == 2.0);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn repeat($($args: usize,)* elem: N) -> Self {
|
pub fn repeat($($args: usize,)* elem: T) -> Self {
|
||||||
Self::repeat_generic($($gargs, )* elem)
|
Self::repeat_generic($($gargs, )* elem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,7 +454,7 @@ macro_rules! impl_constructors(
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn zeros($($args: usize),*) -> Self
|
pub fn zeros($($args: usize),*) -> Self
|
||||||
where N: Zero {
|
where T: Zero {
|
||||||
Self::zeros_generic($($gargs),*)
|
Self::zeros_generic($($gargs),*)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,7 +483,7 @@ macro_rules! impl_constructors(
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_iterator<I>($($args: usize,)* iter: I) -> Self
|
pub fn from_iterator<I>($($args: usize,)* iter: I) -> Self
|
||||||
where I: IntoIterator<Item = N> {
|
where I: IntoIterator<Item = T> {
|
||||||
Self::from_iterator_generic($($gargs, )* iter)
|
Self::from_iterator_generic($($gargs, )* iter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,7 +511,7 @@ macro_rules! impl_constructors(
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_fn<F>($($args: usize,)* f: F) -> Self
|
pub fn from_fn<F>($($args: usize,)* f: F) -> Self
|
||||||
where F: FnMut(usize, usize) -> N {
|
where F: FnMut(usize, usize) -> T {
|
||||||
Self::from_fn_generic($($gargs, )* f)
|
Self::from_fn_generic($($gargs, )* f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,7 +535,7 @@ macro_rules! impl_constructors(
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn identity($($args: usize,)*) -> Self
|
pub fn identity($($args: usize,)*) -> Self
|
||||||
where N: Zero + One {
|
where T: Zero + One {
|
||||||
Self::identity_generic($($gargs),* )
|
Self::identity_generic($($gargs),* )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,8 +557,8 @@ macro_rules! impl_constructors(
|
||||||
/// dm[(1, 0)] == 0.0 && dm[(1, 1)] == 5.0 && dm[(1, 2)] == 0.0);
|
/// dm[(1, 0)] == 0.0 && dm[(1, 1)] == 5.0 && dm[(1, 2)] == 0.0);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_diagonal_element($($args: usize,)* elt: N) -> Self
|
pub fn from_diagonal_element($($args: usize,)* elt: T) -> Self
|
||||||
where N: Zero + One {
|
where T: Zero + One {
|
||||||
Self::from_diagonal_element_generic($($gargs, )* elt)
|
Self::from_diagonal_element_generic($($gargs, )* elt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,15 +584,15 @@ macro_rules! impl_constructors(
|
||||||
/// dm[(2, 0)] == 0.0 && dm[(2, 1)] == 0.0 && dm[(2, 2)] == 0.0);
|
/// dm[(2, 0)] == 0.0 && dm[(2, 1)] == 0.0 && dm[(2, 2)] == 0.0);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_partial_diagonal($($args: usize,)* elts: &[N]) -> Self
|
pub fn from_partial_diagonal($($args: usize,)* elts: &[T]) -> Self
|
||||||
where N: Zero {
|
where T: Zero {
|
||||||
Self::from_partial_diagonal_generic($($gargs, )* elts)
|
Self::from_partial_diagonal_generic($($gargs, )* elts)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a matrix or vector filled with random values from the given distribution.
|
/// Creates a matrix or vector filled with random values from the given distribution.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(feature = "rand-no-std")]
|
#[cfg(feature = "rand-no-std")]
|
||||||
pub fn from_distribution<Distr: Distribution<N> + ?Sized, G: Rng + ?Sized>(
|
pub fn from_distribution<Distr: Distribution<T> + ?Sized, G: Rng + ?Sized>(
|
||||||
$($args: usize,)*
|
$($args: usize,)*
|
||||||
distribution: &Distr,
|
distribution: &Distr,
|
||||||
rng: &mut G,
|
rng: &mut G,
|
||||||
|
@ -601,28 +604,28 @@ macro_rules! impl_constructors(
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(feature = "rand")]
|
#[cfg(feature = "rand")]
|
||||||
pub fn new_random($($args: usize),*) -> Self
|
pub fn new_random($($args: usize),*) -> Self
|
||||||
where Standard: Distribution<N> {
|
where Standard: Distribution<T> {
|
||||||
Self::new_random_generic($($gargs),*)
|
Self::new_random_generic($($gargs),*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
/// # Constructors of statically-sized vectors or statically-sized matrices
|
/// # Constructors of statically-sized vectors or statically-sized matrices
|
||||||
impl<N: Scalar, R: DimName, C: DimName> MatrixMN<N, R, C>
|
impl<T: Scalar, R: DimName, C: DimName> OMatrix<T, R, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, R, C>,
|
DefaultAllocator: Allocator<T, R, C>,
|
||||||
{
|
{
|
||||||
// TODO: this is not very pretty. We could find a better call syntax.
|
// TODO: this is not very pretty. We could find a better call syntax.
|
||||||
impl_constructors!(R, C; // Arguments for Matrix<N, ..., S>
|
impl_constructors!(R, C; // Arguments for Matrix<T, ..., S>
|
||||||
=> R: DimName, => C: DimName; // Type parameters for impl<N, ..., S>
|
=> R: DimName, => C: DimName; // Type parameters for impl<T, ..., S>
|
||||||
R::name(), C::name(); // Arguments for `_generic` constructors.
|
R::name(), C::name(); // Arguments for `_generic` constructors.
|
||||||
); // Arguments for non-generic constructors.
|
); // Arguments for non-generic constructors.
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Constructors of matrices with a dynamic number of columns
|
/// # Constructors of matrices with a dynamic number of columns
|
||||||
impl<N: Scalar, R: DimName> MatrixMN<N, R, Dynamic>
|
impl<T: Scalar, R: DimName> OMatrix<T, R, Dynamic>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, R, Dynamic>,
|
DefaultAllocator: Allocator<T, R, Dynamic>,
|
||||||
{
|
{
|
||||||
impl_constructors!(R, Dynamic;
|
impl_constructors!(R, Dynamic;
|
||||||
=> R: DimName;
|
=> R: DimName;
|
||||||
|
@ -631,9 +634,9 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Constructors of dynamic vectors and matrices with a dynamic number of rows
|
/// # Constructors of dynamic vectors and matrices with a dynamic number of rows
|
||||||
impl<N: Scalar, C: DimName> MatrixMN<N, Dynamic, C>
|
impl<T: Scalar, C: DimName> OMatrix<T, Dynamic, C>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, Dynamic, C>,
|
DefaultAllocator: Allocator<T, Dynamic, C>,
|
||||||
{
|
{
|
||||||
impl_constructors!(Dynamic, C;
|
impl_constructors!(Dynamic, C;
|
||||||
=> C: DimName;
|
=> C: DimName;
|
||||||
|
@ -642,9 +645,9 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Constructors of fully dynamic matrices
|
/// # Constructors of fully dynamic matrices
|
||||||
impl<N: Scalar> MatrixMN<N, Dynamic, Dynamic>
|
impl<T: Scalar> OMatrix<T, Dynamic, Dynamic>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, Dynamic, Dynamic>,
|
DefaultAllocator: Allocator<T, Dynamic, Dynamic>,
|
||||||
{
|
{
|
||||||
impl_constructors!(Dynamic, Dynamic;
|
impl_constructors!(Dynamic, Dynamic;
|
||||||
;
|
;
|
||||||
|
@ -660,8 +663,8 @@ where
|
||||||
*/
|
*/
|
||||||
macro_rules! impl_constructors_from_data(
|
macro_rules! impl_constructors_from_data(
|
||||||
($data: ident; $($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
|
($data: ident; $($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
|
||||||
impl<N: Scalar, $($DimIdent: $DimBound, )*> MatrixMN<N $(, $Dims)*>
|
impl<T: Scalar, $($DimIdent: $DimBound, )*> OMatrix<T $(, $Dims)*>
|
||||||
where DefaultAllocator: Allocator<N $(, $Dims)*> {
|
where DefaultAllocator: Allocator<T $(, $Dims)*> {
|
||||||
/// Creates a matrix with its elements filled with the components provided by a slice
|
/// Creates a matrix with its elements filled with the components provided by a slice
|
||||||
/// in row-major order.
|
/// in row-major order.
|
||||||
///
|
///
|
||||||
|
@ -688,7 +691,7 @@ macro_rules! impl_constructors_from_data(
|
||||||
/// dm[(1, 0)] == 3 && dm[(1, 1)] == 4 && dm[(1, 2)] == 5);
|
/// dm[(1, 0)] == 3 && dm[(1, 1)] == 4 && dm[(1, 2)] == 5);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_row_slice($($args: usize,)* $data: &[N]) -> Self {
|
pub fn from_row_slice($($args: usize,)* $data: &[T]) -> Self {
|
||||||
Self::from_row_slice_generic($($gargs, )* $data)
|
Self::from_row_slice_generic($($gargs, )* $data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -715,7 +718,7 @@ macro_rules! impl_constructors_from_data(
|
||||||
/// dm[(1, 0)] == 1 && dm[(1, 1)] == 3 && dm[(1, 2)] == 5);
|
/// dm[(1, 0)] == 1 && dm[(1, 1)] == 3 && dm[(1, 2)] == 5);
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_column_slice($($args: usize,)* $data: &[N]) -> Self {
|
pub fn from_column_slice($($args: usize,)* $data: &[T]) -> Self {
|
||||||
Self::from_column_slice_generic($($gargs, )* $data)
|
Self::from_column_slice_generic($($gargs, )* $data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -741,7 +744,7 @@ macro_rules! impl_constructors_from_data(
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
pub fn from_vec($($args: usize,)* $data: Vec<N>) -> Self {
|
pub fn from_vec($($args: usize,)* $data: Vec<T>) -> Self {
|
||||||
Self::from_vec_generic($($gargs, )* $data)
|
Self::from_vec_generic($($gargs, )* $data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -749,8 +752,8 @@ macro_rules! impl_constructors_from_data(
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: this is not very pretty. We could find a better call syntax.
|
// TODO: this is not very pretty. We could find a better call syntax.
|
||||||
impl_constructors_from_data!(data; R, C; // Arguments for Matrix<N, ..., S>
|
impl_constructors_from_data!(data; R, C; // Arguments for Matrix<T, ..., S>
|
||||||
=> R: DimName, => C: DimName; // Type parameters for impl<N, ..., S>
|
=> R: DimName, => C: DimName; // Type parameters for impl<T, ..., S>
|
||||||
R::name(), C::name(); // Arguments for `_generic` constructors.
|
R::name(), C::name(); // Arguments for `_generic` constructors.
|
||||||
); // Arguments for non-generic constructors.
|
); // Arguments for non-generic constructors.
|
||||||
|
|
||||||
|
@ -774,14 +777,14 @@ impl_constructors_from_data!(data; Dynamic, Dynamic;
|
||||||
* Zero, One, Rand traits.
|
* Zero, One, Rand traits.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
impl<N, R: DimName, C: DimName> Zero for MatrixMN<N, R, C>
|
impl<T, R: DimName, C: DimName> Zero for OMatrix<T, R, C>
|
||||||
where
|
where
|
||||||
N: Scalar + Zero + ClosedAdd,
|
T: Scalar + Zero + ClosedAdd,
|
||||||
DefaultAllocator: Allocator<N, R, C>,
|
DefaultAllocator: Allocator<T, R, C>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn zero() -> Self {
|
fn zero() -> Self {
|
||||||
Self::from_element(N::zero())
|
Self::from_element(T::zero())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -790,10 +793,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, D: DimName> One for MatrixN<N, D>
|
impl<T, D: DimName> One for OMatrix<T, D, D>
|
||||||
where
|
where
|
||||||
N: Scalar + Zero + One + ClosedMul + ClosedAdd,
|
T: Scalar + Zero + One + ClosedMul + ClosedAdd,
|
||||||
DefaultAllocator: Allocator<N, D, D>,
|
DefaultAllocator: Allocator<T, D, D>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn one() -> Self {
|
fn one() -> Self {
|
||||||
|
@ -801,45 +804,45 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, R: DimName, C: DimName> Bounded for MatrixMN<N, R, C>
|
impl<T, R: DimName, C: DimName> Bounded for OMatrix<T, R, C>
|
||||||
where
|
where
|
||||||
N: Scalar + Bounded,
|
T: Scalar + Bounded,
|
||||||
DefaultAllocator: Allocator<N, R, C>,
|
DefaultAllocator: Allocator<T, R, C>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn max_value() -> Self {
|
fn max_value() -> Self {
|
||||||
Self::from_element(N::max_value())
|
Self::from_element(T::max_value())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn min_value() -> Self {
|
fn min_value() -> Self {
|
||||||
Self::from_element(N::min_value())
|
Self::from_element(T::min_value())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "rand-no-std")]
|
#[cfg(feature = "rand-no-std")]
|
||||||
impl<N: Scalar, R: Dim, C: Dim> Distribution<MatrixMN<N, R, C>> for Standard
|
impl<T: Scalar, R: Dim, C: Dim> Distribution<OMatrix<T, R, C>> for Standard
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, R, C>,
|
DefaultAllocator: Allocator<T, R, C>,
|
||||||
Standard: Distribution<N>,
|
Standard: Distribution<T>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> MatrixMN<N, R, C> {
|
fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> OMatrix<T, R, C> {
|
||||||
let nrows = R::try_to_usize().unwrap_or_else(|| rng.gen_range(0..10));
|
let nrows = R::try_to_usize().unwrap_or_else(|| rng.gen_range(0..10));
|
||||||
let ncols = C::try_to_usize().unwrap_or_else(|| rng.gen_range(0..10));
|
let ncols = C::try_to_usize().unwrap_or_else(|| rng.gen_range(0..10));
|
||||||
|
|
||||||
MatrixMN::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |_, _| rng.gen())
|
OMatrix::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |_, _| rng.gen())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "arbitrary")]
|
#[cfg(feature = "arbitrary")]
|
||||||
impl<N, R, C> Arbitrary for MatrixMN<N, R, C>
|
impl<T, R, C> Arbitrary for OMatrix<T, R, C>
|
||||||
where
|
where
|
||||||
R: Dim,
|
R: Dim,
|
||||||
C: Dim,
|
C: Dim,
|
||||||
N: Scalar + Arbitrary + Send,
|
T: Scalar + Arbitrary + Send,
|
||||||
DefaultAllocator: Allocator<N, R, C>,
|
DefaultAllocator: Allocator<T, R, C>,
|
||||||
Owned<N, R, C>: Clone + Send,
|
Owned<T, R, C>: Clone + Send,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn arbitrary(g: &mut Gen) -> Self {
|
fn arbitrary(g: &mut Gen) -> Self {
|
||||||
|
@ -847,23 +850,24 @@ where
|
||||||
let ncols = C::try_to_usize().unwrap_or(usize::arbitrary(g) % 10);
|
let ncols = C::try_to_usize().unwrap_or(usize::arbitrary(g) % 10);
|
||||||
|
|
||||||
Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |_, _| {
|
Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |_, _| {
|
||||||
N::arbitrary(g)
|
T::arbitrary(g)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(specialization): faster impls possible for D≤4 (see rand_distr::{UnitCircle, UnitSphere})
|
||||||
#[cfg(feature = "rand")]
|
#[cfg(feature = "rand")]
|
||||||
impl<N: crate::RealField, D: DimName> Distribution<Unit<VectorN<N, D>>> for Standard
|
impl<T: crate::RealField, D: DimName> Distribution<Unit<OVector<T, D>>> for Standard
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
DefaultAllocator: Allocator<T, D>,
|
||||||
rand_distr::StandardNormal: Distribution<N>,
|
rand_distr::StandardNormal: Distribution<T>,
|
||||||
{
|
{
|
||||||
/// Generate a uniformly distributed random unit vector.
|
/// Generate a uniformly distributed random unit vector.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Unit<VectorN<N, D>> {
|
fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Unit<OVector<T, D>> {
|
||||||
Unit::new_normalize(VectorN::from_distribution_generic(
|
Unit::new_normalize(OVector::from_distribution_generic(
|
||||||
D::name(),
|
D::name(),
|
||||||
U1,
|
Const::<1>,
|
||||||
&rand_distr::StandardNormal,
|
&rand_distr::StandardNormal,
|
||||||
rng,
|
rng,
|
||||||
))
|
))
|
||||||
|
@ -875,22 +879,44 @@ where
|
||||||
* Constructors for small matrices and vectors.
|
* Constructors for small matrices and vectors.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
macro_rules! transpose_array(
|
||||||
|
[$($a: ident),*;] => {
|
||||||
|
[$([$a]),*]
|
||||||
|
};
|
||||||
|
[$($a: ident),*; $($b: ident),*;] => {
|
||||||
|
[$([$a, $b]),*];
|
||||||
|
};
|
||||||
|
[$($a: ident),*; $($b: ident),*; $($c: ident),*;] => {
|
||||||
|
[$([$a, $b, $c]),*];
|
||||||
|
};
|
||||||
|
[$($a: ident),*; $($b: ident),*; $($c: ident),*; $($d: ident),*;] => {
|
||||||
|
[$([$a, $b, $c, $d]),*];
|
||||||
|
};
|
||||||
|
[$($a: ident),*; $($b: ident),*; $($c: ident),*; $($d: ident),*; $($e: ident),*;] => {
|
||||||
|
[$([$a, $b, $c, $d, $e]),*];
|
||||||
|
};
|
||||||
|
[$($a: ident),*; $($b: ident),*; $($c: ident),*; $($d: ident),*; $($e: ident),*; $($f: ident),*;] => {
|
||||||
|
[$([$a, $b, $c, $d, $e, $f]),*];
|
||||||
|
};
|
||||||
|
);
|
||||||
|
|
||||||
macro_rules! componentwise_constructors_impl(
|
macro_rules! componentwise_constructors_impl(
|
||||||
($($R: ty, $C: ty, $($args: ident:($irow: expr,$icol: expr)),*);* $(;)*) => {$(
|
($($R: expr, $C: expr, [$($($args: ident),*);*] $(;)*)*) => {$(
|
||||||
impl<N> MatrixMN<N, $R, $C>
|
impl<T> Matrix<T, Const<$R>, Const<$C>, ArrayStorage<T, $R, $C>> {
|
||||||
where N: Scalar,
|
|
||||||
DefaultAllocator: Allocator<N, $R, $C> {
|
|
||||||
/// Initializes this matrix from its components.
|
/// Initializes this matrix from its components.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new($($args: N),*) -> Self {
|
pub const fn new($($($args: T),*),*) -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
#[cfg(feature="no_unsound_assume_init")]
|
Self::from_data_statically_unchecked(
|
||||||
let mut res: Self = unimplemented!();
|
ArrayStorage(
|
||||||
#[cfg(not(feature="no_unsound_assume_init"))]
|
transpose_array![
|
||||||
let mut res = Self::new_uninitialized().assume_init();
|
$(
|
||||||
$( *res.get_unchecked_mut(($irow, $icol)) = $args; )*
|
$($args),*
|
||||||
|
;)*
|
||||||
res
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -901,145 +927,145 @@ componentwise_constructors_impl!(
|
||||||
/*
|
/*
|
||||||
* Square matrices 1 .. 6.
|
* Square matrices 1 .. 6.
|
||||||
*/
|
*/
|
||||||
U2, U2, m11:(0,0), m12:(0,1),
|
2, 2, [m11, m12;
|
||||||
m21:(1,0), m22:(1,1);
|
m21, m22];
|
||||||
U3, U3, m11:(0,0), m12:(0,1), m13:(0,2),
|
3, 3, [m11, m12, m13;
|
||||||
m21:(1,0), m22:(1,1), m23:(1,2),
|
m21, m22, m23;
|
||||||
m31:(2,0), m32:(2,1), m33:(2,2);
|
m31, m32, m33];
|
||||||
U4, U4, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3),
|
4, 4, [m11, m12, m13, m14;
|
||||||
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3),
|
m21, m22, m23, m24;
|
||||||
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3),
|
m31, m32, m33, m34;
|
||||||
m41:(3,0), m42:(3,1), m43:(3,2), m44:(3,3);
|
m41, m42, m43, m44];
|
||||||
U5, U5, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3), m15:(0,4),
|
5, 5, [m11, m12, m13, m14, m15;
|
||||||
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3), m25:(1,4),
|
m21, m22, m23, m24, m25;
|
||||||
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3), m35:(2,4),
|
m31, m32, m33, m34, m35;
|
||||||
m41:(3,0), m42:(3,1), m43:(3,2), m44:(3,3), m45:(3,4),
|
m41, m42, m43, m44, m45;
|
||||||
m51:(4,0), m52:(4,1), m53:(4,2), m54:(4,3), m55:(4,4);
|
m51, m52, m53, m54, m55];
|
||||||
U6, U6, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3), m15:(0,4), m16:(0,5),
|
6, 6, [m11, m12, m13, m14, m15, m16;
|
||||||
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3), m25:(1,4), m26:(1,5),
|
m21, m22, m23, m24, m25, m26;
|
||||||
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3), m35:(2,4), m36:(2,5),
|
m31, m32, m33, m34, m35, m36;
|
||||||
m41:(3,0), m42:(3,1), m43:(3,2), m44:(3,3), m45:(3,4), m46:(3,5),
|
m41, m42, m43, m44, m45, m46;
|
||||||
m51:(4,0), m52:(4,1), m53:(4,2), m54:(4,3), m55:(4,4), m56:(4,5),
|
m51, m52, m53, m54, m55, m56;
|
||||||
m61:(5,0), m62:(5,1), m63:(5,2), m64:(5,3), m65:(5,4), m66:(5,5);
|
m61, m62, m63, m64, m65, m66];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Rectangular matrices with 2 rows.
|
* Rectangular matrices with 2 rows.
|
||||||
*/
|
*/
|
||||||
U2, U3, m11:(0,0), m12:(0,1), m13:(0,2),
|
2, 3, [m11, m12, m13;
|
||||||
m21:(1,0), m22:(1,1), m23:(1,2);
|
m21, m22, m23];
|
||||||
U2, U4, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3),
|
2, 4, [m11, m12, m13, m14;
|
||||||
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3);
|
m21, m22, m23, m24];
|
||||||
U2, U5, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3), m15:(0,4),
|
2, 5, [m11, m12, m13, m14, m15;
|
||||||
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3), m25:(1,4);
|
m21, m22, m23, m24, m25];
|
||||||
U2, U6, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3), m15:(0,4), m16:(0,5),
|
2, 6, [m11, m12, m13, m14, m15, m16;
|
||||||
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3), m25:(1,4), m26:(1,5);
|
m21, m22, m23, m24, m25, m26];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Rectangular matrices with 3 rows.
|
* Rectangular matrices with 3 rows.
|
||||||
*/
|
*/
|
||||||
U3, U2, m11:(0,0), m12:(0,1),
|
3, 2, [m11, m12;
|
||||||
m21:(1,0), m22:(1,1),
|
m21, m22;
|
||||||
m31:(2,0), m32:(2,1);
|
m31, m32];
|
||||||
U3, U4, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3),
|
3, 4, [m11, m12, m13, m14;
|
||||||
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3),
|
m21, m22, m23, m24;
|
||||||
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3);
|
m31, m32, m33, m34];
|
||||||
U3, U5, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3), m15:(0,4),
|
3, 5, [m11, m12, m13, m14, m15;
|
||||||
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3), m25:(1,4),
|
m21, m22, m23, m24, m25;
|
||||||
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3), m35:(2,4);
|
m31, m32, m33, m34, m35];
|
||||||
U3, U6, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3), m15:(0,4), m16:(0,5),
|
3, 6, [m11, m12, m13, m14, m15, m16;
|
||||||
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3), m25:(1,4), m26:(1,5),
|
m21, m22, m23, m24, m25, m26;
|
||||||
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3), m35:(2,4), m36:(2,5);
|
m31, m32, m33, m34, m35, m36];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Rectangular matrices with 4 rows.
|
* Rectangular matrices with 4 rows.
|
||||||
*/
|
*/
|
||||||
U4, U2, m11:(0,0), m12:(0,1),
|
4, 2, [m11, m12;
|
||||||
m21:(1,0), m22:(1,1),
|
m21, m22;
|
||||||
m31:(2,0), m32:(2,1),
|
m31, m32;
|
||||||
m41:(3,0), m42:(3,1);
|
m41, m42];
|
||||||
U4, U3, m11:(0,0), m12:(0,1), m13:(0,2),
|
4, 3, [m11, m12, m13;
|
||||||
m21:(1,0), m22:(1,1), m23:(1,2),
|
m21, m22, m23;
|
||||||
m31:(2,0), m32:(2,1), m33:(2,2),
|
m31, m32, m33;
|
||||||
m41:(3,0), m42:(3,1), m43:(3,2);
|
m41, m42, m43];
|
||||||
U4, U5, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3), m15:(0,4),
|
4, 5, [m11, m12, m13, m14, m15;
|
||||||
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3), m25:(1,4),
|
m21, m22, m23, m24, m25;
|
||||||
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3), m35:(2,4),
|
m31, m32, m33, m34, m35;
|
||||||
m41:(3,0), m42:(3,1), m43:(3,2), m44:(3,3), m45:(3,4);
|
m41, m42, m43, m44, m45];
|
||||||
U4, U6, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3), m15:(0,4), m16:(0,5),
|
4, 6, [m11, m12, m13, m14, m15, m16;
|
||||||
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3), m25:(1,4), m26:(1,5),
|
m21, m22, m23, m24, m25, m26;
|
||||||
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3), m35:(2,4), m36:(2,5),
|
m31, m32, m33, m34, m35, m36;
|
||||||
m41:(3,0), m42:(3,1), m43:(3,2), m44:(3,3), m45:(3,4), m46:(3,5);
|
m41, m42, m43, m44, m45, m46];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Rectangular matrices with 5 rows.
|
* Rectangular matrices with 5 rows.
|
||||||
*/
|
*/
|
||||||
U5, U2, m11:(0,0), m12:(0,1),
|
5, 2, [m11, m12;
|
||||||
m21:(1,0), m22:(1,1),
|
m21, m22;
|
||||||
m31:(2,0), m32:(2,1),
|
m31, m32;
|
||||||
m41:(3,0), m42:(3,1),
|
m41, m42;
|
||||||
m51:(4,0), m52:(4,1);
|
m51, m52];
|
||||||
U5, U3, m11:(0,0), m12:(0,1), m13:(0,2),
|
5, 3, [m11, m12, m13;
|
||||||
m21:(1,0), m22:(1,1), m23:(1,2),
|
m21, m22, m23;
|
||||||
m31:(2,0), m32:(2,1), m33:(2,2),
|
m31, m32, m33;
|
||||||
m41:(3,0), m42:(3,1), m43:(3,2),
|
m41, m42, m43;
|
||||||
m51:(4,0), m52:(4,1), m53:(4,2);
|
m51, m52, m53];
|
||||||
U5, U4, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3),
|
5, 4, [m11, m12, m13, m14;
|
||||||
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3),
|
m21, m22, m23, m24;
|
||||||
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3),
|
m31, m32, m33, m34;
|
||||||
m41:(3,0), m42:(3,1), m43:(3,2), m44:(3,3),
|
m41, m42, m43, m44;
|
||||||
m51:(4,0), m52:(4,1), m53:(4,2), m54:(4,3);
|
m51, m52, m53, m54];
|
||||||
U5, U6, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3), m15:(0,4), m16:(0,5),
|
5, 6, [m11, m12, m13, m14, m15, m16;
|
||||||
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3), m25:(1,4), m26:(1,5),
|
m21, m22, m23, m24, m25, m26;
|
||||||
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3), m35:(2,4), m36:(2,5),
|
m31, m32, m33, m34, m35, m36;
|
||||||
m41:(3,0), m42:(3,1), m43:(3,2), m44:(3,3), m45:(3,4), m46:(3,5),
|
m41, m42, m43, m44, m45, m46;
|
||||||
m51:(4,0), m52:(4,1), m53:(4,2), m54:(4,3), m55:(4,4), m56:(4,5);
|
m51, m52, m53, m54, m55, m56];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Rectangular matrices with 6 rows.
|
* Rectangular matrices with 6 rows.
|
||||||
*/
|
*/
|
||||||
U6, U2, m11:(0,0), m12:(0,1),
|
6, 2, [m11, m12;
|
||||||
m21:(1,0), m22:(1,1),
|
m21, m22;
|
||||||
m31:(2,0), m32:(2,1),
|
m31, m32;
|
||||||
m41:(3,0), m42:(3,1),
|
m41, m42;
|
||||||
m51:(4,0), m52:(4,1),
|
m51, m52;
|
||||||
m61:(5,0), m62:(5,1);
|
m61, m62];
|
||||||
U6, U3, m11:(0,0), m12:(0,1), m13:(0,2),
|
6, 3, [m11, m12, m13;
|
||||||
m21:(1,0), m22:(1,1), m23:(1,2),
|
m21, m22, m23;
|
||||||
m31:(2,0), m32:(2,1), m33:(2,2),
|
m31, m32, m33;
|
||||||
m41:(3,0), m42:(3,1), m43:(3,2),
|
m41, m42, m43;
|
||||||
m51:(4,0), m52:(4,1), m53:(4,2),
|
m51, m52, m53;
|
||||||
m61:(5,0), m62:(5,1), m63:(5,2);
|
m61, m62, m63];
|
||||||
U6, U4, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3),
|
6, 4, [m11, m12, m13, m14;
|
||||||
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3),
|
m21, m22, m23, m24;
|
||||||
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3),
|
m31, m32, m33, m34;
|
||||||
m41:(3,0), m42:(3,1), m43:(3,2), m44:(3,3),
|
m41, m42, m43, m44;
|
||||||
m51:(4,0), m52:(4,1), m53:(4,2), m54:(4,3),
|
m51, m52, m53, m54;
|
||||||
m61:(5,0), m62:(5,1), m63:(5,2), m64:(5,3);
|
m61, m62, m63, m64];
|
||||||
U6, U5, m11:(0,0), m12:(0,1), m13:(0,2), m14:(0,3), m15:(0,4),
|
6, 5, [m11, m12, m13, m14, m15;
|
||||||
m21:(1,0), m22:(1,1), m23:(1,2), m24:(1,3), m25:(1,4),
|
m21, m22, m23, m24, m25;
|
||||||
m31:(2,0), m32:(2,1), m33:(2,2), m34:(2,3), m35:(2,4),
|
m31, m32, m33, m34, m35;
|
||||||
m41:(3,0), m42:(3,1), m43:(3,2), m44:(3,3), m45:(3,4),
|
m41, m42, m43, m44, m45;
|
||||||
m51:(4,0), m52:(4,1), m53:(4,2), m54:(4,3), m55:(4,4),
|
m51, m52, m53, m54, m55;
|
||||||
m61:(5,0), m62:(5,1), m63:(5,2), m64:(5,3), m65:(5,4);
|
m61, m62, m63, m64, m65];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Row vectors 1 .. 6.
|
* Row vectors 1 .. 6.
|
||||||
*/
|
*/
|
||||||
U1, U1, x:(0,0);
|
1, 1, [x];
|
||||||
U1, U2, x:(0,0), y:(0,1);
|
1, 2, [x, y];
|
||||||
U1, U3, x:(0,0), y:(0,1), z:(0,2);
|
1, 3, [x, y, z];
|
||||||
U1, U4, x:(0,0), y:(0,1), z:(0,2), w:(0,3);
|
1, 4, [x, y, z, w];
|
||||||
U1, U5, x:(0,0), y:(0,1), z:(0,2), w:(0,3), a:(0,4);
|
1, 5, [x, y, z, w, a];
|
||||||
U1, U6, x:(0,0), y:(0,1), z:(0,2), w:(0,3), a:(0,4), b:(0,5);
|
1, 6, [x, y, z, w, a, b];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Column vectors 1 .. 6.
|
* Column vectors 1 .. 6.
|
||||||
*/
|
*/
|
||||||
U2, U1, x:(0,0), y:(1,0);
|
2, 1, [x; y];
|
||||||
U3, U1, x:(0,0), y:(1,0), z:(2,0);
|
3, 1, [x; y; z];
|
||||||
U4, U1, x:(0,0), y:(1,0), z:(2,0), w:(3,0);
|
4, 1, [x; y; z; w];
|
||||||
U5, U1, x:(0,0), y:(1,0), z:(2,0), w:(3,0), a:(4,0);
|
5, 1, [x; y; z; w; a];
|
||||||
U6, U1, x:(0,0), y:(1,0), z:(2,0), w:(3,0), a:(4,0), b:(5,0);
|
6, 1, [x; y; z; w; a; b];
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1047,34 +1073,35 @@ componentwise_constructors_impl!(
|
||||||
* Axis constructors.
|
* Axis constructors.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
impl<N, R: DimName> VectorN<N, R>
|
impl<T, R: DimName> OVector<T, R>
|
||||||
where
|
where
|
||||||
N: Scalar + Zero + One,
|
R: ToTypenum,
|
||||||
DefaultAllocator: Allocator<N, R>,
|
T: Scalar + Zero + One,
|
||||||
|
DefaultAllocator: Allocator<T, R>,
|
||||||
{
|
{
|
||||||
/// The column vector with `val` as its i-th component.
|
/// The column vector with `val` as its i-th component.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn ith(i: usize, val: N) -> Self {
|
pub fn ith(i: usize, val: T) -> Self {
|
||||||
let mut res = Self::zeros();
|
let mut res = Self::zeros();
|
||||||
res[i] = val;
|
res[i] = val;
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The column unit vector with `N::one()` as its i-th component.
|
/// The column unit vector with `T::one()` as its i-th component.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn ith_axis(i: usize) -> Unit<Self> {
|
pub fn ith_axis(i: usize) -> Unit<Self> {
|
||||||
Unit::new_unchecked(Self::ith(i, N::one()))
|
Unit::new_unchecked(Self::ith(i, T::one()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The column vector with a 1 as its first component, and zero elsewhere.
|
/// The column vector with a 1 as its first component, and zero elsewhere.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn x() -> Self
|
pub fn x() -> Self
|
||||||
where
|
where
|
||||||
R::Value: Cmp<typenum::U0, Output = Greater>,
|
R::Typenum: Cmp<typenum::U0, Output = Greater>,
|
||||||
{
|
{
|
||||||
let mut res = Self::zeros();
|
let mut res = Self::zeros();
|
||||||
unsafe {
|
unsafe {
|
||||||
*res.vget_unchecked_mut(0) = N::one();
|
*res.vget_unchecked_mut(0) = T::one();
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -1084,11 +1111,11 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn y() -> Self
|
pub fn y() -> Self
|
||||||
where
|
where
|
||||||
R::Value: Cmp<typenum::U1, Output = Greater>,
|
R::Typenum: Cmp<typenum::U1, Output = Greater>,
|
||||||
{
|
{
|
||||||
let mut res = Self::zeros();
|
let mut res = Self::zeros();
|
||||||
unsafe {
|
unsafe {
|
||||||
*res.vget_unchecked_mut(1) = N::one();
|
*res.vget_unchecked_mut(1) = T::one();
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -1098,11 +1125,11 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn z() -> Self
|
pub fn z() -> Self
|
||||||
where
|
where
|
||||||
R::Value: Cmp<typenum::U2, Output = Greater>,
|
R::Typenum: Cmp<typenum::U2, Output = Greater>,
|
||||||
{
|
{
|
||||||
let mut res = Self::zeros();
|
let mut res = Self::zeros();
|
||||||
unsafe {
|
unsafe {
|
||||||
*res.vget_unchecked_mut(2) = N::one();
|
*res.vget_unchecked_mut(2) = T::one();
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -1112,11 +1139,11 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn w() -> Self
|
pub fn w() -> Self
|
||||||
where
|
where
|
||||||
R::Value: Cmp<typenum::U3, Output = Greater>,
|
R::Typenum: Cmp<typenum::U3, Output = Greater>,
|
||||||
{
|
{
|
||||||
let mut res = Self::zeros();
|
let mut res = Self::zeros();
|
||||||
unsafe {
|
unsafe {
|
||||||
*res.vget_unchecked_mut(3) = N::one();
|
*res.vget_unchecked_mut(3) = T::one();
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -1126,11 +1153,11 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn a() -> Self
|
pub fn a() -> Self
|
||||||
where
|
where
|
||||||
R::Value: Cmp<typenum::U4, Output = Greater>,
|
R::Typenum: Cmp<typenum::U4, Output = Greater>,
|
||||||
{
|
{
|
||||||
let mut res = Self::zeros();
|
let mut res = Self::zeros();
|
||||||
unsafe {
|
unsafe {
|
||||||
*res.vget_unchecked_mut(4) = N::one();
|
*res.vget_unchecked_mut(4) = T::one();
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -1140,11 +1167,11 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn b() -> Self
|
pub fn b() -> Self
|
||||||
where
|
where
|
||||||
R::Value: Cmp<typenum::U5, Output = Greater>,
|
R::Typenum: Cmp<typenum::U5, Output = Greater>,
|
||||||
{
|
{
|
||||||
let mut res = Self::zeros();
|
let mut res = Self::zeros();
|
||||||
unsafe {
|
unsafe {
|
||||||
*res.vget_unchecked_mut(5) = N::one();
|
*res.vget_unchecked_mut(5) = T::one();
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
|
@ -1154,7 +1181,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn x_axis() -> Unit<Self>
|
pub fn x_axis() -> Unit<Self>
|
||||||
where
|
where
|
||||||
R::Value: Cmp<typenum::U0, Output = Greater>,
|
R::Typenum: Cmp<typenum::U0, Output = Greater>,
|
||||||
{
|
{
|
||||||
Unit::new_unchecked(Self::x())
|
Unit::new_unchecked(Self::x())
|
||||||
}
|
}
|
||||||
|
@ -1163,7 +1190,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn y_axis() -> Unit<Self>
|
pub fn y_axis() -> Unit<Self>
|
||||||
where
|
where
|
||||||
R::Value: Cmp<typenum::U1, Output = Greater>,
|
R::Typenum: Cmp<typenum::U1, Output = Greater>,
|
||||||
{
|
{
|
||||||
Unit::new_unchecked(Self::y())
|
Unit::new_unchecked(Self::y())
|
||||||
}
|
}
|
||||||
|
@ -1172,7 +1199,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn z_axis() -> Unit<Self>
|
pub fn z_axis() -> Unit<Self>
|
||||||
where
|
where
|
||||||
R::Value: Cmp<typenum::U2, Output = Greater>,
|
R::Typenum: Cmp<typenum::U2, Output = Greater>,
|
||||||
{
|
{
|
||||||
Unit::new_unchecked(Self::z())
|
Unit::new_unchecked(Self::z())
|
||||||
}
|
}
|
||||||
|
@ -1181,7 +1208,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn w_axis() -> Unit<Self>
|
pub fn w_axis() -> Unit<Self>
|
||||||
where
|
where
|
||||||
R::Value: Cmp<typenum::U3, Output = Greater>,
|
R::Typenum: Cmp<typenum::U3, Output = Greater>,
|
||||||
{
|
{
|
||||||
Unit::new_unchecked(Self::w())
|
Unit::new_unchecked(Self::w())
|
||||||
}
|
}
|
||||||
|
@ -1190,7 +1217,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn a_axis() -> Unit<Self>
|
pub fn a_axis() -> Unit<Self>
|
||||||
where
|
where
|
||||||
R::Value: Cmp<typenum::U4, Output = Greater>,
|
R::Typenum: Cmp<typenum::U4, Output = Greater>,
|
||||||
{
|
{
|
||||||
Unit::new_unchecked(Self::a())
|
Unit::new_unchecked(Self::a())
|
||||||
}
|
}
|
||||||
|
@ -1199,7 +1226,7 @@ where
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn b_axis() -> Unit<Self>
|
pub fn b_axis() -> Unit<Self>
|
||||||
where
|
where
|
||||||
R::Value: Cmp<typenum::U5, Output = Greater>,
|
R::Typenum: Cmp<typenum::U5, Output = Greater>,
|
||||||
{
|
{
|
||||||
Unit::new_unchecked(Self::b())
|
Unit::new_unchecked(Self::b())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
use crate::base::dimension::{Dim, DimName, Dynamic, U1};
|
use crate::base::dimension::{Const, Dim, DimName, Dynamic};
|
||||||
use crate::base::matrix_slice::{SliceStorage, SliceStorageMut};
|
use crate::base::matrix_slice::{SliceStorage, SliceStorageMut};
|
||||||
use crate::base::{MatrixSliceMN, MatrixSliceMutMN, Scalar};
|
use crate::base::{MatrixSlice, MatrixSliceMutMN, Scalar};
|
||||||
|
|
||||||
use num_rational::Ratio;
|
use num_rational::Ratio;
|
||||||
|
|
||||||
/// # Creating matrix slices from `&[T]`
|
/// # Creating matrix slices from `&[T]`
|
||||||
impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
||||||
MatrixSliceMN<'a, N, R, C, RStride, CStride>
|
MatrixSlice<'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 bound-checking, a matrix slice from an array and with dimensions and strides specified by generic types instances.
|
||||||
///
|
///
|
||||||
|
@ -14,7 +14,7 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
||||||
/// 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 `Dynamic::new()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_slice_with_strides_generic_unchecked(
|
pub unsafe fn from_slice_with_strides_generic_unchecked(
|
||||||
data: &'a [N],
|
data: &'a [T],
|
||||||
start: usize,
|
start: usize,
|
||||||
nrows: R,
|
nrows: R,
|
||||||
ncols: C,
|
ncols: C,
|
||||||
|
@ -35,7 +35,7 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
||||||
/// 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 `Dynamic::new()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice_with_strides_generic(
|
pub fn from_slice_with_strides_generic(
|
||||||
data: &'a [N],
|
data: &'a [T],
|
||||||
nrows: R,
|
nrows: R,
|
||||||
ncols: C,
|
ncols: C,
|
||||||
rstride: RStride,
|
rstride: RStride,
|
||||||
|
@ -56,19 +56,21 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, N: Scalar, R: Dim, C: Dim> MatrixSliceMN<'a, N, R, C> {
|
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.
|
/// Creates, without bound-checking, a matrix slice from an array and with dimensions specified by generic types instances.
|
||||||
///
|
///
|
||||||
/// This method is unsafe because the input data array is not checked to contain enough elements.
|
/// This method is unsafe because the input data array is not checked to contain enough elements.
|
||||||
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_slice_generic_unchecked(
|
pub unsafe fn from_slice_generic_unchecked(
|
||||||
data: &'a [N],
|
data: &'a [T],
|
||||||
start: usize,
|
start: usize,
|
||||||
nrows: R,
|
nrows: R,
|
||||||
ncols: C,
|
ncols: C,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::from_slice_with_strides_generic_unchecked(data, start, nrows, ncols, U1, nrows)
|
Self::from_slice_with_strides_generic_unchecked(
|
||||||
|
data, start, nrows, ncols, Const::<1>, nrows,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a matrix slice from an array and with dimensions and strides specified by generic types instances.
|
/// Creates a matrix slice from an array and with dimensions and strides specified by generic types instances.
|
||||||
|
@ -76,41 +78,41 @@ impl<'a, N: Scalar, R: Dim, C: Dim> MatrixSliceMN<'a, N, R, C> {
|
||||||
/// Panics if the input data array dose not contain enough elements.
|
/// Panics if the input data array dose not contain enough elements.
|
||||||
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice_generic(data: &'a [N], nrows: R, ncols: C) -> Self {
|
pub fn from_slice_generic(data: &'a [T], nrows: R, ncols: C) -> Self {
|
||||||
Self::from_slice_with_strides_generic(data, nrows, ncols, U1, nrows)
|
Self::from_slice_with_strides_generic(data, nrows, ncols, Const::<1>, nrows)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_constructors(
|
macro_rules! impl_constructors(
|
||||||
($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
|
($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
|
||||||
impl<'a, N: Scalar, $($DimIdent: $DimBound),*> MatrixSliceMN<'a, N, $($Dims),*> {
|
impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixSlice<'a, T, $($Dims),*> {
|
||||||
/// Creates a new matrix slice from the given data array.
|
/// Creates a new matrix slice from the given data array.
|
||||||
///
|
///
|
||||||
/// Panics if `data` does not contain enough elements.
|
/// Panics if `data` does not contain enough elements.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice(data: &'a [N], $($args: usize),*) -> Self {
|
pub fn from_slice(data: &'a [T], $($args: usize),*) -> Self {
|
||||||
Self::from_slice_generic(data, $($gargs),*)
|
Self::from_slice_generic(data, $($gargs),*)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates, without bound checking, a new matrix slice from the given data array.
|
/// Creates, without bound checking, a new matrix slice from the given data array.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_slice_unchecked(data: &'a [N], start: usize, $($args: usize),*) -> Self {
|
pub unsafe fn from_slice_unchecked(data: &'a [T], start: usize, $($args: usize),*) -> Self {
|
||||||
Self::from_slice_generic_unchecked(data, start, $($gargs),*)
|
Self::from_slice_generic_unchecked(data, start, $($gargs),*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, N: Scalar, $($DimIdent: $DimBound, )*> MatrixSliceMN<'a, N, $($Dims,)* Dynamic, Dynamic> {
|
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.
|
/// Creates a new matrix slice with the specified strides from the given data array.
|
||||||
///
|
///
|
||||||
/// Panics if `data` does not contain enough elements.
|
/// Panics if `data` does not contain enough elements.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice_with_strides(data: &'a [N], $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
pub fn from_slice_with_strides(data: &'a [T], $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
||||||
Self::from_slice_with_strides_generic(data, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
|
Self::from_slice_with_strides_generic(data, $($gargs,)* Dynamic::new(rstride), Dynamic::new(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 slice with the specified strides from the given data array.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_slice_with_strides_unchecked(data: &'a [N], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
pub unsafe fn from_slice_with_strides_unchecked(data: &'a [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
||||||
Self::from_slice_with_strides_generic_unchecked(data, start, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
|
Self::from_slice_with_strides_generic_unchecked(data, start, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,8 +120,8 @@ macro_rules! impl_constructors(
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: this is not very pretty. We could find a better call syntax.
|
// TODO: this is not very pretty. We could find a better call syntax.
|
||||||
impl_constructors!(R, C; // Arguments for Matrix<N, ..., S>
|
impl_constructors!(R, C; // Arguments for Matrix<T, ..., S>
|
||||||
=> R: DimName, => C: DimName; // Type parameters for impl<N, ..., S>
|
=> R: DimName, => C: DimName; // Type parameters for impl<T, ..., S>
|
||||||
R::name(), C::name(); // Arguments for `_generic` constructors.
|
R::name(), C::name(); // Arguments for `_generic` constructors.
|
||||||
); // Arguments for non-generic constructors.
|
); // Arguments for non-generic constructors.
|
||||||
|
|
||||||
|
@ -139,8 +141,8 @@ impl_constructors!(Dynamic, Dynamic;
|
||||||
nrows, ncols);
|
nrows, ncols);
|
||||||
|
|
||||||
/// # Creating mutable matrix slices from `&mut [T]`
|
/// # Creating mutable matrix slices from `&mut [T]`
|
||||||
impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
||||||
MatrixSliceMutMN<'a, N, R, C, RStride, CStride>
|
MatrixSliceMutMN<'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 slice from an array and with dimensions and strides specified by generic types instances.
|
||||||
///
|
///
|
||||||
|
@ -148,7 +150,7 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
||||||
/// 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 `Dynamic::new()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_slice_with_strides_generic_unchecked(
|
pub unsafe fn from_slice_with_strides_generic_unchecked(
|
||||||
data: &'a mut [N],
|
data: &'a mut [T],
|
||||||
start: usize,
|
start: usize,
|
||||||
nrows: R,
|
nrows: R,
|
||||||
ncols: C,
|
ncols: C,
|
||||||
|
@ -169,7 +171,7 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
||||||
/// 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 `Dynamic::new()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice_with_strides_generic(
|
pub fn from_slice_with_strides_generic(
|
||||||
data: &'a mut [N],
|
data: &'a mut [T],
|
||||||
nrows: R,
|
nrows: R,
|
||||||
ncols: C,
|
ncols: C,
|
||||||
rstride: RStride,
|
rstride: RStride,
|
||||||
|
@ -212,19 +214,21 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, N: Scalar, R: Dim, C: Dim> MatrixSliceMutMN<'a, N, R, C> {
|
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.
|
/// Creates, without bound-checking, a mutable matrix slice from an array and with dimensions specified by generic types instances.
|
||||||
///
|
///
|
||||||
/// This method is unsafe because the input data array is not checked to contain enough elements.
|
/// This method is unsafe because the input data array is not checked to contain enough elements.
|
||||||
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_slice_generic_unchecked(
|
pub unsafe fn from_slice_generic_unchecked(
|
||||||
data: &'a mut [N],
|
data: &'a mut [T],
|
||||||
start: usize,
|
start: usize,
|
||||||
nrows: R,
|
nrows: R,
|
||||||
ncols: C,
|
ncols: C,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::from_slice_with_strides_generic_unchecked(data, start, nrows, ncols, U1, nrows)
|
Self::from_slice_with_strides_generic_unchecked(
|
||||||
|
data, start, nrows, ncols, Const::<1>, nrows,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a mutable matrix slice from an array and with dimensions and strides specified by generic types instances.
|
/// Creates a mutable matrix slice from an array and with dimensions and strides specified by generic types instances.
|
||||||
|
@ -232,42 +236,42 @@ impl<'a, N: Scalar, R: Dim, C: Dim> MatrixSliceMutMN<'a, N, R, C> {
|
||||||
/// Panics if the input data array dose not contain enough elements.
|
/// Panics if the input data array dose not contain enough elements.
|
||||||
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice_generic(data: &'a mut [N], nrows: R, ncols: C) -> Self {
|
pub fn from_slice_generic(data: &'a mut [T], nrows: R, ncols: C) -> Self {
|
||||||
Self::from_slice_with_strides_generic(data, nrows, ncols, U1, nrows)
|
Self::from_slice_with_strides_generic(data, nrows, ncols, Const::<1>, nrows)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_constructors_mut(
|
macro_rules! impl_constructors_mut(
|
||||||
($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
|
($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
|
||||||
impl<'a, N: Scalar, $($DimIdent: $DimBound),*> MatrixSliceMutMN<'a, N, $($Dims),*> {
|
impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixSliceMutMN<'a, T, $($Dims),*> {
|
||||||
/// Creates a new mutable matrix slice from the given data array.
|
/// Creates a new mutable matrix slice from the given data array.
|
||||||
///
|
///
|
||||||
/// Panics if `data` does not contain enough elements.
|
/// Panics if `data` does not contain enough elements.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice(data: &'a mut [N], $($args: usize),*) -> Self {
|
pub fn from_slice(data: &'a mut [T], $($args: usize),*) -> Self {
|
||||||
Self::from_slice_generic(data, $($gargs),*)
|
Self::from_slice_generic(data, $($gargs),*)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates, without bound checking, a new mutable matrix slice from the given data array.
|
/// Creates, without bound checking, a new mutable matrix slice from the given data array.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_slice_unchecked(data: &'a mut [N], start: usize, $($args: usize),*) -> Self {
|
pub unsafe fn from_slice_unchecked(data: &'a mut [T], start: usize, $($args: usize),*) -> Self {
|
||||||
Self::from_slice_generic_unchecked(data, start, $($gargs),*)
|
Self::from_slice_generic_unchecked(data, start, $($gargs),*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, N: Scalar, $($DimIdent: $DimBound, )*> MatrixSliceMutMN<'a, N, $($Dims,)* Dynamic, Dynamic> {
|
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.
|
/// Creates a new mutable matrix slice with the specified strides from the given data array.
|
||||||
///
|
///
|
||||||
/// Panics if `data` does not contain enough elements.
|
/// Panics if `data` does not contain enough elements.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_slice_with_strides_mut(data: &'a mut [N], $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
pub fn from_slice_with_strides_mut(data: &'a mut [T], $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
||||||
Self::from_slice_with_strides_generic(
|
Self::from_slice_with_strides_generic(
|
||||||
data, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
|
data, $($gargs,)* Dynamic::new(rstride), Dynamic::new(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 slice with the specified strides from the given data array.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_slice_with_strides_unchecked(data: &'a mut [N], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
pub unsafe fn from_slice_with_strides_unchecked(data: &'a mut [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
|
||||||
Self::from_slice_with_strides_generic_unchecked(
|
Self::from_slice_with_strides_generic_unchecked(
|
||||||
data, start, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
|
data, start, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
|
||||||
}
|
}
|
||||||
|
@ -276,8 +280,8 @@ macro_rules! impl_constructors_mut(
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: this is not very pretty. We could find a better call syntax.
|
// TODO: this is not very pretty. We could find a better call syntax.
|
||||||
impl_constructors_mut!(R, C; // Arguments for Matrix<N, ..., S>
|
impl_constructors_mut!(R, C; // Arguments for Matrix<T, ..., S>
|
||||||
=> R: DimName, => C: DimName; // Type parameters for impl<N, ..., S>
|
=> R: DimName, => C: DimName; // Type parameters for impl<T, ..., S>
|
||||||
R::name(), C::name(); // Arguments for `_generic` constructors.
|
R::name(), C::name(); // Arguments for `_generic` constructors.
|
||||||
); // Arguments for non-generic constructors.
|
); // Arguments for non-generic constructors.
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,6 @@ use std::convert::{AsMut, AsRef, From, Into};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
use generic_array::ArrayLength;
|
|
||||||
use std::ops::Mul;
|
|
||||||
use typenum::Prod;
|
|
||||||
|
|
||||||
use simba::simd::{PrimitiveSimdValue, SimdValue};
|
use simba::simd::{PrimitiveSimdValue, SimdValue};
|
||||||
|
|
||||||
use crate::base::allocator::{Allocator, SameShapeAllocator};
|
use crate::base::allocator::{Allocator, SameShapeAllocator};
|
||||||
|
@ -16,13 +12,13 @@ use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstr
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
use crate::base::dimension::Dynamic;
|
use crate::base::dimension::Dynamic;
|
||||||
use crate::base::dimension::{
|
use crate::base::dimension::{
|
||||||
Dim, DimName, U1, U10, U11, U12, U13, U14, U15, U16, U2, U3, U4, U5, U6, U7, U8, U9,
|
Const, Dim, DimName, U1, U10, U11, U12, U13, U14, U15, U16, U2, U3, U4, U5, U6, U7, U8, U9,
|
||||||
};
|
};
|
||||||
use crate::base::iter::{MatrixIter, MatrixIterMut};
|
use crate::base::iter::{MatrixIter, MatrixIterMut};
|
||||||
use crate::base::storage::{ContiguousStorage, ContiguousStorageMut, Storage, StorageMut};
|
use crate::base::storage::{ContiguousStorage, ContiguousStorageMut, Storage, StorageMut};
|
||||||
use crate::base::{
|
use crate::base::{
|
||||||
ArrayStorage, DVectorSlice, DVectorSliceMut, DefaultAllocator, Matrix, MatrixMN, MatrixSlice,
|
ArrayStorage, DVectorSlice, DVectorSliceMut, DefaultAllocator, Matrix, MatrixSlice,
|
||||||
MatrixSliceMut, Scalar,
|
MatrixSliceMut, OMatrix, Scalar,
|
||||||
};
|
};
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
use crate::base::{DVector, VecStorage};
|
use crate::base::{DVector, VecStorage};
|
||||||
|
@ -30,30 +26,30 @@ use crate::base::{SliceStorage, SliceStorageMut};
|
||||||
use crate::constraint::DimEq;
|
use crate::constraint::DimEq;
|
||||||
|
|
||||||
// TODO: too bad this won't work allo slice conversions.
|
// TODO: too bad this won't work allo slice conversions.
|
||||||
impl<N1, N2, R1, C1, R2, C2> SubsetOf<MatrixMN<N2, R2, C2>> for MatrixMN<N1, R1, C1>
|
impl<T1, T2, R1, C1, R2, C2> SubsetOf<OMatrix<T2, R2, C2>> for OMatrix<T1, R1, C1>
|
||||||
where
|
where
|
||||||
R1: Dim,
|
R1: Dim,
|
||||||
C1: Dim,
|
C1: Dim,
|
||||||
R2: Dim,
|
R2: Dim,
|
||||||
C2: Dim,
|
C2: Dim,
|
||||||
N1: Scalar,
|
T1: Scalar,
|
||||||
N2: Scalar + SupersetOf<N1>,
|
T2: Scalar + SupersetOf<T1>,
|
||||||
DefaultAllocator:
|
DefaultAllocator:
|
||||||
Allocator<N2, R2, C2> + Allocator<N1, R1, C1> + SameShapeAllocator<N1, R1, C1, R2, C2>,
|
Allocator<T2, R2, C2> + Allocator<T1, R1, C1> + SameShapeAllocator<T1, R1, C1, R2, C2>,
|
||||||
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>,
|
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_superset(&self) -> MatrixMN<N2, R2, C2> {
|
fn to_superset(&self) -> OMatrix<T2, R2, C2> {
|
||||||
let (nrows, ncols) = self.shape();
|
let (nrows, ncols) = self.shape();
|
||||||
let nrows2 = R2::from_usize(nrows);
|
let nrows2 = R2::from_usize(nrows);
|
||||||
let ncols2 = C2::from_usize(ncols);
|
let ncols2 = C2::from_usize(ncols);
|
||||||
|
|
||||||
let mut res: MatrixMN<N2, R2, C2> =
|
let mut res: OMatrix<T2, R2, C2> =
|
||||||
unsafe { crate::unimplemented_or_uninitialized_generic!(nrows2, ncols2) };
|
unsafe { crate::unimplemented_or_uninitialized_generic!(nrows2, ncols2) };
|
||||||
for i in 0..nrows {
|
for i in 0..nrows {
|
||||||
for j in 0..ncols {
|
for j in 0..ncols {
|
||||||
unsafe {
|
unsafe {
|
||||||
*res.get_unchecked_mut((i, j)) = N2::from_subset(self.get_unchecked((i, j)))
|
*res.get_unchecked_mut((i, j)) = T2::from_subset(self.get_unchecked((i, j)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,12 +58,12 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_in_subset(m: &MatrixMN<N2, R2, C2>) -> bool {
|
fn is_in_subset(m: &OMatrix<T2, R2, C2>) -> bool {
|
||||||
m.iter().all(|e| e.is_in_subset())
|
m.iter().all(|e| e.is_in_subset())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_superset_unchecked(m: &MatrixMN<N2, R2, C2>) -> Self {
|
fn from_superset_unchecked(m: &OMatrix<T2, R2, C2>) -> Self {
|
||||||
let (nrows2, ncols2) = m.shape();
|
let (nrows2, ncols2) = m.shape();
|
||||||
let nrows = R1::from_usize(nrows2);
|
let nrows = R1::from_usize(nrows2);
|
||||||
let ncols = C1::from_usize(ncols2);
|
let ncols = C1::from_usize(ncols2);
|
||||||
|
@ -85,9 +81,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> IntoIterator for &'a Matrix<N, R, C, S> {
|
impl<'a, T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> IntoIterator for &'a Matrix<T, R, C, S> {
|
||||||
type Item = &'a N;
|
type Item = &'a T;
|
||||||
type IntoIter = MatrixIter<'a, N, R, C, S>;
|
type IntoIter = MatrixIter<'a, T, R, C, S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
@ -95,11 +91,11 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> IntoIterator for &'a Ma
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> IntoIterator
|
impl<'a, T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> IntoIterator
|
||||||
for &'a mut Matrix<N, R, C, S>
|
for &'a mut Matrix<T, R, C, S>
|
||||||
{
|
{
|
||||||
type Item = &'a mut N;
|
type Item = &'a mut T;
|
||||||
type IntoIter = MatrixIterMut<'a, N, R, C, S>;
|
type IntoIter = MatrixIterMut<'a, T, R, C, S>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
@ -109,11 +105,11 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> IntoIterator
|
||||||
|
|
||||||
macro_rules! impl_from_into_asref_1D(
|
macro_rules! impl_from_into_asref_1D(
|
||||||
($(($NRows: ident, $NCols: ident) => $SZ: expr);* $(;)*) => {$(
|
($(($NRows: ident, $NCols: ident) => $SZ: expr);* $(;)*) => {$(
|
||||||
impl<N> From<[N; $SZ]> for MatrixMN<N, $NRows, $NCols>
|
impl<T> From<[T; $SZ]> for OMatrix<T, $NRows, $NCols>
|
||||||
where N: Scalar,
|
where T: Scalar,
|
||||||
DefaultAllocator: Allocator<N, $NRows, $NCols> {
|
DefaultAllocator: Allocator<T, $NRows, $NCols> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [N; $SZ]) -> Self {
|
fn from(arr: [T; $SZ]) -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut res = Self::new_uninitialized();
|
let mut res = Self::new_uninitialized();
|
||||||
ptr::copy_nonoverlapping(&arr[0], (*res.as_mut_ptr()).data.ptr_mut(), $SZ);
|
ptr::copy_nonoverlapping(&arr[0], (*res.as_mut_ptr()).data.ptr_mut(), $SZ);
|
||||||
|
@ -123,35 +119,35 @@ macro_rules! impl_from_into_asref_1D(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, S> Into<[N; $SZ]> for Matrix<N, $NRows, $NCols, S>
|
impl<T, S> Into<[T; $SZ]> for Matrix<T, $NRows, $NCols, S>
|
||||||
where N: Scalar,
|
where T: Scalar,
|
||||||
S: ContiguousStorage<N, $NRows, $NCols> {
|
S: ContiguousStorage<T, $NRows, $NCols> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into(self) -> [N; $SZ] {
|
fn into(self) -> [T; $SZ] {
|
||||||
let mut res = mem::MaybeUninit::<[N; $SZ]>::uninit();
|
let mut res = mem::MaybeUninit::<[T; $SZ]>::uninit();
|
||||||
|
|
||||||
unsafe { ptr::copy_nonoverlapping(self.data.ptr(), res.as_mut_ptr() as *mut N, $SZ) };
|
unsafe { ptr::copy_nonoverlapping(self.data.ptr(), res.as_mut_ptr() as *mut T, $SZ) };
|
||||||
|
|
||||||
unsafe { res.assume_init() }
|
unsafe { res.assume_init() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, S> AsRef<[N; $SZ]> for Matrix<N, $NRows, $NCols, S>
|
impl<T, S> AsRef<[T; $SZ]> for Matrix<T, $NRows, $NCols, S>
|
||||||
where N: Scalar,
|
where T: Scalar,
|
||||||
S: ContiguousStorage<N, $NRows, $NCols> {
|
S: ContiguousStorage<T, $NRows, $NCols> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_ref(&self) -> &[N; $SZ] {
|
fn as_ref(&self) -> &[T; $SZ] {
|
||||||
unsafe {
|
unsafe {
|
||||||
mem::transmute(self.data.ptr())
|
mem::transmute(self.data.ptr())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, S> AsMut<[N; $SZ]> for Matrix<N, $NRows, $NCols, S>
|
impl<T, S> AsMut<[T; $SZ]> for Matrix<T, $NRows, $NCols, S>
|
||||||
where N: Scalar,
|
where T: Scalar,
|
||||||
S: ContiguousStorageMut<N, $NRows, $NCols> {
|
S: ContiguousStorageMut<T, $NRows, $NCols> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_mut(&mut self) -> &mut [N; $SZ] {
|
fn as_mut(&mut self) -> &mut [T; $SZ] {
|
||||||
unsafe {
|
unsafe {
|
||||||
mem::transmute(self.data.ptr_mut())
|
mem::transmute(self.data.ptr_mut())
|
||||||
}
|
}
|
||||||
|
@ -177,10 +173,10 @@ impl_from_into_asref_1D!(
|
||||||
|
|
||||||
macro_rules! impl_from_into_asref_2D(
|
macro_rules! impl_from_into_asref_2D(
|
||||||
($(($NRows: ty, $NCols: ty) => ($SZRows: expr, $SZCols: expr));* $(;)*) => {$(
|
($(($NRows: ty, $NCols: ty) => ($SZRows: expr, $SZCols: expr));* $(;)*) => {$(
|
||||||
impl<N: Scalar> From<[[N; $SZRows]; $SZCols]> for MatrixMN<N, $NRows, $NCols>
|
impl<T: Scalar> From<[[T; $SZRows]; $SZCols]> for OMatrix<T, $NRows, $NCols>
|
||||||
where DefaultAllocator: Allocator<N, $NRows, $NCols> {
|
where DefaultAllocator: Allocator<T, $NRows, $NCols> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [[N; $SZRows]; $SZCols]) -> Self {
|
fn from(arr: [[T; $SZRows]; $SZCols]) -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut res = Self::new_uninitialized();
|
let mut res = Self::new_uninitialized();
|
||||||
ptr::copy_nonoverlapping(&arr[0][0], (*res.as_mut_ptr()).data.ptr_mut(), $SZRows * $SZCols);
|
ptr::copy_nonoverlapping(&arr[0][0], (*res.as_mut_ptr()).data.ptr_mut(), $SZRows * $SZCols);
|
||||||
|
@ -190,32 +186,32 @@ macro_rules! impl_from_into_asref_2D(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar, S> Into<[[N; $SZRows]; $SZCols]> for Matrix<N, $NRows, $NCols, S>
|
impl<T: Scalar, S> Into<[[T; $SZRows]; $SZCols]> for Matrix<T, $NRows, $NCols, S>
|
||||||
where S: ContiguousStorage<N, $NRows, $NCols> {
|
where S: ContiguousStorage<T, $NRows, $NCols> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into(self) -> [[N; $SZRows]; $SZCols] {
|
fn into(self) -> [[T; $SZRows]; $SZCols] {
|
||||||
let mut res = mem::MaybeUninit::<[[N; $SZRows]; $SZCols]>::uninit();
|
let mut res = mem::MaybeUninit::<[[T; $SZRows]; $SZCols]>::uninit();
|
||||||
|
|
||||||
unsafe { ptr::copy_nonoverlapping(self.data.ptr(), res.as_mut_ptr() as *mut N, $SZRows * $SZCols) };
|
unsafe { ptr::copy_nonoverlapping(self.data.ptr(), res.as_mut_ptr() as *mut T, $SZRows * $SZCols) };
|
||||||
|
|
||||||
unsafe { res.assume_init() }
|
unsafe { res.assume_init() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar, S> AsRef<[[N; $SZRows]; $SZCols]> for Matrix<N, $NRows, $NCols, S>
|
impl<T: Scalar, S> AsRef<[[T; $SZRows]; $SZCols]> for Matrix<T, $NRows, $NCols, S>
|
||||||
where S: ContiguousStorage<N, $NRows, $NCols> {
|
where S: ContiguousStorage<T, $NRows, $NCols> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_ref(&self) -> &[[N; $SZRows]; $SZCols] {
|
fn as_ref(&self) -> &[[T; $SZRows]; $SZCols] {
|
||||||
unsafe {
|
unsafe {
|
||||||
mem::transmute(self.data.ptr())
|
mem::transmute(self.data.ptr())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar, S> AsMut<[[N; $SZRows]; $SZCols]> for Matrix<N, $NRows, $NCols, S>
|
impl<T: Scalar, S> AsMut<[[T; $SZRows]; $SZCols]> for Matrix<T, $NRows, $NCols, S>
|
||||||
where S: ContiguousStorageMut<N, $NRows, $NCols> {
|
where S: ContiguousStorageMut<T, $NRows, $NCols> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_mut(&mut self) -> &mut [[N; $SZRows]; $SZCols] {
|
fn as_mut(&mut self) -> &mut [[T; $SZRows]; $SZCols] {
|
||||||
unsafe {
|
unsafe {
|
||||||
mem::transmute(self.data.ptr_mut())
|
mem::transmute(self.data.ptr_mut())
|
||||||
}
|
}
|
||||||
|
@ -233,111 +229,105 @@ impl_from_into_asref_2D!(
|
||||||
(U6, U2) => (6, 2); (U6, U3) => (6, 3); (U6, U4) => (6, 4); (U6, U5) => (6, 5); (U6, U6) => (6, 6);
|
(U6, U2) => (6, 2); (U6, U3) => (6, 3); (U6, U4) => (6, 4); (U6, U5) => (6, 5); (U6, U6) => (6, 6);
|
||||||
);
|
);
|
||||||
|
|
||||||
impl<'a, N, R, C, RStride, CStride> From<MatrixSlice<'a, N, R, C, RStride, CStride>>
|
impl<'a, T, RStride, CStride, const R: usize, const C: usize>
|
||||||
for Matrix<N, R, C, ArrayStorage<N, R, C>>
|
From<MatrixSlice<'a, T, Const<R>, Const<C>, RStride, CStride>>
|
||||||
|
for Matrix<T, Const<R>, Const<C>, ArrayStorage<T, R, C>>
|
||||||
where
|
where
|
||||||
N: Scalar,
|
T: Scalar,
|
||||||
R: DimName,
|
|
||||||
C: DimName,
|
|
||||||
RStride: Dim,
|
RStride: Dim,
|
||||||
CStride: Dim,
|
CStride: Dim,
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
{
|
{
|
||||||
fn from(matrix_slice: MatrixSlice<'a, N, R, C, RStride, CStride>) -> Self {
|
fn from(matrix_slice: MatrixSlice<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
|
||||||
matrix_slice.into_owned()
|
matrix_slice.into_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<'a, N, C, RStride, CStride> From<MatrixSlice<'a, N, Dynamic, C, RStride, CStride>>
|
impl<'a, T, C, RStride, CStride> From<MatrixSlice<'a, T, Dynamic, C, RStride, CStride>>
|
||||||
for Matrix<N, Dynamic, C, VecStorage<N, Dynamic, C>>
|
for Matrix<T, Dynamic, C, VecStorage<T, Dynamic, C>>
|
||||||
where
|
where
|
||||||
N: Scalar,
|
T: Scalar,
|
||||||
C: Dim,
|
C: Dim,
|
||||||
RStride: Dim,
|
RStride: Dim,
|
||||||
CStride: Dim,
|
CStride: Dim,
|
||||||
{
|
{
|
||||||
fn from(matrix_slice: MatrixSlice<'a, N, Dynamic, C, RStride, CStride>) -> Self {
|
fn from(matrix_slice: MatrixSlice<'a, T, Dynamic, C, RStride, CStride>) -> Self {
|
||||||
matrix_slice.into_owned()
|
matrix_slice.into_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<'a, N, R, RStride, CStride> From<MatrixSlice<'a, N, R, Dynamic, RStride, CStride>>
|
impl<'a, T, R, RStride, CStride> From<MatrixSlice<'a, T, R, Dynamic, RStride, CStride>>
|
||||||
for Matrix<N, R, Dynamic, VecStorage<N, R, Dynamic>>
|
for Matrix<T, R, Dynamic, VecStorage<T, R, Dynamic>>
|
||||||
where
|
where
|
||||||
N: Scalar,
|
T: Scalar,
|
||||||
R: DimName,
|
R: DimName,
|
||||||
RStride: Dim,
|
RStride: Dim,
|
||||||
CStride: Dim,
|
CStride: Dim,
|
||||||
{
|
{
|
||||||
fn from(matrix_slice: MatrixSlice<'a, N, R, Dynamic, RStride, CStride>) -> Self {
|
fn from(matrix_slice: MatrixSlice<'a, T, R, Dynamic, RStride, CStride>) -> Self {
|
||||||
matrix_slice.into_owned()
|
matrix_slice.into_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, N, R, C, RStride, CStride> From<MatrixSliceMut<'a, N, R, C, RStride, CStride>>
|
impl<'a, T, RStride, CStride, const R: usize, const C: usize>
|
||||||
for Matrix<N, R, C, ArrayStorage<N, R, C>>
|
From<MatrixSliceMut<'a, T, Const<R>, Const<C>, RStride, CStride>>
|
||||||
|
for Matrix<T, Const<R>, Const<C>, ArrayStorage<T, R, C>>
|
||||||
where
|
where
|
||||||
N: Scalar,
|
T: Scalar,
|
||||||
R: DimName,
|
|
||||||
C: DimName,
|
|
||||||
RStride: Dim,
|
RStride: Dim,
|
||||||
CStride: Dim,
|
CStride: Dim,
|
||||||
R::Value: Mul<C::Value>,
|
|
||||||
Prod<R::Value, C::Value>: ArrayLength<N>,
|
|
||||||
{
|
{
|
||||||
fn from(matrix_slice: MatrixSliceMut<'a, N, R, C, RStride, CStride>) -> Self {
|
fn from(matrix_slice: MatrixSliceMut<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
|
||||||
matrix_slice.into_owned()
|
matrix_slice.into_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<'a, N, C, RStride, CStride> From<MatrixSliceMut<'a, N, Dynamic, C, RStride, CStride>>
|
impl<'a, T, C, RStride, CStride> From<MatrixSliceMut<'a, T, Dynamic, C, RStride, CStride>>
|
||||||
for Matrix<N, Dynamic, C, VecStorage<N, Dynamic, C>>
|
for Matrix<T, Dynamic, C, VecStorage<T, Dynamic, C>>
|
||||||
where
|
where
|
||||||
N: Scalar,
|
T: Scalar,
|
||||||
C: Dim,
|
C: Dim,
|
||||||
RStride: Dim,
|
RStride: Dim,
|
||||||
CStride: Dim,
|
CStride: Dim,
|
||||||
{
|
{
|
||||||
fn from(matrix_slice: MatrixSliceMut<'a, N, Dynamic, C, RStride, CStride>) -> Self {
|
fn from(matrix_slice: MatrixSliceMut<'a, T, Dynamic, C, RStride, CStride>) -> Self {
|
||||||
matrix_slice.into_owned()
|
matrix_slice.into_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<'a, N, R, RStride, CStride> From<MatrixSliceMut<'a, N, R, Dynamic, RStride, CStride>>
|
impl<'a, T, R, RStride, CStride> From<MatrixSliceMut<'a, T, R, Dynamic, RStride, CStride>>
|
||||||
for Matrix<N, R, Dynamic, VecStorage<N, R, Dynamic>>
|
for Matrix<T, R, Dynamic, VecStorage<T, R, Dynamic>>
|
||||||
where
|
where
|
||||||
N: Scalar,
|
T: Scalar,
|
||||||
R: DimName,
|
R: DimName,
|
||||||
RStride: Dim,
|
RStride: Dim,
|
||||||
CStride: Dim,
|
CStride: Dim,
|
||||||
{
|
{
|
||||||
fn from(matrix_slice: MatrixSliceMut<'a, N, R, Dynamic, RStride, CStride>) -> Self {
|
fn from(matrix_slice: MatrixSliceMut<'a, T, R, Dynamic, RStride, CStride>) -> Self {
|
||||||
matrix_slice.into_owned()
|
matrix_slice.into_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, N, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a Matrix<N, R, C, S>>
|
impl<'a, T, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a Matrix<T, R, C, S>>
|
||||||
for MatrixSlice<'a, N, RSlice, CSlice, RStride, CStride>
|
for MatrixSlice<'a, T, RSlice, CSlice, RStride, CStride>
|
||||||
where
|
where
|
||||||
N: Scalar,
|
T: Scalar,
|
||||||
R: Dim,
|
R: Dim,
|
||||||
C: Dim,
|
C: Dim,
|
||||||
RSlice: Dim,
|
RSlice: Dim,
|
||||||
CSlice: Dim,
|
CSlice: Dim,
|
||||||
RStride: Dim,
|
RStride: Dim,
|
||||||
CStride: Dim,
|
CStride: Dim,
|
||||||
S: Storage<N, R, C>,
|
S: Storage<T, R, C>,
|
||||||
ShapeConstraint: DimEq<R, RSlice>
|
ShapeConstraint: DimEq<R, RSlice>
|
||||||
+ DimEq<C, CSlice>
|
+ DimEq<C, CSlice>
|
||||||
+ DimEq<RStride, S::RStride>
|
+ DimEq<RStride, S::RStride>
|
||||||
+ DimEq<CStride, S::CStride>,
|
+ DimEq<CStride, S::CStride>,
|
||||||
{
|
{
|
||||||
fn from(m: &'a Matrix<N, R, C, S>) -> Self {
|
fn from(m: &'a Matrix<T, R, C, S>) -> Self {
|
||||||
let (row, col) = m.data.shape();
|
let (row, col) = m.data.shape();
|
||||||
let row_slice = RSlice::from_usize(row.value());
|
let row_slice = RSlice::from_usize(row.value());
|
||||||
let col_slice = CSlice::from_usize(col.value());
|
let col_slice = CSlice::from_usize(col.value());
|
||||||
|
@ -358,23 +348,23 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, N, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix<N, R, C, S>>
|
impl<'a, T, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix<T, R, C, S>>
|
||||||
for MatrixSlice<'a, N, RSlice, CSlice, RStride, CStride>
|
for MatrixSlice<'a, T, RSlice, CSlice, RStride, CStride>
|
||||||
where
|
where
|
||||||
N: Scalar,
|
T: Scalar,
|
||||||
R: Dim,
|
R: Dim,
|
||||||
C: Dim,
|
C: Dim,
|
||||||
RSlice: Dim,
|
RSlice: Dim,
|
||||||
CSlice: Dim,
|
CSlice: Dim,
|
||||||
RStride: Dim,
|
RStride: Dim,
|
||||||
CStride: Dim,
|
CStride: Dim,
|
||||||
S: Storage<N, R, C>,
|
S: Storage<T, R, C>,
|
||||||
ShapeConstraint: DimEq<R, RSlice>
|
ShapeConstraint: DimEq<R, RSlice>
|
||||||
+ DimEq<C, CSlice>
|
+ DimEq<C, CSlice>
|
||||||
+ DimEq<RStride, S::RStride>
|
+ DimEq<RStride, S::RStride>
|
||||||
+ DimEq<CStride, S::CStride>,
|
+ DimEq<CStride, S::CStride>,
|
||||||
{
|
{
|
||||||
fn from(m: &'a mut Matrix<N, R, C, S>) -> Self {
|
fn from(m: &'a mut Matrix<T, R, C, S>) -> Self {
|
||||||
let (row, col) = m.data.shape();
|
let (row, col) = m.data.shape();
|
||||||
let row_slice = RSlice::from_usize(row.value());
|
let row_slice = RSlice::from_usize(row.value());
|
||||||
let col_slice = CSlice::from_usize(col.value());
|
let col_slice = CSlice::from_usize(col.value());
|
||||||
|
@ -395,23 +385,23 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, N, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix<N, R, C, S>>
|
impl<'a, T, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix<T, R, C, S>>
|
||||||
for MatrixSliceMut<'a, N, RSlice, CSlice, RStride, CStride>
|
for MatrixSliceMut<'a, T, RSlice, CSlice, RStride, CStride>
|
||||||
where
|
where
|
||||||
N: Scalar,
|
T: Scalar,
|
||||||
R: Dim,
|
R: Dim,
|
||||||
C: Dim,
|
C: Dim,
|
||||||
RSlice: Dim,
|
RSlice: Dim,
|
||||||
CSlice: Dim,
|
CSlice: Dim,
|
||||||
RStride: Dim,
|
RStride: Dim,
|
||||||
CStride: Dim,
|
CStride: Dim,
|
||||||
S: StorageMut<N, R, C>,
|
S: StorageMut<T, R, C>,
|
||||||
ShapeConstraint: DimEq<R, RSlice>
|
ShapeConstraint: DimEq<R, RSlice>
|
||||||
+ DimEq<C, CSlice>
|
+ DimEq<C, CSlice>
|
||||||
+ DimEq<RStride, S::RStride>
|
+ DimEq<RStride, S::RStride>
|
||||||
+ DimEq<CStride, S::CStride>,
|
+ DimEq<CStride, S::CStride>,
|
||||||
{
|
{
|
||||||
fn from(m: &'a mut Matrix<N, R, C, S>) -> Self {
|
fn from(m: &'a mut Matrix<T, R, C, S>) -> Self {
|
||||||
let (row, col) = m.data.shape();
|
let (row, col) = m.data.shape();
|
||||||
let row_slice = RSlice::from_usize(row.value());
|
let row_slice = RSlice::from_usize(row.value());
|
||||||
let col_slice = CSlice::from_usize(col.value());
|
let col_slice = CSlice::from_usize(col.value());
|
||||||
|
@ -433,54 +423,54 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
impl<'a, N: Scalar> From<Vec<N>> for DVector<N> {
|
impl<'a, T: Scalar> From<Vec<T>> for DVector<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(vec: Vec<N>) -> Self {
|
fn from(vec: Vec<T>) -> Self {
|
||||||
Self::from_vec(vec)
|
Self::from_vec(vec)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, N: Scalar + Copy, R: Dim, C: Dim, S: ContiguousStorage<N, R, C>> Into<&'a [N]>
|
impl<'a, T: Scalar + Copy, R: Dim, C: Dim, S: ContiguousStorage<T, R, C>> Into<&'a [T]>
|
||||||
for &'a Matrix<N, R, C, S>
|
for &'a Matrix<T, R, C, S>
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into(self) -> &'a [N] {
|
fn into(self) -> &'a [T] {
|
||||||
self.as_slice()
|
self.as_slice()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, N: Scalar + Copy, R: Dim, C: Dim, S: ContiguousStorageMut<N, R, C>> Into<&'a mut [N]>
|
impl<'a, T: Scalar + Copy, R: Dim, C: Dim, S: ContiguousStorageMut<T, R, C>> Into<&'a mut [T]>
|
||||||
for &'a mut Matrix<N, R, C, S>
|
for &'a mut Matrix<T, R, C, S>
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into(self) -> &'a mut [N] {
|
fn into(self) -> &'a mut [T] {
|
||||||
self.as_mut_slice()
|
self.as_mut_slice()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, N: Scalar + Copy> From<&'a [N]> for DVectorSlice<'a, N> {
|
impl<'a, T: Scalar + Copy> From<&'a [T]> for DVectorSlice<'a, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(slice: &'a [N]) -> Self {
|
fn from(slice: &'a [T]) -> Self {
|
||||||
Self::from_slice(slice, slice.len())
|
Self::from_slice(slice, slice.len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, N: Scalar + Copy> From<&'a mut [N]> for DVectorSliceMut<'a, N> {
|
impl<'a, T: Scalar + Copy> From<&'a mut [T]> for DVectorSliceMut<'a, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(slice: &'a mut [N]) -> Self {
|
fn from(slice: &'a mut [T]) -> Self {
|
||||||
Self::from_slice(slice, slice.len())
|
Self::from_slice(slice, slice.len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[MatrixMN<N::Element, R, C>; 2]>
|
impl<T: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[OMatrix<T::Element, R, C>; 2]>
|
||||||
for MatrixMN<N, R, C>
|
for OMatrix<T, R, C>
|
||||||
where
|
where
|
||||||
N: From<[<N as SimdValue>::Element; 2]>,
|
T: From<[<T as SimdValue>::Element; 2]>,
|
||||||
N::Element: Scalar + SimdValue,
|
T::Element: Scalar + SimdValue,
|
||||||
DefaultAllocator: Allocator<N, R, C> + Allocator<N::Element, R, C>,
|
DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [MatrixMN<N::Element, R, C>; 2]) -> Self {
|
fn from(arr: [OMatrix<T::Element, R, C>; 2]) -> Self {
|
||||||
let (nrows, ncols) = arr[0].data.shape();
|
let (nrows, ncols) = arr[0].data.shape();
|
||||||
|
|
||||||
Self::from_fn_generic(nrows, ncols, |i, j| {
|
Self::from_fn_generic(nrows, ncols, |i, j| {
|
||||||
|
@ -493,15 +483,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[MatrixMN<N::Element, R, C>; 4]>
|
impl<T: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[OMatrix<T::Element, R, C>; 4]>
|
||||||
for MatrixMN<N, R, C>
|
for OMatrix<T, R, C>
|
||||||
where
|
where
|
||||||
N: From<[<N as SimdValue>::Element; 4]>,
|
T: From<[<T as SimdValue>::Element; 4]>,
|
||||||
N::Element: Scalar + SimdValue,
|
T::Element: Scalar + SimdValue,
|
||||||
DefaultAllocator: Allocator<N, R, C> + Allocator<N::Element, R, C>,
|
DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [MatrixMN<N::Element, R, C>; 4]) -> Self {
|
fn from(arr: [OMatrix<T::Element, R, C>; 4]) -> Self {
|
||||||
let (nrows, ncols) = arr[0].data.shape();
|
let (nrows, ncols) = arr[0].data.shape();
|
||||||
|
|
||||||
Self::from_fn_generic(nrows, ncols, |i, j| {
|
Self::from_fn_generic(nrows, ncols, |i, j| {
|
||||||
|
@ -516,15 +506,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[MatrixMN<N::Element, R, C>; 8]>
|
impl<T: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[OMatrix<T::Element, R, C>; 8]>
|
||||||
for MatrixMN<N, R, C>
|
for OMatrix<T, R, C>
|
||||||
where
|
where
|
||||||
N: From<[<N as SimdValue>::Element; 8]>,
|
T: From<[<T as SimdValue>::Element; 8]>,
|
||||||
N::Element: Scalar + SimdValue,
|
T::Element: Scalar + SimdValue,
|
||||||
DefaultAllocator: Allocator<N, R, C> + Allocator<N::Element, R, C>,
|
DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(arr: [MatrixMN<N::Element, R, C>; 8]) -> Self {
|
fn from(arr: [OMatrix<T::Element, R, C>; 8]) -> Self {
|
||||||
let (nrows, ncols) = arr[0].data.shape();
|
let (nrows, ncols) = arr[0].data.shape();
|
||||||
|
|
||||||
Self::from_fn_generic(nrows, ncols, |i, j| {
|
Self::from_fn_generic(nrows, ncols, |i, j| {
|
||||||
|
@ -543,14 +533,14 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[MatrixMN<N::Element, R, C>; 16]>
|
impl<T: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[OMatrix<T::Element, R, C>; 16]>
|
||||||
for MatrixMN<N, R, C>
|
for OMatrix<T, R, C>
|
||||||
where
|
where
|
||||||
N: From<[<N as SimdValue>::Element; 16]>,
|
T: From<[<T as SimdValue>::Element; 16]>,
|
||||||
N::Element: Scalar + SimdValue,
|
T::Element: Scalar + SimdValue,
|
||||||
DefaultAllocator: Allocator<N, R, C> + Allocator<N::Element, R, C>,
|
DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
|
||||||
{
|
{
|
||||||
fn from(arr: [MatrixMN<N::Element, R, C>; 16]) -> Self {
|
fn from(arr: [OMatrix<T::Element, R, C>; 16]) -> Self {
|
||||||
let (nrows, ncols) = arr[0].data.shape();
|
let (nrows, ncols) = arr[0].data.shape();
|
||||||
|
|
||||||
Self::from_fn_generic(nrows, ncols, |i, j| {
|
Self::from_fn_generic(nrows, ncols, |i, j| {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue