Release v0.18.0
This commit is contained in:
commit
b5f452087e
37
CHANGELOG.md
37
CHANGELOG.md
|
@ -4,14 +4,47 @@ documented here.
|
||||||
|
|
||||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
## [0.18.0] - WIP
|
## [0.18.0]
|
||||||
|
This release adds full complex number support to nalgebra. This includes all common vector/matrix operations as well
|
||||||
|
as matrix decomposition. This excludes geometric type (like `Isometry`, `Rotation`, `Translation`, etc.) from the
|
||||||
|
`geometry` module.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
#### Quaternion and geometric operations
|
||||||
|
* Add trigonometric functions for quaternions: `.cos, .sin, .tan, .acos, .asin, .atan, .cosh, .sinh, .tanh, .acosh, .asinh, .atanh`.
|
||||||
|
* Add geometric algebra operations for quaternions: `.inner, .outer, .project, .rejection`
|
||||||
* Add `.renormalize` to `Unit<...>` and `Rotation3` to correct potential drift due to repeated operations.
|
* Add `.renormalize` to `Unit<...>` and `Rotation3` to correct potential drift due to repeated operations.
|
||||||
Those drifts can cause them not to be pure rotations anymore.
|
Those drifts could cause them not to be pure rotations anymore.
|
||||||
|
|
||||||
|
#### Convolution
|
||||||
|
* `.convolve_full(kernel)` returns the convolution of `self` by `kernel`.
|
||||||
|
* `.convolve_valid(kernel)` returns the convolution of `self` by `kernel` after removal of all the elements relying on zero-padding.
|
||||||
|
* `.convolve_same(kernel)` returns the convolution of `self` by `kernel` with a result of the same size as `self`.
|
||||||
|
|
||||||
|
#### Complex number support
|
||||||
* Add the `::from_matrix` constructor too all rotation types to extract a rotation from a raw matrix.
|
* Add the `::from_matrix` constructor too all rotation types to extract a rotation from a raw matrix.
|
||||||
* Add the `::from_matrix_eps` constructor too all rotation types to extract a rotation from a raw matrix. This takes
|
* Add the `::from_matrix_eps` constructor too all rotation types to extract a rotation from a raw matrix. This takes
|
||||||
more argument than `::from_matrix` to control the convergence of the underlying optimization algorithm.
|
more argument than `::from_matrix` to control the convergence of the underlying optimization algorithm.
|
||||||
|
* Add `.camax()` which returns the matrix component with the greatest L1-norm.
|
||||||
|
* Add `.camin()` which returns the matrix component with the smallest L1-norm.
|
||||||
|
* Add `.ad_mul(b)` for matrix-multiplication of `self.adjoint() * b`.
|
||||||
|
* Add `.ad_mul_to(b)` which is the same as `.ad_mul` but with a provided matrix to be filled with the result of the multiplication.
|
||||||
|
* Add BLAS operations involving complex conjugation (following similar names as the original BLAS spec):
|
||||||
|
* `.dotc(rhs)` equal to `self.adjoint() * rhs`.
|
||||||
|
* `.gerc(alpha, x, y, beta)` equivalent to `self = alpha * x * y.adjoint() + beta * self`
|
||||||
|
* `.hegerc` which is like `gerc` but for Hermitian matrices.
|
||||||
|
* `.syger` which is the new name of `.ger_symm` which is equivalent to `self = alpha * x * y.transpose() + beta * self`.
|
||||||
|
* `.sygemv` which is the new name of `.gemv_symm` which is equivalent to `self = alpha * a * x + beta * self` with `a` symmetric.
|
||||||
|
* `.hegemv(alpha, a, x, beta)` which is like `.sygemv` but with `a` Hermitian.
|
||||||
|
* `.gemv_ad(alpha, a, x, beta)` which is equivalent to `self = alpha * a.adjoint() * x + beta * self`.
|
||||||
|
* `.gemm_ad(alpha, a, b, beta)` which is equivalent to `self = alpha * a.adjoint() * b + beta * self`.
|
||||||
|
* `.icamax()` which returns the index of the complex vector component with the greatest L1-norm.
|
||||||
|
|
||||||
|
Note that all the other BLAS operation will continue to work for all fields, including floats and complex numbers.
|
||||||
|
|
||||||
|
### Renamed
|
||||||
|
* `RealSchur` has been renamed `Schur` because it can now work with complex matrices.
|
||||||
|
|
||||||
|
|
||||||
## [0.17.0]
|
## [0.17.0]
|
||||||
|
|
||||||
|
|
23
Cargo.toml
23
Cargo.toml
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "nalgebra"
|
name = "nalgebra"
|
||||||
version = "0.17.3"
|
version = "0.18.0"
|
||||||
authors = [ "Sébastien Crozet <developer@crozet.re>" ]
|
authors = [ "Sébastien Crozet <developer@crozet.re>" ]
|
||||||
|
|
||||||
description = "Linear algebra library with transformations and statically-sized or dynamically-sized matrices."
|
description = "Linear algebra library with transformations and statically-sized or dynamically-sized matrices."
|
||||||
|
@ -11,6 +11,7 @@ readme = "README.md"
|
||||||
categories = [ "science" ]
|
categories = [ "science" ]
|
||||||
keywords = [ "linear", "algebra", "matrix", "vector", "math" ]
|
keywords = [ "linear", "algebra", "matrix", "vector", "math" ]
|
||||||
license = "BSD-3-Clause"
|
license = "BSD-3-Clause"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
exclude = ["/ci/*", "/.travis.yml", "/Makefile"]
|
exclude = ["/ci/*", "/.travis.yml", "/Makefile"]
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ arbitrary = [ "quickcheck" ]
|
||||||
serde-serialize = [ "serde", "serde_derive", "num-complex/serde" ]
|
serde-serialize = [ "serde", "serde_derive", "num-complex/serde" ]
|
||||||
abomonation-serialize = [ "abomonation" ]
|
abomonation-serialize = [ "abomonation" ]
|
||||||
sparse = [ ]
|
sparse = [ ]
|
||||||
debug = [ ]
|
debug = [ "approx/num-complex", "rand/std" ]
|
||||||
alloc = [ ]
|
alloc = [ ]
|
||||||
io = [ "pest", "pest_derive" ]
|
io = [ "pest", "pest_derive" ]
|
||||||
|
|
||||||
|
@ -37,7 +38,7 @@ rand = { version = "0.6", default-features = false }
|
||||||
num-traits = { version = "0.2", default-features = false }
|
num-traits = { version = "0.2", default-features = false }
|
||||||
num-complex = { version = "0.2", default-features = false }
|
num-complex = { version = "0.2", default-features = false }
|
||||||
approx = { version = "0.3", default-features = false }
|
approx = { version = "0.3", default-features = false }
|
||||||
alga = { version = "0.8", default-features = false }
|
alga = { version = "0.9", default-features = false }
|
||||||
matrixmultiply = { version = "0.2", optional = true }
|
matrixmultiply = { version = "0.2", optional = true }
|
||||||
serde = { version = "1.0", optional = true }
|
serde = { version = "1.0", optional = true }
|
||||||
serde_derive = { version = "1.0", optional = true }
|
serde_derive = { version = "1.0", optional = true }
|
||||||
|
@ -47,9 +48,25 @@ quickcheck = { version = "0.8", optional = true }
|
||||||
pest = { version = "2.0", optional = true }
|
pest = { version = "2.0", optional = true }
|
||||||
pest_derive = { version = "2.0", optional = true }
|
pest_derive = { version = "2.0", optional = true }
|
||||||
|
|
||||||
|
#[patch.crates-io]
|
||||||
|
#alga = { git = "https://github.com/rustsim/alga", branch = "dev" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
rand_xorshift = "0.1"
|
rand_xorshift = "0.1"
|
||||||
|
### Uncomment this line before running benchmarks.
|
||||||
|
### We can't just let this uncommented because that would breack
|
||||||
|
### compilation for #[no-std] because of the terrible Cargo bug
|
||||||
|
### https://github.com/rust-lang/cargo/issues/4866
|
||||||
|
#criterion = "0.2.10"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [ "nalgebra-lapack", "nalgebra-glm" ]
|
members = [ "nalgebra-lapack", "nalgebra-glm" ]
|
||||||
|
|
||||||
|
[[bench]]
|
||||||
|
name = "nalgebra_bench"
|
||||||
|
harness = false
|
||||||
|
path = "benches/lib.rs"
|
||||||
|
|
||||||
|
[profile.bench]
|
||||||
|
lto = true
|
||||||
|
|
|
@ -2,56 +2,52 @@
|
||||||
|
|
||||||
macro_rules! bench_binop(
|
macro_rules! bench_binop(
|
||||||
($name: ident, $t1: ty, $t2: ty, $binop: ident) => {
|
($name: ident, $t1: ty, $t2: ty, $binop: ident) => {
|
||||||
#[bench]
|
fn $name(bh: &mut criterion::Criterion) {
|
||||||
fn $name(bh: &mut Bencher) {
|
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
let mut rng = IsaacRng::seed_from_u64(0);
|
let mut rng = IsaacRng::seed_from_u64(0);
|
||||||
let a = rng.gen::<$t1>();
|
let a = rng.gen::<$t1>();
|
||||||
let b = rng.gen::<$t2>();
|
let b = rng.gen::<$t2>();
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function(stringify!($name), move |bh| bh.iter(|| {
|
||||||
a.$binop(b)
|
a.$binop(b)
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
macro_rules! bench_binop_ref(
|
macro_rules! bench_binop_ref(
|
||||||
($name: ident, $t1: ty, $t2: ty, $binop: ident) => {
|
($name: ident, $t1: ty, $t2: ty, $binop: ident) => {
|
||||||
#[bench]
|
fn $name(bh: &mut criterion::Criterion) {
|
||||||
fn $name(bh: &mut Bencher) {
|
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
let mut rng = IsaacRng::seed_from_u64(0);
|
let mut rng = IsaacRng::seed_from_u64(0);
|
||||||
let a = rng.gen::<$t1>();
|
let a = rng.gen::<$t1>();
|
||||||
let b = rng.gen::<$t2>();
|
let b = rng.gen::<$t2>();
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function(stringify!($name), move |bh| bh.iter(|| {
|
||||||
a.$binop(&b)
|
a.$binop(&b)
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
macro_rules! bench_binop_fn(
|
macro_rules! bench_binop_fn(
|
||||||
($name: ident, $t1: ty, $t2: ty, $binop: path) => {
|
($name: ident, $t1: ty, $t2: ty, $binop: path) => {
|
||||||
#[bench]
|
fn $name(bh: &mut criterion::Criterion) {
|
||||||
fn $name(bh: &mut Bencher) {
|
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
let mut rng = IsaacRng::seed_from_u64(0);
|
let mut rng = IsaacRng::seed_from_u64(0);
|
||||||
let a = rng.gen::<$t1>();
|
let a = rng.gen::<$t1>();
|
||||||
let b = rng.gen::<$t2>();
|
let b = rng.gen::<$t2>();
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function(stringify!($name), move |bh| bh.iter(|| {
|
||||||
$binop(&a, &b)
|
$binop(&a, &b)
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
macro_rules! bench_unop_na(
|
macro_rules! bench_unop_na(
|
||||||
($name: ident, $t: ty, $unop: ident) => {
|
($name: ident, $t: ty, $unop: ident) => {
|
||||||
#[bench]
|
fn $name(bh: &mut criterion::Criterion) {
|
||||||
fn $name(bh: &mut Bencher) {
|
|
||||||
const LEN: usize = 1 << 13;
|
const LEN: usize = 1 << 13;
|
||||||
|
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
|
@ -60,21 +56,20 @@ macro_rules! bench_unop_na(
|
||||||
let elems: Vec<$t> = (0usize .. LEN).map(|_| rng.gen::<$t>()).collect();
|
let elems: Vec<$t> = (0usize .. LEN).map(|_| rng.gen::<$t>()).collect();
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function(stringify!($name), move |bh| bh.iter(|| {
|
||||||
i = (i + 1) & (LEN - 1);
|
i = (i + 1) & (LEN - 1);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
test::black_box(na::$unop(elems.get_unchecked(i)))
|
test::black_box(na::$unop(elems.get_unchecked(i)))
|
||||||
}
|
}
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
macro_rules! bench_unop(
|
macro_rules! bench_unop(
|
||||||
($name: ident, $t: ty, $unop: ident) => {
|
($name: ident, $t: ty, $unop: ident) => {
|
||||||
#[bench]
|
fn $name(bh: &mut criterion::Criterion) {
|
||||||
fn $name(bh: &mut Bencher) {
|
|
||||||
const LEN: usize = 1 << 13;
|
const LEN: usize = 1 << 13;
|
||||||
|
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
|
@ -83,21 +78,20 @@ macro_rules! bench_unop(
|
||||||
let mut elems: Vec<$t> = (0usize .. LEN).map(|_| rng.gen::<$t>()).collect();
|
let mut elems: Vec<$t> = (0usize .. LEN).map(|_| rng.gen::<$t>()).collect();
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function(stringify!($name), move |bh| bh.iter(|| {
|
||||||
i = (i + 1) & (LEN - 1);
|
i = (i + 1) & (LEN - 1);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
test::black_box(elems.get_unchecked_mut(i).$unop())
|
test::black_box(elems.get_unchecked_mut(i).$unop())
|
||||||
}
|
}
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
macro_rules! bench_construction(
|
macro_rules! bench_construction(
|
||||||
($name: ident, $constructor: path, $( $args: ident: $types: ty),*) => {
|
($name: ident, $constructor: path, $( $args: ident: $types: ty),*) => {
|
||||||
#[bench]
|
fn $name(bh: &mut criterion::Criterion) {
|
||||||
fn $name(bh: &mut Bencher) {
|
|
||||||
const LEN: usize = 1 << 13;
|
const LEN: usize = 1 << 13;
|
||||||
|
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
|
@ -106,14 +100,14 @@ macro_rules! bench_construction(
|
||||||
$(let $args: Vec<$types> = (0usize .. LEN).map(|_| rng.gen::<$types>()).collect();)*
|
$(let $args: Vec<$types> = (0usize .. LEN).map(|_| rng.gen::<$types>()).collect();)*
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function(stringify!($name), move |bh| bh.iter(|| {
|
||||||
i = (i + 1) & (LEN - 1);
|
i = (i + 1) & (LEN - 1);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let res = $constructor($(*$args.get_unchecked(i),)*);
|
let res = $constructor($(*$args.get_unchecked(i),)*);
|
||||||
test::black_box(res)
|
test::black_box(res)
|
||||||
}
|
}
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use na::{DMatrix, DVector, Matrix2, Matrix3, Matrix4, MatrixN, Vector2, Vector3, Vector4, U10};
|
use na::{DMatrix, DVector, Matrix2, Matrix3, Matrix4, MatrixN, Vector2, Vector3, Vector4, U10};
|
||||||
use rand::{IsaacRng, Rng};
|
use rand::{IsaacRng, Rng};
|
||||||
use std::ops::{Add, Div, Mul, Sub};
|
use std::ops::{Add, Div, Mul, Sub};
|
||||||
use test::{self, Bencher};
|
|
||||||
|
|
||||||
#[path = "../common/macros.rs"]
|
#[path = "../common/macros.rs"]
|
||||||
mod macros;
|
mod macros;
|
||||||
|
@ -46,153 +45,196 @@ bench_unop!(mat2_transpose, Matrix2<f32>, transpose);
|
||||||
bench_unop!(mat3_transpose, Matrix3<f32>, transpose);
|
bench_unop!(mat3_transpose, Matrix3<f32>, transpose);
|
||||||
bench_unop!(mat4_transpose, Matrix4<f32>, transpose);
|
bench_unop!(mat4_transpose, Matrix4<f32>, transpose);
|
||||||
|
|
||||||
#[bench]
|
fn mat_div_scalar(b: &mut criterion::Criterion) {
|
||||||
fn mat_div_scalar(b: &mut Bencher) {
|
|
||||||
let a = DMatrix::from_row_slice(1000, 1000, &vec![2.0; 1000000]);
|
let a = DMatrix::from_row_slice(1000, 1000, &vec![2.0; 1000000]);
|
||||||
let n = 42.0;
|
let n = 42.0;
|
||||||
|
|
||||||
b.iter(|| {
|
b.bench_function("mat_div_scalar", move |bh| bh.iter(|| {
|
||||||
let mut aa = a.clone();
|
let mut aa = a.clone();
|
||||||
let mut b = aa.slice_mut((0, 0), (1000, 1000));
|
let mut b = aa.slice_mut((0, 0), (1000, 1000));
|
||||||
b /= n
|
b /= n
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn mat100_add_mat100(bench: &mut criterion::Criterion) {
|
||||||
fn mat100_add_mat100(bench: &mut Bencher) {
|
|
||||||
let a = DMatrix::<f64>::new_random(100, 100);
|
let a = DMatrix::<f64>::new_random(100, 100);
|
||||||
let b = DMatrix::<f64>::new_random(100, 100);
|
let b = DMatrix::<f64>::new_random(100, 100);
|
||||||
|
|
||||||
bench.iter(|| &a + &b)
|
bench.bench_function("mat100_add_mat100", move |bh| bh.iter(|| &a + &b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn mat4_mul_mat4(bench: &mut criterion::Criterion) {
|
||||||
fn mat4_mul_mat4(bench: &mut Bencher) {
|
|
||||||
let a = DMatrix::<f64>::new_random(4, 4);
|
let a = DMatrix::<f64>::new_random(4, 4);
|
||||||
let b = DMatrix::<f64>::new_random(4, 4);
|
let b = DMatrix::<f64>::new_random(4, 4);
|
||||||
|
|
||||||
bench.iter(|| &a * &b)
|
bench.bench_function("mat4_mul_mat4", move |bh| bh.iter(|| &a * &b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn mat5_mul_mat5(bench: &mut criterion::Criterion) {
|
||||||
fn mat5_mul_mat5(bench: &mut Bencher) {
|
|
||||||
let a = DMatrix::<f64>::new_random(5, 5);
|
let a = DMatrix::<f64>::new_random(5, 5);
|
||||||
let b = DMatrix::<f64>::new_random(5, 5);
|
let b = DMatrix::<f64>::new_random(5, 5);
|
||||||
|
|
||||||
bench.iter(|| &a * &b)
|
bench.bench_function("mat5_mul_mat5", move |bh| bh.iter(|| &a * &b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn mat6_mul_mat6(bench: &mut criterion::Criterion) {
|
||||||
fn mat6_mul_mat6(bench: &mut Bencher) {
|
|
||||||
let a = DMatrix::<f64>::new_random(6, 6);
|
let a = DMatrix::<f64>::new_random(6, 6);
|
||||||
let b = DMatrix::<f64>::new_random(6, 6);
|
let b = DMatrix::<f64>::new_random(6, 6);
|
||||||
|
|
||||||
bench.iter(|| &a * &b)
|
bench.bench_function("mat6_mul_mat6", move |bh| bh.iter(|| &a * &b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn mat7_mul_mat7(bench: &mut criterion::Criterion) {
|
||||||
fn mat7_mul_mat7(bench: &mut Bencher) {
|
|
||||||
let a = DMatrix::<f64>::new_random(7, 7);
|
let a = DMatrix::<f64>::new_random(7, 7);
|
||||||
let b = DMatrix::<f64>::new_random(7, 7);
|
let b = DMatrix::<f64>::new_random(7, 7);
|
||||||
|
|
||||||
bench.iter(|| &a * &b)
|
bench.bench_function("mat7_mul_mat7", move |bh| bh.iter(|| &a * &b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn mat8_mul_mat8(bench: &mut criterion::Criterion) {
|
||||||
fn mat8_mul_mat8(bench: &mut Bencher) {
|
|
||||||
let a = DMatrix::<f64>::new_random(8, 8);
|
let a = DMatrix::<f64>::new_random(8, 8);
|
||||||
let b = DMatrix::<f64>::new_random(8, 8);
|
let b = DMatrix::<f64>::new_random(8, 8);
|
||||||
|
|
||||||
bench.iter(|| &a * &b)
|
bench.bench_function("mat8_mul_mat8", move |bh| bh.iter(|| &a * &b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn mat9_mul_mat9(bench: &mut criterion::Criterion) {
|
||||||
fn mat9_mul_mat9(bench: &mut Bencher) {
|
|
||||||
let a = DMatrix::<f64>::new_random(9, 9);
|
let a = DMatrix::<f64>::new_random(9, 9);
|
||||||
let b = DMatrix::<f64>::new_random(9, 9);
|
let b = DMatrix::<f64>::new_random(9, 9);
|
||||||
|
|
||||||
bench.iter(|| &a * &b)
|
bench.bench_function("mat9_mul_mat9", move |bh| bh.iter(|| &a * &b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn mat10_mul_mat10(bench: &mut criterion::Criterion) {
|
||||||
fn mat10_mul_mat10(bench: &mut Bencher) {
|
|
||||||
let a = DMatrix::<f64>::new_random(10, 10);
|
let a = DMatrix::<f64>::new_random(10, 10);
|
||||||
let b = DMatrix::<f64>::new_random(10, 10);
|
let b = DMatrix::<f64>::new_random(10, 10);
|
||||||
|
|
||||||
bench.iter(|| &a * &b)
|
bench.bench_function("mat10_mul_mat10", move |bh| bh.iter(|| &a * &b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn mat10_mul_mat10_static(bench: &mut criterion::Criterion) {
|
||||||
fn mat10_mul_mat10_static(bench: &mut Bencher) {
|
|
||||||
let a = MatrixN::<f64, U10>::new_random();
|
let a = MatrixN::<f64, U10>::new_random();
|
||||||
let b = MatrixN::<f64, U10>::new_random();
|
let b = MatrixN::<f64, U10>::new_random();
|
||||||
|
|
||||||
bench.iter(|| &a * &b)
|
bench.bench_function("mat10_mul_mat10_static", move |bh| bh.iter(|| &a * &b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn mat100_mul_mat100(bench: &mut criterion::Criterion) {
|
||||||
fn mat100_mul_mat100(bench: &mut Bencher) {
|
|
||||||
let a = DMatrix::<f64>::new_random(100, 100);
|
let a = DMatrix::<f64>::new_random(100, 100);
|
||||||
let b = DMatrix::<f64>::new_random(100, 100);
|
let b = DMatrix::<f64>::new_random(100, 100);
|
||||||
|
|
||||||
bench.iter(|| &a * &b)
|
bench.bench_function("mat100_mul_mat100", move |bh| bh.iter(|| &a * &b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn mat500_mul_mat500(bench: &mut criterion::Criterion) {
|
||||||
fn mat500_mul_mat500(bench: &mut Bencher) {
|
|
||||||
let a = DMatrix::<f64>::from_element(500, 500, 5f64);
|
let a = DMatrix::<f64>::from_element(500, 500, 5f64);
|
||||||
let b = DMatrix::<f64>::from_element(500, 500, 6f64);
|
let b = DMatrix::<f64>::from_element(500, 500, 6f64);
|
||||||
|
|
||||||
bench.iter(|| &a * &b)
|
bench.bench_function("mat500_mul_mat500", move |bh| bh.iter(|| &a * &b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn copy_from(bench: &mut criterion::Criterion) {
|
||||||
fn copy_from(bench: &mut Bencher) {
|
|
||||||
let a = DMatrix::<f64>::new_random(1000, 1000);
|
let a = DMatrix::<f64>::new_random(1000, 1000);
|
||||||
let mut b = DMatrix::<f64>::new_random(1000, 1000);
|
let mut b = DMatrix::<f64>::new_random(1000, 1000);
|
||||||
|
|
||||||
bench.iter(|| {
|
bench.bench_function("copy_from", move |bh| bh.iter(|| {
|
||||||
b.copy_from(&a);
|
b.copy_from(&a);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn axpy(bench: &mut criterion::Criterion) {
|
||||||
fn axpy(bench: &mut Bencher) {
|
|
||||||
let x = DVector::<f64>::from_element(100000, 2.0);
|
let x = DVector::<f64>::from_element(100000, 2.0);
|
||||||
let mut y = DVector::<f64>::from_element(100000, 3.0);
|
let mut y = DVector::<f64>::from_element(100000, 3.0);
|
||||||
let a = 42.0;
|
let a = 42.0;
|
||||||
|
|
||||||
bench.iter(|| {
|
bench.bench_function("axpy", move |bh| bh.iter(|| {
|
||||||
y.axpy(a, &x, 1.0);
|
y.axpy(a, &x, 1.0);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn tr_mul_to(bench: &mut criterion::Criterion) {
|
||||||
fn tr_mul_to(bench: &mut Bencher) {
|
|
||||||
let a = DMatrix::<f64>::new_random(1000, 1000);
|
let a = DMatrix::<f64>::new_random(1000, 1000);
|
||||||
let b = DVector::<f64>::new_random(1000);
|
let b = DVector::<f64>::new_random(1000);
|
||||||
let mut c = DVector::from_element(1000, 0.0);
|
let mut c = DVector::from_element(1000, 0.0);
|
||||||
|
|
||||||
bench.iter(|| a.tr_mul_to(&b, &mut c))
|
bench.bench_function("", move |bh| bh.iter(|| a.tr_mul_to(&b, &mut c)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn mat_mul_mat(bench: &mut criterion::Criterion) {
|
||||||
fn mat_mul_mat(bench: &mut Bencher) {
|
|
||||||
let a = DMatrix::<f64>::new_random(100, 100);
|
let a = DMatrix::<f64>::new_random(100, 100);
|
||||||
let b = DMatrix::<f64>::new_random(100, 100);
|
let b = DMatrix::<f64>::new_random(100, 100);
|
||||||
let mut ab = DMatrix::<f64>::from_element(100, 100, 0.0);
|
let mut ab = DMatrix::<f64>::from_element(100, 100, 0.0);
|
||||||
|
|
||||||
bench.iter(|| {
|
bench.bench_function("mat_mul_mat", move |bh| bh.iter(|| {
|
||||||
test::black_box(a.mul_to(&b, &mut ab));
|
test::black_box(a.mul_to(&b, &mut ab));
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn mat100_from_fn(bench: &mut criterion::Criterion) {
|
||||||
fn mat100_from_fn(bench: &mut Bencher) {
|
bench.bench_function("mat100_from_fn", move |bh| bh.iter(|| DMatrix::from_fn(100, 100, |a, b| a + b)));
|
||||||
bench.iter(|| DMatrix::from_fn(100, 100, |a, b| a + b))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn mat500_from_fn(bench: &mut criterion::Criterion) {
|
||||||
fn mat500_from_fn(bench: &mut Bencher) {
|
bench.bench_function("mat500_from_fn", move |bh| bh.iter(|| DMatrix::from_fn(500, 500, |a, b| a + b)));
|
||||||
bench.iter(|| DMatrix::from_fn(500, 500, |a, b| a + b))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
criterion_group!(matrix,
|
||||||
|
mat2_mul_m,
|
||||||
|
mat3_mul_m,
|
||||||
|
mat4_mul_m,
|
||||||
|
|
||||||
|
mat2_tr_mul_m,
|
||||||
|
mat3_tr_mul_m,
|
||||||
|
mat4_tr_mul_m,
|
||||||
|
|
||||||
|
mat2_add_m,
|
||||||
|
mat3_add_m,
|
||||||
|
mat4_add_m,
|
||||||
|
|
||||||
|
mat2_sub_m,
|
||||||
|
mat3_sub_m,
|
||||||
|
mat4_sub_m,
|
||||||
|
|
||||||
|
mat2_mul_v,
|
||||||
|
mat3_mul_v,
|
||||||
|
mat4_mul_v,
|
||||||
|
|
||||||
|
mat2_tr_mul_v,
|
||||||
|
mat3_tr_mul_v,
|
||||||
|
mat4_tr_mul_v,
|
||||||
|
|
||||||
|
mat2_mul_s,
|
||||||
|
mat3_mul_s,
|
||||||
|
mat4_mul_s,
|
||||||
|
|
||||||
|
mat2_div_s,
|
||||||
|
mat3_div_s,
|
||||||
|
mat4_div_s,
|
||||||
|
|
||||||
|
mat2_inv,
|
||||||
|
mat3_inv,
|
||||||
|
mat4_inv,
|
||||||
|
|
||||||
|
mat2_transpose,
|
||||||
|
mat3_transpose,
|
||||||
|
mat4_transpose,
|
||||||
|
|
||||||
|
mat_div_scalar,
|
||||||
|
mat100_add_mat100,
|
||||||
|
mat4_mul_mat4,
|
||||||
|
mat5_mul_mat5,
|
||||||
|
mat6_mul_mat6,
|
||||||
|
mat7_mul_mat7,
|
||||||
|
mat8_mul_mat8,
|
||||||
|
mat9_mul_mat9,
|
||||||
|
mat10_mul_mat10,
|
||||||
|
mat10_mul_mat10_static,
|
||||||
|
mat100_mul_mat100,
|
||||||
|
mat500_mul_mat500,
|
||||||
|
copy_from,
|
||||||
|
axpy,
|
||||||
|
tr_mul_to,
|
||||||
|
mat_mul_mat,
|
||||||
|
mat100_from_fn,
|
||||||
|
mat500_from_fn,
|
||||||
|
);
|
|
@ -1,2 +1,5 @@
|
||||||
|
pub use self::matrix::matrix;
|
||||||
|
pub use self::vector::vector;
|
||||||
|
|
||||||
mod matrix;
|
mod matrix;
|
||||||
mod vector;
|
mod vector;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use na::{DVector, Vector2, Vector3, Vector4, VectorN};
|
use na::{DVector, Vector2, Vector3, Vector4, VectorN};
|
||||||
use rand::{IsaacRng, Rng};
|
use rand::{IsaacRng, Rng};
|
||||||
use std::ops::{Add, Div, Mul, Sub};
|
use std::ops::{Add, Div, Mul, Sub};
|
||||||
use test::{self, Bencher};
|
|
||||||
use typenum::U10000;
|
use typenum::U10000;
|
||||||
|
|
||||||
#[path = "../common/macros.rs"]
|
#[path = "../common/macros.rs"]
|
||||||
|
@ -48,19 +47,17 @@ 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, VectorN<f64, U10000>, VectorN<f64, U10000>, dot);
|
||||||
bench_binop_ref!(vec10000_dot_f32, VectorN<f32, U10000>, VectorN<f32, U10000>, dot);
|
bench_binop_ref!(vec10000_dot_f32, VectorN<f32, U10000>, VectorN<f32, U10000>, dot);
|
||||||
|
|
||||||
#[bench]
|
fn vec10000_axpy_f64(bh: &mut criterion::Criterion) {
|
||||||
fn vec10000_axpy_f64(bh: &mut Bencher) {
|
|
||||||
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 = DVector::new_random(10000);
|
let mut a = DVector::new_random(10000);
|
||||||
let b = DVector::new_random(10000);
|
let b = DVector::new_random(10000);
|
||||||
let n = rng.gen::<f64>();
|
let n = rng.gen::<f64>();
|
||||||
|
|
||||||
bh.iter(|| a.axpy(n, &b, 1.0))
|
bh.bench_function("vec10000_axpy_f64", move |bh| bh.iter(|| a.axpy(n, &b, 1.0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn vec10000_axpy_beta_f64(bh: &mut criterion::Criterion) {
|
||||||
fn vec10000_axpy_beta_f64(bh: &mut Bencher) {
|
|
||||||
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 = DVector::new_random(10000);
|
let mut a = DVector::new_random(10000);
|
||||||
|
@ -68,27 +65,25 @@ fn vec10000_axpy_beta_f64(bh: &mut Bencher) {
|
||||||
let n = rng.gen::<f64>();
|
let n = rng.gen::<f64>();
|
||||||
let beta = rng.gen::<f64>();
|
let beta = rng.gen::<f64>();
|
||||||
|
|
||||||
bh.iter(|| a.axpy(n, &b, beta))
|
bh.bench_function("vec10000_axpy_beta_f64", move |bh| bh.iter(|| a.axpy(n, &b, beta)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn vec10000_axpy_f64_slice(bh: &mut criterion::Criterion) {
|
||||||
fn vec10000_axpy_f64_slice(bh: &mut Bencher) {
|
|
||||||
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 = DVector::new_random(10000);
|
let mut a = DVector::new_random(10000);
|
||||||
let b = DVector::new_random(10000);
|
let b = DVector::new_random(10000);
|
||||||
let n = rng.gen::<f64>();
|
let n = rng.gen::<f64>();
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("vec10000_axpy_f64_slice", move |bh| bh.iter(|| {
|
||||||
let mut a = a.fixed_rows_mut::<U10000>(0);
|
let mut a = a.fixed_rows_mut::<U10000>(0);
|
||||||
let b = b.fixed_rows::<U10000>(0);
|
let b = b.fixed_rows::<U10000>(0);
|
||||||
|
|
||||||
a.axpy(n, &b, 1.0)
|
a.axpy(n, &b, 1.0)
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn vec10000_axpy_f64_static(bh: &mut criterion::Criterion) {
|
||||||
fn vec10000_axpy_f64_static(bh: &mut Bencher) {
|
|
||||||
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 = VectorN::<f64, U10000>::new_random();
|
||||||
|
@ -96,22 +91,20 @@ fn vec10000_axpy_f64_static(bh: &mut Bencher) {
|
||||||
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(VectorN...)).
|
||||||
bh.iter(|| a.axpy(n, &b, 1.0))
|
bh.bench_function("vec10000_axpy_f64_static", move |bh| bh.iter(|| a.axpy(n, &b, 1.0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn vec10000_axpy_f32(bh: &mut criterion::Criterion) {
|
||||||
fn vec10000_axpy_f32(bh: &mut Bencher) {
|
|
||||||
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 = DVector::new_random(10000);
|
let mut a = DVector::new_random(10000);
|
||||||
let b = DVector::new_random(10000);
|
let b = DVector::new_random(10000);
|
||||||
let n = rng.gen::<f32>();
|
let n = rng.gen::<f32>();
|
||||||
|
|
||||||
bh.iter(|| a.axpy(n, &b, 1.0))
|
bh.bench_function("vec10000_axpy_f32", move |bh| bh.iter(|| a.axpy(n, &b, 1.0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn vec10000_axpy_beta_f32(bh: &mut criterion::Criterion) {
|
||||||
fn vec10000_axpy_beta_f32(bh: &mut Bencher) {
|
|
||||||
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 = DVector::new_random(10000);
|
let mut a = DVector::new_random(10000);
|
||||||
|
@ -119,5 +112,55 @@ fn vec10000_axpy_beta_f32(bh: &mut Bencher) {
|
||||||
let n = rng.gen::<f32>();
|
let n = rng.gen::<f32>();
|
||||||
let beta = rng.gen::<f32>();
|
let beta = rng.gen::<f32>();
|
||||||
|
|
||||||
bh.iter(|| a.axpy(n, &b, beta))
|
bh.bench_function("vec10000_axpy_beta_f32", move |bh| bh.iter(|| a.axpy(n, &b, beta)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
criterion_group!(vector,
|
||||||
|
vec2_add_v_f32,
|
||||||
|
vec3_add_v_f32,
|
||||||
|
vec4_add_v_f32,
|
||||||
|
|
||||||
|
vec2_add_v_f64,
|
||||||
|
vec3_add_v_f64,
|
||||||
|
vec4_add_v_f64,
|
||||||
|
|
||||||
|
vec2_sub_v,
|
||||||
|
vec3_sub_v,
|
||||||
|
vec4_sub_v,
|
||||||
|
|
||||||
|
vec2_mul_s,
|
||||||
|
vec3_mul_s,
|
||||||
|
vec4_mul_s,
|
||||||
|
|
||||||
|
vec2_div_s,
|
||||||
|
vec3_div_s,
|
||||||
|
vec4_div_s,
|
||||||
|
|
||||||
|
vec2_dot_f32,
|
||||||
|
vec3_dot_f32,
|
||||||
|
vec4_dot_f32,
|
||||||
|
|
||||||
|
vec2_dot_f64,
|
||||||
|
vec3_dot_f64,
|
||||||
|
vec4_dot_f64,
|
||||||
|
|
||||||
|
vec3_cross,
|
||||||
|
|
||||||
|
vec2_norm,
|
||||||
|
vec3_norm,
|
||||||
|
vec4_norm,
|
||||||
|
|
||||||
|
vec2_normalize,
|
||||||
|
vec3_normalize,
|
||||||
|
vec4_normalize,
|
||||||
|
|
||||||
|
vec10000_dot_f64,
|
||||||
|
vec10000_dot_f32,
|
||||||
|
|
||||||
|
vec10000_axpy_f64,
|
||||||
|
vec10000_axpy_beta_f64,
|
||||||
|
vec10000_axpy_f64_slice,
|
||||||
|
vec10000_axpy_f64_static,
|
||||||
|
vec10000_axpy_f32,
|
||||||
|
vec10000_axpy_beta_f32
|
||||||
|
);
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
|
pub use self::quaternion::quaternion;
|
||||||
|
|
||||||
mod quaternion;
|
mod quaternion;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use na::{Quaternion, UnitQuaternion, Vector3};
|
use na::{Quaternion, UnitQuaternion, Vector3};
|
||||||
use rand::{IsaacRng, Rng};
|
use rand::{IsaacRng, Rng};
|
||||||
use std::ops::{Add, Div, Mul, Sub};
|
use std::ops::{Add, Div, Mul, Sub};
|
||||||
use test::{self, Bencher};
|
|
||||||
|
|
||||||
#[path = "../common/macros.rs"]
|
#[path = "../common/macros.rs"]
|
||||||
mod macros;
|
mod macros;
|
||||||
|
@ -25,3 +24,14 @@ bench_unop!(unit_quaternion_inv, UnitQuaternion<f32>, inverse);
|
||||||
|
|
||||||
// bench_unop_self!(quaternion_conjugate, Quaternion<f32>, conjugate);
|
// bench_unop_self!(quaternion_conjugate, Quaternion<f32>, conjugate);
|
||||||
// bench_unop!(quaternion_normalize, Quaternion<f32>, normalize);
|
// bench_unop!(quaternion_normalize, Quaternion<f32>, normalize);
|
||||||
|
|
||||||
|
criterion_group!(quaternion,
|
||||||
|
quaternion_add_q,
|
||||||
|
quaternion_sub_q,
|
||||||
|
quaternion_mul_q,
|
||||||
|
unit_quaternion_mul_v,
|
||||||
|
quaternion_mul_s,
|
||||||
|
quaternion_div_s,
|
||||||
|
quaternion_inv,
|
||||||
|
unit_quaternion_inv
|
||||||
|
);
|
|
@ -6,15 +6,34 @@ extern crate rand;
|
||||||
extern crate test;
|
extern crate test;
|
||||||
extern crate typenum;
|
extern crate typenum;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate criterion;
|
||||||
|
|
||||||
use na::DMatrix;
|
use na::DMatrix;
|
||||||
use rand::{IsaacRng, Rng};
|
use rand::{IsaacRng, Rng};
|
||||||
|
|
||||||
mod core;
|
pub mod core;
|
||||||
mod geometry;
|
pub mod geometry;
|
||||||
mod linalg;
|
pub mod linalg;
|
||||||
|
|
||||||
fn reproductible_dmatrix(nrows: usize, ncols: usize) -> DMatrix<f64> {
|
fn reproductible_dmatrix(nrows: usize, ncols: usize) -> DMatrix<f64> {
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
let mut rng = IsaacRng::seed_from_u64(0);
|
let mut rng = IsaacRng::seed_from_u64(0);
|
||||||
DMatrix::<f64>::from_fn(nrows, ncols, |_, _| rng.gen())
|
DMatrix::<f64>::from_fn(nrows, ncols, |_, _| rng.gen())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
criterion_main!(
|
||||||
|
core::matrix,
|
||||||
|
core::vector,
|
||||||
|
geometry::quaternion,
|
||||||
|
linalg::bidiagonal,
|
||||||
|
linalg::cholesky,
|
||||||
|
linalg::full_piv_lu,
|
||||||
|
linalg::hessenberg,
|
||||||
|
linalg::lu,
|
||||||
|
linalg::qr,
|
||||||
|
linalg::schur,
|
||||||
|
linalg::solve,
|
||||||
|
linalg::svd,
|
||||||
|
linalg::symmetric_eigen,
|
||||||
|
);
|
|
@ -1,73 +1,75 @@
|
||||||
use na::{Bidiagonal, DMatrix, Matrix4};
|
use na::{Bidiagonal, DMatrix, Matrix4};
|
||||||
use test::{self, Bencher};
|
|
||||||
|
|
||||||
#[path = "../common/macros.rs"]
|
#[path = "../common/macros.rs"]
|
||||||
mod macros;
|
mod macros;
|
||||||
|
|
||||||
// Without unpack.
|
// Without unpack.
|
||||||
#[bench]
|
fn bidiagonalize_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn bidiagonalize_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(Bidiagonal::new(m.clone())))
|
bh.bench_function("bidiagonalize_100x100", move |bh| bh.iter(|| test::black_box(Bidiagonal::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn bidiagonalize_100x500(bh: &mut criterion::Criterion) {
|
||||||
fn bidiagonalize_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(Bidiagonal::new(m.clone())))
|
bh.bench_function("bidiagonalize_100x500", move |bh| bh.iter(|| test::black_box(Bidiagonal::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn bidiagonalize_4x4(bh: &mut criterion::Criterion) {
|
||||||
fn bidiagonalize_4x4(bh: &mut Bencher) {
|
|
||||||
let m = Matrix4::<f64>::new_random();
|
let m = Matrix4::<f64>::new_random();
|
||||||
bh.iter(|| test::black_box(Bidiagonal::new(m.clone())))
|
bh.bench_function("bidiagonalize_4x4", move |bh| bh.iter(|| test::black_box(Bidiagonal::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn bidiagonalize_500x100(bh: &mut criterion::Criterion) {
|
||||||
fn bidiagonalize_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(Bidiagonal::new(m.clone())))
|
bh.bench_function("bidiagonalize_500x100", move |bh| bh.iter(|| test::black_box(Bidiagonal::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn bidiagonalize_500x500(bh: &mut criterion::Criterion) {
|
||||||
fn bidiagonalize_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(Bidiagonal::new(m.clone())))
|
bh.bench_function("bidiagonalize_500x500", move |bh| bh.iter(|| test::black_box(Bidiagonal::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// With unpack.
|
// With unpack.
|
||||||
#[bench]
|
fn bidiagonalize_unpack_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn bidiagonalize_unpack_100x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
bh.iter(|| {
|
bh.bench_function("bidiagonalize_unpack_100x100", move |bh| bh.iter(|| {
|
||||||
let bidiag = Bidiagonal::new(m.clone());
|
let bidiag = Bidiagonal::new(m.clone());
|
||||||
let _ = bidiag.unpack();
|
let _ = bidiag.unpack();
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn bidiagonalize_unpack_100x500(bh: &mut criterion::Criterion) {
|
||||||
fn bidiagonalize_unpack_100x500(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 500);
|
let m = DMatrix::<f64>::new_random(100, 500);
|
||||||
bh.iter(|| {
|
bh.bench_function("bidiagonalize_unpack_100x500", move |bh| bh.iter(|| {
|
||||||
let bidiag = Bidiagonal::new(m.clone());
|
let bidiag = Bidiagonal::new(m.clone());
|
||||||
let _ = bidiag.unpack();
|
let _ = bidiag.unpack();
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn bidiagonalize_unpack_500x100(bh: &mut criterion::Criterion) {
|
||||||
fn bidiagonalize_unpack_500x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(500, 100);
|
let m = DMatrix::<f64>::new_random(500, 100);
|
||||||
bh.iter(|| {
|
bh.bench_function("bidiagonalize_unpack_500x100", move |bh| bh.iter(|| {
|
||||||
let bidiag = Bidiagonal::new(m.clone());
|
let bidiag = Bidiagonal::new(m.clone());
|
||||||
let _ = bidiag.unpack();
|
let _ = bidiag.unpack();
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn bidiagonalize_unpack_500x500(bh: &mut criterion::Criterion) {
|
||||||
fn bidiagonalize_unpack_500x500(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
bh.iter(|| {
|
bh.bench_function("bidiagonalize_unpack_500x500", move |bh| bh.iter(|| {
|
||||||
let bidiag = Bidiagonal::new(m.clone());
|
let bidiag = Bidiagonal::new(m.clone());
|
||||||
let _ = bidiag.unpack();
|
let _ = bidiag.unpack();
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
criterion_group!(bidiagonal,
|
||||||
|
bidiagonalize_100x100,
|
||||||
|
bidiagonalize_100x500,
|
||||||
|
bidiagonalize_4x4,
|
||||||
|
bidiagonalize_500x100,
|
||||||
|
// bidiagonalize_500x500, // too long
|
||||||
|
bidiagonalize_unpack_100x100,
|
||||||
|
bidiagonalize_unpack_100x500,
|
||||||
|
bidiagonalize_unpack_500x100,
|
||||||
|
// bidiagonalize_unpack_500x500 // too long
|
||||||
|
);
|
|
@ -1,109 +1,112 @@
|
||||||
use na::{Cholesky, DMatrix, DVector};
|
use na::{Cholesky, DMatrix, DVector};
|
||||||
use test::{self, Bencher};
|
|
||||||
|
|
||||||
#[bench]
|
fn cholesky_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn cholesky_100x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
let m = &m * m.transpose();
|
let m = &m * m.transpose();
|
||||||
|
|
||||||
bh.iter(|| test::black_box(Cholesky::new(m.clone())))
|
bh.bench_function("cholesky_100x100", move |bh| bh.iter(|| test::black_box(Cholesky::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn cholesky_500x500(bh: &mut criterion::Criterion) {
|
||||||
fn cholesky_500x500(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
let m = &m * m.transpose();
|
let m = &m * m.transpose();
|
||||||
|
|
||||||
bh.iter(|| test::black_box(Cholesky::new(m.clone())))
|
bh.bench_function("cholesky_500x500", move |bh| bh.iter(|| test::black_box(Cholesky::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// With unpack.
|
// With unpack.
|
||||||
#[bench]
|
fn cholesky_decompose_unpack_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn cholesky_decompose_unpack_100x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
let m = &m * m.transpose();
|
let m = &m * m.transpose();
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("cholesky_decompose_unpack_100x100", move |bh| bh.iter(|| {
|
||||||
let chol = Cholesky::new(m.clone()).unwrap();
|
let chol = Cholesky::new(m.clone()).unwrap();
|
||||||
let _ = chol.unpack();
|
let _ = chol.unpack();
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
#[bench]
|
fn cholesky_decompose_unpack_500x500(bh: &mut criterion::Criterion) {
|
||||||
fn cholesky_decompose_unpack_500x500(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
let m = &m * m.transpose();
|
let m = &m * m.transpose();
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("cholesky_decompose_unpack_500x500", move |bh| bh.iter(|| {
|
||||||
let chol = Cholesky::new(m.clone()).unwrap();
|
let chol = Cholesky::new(m.clone()).unwrap();
|
||||||
let _ = chol.unpack();
|
let _ = chol.unpack();
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn cholesky_solve_10x10(bh: &mut criterion::Criterion) {
|
||||||
fn cholesky_solve_10x10(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(10, 10);
|
let m = DMatrix::<f64>::new_random(10, 10);
|
||||||
let m = &m * m.transpose();
|
let m = &m * m.transpose();
|
||||||
let v = DVector::<f64>::new_random(10);
|
let v = DVector::<f64>::new_random(10);
|
||||||
let chol = Cholesky::new(m.clone()).unwrap();
|
let chol = Cholesky::new(m.clone()).unwrap();
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("cholesky_solve_10x10", move |bh| bh.iter(|| {
|
||||||
let _ = chol.solve(&v);
|
let _ = chol.solve(&v);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn cholesky_solve_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn cholesky_solve_100x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
let m = &m * m.transpose();
|
let m = &m * m.transpose();
|
||||||
let v = DVector::<f64>::new_random(100);
|
let v = DVector::<f64>::new_random(100);
|
||||||
let chol = Cholesky::new(m.clone()).unwrap();
|
let chol = Cholesky::new(m.clone()).unwrap();
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("cholesky_solve_100x100", move |bh| bh.iter(|| {
|
||||||
let _ = chol.solve(&v);
|
let _ = chol.solve(&v);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn cholesky_solve_500x500(bh: &mut criterion::Criterion) {
|
||||||
fn cholesky_solve_500x500(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
let m = &m * m.transpose();
|
let m = &m * m.transpose();
|
||||||
let v = DVector::<f64>::new_random(500);
|
let v = DVector::<f64>::new_random(500);
|
||||||
let chol = Cholesky::new(m.clone()).unwrap();
|
let chol = Cholesky::new(m.clone()).unwrap();
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("cholesky_solve_500x500", move |bh| bh.iter(|| {
|
||||||
let _ = chol.solve(&v);
|
let _ = chol.solve(&v);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn cholesky_inverse_10x10(bh: &mut Bencher) {
|
fn cholesky_inverse_10x10(bh: &mut criterion::Criterion) {
|
||||||
let m = DMatrix::<f64>::new_random(10, 10);
|
let m = DMatrix::<f64>::new_random(10, 10);
|
||||||
let m = &m * m.transpose();
|
let m = &m * m.transpose();
|
||||||
let chol = Cholesky::new(m.clone()).unwrap();
|
let chol = Cholesky::new(m.clone()).unwrap();
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("cholesky_inverse_10x10", move |bh| bh.iter(|| {
|
||||||
let _ = chol.inverse();
|
let _ = chol.inverse();
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn cholesky_inverse_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn cholesky_inverse_100x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
let m = &m * m.transpose();
|
let m = &m * m.transpose();
|
||||||
let chol = Cholesky::new(m.clone()).unwrap();
|
let chol = Cholesky::new(m.clone()).unwrap();
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("cholesky_inverse_100x100", move |bh| bh.iter(|| {
|
||||||
let _ = chol.inverse();
|
let _ = chol.inverse();
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn cholesky_inverse_500x500(bh: &mut criterion::Criterion) {
|
||||||
fn cholesky_inverse_500x500(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
let m = &m * m.transpose();
|
let m = &m * m.transpose();
|
||||||
let chol = Cholesky::new(m.clone()).unwrap();
|
let chol = Cholesky::new(m.clone()).unwrap();
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("cholesky_inverse_500x500", move |bh| bh.iter(|| {
|
||||||
let _ = chol.inverse();
|
let _ = chol.inverse();
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
criterion_group!(cholesky,
|
||||||
|
cholesky_100x100,
|
||||||
|
cholesky_500x500,
|
||||||
|
cholesky_decompose_unpack_100x100,
|
||||||
|
cholesky_decompose_unpack_500x500,
|
||||||
|
cholesky_solve_10x10,
|
||||||
|
cholesky_solve_100x100,
|
||||||
|
cholesky_solve_500x500,
|
||||||
|
cholesky_inverse_10x10,
|
||||||
|
cholesky_inverse_100x100,
|
||||||
|
cholesky_inverse_500x500
|
||||||
|
);
|
|
@ -1,30 +1,33 @@
|
||||||
use test::Bencher;
|
use test::Bencher;
|
||||||
use na::{DMatrix, Eigen};
|
use na::{DMatrix, Eigen};
|
||||||
|
|
||||||
#[bench]
|
fn eigen_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn eigen_100x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
|
|
||||||
bh.iter(|| Eigen::new(m.clone(), 1.0e-7, 0))
|
bh.bench_function("eigen_100x100", move |bh| bh.iter(|| Eigen::new(m.clone(), 1.0e-7, 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn eigen_500x500(bh: &mut criterion::Criterion) {
|
||||||
fn eigen_500x500(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
|
|
||||||
bh.iter(|| Eigen::new(m.clone(), 1.0e-7, 0))
|
bh.bench_function("eigen_500x500", move |bh| bh.iter(|| Eigen::new(m.clone(), 1.0e-7, 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn eigenvalues_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn eigenvalues_100x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
|
|
||||||
bh.iter(|| m.clone().eigenvalues(1.0e-7, 0))
|
bh.bench_function("eigenvalues_100x100", move |bh| bh.iter(|| m.clone().eigenvalues(1.0e-7, 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn eigenvalues_500x500(bh: &mut criterion::Criterion) {
|
||||||
fn eigenvalues_500x500(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
|
|
||||||
bh.iter(|| m.clone().eigenvalues(1.0e-7, 0))
|
bh.bench_function("eigenvalues_500x500", move |bh| bh.iter(|| m.clone().eigenvalues(1.0e-7, 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
criterion_group!(eigen,
|
||||||
|
eigen_100x100,
|
||||||
|
// eigen_500x500,
|
||||||
|
eigenvalues_100x100,
|
||||||
|
// eigenvalues_500x500
|
||||||
|
);
|
||||||
|
|
|
@ -1,102 +1,105 @@
|
||||||
use na::{DMatrix, DVector, FullPivLU};
|
use na::{DMatrix, DVector, FullPivLU};
|
||||||
use test::{self, Bencher};
|
|
||||||
|
|
||||||
// Without unpack.
|
// Without unpack.
|
||||||
#[bench]
|
fn full_piv_lu_decompose_10x10(bh: &mut criterion::Criterion) {
|
||||||
fn full_piv_lu_decompose_10x10(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(10, 10);
|
let m = DMatrix::<f64>::new_random(10, 10);
|
||||||
bh.iter(|| test::black_box(FullPivLU::new(m.clone())))
|
bh.bench_function("full_piv_lu_decompose_10x10", move |bh| bh.iter(|| test::black_box(FullPivLU::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn full_piv_lu_decompose_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn full_piv_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(FullPivLU::new(m.clone())))
|
bh.bench_function("full_piv_lu_decompose_100x100", move |bh| bh.iter(|| test::black_box(FullPivLU::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn full_piv_lu_decompose_500x500(bh: &mut criterion::Criterion) {
|
||||||
fn full_piv_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(FullPivLU::new(m.clone())))
|
bh.bench_function("full_piv_lu_decompose_500x500", move |bh| bh.iter(|| test::black_box(FullPivLU::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn full_piv_lu_solve_10x10(bh: &mut criterion::Criterion) {
|
||||||
fn full_piv_lu_solve_10x10(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(10, 10);
|
let m = DMatrix::<f64>::new_random(10, 10);
|
||||||
let lu = FullPivLU::new(m.clone());
|
let lu = FullPivLU::new(m.clone());
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("full_piv_lu_solve_10x10", move |bh| bh.iter(|| {
|
||||||
let mut b = DVector::<f64>::from_element(10, 1.0);
|
let mut b = DVector::<f64>::from_element(10, 1.0);
|
||||||
lu.solve(&mut b);
|
lu.solve(&mut b);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn full_piv_lu_solve_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn full_piv_lu_solve_100x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
let lu = FullPivLU::new(m.clone());
|
let lu = FullPivLU::new(m.clone());
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("full_piv_lu_solve_100x100", move |bh| bh.iter(|| {
|
||||||
let mut b = DVector::<f64>::from_element(100, 1.0);
|
let mut b = DVector::<f64>::from_element(100, 1.0);
|
||||||
lu.solve(&mut b);
|
lu.solve(&mut b);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn full_piv_lu_solve_500x500(bh: &mut criterion::Criterion) {
|
||||||
fn full_piv_lu_solve_500x500(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
let lu = FullPivLU::new(m.clone());
|
let lu = FullPivLU::new(m.clone());
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("full_piv_lu_solve_500x500", move |bh| bh.iter(|| {
|
||||||
let mut b = DVector::<f64>::from_element(500, 1.0);
|
let mut b = DVector::<f64>::from_element(500, 1.0);
|
||||||
lu.solve(&mut b);
|
lu.solve(&mut b);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn full_piv_lu_inverse_10x10(bh: &mut criterion::Criterion) {
|
||||||
fn full_piv_lu_inverse_10x10(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(10, 10);
|
let m = DMatrix::<f64>::new_random(10, 10);
|
||||||
let lu = FullPivLU::new(m.clone());
|
let lu = FullPivLU::new(m.clone());
|
||||||
|
|
||||||
bh.iter(|| test::black_box(lu.try_inverse()))
|
bh.bench_function("full_piv_lu_inverse_10x10", move |bh| bh.iter(|| test::black_box(lu.try_inverse())));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn full_piv_lu_inverse_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn full_piv_lu_inverse_100x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
let lu = FullPivLU::new(m.clone());
|
let lu = FullPivLU::new(m.clone());
|
||||||
|
|
||||||
bh.iter(|| test::black_box(lu.try_inverse()))
|
bh.bench_function("full_piv_lu_inverse_100x100", move |bh| bh.iter(|| test::black_box(lu.try_inverse())));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn full_piv_lu_inverse_500x500(bh: &mut criterion::Criterion) {
|
||||||
fn full_piv_lu_inverse_500x500(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
let lu = FullPivLU::new(m.clone());
|
let lu = FullPivLU::new(m.clone());
|
||||||
|
|
||||||
bh.iter(|| test::black_box(lu.try_inverse()))
|
bh.bench_function("full_piv_lu_inverse_500x500", move |bh| bh.iter(|| test::black_box(lu.try_inverse())));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn full_piv_lu_determinant_10x10(bh: &mut criterion::Criterion) {
|
||||||
fn full_piv_lu_determinant_10x10(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(10, 10);
|
let m = DMatrix::<f64>::new_random(10, 10);
|
||||||
let lu = FullPivLU::new(m.clone());
|
let lu = FullPivLU::new(m.clone());
|
||||||
|
|
||||||
bh.iter(|| test::black_box(lu.determinant()))
|
bh.bench_function("full_piv_lu_determinant_10x10", move |bh| bh.iter(|| test::black_box(lu.determinant())));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn full_piv_lu_determinant_100x100(bh: &mut Bencher) {
|
fn full_piv_lu_determinant_100x100(bh: &mut criterion::Criterion) {
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
let lu = FullPivLU::new(m.clone());
|
let lu = FullPivLU::new(m.clone());
|
||||||
|
|
||||||
bh.iter(|| test::black_box(lu.determinant()))
|
bh.bench_function("full_piv_lu_determinant_100x100", move |bh| bh.iter(|| test::black_box(lu.determinant())));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn full_piv_lu_determinant_500x500(bh: &mut criterion::Criterion) {
|
||||||
fn full_piv_lu_determinant_500x500(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
let lu = FullPivLU::new(m.clone());
|
let lu = FullPivLU::new(m.clone());
|
||||||
|
|
||||||
bh.iter(|| test::black_box(lu.determinant()))
|
bh.bench_function("full_piv_lu_determinant_500x500", move |bh| bh.iter(|| test::black_box(lu.determinant())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
criterion_group!(full_piv_lu,
|
||||||
|
full_piv_lu_decompose_10x10,
|
||||||
|
full_piv_lu_decompose_100x100,
|
||||||
|
// full_piv_lu_decompose_500x500,
|
||||||
|
full_piv_lu_solve_10x10,
|
||||||
|
full_piv_lu_solve_100x100,
|
||||||
|
// full_piv_lu_solve_500x500,
|
||||||
|
full_piv_lu_inverse_10x10,
|
||||||
|
full_piv_lu_inverse_100x100,
|
||||||
|
// full_piv_lu_inverse_500x500,
|
||||||
|
full_piv_lu_determinant_10x10,
|
||||||
|
full_piv_lu_determinant_100x100,
|
||||||
|
// full_piv_lu_determinant_500x500
|
||||||
|
);
|
|
@ -1,58 +1,60 @@
|
||||||
use na::{DMatrix, Hessenberg, Matrix4};
|
use na::{DMatrix, Hessenberg, Matrix4};
|
||||||
use test::{self, Bencher};
|
|
||||||
|
|
||||||
#[path = "../common/macros.rs"]
|
#[path = "../common/macros.rs"]
|
||||||
mod macros;
|
mod macros;
|
||||||
|
|
||||||
// Without unpack.
|
// Without unpack.
|
||||||
#[bench]
|
fn hessenberg_decompose_4x4(bh: &mut criterion::Criterion) {
|
||||||
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.bench_function("hessenberg_decompose_4x4", move |bh| bh.iter(|| test::black_box(Hessenberg::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn hessenberg_decompose_100x100(bh: &mut criterion::Criterion) {
|
||||||
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.bench_function("hessenberg_decompose_100x100", move |bh| bh.iter(|| test::black_box(Hessenberg::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn hessenberg_decompose_200x200(bh: &mut criterion::Criterion) {
|
||||||
fn hessenberg_decompose_200x200(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(200, 200);
|
let m = DMatrix::<f64>::new_random(200, 200);
|
||||||
bh.iter(|| test::black_box(Hessenberg::new(m.clone())))
|
bh.bench_function("hessenberg_decompose_200x200", move |bh| bh.iter(|| test::black_box(Hessenberg::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn hessenberg_decompose_500x500(bh: &mut criterion::Criterion) {
|
||||||
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.bench_function("hessenberg_decompose_500x500", move |bh| bh.iter(|| test::black_box(Hessenberg::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// With unpack.
|
// With unpack.
|
||||||
#[bench]
|
fn hessenberg_decompose_unpack_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn hessenberg_decompose_unpack_100x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
bh.iter(|| {
|
bh.bench_function("hessenberg_decompose_unpack_100x100", move |bh| bh.iter(|| {
|
||||||
let hess = Hessenberg::new(m.clone());
|
let hess = Hessenberg::new(m.clone());
|
||||||
let _ = hess.unpack();
|
let _ = hess.unpack();
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn hessenberg_decompose_unpack_200x200(bh: &mut criterion::Criterion) {
|
||||||
fn hessenberg_decompose_unpack_200x200(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(200, 200);
|
let m = DMatrix::<f64>::new_random(200, 200);
|
||||||
bh.iter(|| {
|
bh.bench_function("hessenberg_decompose_unpack_200x200", move |bh| bh.iter(|| {
|
||||||
let hess = Hessenberg::new(m.clone());
|
let hess = Hessenberg::new(m.clone());
|
||||||
let _ = hess.unpack();
|
let _ = hess.unpack();
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn hessenberg_decompose_unpack_500x500(bh: &mut criterion::Criterion) {
|
||||||
fn hessenberg_decompose_unpack_500x500(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
bh.iter(|| {
|
bh.bench_function("hessenberg_decompose_unpack_500x500", move |bh| bh.iter(|| {
|
||||||
let hess = Hessenberg::new(m.clone());
|
let hess = Hessenberg::new(m.clone());
|
||||||
let _ = hess.unpack();
|
let _ = hess.unpack();
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
criterion_group!(hessenberg,
|
||||||
|
hessenberg_decompose_4x4,
|
||||||
|
hessenberg_decompose_100x100,
|
||||||
|
hessenberg_decompose_200x200,
|
||||||
|
// hessenberg_decompose_500x500,
|
||||||
|
hessenberg_decompose_unpack_100x100,
|
||||||
|
hessenberg_decompose_unpack_200x200,
|
||||||
|
// hessenberg_decompose_unpack_500x500
|
||||||
|
);
|
|
@ -1,102 +1,102 @@
|
||||||
use na::{DMatrix, DVector, LU};
|
use na::{DMatrix, DVector, LU};
|
||||||
use test::{self, Bencher};
|
|
||||||
|
|
||||||
// Without unpack.
|
// Without unpack.
|
||||||
#[bench]
|
fn lu_decompose_10x10(bh: &mut criterion::Criterion) {
|
||||||
fn lu_decompose_10x10(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(10, 10);
|
let m = DMatrix::<f64>::new_random(10, 10);
|
||||||
bh.iter(|| test::black_box(LU::new(m.clone())))
|
bh.bench_function("lu_decompose_10x10", move |bh| bh.iter(|| test::black_box(LU::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn lu_decompose_100x100(bh: &mut criterion::Criterion) {
|
||||||
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.bench_function("lu_decompose_100x100", move |bh| bh.iter(|| test::black_box(LU::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn lu_decompose_500x500(bh: &mut criterion::Criterion) {
|
||||||
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.bench_function("lu_decompose_500x500", move |bh| bh.iter(|| test::black_box(LU::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn lu_solve_10x10(bh: &mut criterion::Criterion) {
|
||||||
fn lu_solve_10x10(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(10, 10);
|
let m = DMatrix::<f64>::new_random(10, 10);
|
||||||
let lu = LU::new(m.clone());
|
let lu = LU::new(m.clone());
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("lu_solve_10x10", move |bh| bh.iter(|| {
|
||||||
let mut b = DVector::<f64>::from_element(10, 1.0);
|
let mut b = DVector::<f64>::from_element(10, 1.0);
|
||||||
lu.solve(&mut b);
|
lu.solve(&mut b);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn lu_solve_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn lu_solve_100x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
let lu = LU::new(m.clone());
|
let lu = LU::new(m.clone());
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("lu_solve_100x100", move |bh| bh.iter(|| {
|
||||||
let mut b = DVector::<f64>::from_element(100, 1.0);
|
let mut b = DVector::<f64>::from_element(100, 1.0);
|
||||||
lu.solve(&mut b);
|
lu.solve(&mut b);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn lu_solve_500x500(bh: &mut criterion::Criterion) {
|
||||||
fn lu_solve_500x500(bh: &mut Bencher) {
|
|
||||||
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.iter(|| {
|
bh.bench_function("", move |bh| bh.iter(|| {
|
||||||
let mut b = DVector::<f64>::from_element(500, 1.0);
|
let mut b = DVector::<f64>::from_element(500, 1.0);
|
||||||
lu.solve(&mut b);
|
lu.solve(&mut b);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn lu_inverse_10x10(bh: &mut criterion::Criterion) {
|
||||||
fn lu_inverse_10x10(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(10, 10);
|
let m = DMatrix::<f64>::new_random(10, 10);
|
||||||
let lu = LU::new(m.clone());
|
let lu = LU::new(m.clone());
|
||||||
|
|
||||||
bh.iter(|| test::black_box(lu.try_inverse()))
|
bh.bench_function("lu_inverse_10x10", move |bh| bh.iter(|| test::black_box(lu.try_inverse())));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn lu_inverse_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn lu_inverse_100x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
let lu = LU::new(m.clone());
|
let lu = LU::new(m.clone());
|
||||||
|
|
||||||
bh.iter(|| test::black_box(lu.try_inverse()))
|
bh.bench_function("lu_inverse_100x100", move |bh| bh.iter(|| test::black_box(lu.try_inverse())));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn lu_inverse_500x500(bh: &mut criterion::Criterion) {
|
||||||
fn lu_inverse_500x500(bh: &mut Bencher) {
|
|
||||||
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.iter(|| test::black_box(lu.try_inverse()))
|
bh.bench_function("lu_inverse_500x500", move |bh| bh.iter(|| test::black_box(lu.try_inverse())));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn lu_determinant_10x10(bh: &mut criterion::Criterion) {
|
||||||
fn lu_determinant_10x10(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(10, 10);
|
let m = DMatrix::<f64>::new_random(10, 10);
|
||||||
let lu = LU::new(m.clone());
|
let lu = LU::new(m.clone());
|
||||||
|
|
||||||
bh.iter(|| test::black_box(lu.determinant()))
|
bh.bench_function("lu_determinant_10x10", move |bh| bh.iter(|| test::black_box(lu.determinant())));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn lu_determinant_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn lu_determinant_100x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
let lu = LU::new(m.clone());
|
let lu = LU::new(m.clone());
|
||||||
|
|
||||||
bh.iter(|| test::black_box(lu.determinant()))
|
bh.bench_function("lu_determinant_100x100", move |bh| bh.iter(|| test::black_box(lu.determinant())));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn lu_determinant_500x500(bh: &mut criterion::Criterion) {
|
||||||
fn lu_determinant_500x500(bh: &mut Bencher) {
|
|
||||||
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.iter(|| test::black_box(lu.determinant()))
|
bh.bench_function("", move |bh| bh.iter(|| test::black_box(lu.determinant())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
criterion_group!(lu,
|
||||||
|
lu_decompose_10x10,
|
||||||
|
lu_decompose_100x100,
|
||||||
|
// lu_decompose_500x500,
|
||||||
|
lu_solve_10x10,
|
||||||
|
lu_solve_100x100,
|
||||||
|
lu_inverse_10x10,
|
||||||
|
lu_inverse_100x100,
|
||||||
|
// lu_inverse_500x500,
|
||||||
|
lu_determinant_10x10,
|
||||||
|
lu_determinant_100x100
|
||||||
|
);
|
|
@ -1,3 +1,14 @@
|
||||||
|
pub use self::bidiagonal::bidiagonal;
|
||||||
|
pub use self::cholesky::cholesky;
|
||||||
|
pub use self::full_piv_lu::full_piv_lu;
|
||||||
|
pub use self::hessenberg::hessenberg;
|
||||||
|
pub use self::lu::lu;
|
||||||
|
pub use self::qr::qr;
|
||||||
|
pub use self::schur::schur;
|
||||||
|
pub use self::solve::solve;
|
||||||
|
pub use self::svd::svd;
|
||||||
|
pub use self::symmetric_eigen::symmetric_eigen;
|
||||||
|
|
||||||
mod bidiagonal;
|
mod bidiagonal;
|
||||||
mod cholesky;
|
mod cholesky;
|
||||||
mod full_piv_lu;
|
mod full_piv_lu;
|
||||||
|
@ -8,4 +19,4 @@ mod schur;
|
||||||
mod solve;
|
mod solve;
|
||||||
mod svd;
|
mod svd;
|
||||||
mod symmetric_eigen;
|
mod symmetric_eigen;
|
||||||
// mod eigen;
|
// mod eigen;
|
|
@ -1,130 +1,133 @@
|
||||||
use na::{DMatrix, DVector, Matrix4, QR};
|
use na::{DMatrix, DVector, Matrix4, QR};
|
||||||
use test::{self, Bencher};
|
|
||||||
|
|
||||||
#[path = "../common/macros.rs"]
|
#[path = "../common/macros.rs"]
|
||||||
mod macros;
|
mod macros;
|
||||||
|
|
||||||
// Without unpack.
|
// Without unpack.
|
||||||
#[bench]
|
fn qr_decompose_100x100(bh: &mut criterion::Criterion) {
|
||||||
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.bench_function("qr_decompose_100x100", move |bh| bh.iter(|| test::black_box(QR::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn qr_decompose_100x500(bh: &mut criterion::Criterion) {
|
||||||
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.bench_function("qr_decompose_100x500", move |bh| bh.iter(|| test::black_box(QR::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn qr_decompose_4x4(bh: &mut criterion::Criterion) {
|
||||||
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.bench_function("qr_decompose_4x4", move |bh| bh.iter(|| test::black_box(QR::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn qr_decompose_500x100(bh: &mut criterion::Criterion) {
|
||||||
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.bench_function("qr_decompose_500x100", move |bh| bh.iter(|| test::black_box(QR::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn qr_decompose_500x500(bh: &mut criterion::Criterion) {
|
||||||
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.bench_function("qr_decompose_500x500", move |bh| bh.iter(|| test::black_box(QR::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// With unpack.
|
// With unpack.
|
||||||
#[bench]
|
fn qr_decompose_unpack_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn qr_decompose_unpack_100x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
bh.iter(|| {
|
bh.bench_function("qr_decompose_unpack_100x100", move |bh| bh.iter(|| {
|
||||||
let qr = QR::new(m.clone());
|
let qr = QR::new(m.clone());
|
||||||
let _ = qr.unpack();
|
let _ = qr.unpack();
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn qr_decompose_unpack_100x500(bh: &mut criterion::Criterion) {
|
||||||
fn qr_decompose_unpack_100x500(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 500);
|
let m = DMatrix::<f64>::new_random(100, 500);
|
||||||
bh.iter(|| {
|
bh.bench_function("qr_decompose_unpack_100x500", move |bh| bh.iter(|| {
|
||||||
let qr = QR::new(m.clone());
|
let qr = QR::new(m.clone());
|
||||||
let _ = qr.unpack();
|
let _ = qr.unpack();
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn qr_decompose_unpack_500x100(bh: &mut criterion::Criterion) {
|
||||||
fn qr_decompose_unpack_500x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(500, 100);
|
let m = DMatrix::<f64>::new_random(500, 100);
|
||||||
bh.iter(|| {
|
bh.bench_function("qr_decompose_unpack_500x100", move |bh| bh.iter(|| {
|
||||||
let qr = QR::new(m.clone());
|
let qr = QR::new(m.clone());
|
||||||
let _ = qr.unpack();
|
let _ = qr.unpack();
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn qr_decompose_unpack_500x500(bh: &mut criterion::Criterion) {
|
||||||
fn qr_decompose_unpack_500x500(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
bh.iter(|| {
|
bh.bench_function("qr_decompose_unpack_500x500", move |bh| bh.iter(|| {
|
||||||
let qr = QR::new(m.clone());
|
let qr = QR::new(m.clone());
|
||||||
let _ = qr.unpack();
|
let _ = qr.unpack();
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn qr_solve_10x10(bh: &mut criterion::Criterion) {
|
||||||
fn qr_solve_10x10(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(10, 10);
|
let m = DMatrix::<f64>::new_random(10, 10);
|
||||||
let qr = QR::new(m.clone());
|
let qr = QR::new(m.clone());
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("qr_solve_10x10", move |bh| bh.iter(|| {
|
||||||
let mut b = DVector::<f64>::from_element(10, 1.0);
|
let mut b = DVector::<f64>::from_element(10, 1.0);
|
||||||
qr.solve(&mut b);
|
qr.solve(&mut b);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn qr_solve_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn qr_solve_100x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
let qr = QR::new(m.clone());
|
let qr = QR::new(m.clone());
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("qr_solve_100x100", move |bh| bh.iter(|| {
|
||||||
let mut b = DVector::<f64>::from_element(100, 1.0);
|
let mut b = DVector::<f64>::from_element(100, 1.0);
|
||||||
qr.solve(&mut b);
|
qr.solve(&mut b);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn qr_solve_500x500(bh: &mut criterion::Criterion) {
|
||||||
fn qr_solve_500x500(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
let qr = QR::new(m.clone());
|
let qr = QR::new(m.clone());
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("qr_solve_500x500", move |bh| bh.iter(|| {
|
||||||
let mut b = DVector::<f64>::from_element(500, 1.0);
|
let mut b = DVector::<f64>::from_element(500, 1.0);
|
||||||
qr.solve(&mut b);
|
qr.solve(&mut b);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn qr_inverse_10x10(bh: &mut criterion::Criterion) {
|
||||||
fn qr_inverse_10x10(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(10, 10);
|
let m = DMatrix::<f64>::new_random(10, 10);
|
||||||
let qr = QR::new(m.clone());
|
let qr = QR::new(m.clone());
|
||||||
|
|
||||||
bh.iter(|| test::black_box(qr.try_inverse()))
|
bh.bench_function("qr_inverse_10x10", move |bh| bh.iter(|| test::black_box(qr.try_inverse())));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn qr_inverse_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn qr_inverse_100x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
let qr = QR::new(m.clone());
|
let qr = QR::new(m.clone());
|
||||||
|
|
||||||
bh.iter(|| test::black_box(qr.try_inverse()))
|
bh.bench_function("qr_inverse_100x100", move |bh| bh.iter(|| test::black_box(qr.try_inverse())));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn qr_inverse_500x500(bh: &mut criterion::Criterion) {
|
||||||
fn qr_inverse_500x500(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(500, 500);
|
let m = DMatrix::<f64>::new_random(500, 500);
|
||||||
let qr = QR::new(m.clone());
|
let qr = QR::new(m.clone());
|
||||||
|
|
||||||
bh.iter(|| test::black_box(qr.try_inverse()))
|
bh.bench_function("qr_inverse_500x500", move |bh| bh.iter(|| test::black_box(qr.try_inverse())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
criterion_group!(qr,
|
||||||
|
qr_decompose_100x100,
|
||||||
|
qr_decompose_100x500,
|
||||||
|
qr_decompose_4x4,
|
||||||
|
qr_decompose_500x100,
|
||||||
|
// qr_decompose_500x500,
|
||||||
|
qr_decompose_unpack_100x100,
|
||||||
|
qr_decompose_unpack_100x500,
|
||||||
|
qr_decompose_unpack_500x100,
|
||||||
|
// qr_decompose_unpack_500x500,
|
||||||
|
qr_solve_10x10,
|
||||||
|
qr_solve_100x100,
|
||||||
|
// qr_solve_500x500,
|
||||||
|
qr_inverse_10x10,
|
||||||
|
qr_inverse_100x100,
|
||||||
|
// qr_inverse_500x500
|
||||||
|
);
|
|
@ -1,50 +1,52 @@
|
||||||
use na::{Matrix4, RealSchur};
|
use na::{Matrix4, Schur};
|
||||||
use test::{self, Bencher};
|
|
||||||
|
|
||||||
#[bench]
|
fn schur_decompose_4x4(bh: &mut criterion::Criterion) {
|
||||||
fn schur_decompose_4x4(bh: &mut Bencher) {
|
|
||||||
let m = Matrix4::<f64>::new_random();
|
let m = Matrix4::<f64>::new_random();
|
||||||
bh.iter(|| test::black_box(RealSchur::new(m.clone())))
|
bh.bench_function("schur_decompose_4x4", move |bh| bh.iter(|| test::black_box(Schur::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn schur_decompose_10x10(bh: &mut criterion::Criterion) {
|
||||||
fn schur_decompose_10x10(bh: &mut Bencher) {
|
let m = crate::reproductible_dmatrix(10, 10);
|
||||||
let m = ::reproductible_dmatrix(10, 10);
|
bh.bench_function("schur_decompose_10x10", move |bh| bh.iter(|| test::black_box(Schur::new(m.clone()))));
|
||||||
bh.iter(|| test::black_box(RealSchur::new(m.clone())))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn schur_decompose_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn schur_decompose_100x100(bh: &mut Bencher) {
|
let m = crate::reproductible_dmatrix(100, 100);
|
||||||
let m = ::reproductible_dmatrix(100, 100);
|
bh.bench_function("schur_decompose_100x100", move |bh| bh.iter(|| test::black_box(Schur::new(m.clone()))));
|
||||||
bh.iter(|| test::black_box(RealSchur::new(m.clone())))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn schur_decompose_200x200(bh: &mut criterion::Criterion) {
|
||||||
fn schur_decompose_200x200(bh: &mut Bencher) {
|
let m = crate::reproductible_dmatrix(200, 200);
|
||||||
let m = ::reproductible_dmatrix(200, 200);
|
bh.bench_function("schur_decompose_200x200", move |bh| bh.iter(|| test::black_box(Schur::new(m.clone()))));
|
||||||
bh.iter(|| test::black_box(RealSchur::new(m.clone())))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn eigenvalues_4x4(bh: &mut criterion::Criterion) {
|
||||||
fn eigenvalues_4x4(bh: &mut Bencher) {
|
|
||||||
let m = Matrix4::<f64>::new_random();
|
let m = Matrix4::<f64>::new_random();
|
||||||
bh.iter(|| test::black_box(m.complex_eigenvalues()))
|
bh.bench_function("eigenvalues_4x4", move |bh| bh.iter(|| test::black_box(m.complex_eigenvalues())));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn eigenvalues_10x10(bh: &mut criterion::Criterion) {
|
||||||
fn eigenvalues_10x10(bh: &mut Bencher) {
|
let m = crate::reproductible_dmatrix(10, 10);
|
||||||
let m = ::reproductible_dmatrix(10, 10);
|
bh.bench_function("eigenvalues_10x10", move |bh| bh.iter(|| test::black_box(m.complex_eigenvalues())));
|
||||||
bh.iter(|| test::black_box(m.complex_eigenvalues()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn eigenvalues_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn eigenvalues_100x100(bh: &mut Bencher) {
|
let m = crate::reproductible_dmatrix(100, 100);
|
||||||
let m = ::reproductible_dmatrix(100, 100);
|
bh.bench_function("eigenvalues_100x100", move |bh| bh.iter(|| test::black_box(m.complex_eigenvalues())));
|
||||||
bh.iter(|| test::black_box(m.complex_eigenvalues()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn eigenvalues_200x200(bh: &mut criterion::Criterion) {
|
||||||
fn eigenvalues_200x200(bh: &mut Bencher) {
|
let m = crate::reproductible_dmatrix(200, 200);
|
||||||
let m = ::reproductible_dmatrix(200, 200);
|
bh.bench_function("eigenvalues_200x200", move |bh| bh.iter(|| test::black_box(m.complex_eigenvalues())));
|
||||||
bh.iter(|| test::black_box(m.complex_eigenvalues()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
criterion_group!(schur,
|
||||||
|
schur_decompose_4x4,
|
||||||
|
schur_decompose_10x10,
|
||||||
|
schur_decompose_100x100,
|
||||||
|
schur_decompose_200x200,
|
||||||
|
eigenvalues_4x4,
|
||||||
|
eigenvalues_10x10,
|
||||||
|
eigenvalues_100x100,
|
||||||
|
eigenvalues_200x200
|
||||||
|
);
|
|
@ -1,82 +1,85 @@
|
||||||
use na::{DMatrix, DVector};
|
use na::{DMatrix, DVector};
|
||||||
use test::Bencher;
|
|
||||||
|
|
||||||
#[bench]
|
fn solve_l_triangular_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn solve_l_triangular_100x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
let v = DVector::<f64>::new_random(100);
|
let v = DVector::<f64>::new_random(100);
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("solve_l_triangular_100x100", move |bh| bh.iter(|| {
|
||||||
let _ = m.solve_lower_triangular(&v);
|
let _ = m.solve_lower_triangular(&v);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn solve_l_triangular_1000x1000(bh: &mut criterion::Criterion) {
|
||||||
fn solve_l_triangular_1000x1000(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(1000, 1000);
|
let m = DMatrix::<f64>::new_random(1000, 1000);
|
||||||
let v = DVector::<f64>::new_random(1000);
|
let v = DVector::<f64>::new_random(1000);
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("solve_l_triangular_1000x1000", move |bh| bh.iter(|| {
|
||||||
let _ = m.solve_lower_triangular(&v);
|
let _ = m.solve_lower_triangular(&v);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn tr_solve_l_triangular_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn tr_solve_l_triangular_100x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
let v = DVector::<f64>::new_random(100);
|
let v = DVector::<f64>::new_random(100);
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("tr_solve_l_triangular_100x100", move |bh| bh.iter(|| {
|
||||||
let _ = m.tr_solve_lower_triangular(&v);
|
let _ = m.tr_solve_lower_triangular(&v);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn tr_solve_l_triangular_1000x1000(bh: &mut criterion::Criterion) {
|
||||||
fn tr_solve_l_triangular_1000x1000(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(1000, 1000);
|
let m = DMatrix::<f64>::new_random(1000, 1000);
|
||||||
let v = DVector::<f64>::new_random(1000);
|
let v = DVector::<f64>::new_random(1000);
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("tr_solve_l_triangular_1000x1000", move |bh| bh.iter(|| {
|
||||||
let _ = m.tr_solve_lower_triangular(&v);
|
let _ = m.tr_solve_lower_triangular(&v);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn solve_u_triangular_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn solve_u_triangular_100x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
let v = DVector::<f64>::new_random(100);
|
let v = DVector::<f64>::new_random(100);
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("solve_u_triangular_100x100", move |bh| bh.iter(|| {
|
||||||
let _ = m.solve_upper_triangular(&v);
|
let _ = m.solve_upper_triangular(&v);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn solve_u_triangular_1000x1000(bh: &mut criterion::Criterion) {
|
||||||
fn solve_u_triangular_1000x1000(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(1000, 1000);
|
let m = DMatrix::<f64>::new_random(1000, 1000);
|
||||||
let v = DVector::<f64>::new_random(1000);
|
let v = DVector::<f64>::new_random(1000);
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("solve_u_triangular_1000x1000", move |bh| bh.iter(|| {
|
||||||
let _ = m.solve_upper_triangular(&v);
|
let _ = m.solve_upper_triangular(&v);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn tr_solve_u_triangular_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn tr_solve_u_triangular_100x100(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(100, 100);
|
let m = DMatrix::<f64>::new_random(100, 100);
|
||||||
let v = DVector::<f64>::new_random(100);
|
let v = DVector::<f64>::new_random(100);
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("tr_solve_u_triangular_100x100", move |bh| bh.iter(|| {
|
||||||
let _ = m.tr_solve_upper_triangular(&v);
|
let _ = m.tr_solve_upper_triangular(&v);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn tr_solve_u_triangular_1000x1000(bh: &mut criterion::Criterion) {
|
||||||
fn tr_solve_u_triangular_1000x1000(bh: &mut Bencher) {
|
|
||||||
let m = DMatrix::<f64>::new_random(1000, 1000);
|
let m = DMatrix::<f64>::new_random(1000, 1000);
|
||||||
let v = DVector::<f64>::new_random(1000);
|
let v = DVector::<f64>::new_random(1000);
|
||||||
|
|
||||||
bh.iter(|| {
|
bh.bench_function("tr_solve_u_triangular_1000x1000", move |bh| bh.iter(|| {
|
||||||
let _ = m.tr_solve_upper_triangular(&v);
|
let _ = m.tr_solve_upper_triangular(&v);
|
||||||
})
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
criterion_group!(solve,
|
||||||
|
solve_l_triangular_100x100,
|
||||||
|
solve_l_triangular_1000x1000,
|
||||||
|
tr_solve_l_triangular_100x100,
|
||||||
|
tr_solve_l_triangular_1000x1000,
|
||||||
|
solve_u_triangular_100x100,
|
||||||
|
solve_u_triangular_1000x1000,
|
||||||
|
tr_solve_u_triangular_100x100,
|
||||||
|
tr_solve_u_triangular_1000x1000
|
||||||
|
);
|
|
@ -1,98 +1,101 @@
|
||||||
use na::{Matrix4, SVD};
|
use na::{Matrix4, SVD};
|
||||||
use test::{self, Bencher};
|
|
||||||
|
|
||||||
#[bench]
|
fn svd_decompose_4x4(bh: &mut criterion::Criterion) {
|
||||||
fn svd_decompose_4x4(bh: &mut Bencher) {
|
|
||||||
let m = Matrix4::<f64>::new_random();
|
let m = Matrix4::<f64>::new_random();
|
||||||
bh.iter(|| test::black_box(SVD::new(m.clone(), true, true)))
|
bh.bench_function("svd_decompose_4x4", move |bh| bh.iter(|| test::black_box(SVD::new(m.clone(), true, true))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn svd_decompose_10x10(bh: &mut criterion::Criterion) {
|
||||||
fn svd_decompose_10x10(bh: &mut Bencher) {
|
let m = crate::reproductible_dmatrix(10, 10);
|
||||||
let m = ::reproductible_dmatrix(10, 10);
|
bh.bench_function("svd_decompose_10x10", move |bh| bh.iter(|| test::black_box(SVD::new(m.clone(), true, true))));
|
||||||
bh.iter(|| test::black_box(SVD::new(m.clone(), true, true)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn svd_decompose_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn svd_decompose_100x100(bh: &mut Bencher) {
|
let m = crate::reproductible_dmatrix(100, 100);
|
||||||
let m = ::reproductible_dmatrix(100, 100);
|
bh.bench_function("svd_decompose_100x100", move |bh| bh.iter(|| test::black_box(SVD::new(m.clone(), true, true))));
|
||||||
bh.iter(|| test::black_box(SVD::new(m.clone(), true, true)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn svd_decompose_200x200(bh: &mut criterion::Criterion) {
|
||||||
fn svd_decompose_200x200(bh: &mut Bencher) {
|
let m = crate::reproductible_dmatrix(200, 200);
|
||||||
let m = ::reproductible_dmatrix(200, 200);
|
bh.bench_function("svd_decompose_200x200", move |bh| bh.iter(|| test::black_box(SVD::new(m.clone(), true, true))));
|
||||||
bh.iter(|| test::black_box(SVD::new(m.clone(), true, true)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn rank_4x4(bh: &mut criterion::Criterion) {
|
||||||
fn rank_4x4(bh: &mut Bencher) {
|
|
||||||
let m = Matrix4::<f64>::new_random();
|
let m = Matrix4::<f64>::new_random();
|
||||||
bh.iter(|| test::black_box(m.rank(1.0e-10)))
|
bh.bench_function("rank_4x4", move |bh| bh.iter(|| test::black_box(m.rank(1.0e-10))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn rank_10x10(bh: &mut criterion::Criterion) {
|
||||||
fn rank_10x10(bh: &mut Bencher) {
|
let m = crate::reproductible_dmatrix(10, 10);
|
||||||
let m = ::reproductible_dmatrix(10, 10);
|
bh.bench_function("rank_10x10", move |bh| bh.iter(|| test::black_box(m.rank(1.0e-10))));
|
||||||
bh.iter(|| test::black_box(m.rank(1.0e-10)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn rank_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn rank_100x100(bh: &mut Bencher) {
|
let m = crate::reproductible_dmatrix(100, 100);
|
||||||
let m = ::reproductible_dmatrix(100, 100);
|
bh.bench_function("rank_100x100", move |bh| bh.iter(|| test::black_box(m.rank(1.0e-10))));
|
||||||
bh.iter(|| test::black_box(m.rank(1.0e-10)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn rank_200x200(bh: &mut criterion::Criterion) {
|
||||||
fn rank_200x200(bh: &mut Bencher) {
|
let m = crate::reproductible_dmatrix(200, 200);
|
||||||
let m = ::reproductible_dmatrix(200, 200);
|
bh.bench_function("rank_200x200", move |bh| bh.iter(|| test::black_box(m.rank(1.0e-10))));
|
||||||
bh.iter(|| test::black_box(m.rank(1.0e-10)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn singular_values_4x4(bh: &mut criterion::Criterion) {
|
||||||
fn singular_values_4x4(bh: &mut Bencher) {
|
|
||||||
let m = Matrix4::<f64>::new_random();
|
let m = Matrix4::<f64>::new_random();
|
||||||
bh.iter(|| test::black_box(m.singular_values()))
|
bh.bench_function("singular_values_4x4", move |bh| bh.iter(|| test::black_box(m.singular_values())));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn singular_values_10x10(bh: &mut criterion::Criterion) {
|
||||||
fn singular_values_10x10(bh: &mut Bencher) {
|
let m = crate::reproductible_dmatrix(10, 10);
|
||||||
let m = ::reproductible_dmatrix(10, 10);
|
bh.bench_function("singular_values_10x10", move |bh| bh.iter(|| test::black_box(m.singular_values())));
|
||||||
bh.iter(|| test::black_box(m.singular_values()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn singular_values_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn singular_values_100x100(bh: &mut Bencher) {
|
let m = crate::reproductible_dmatrix(100, 100);
|
||||||
let m = ::reproductible_dmatrix(100, 100);
|
bh.bench_function("singular_values_100x100", move |bh| bh.iter(|| test::black_box(m.singular_values())));
|
||||||
bh.iter(|| test::black_box(m.singular_values()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn singular_values_200x200(bh: &mut criterion::Criterion) {
|
||||||
fn singular_values_200x200(bh: &mut Bencher) {
|
let m = crate::reproductible_dmatrix(200, 200);
|
||||||
let m = ::reproductible_dmatrix(200, 200);
|
bh.bench_function("singular_values_200x200", move |bh| bh.iter(|| test::black_box(m.singular_values())));
|
||||||
bh.iter(|| test::black_box(m.singular_values()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn pseudo_inverse_4x4(bh: &mut criterion::Criterion) {
|
||||||
fn pseudo_inverse_4x4(bh: &mut Bencher) {
|
|
||||||
let m = Matrix4::<f64>::new_random();
|
let m = Matrix4::<f64>::new_random();
|
||||||
bh.iter(|| test::black_box(m.clone().pseudo_inverse(1.0e-10)))
|
bh.bench_function("pseudo_inverse_4x4", move |bh| bh.iter(|| test::black_box(m.clone().pseudo_inverse(1.0e-10))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn pseudo_inverse_10x10(bh: &mut criterion::Criterion) {
|
||||||
fn pseudo_inverse_10x10(bh: &mut Bencher) {
|
let m = crate::reproductible_dmatrix(10, 10);
|
||||||
let m = ::reproductible_dmatrix(10, 10);
|
bh.bench_function("pseudo_inverse_10x10", move |bh| bh.iter(|| test::black_box(m.clone().pseudo_inverse(1.0e-10))));
|
||||||
bh.iter(|| test::black_box(m.clone().pseudo_inverse(1.0e-10)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn pseudo_inverse_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn pseudo_inverse_100x100(bh: &mut Bencher) {
|
let m = crate::reproductible_dmatrix(100, 100);
|
||||||
let m = ::reproductible_dmatrix(100, 100);
|
bh.bench_function("pseudo_inverse_100x100", move |bh| bh.iter(|| test::black_box(m.clone().pseudo_inverse(1.0e-10))));
|
||||||
bh.iter(|| test::black_box(m.clone().pseudo_inverse(1.0e-10)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn pseudo_inverse_200x200(bh: &mut criterion::Criterion) {
|
||||||
fn pseudo_inverse_200x200(bh: &mut Bencher) {
|
let m = crate::reproductible_dmatrix(200, 200);
|
||||||
let m = ::reproductible_dmatrix(200, 200);
|
bh.bench_function("pseudo_inverse_200x200", move |bh| bh.iter(|| test::black_box(m.clone().pseudo_inverse(1.0e-10))));
|
||||||
bh.iter(|| test::black_box(m.clone().pseudo_inverse(1.0e-10)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
criterion_group!(svd,
|
||||||
|
svd_decompose_4x4,
|
||||||
|
svd_decompose_10x10,
|
||||||
|
svd_decompose_100x100,
|
||||||
|
svd_decompose_200x200,
|
||||||
|
rank_4x4,
|
||||||
|
rank_10x10,
|
||||||
|
rank_100x100,
|
||||||
|
rank_200x200,
|
||||||
|
singular_values_4x4,
|
||||||
|
singular_values_10x10,
|
||||||
|
singular_values_100x100,
|
||||||
|
singular_values_200x200,
|
||||||
|
pseudo_inverse_4x4,
|
||||||
|
pseudo_inverse_10x10,
|
||||||
|
pseudo_inverse_100x100,
|
||||||
|
pseudo_inverse_200x200
|
||||||
|
);
|
|
@ -1,26 +1,28 @@
|
||||||
use na::{Matrix4, SymmetricEigen};
|
use na::{Matrix4, SymmetricEigen};
|
||||||
use test::{self, Bencher};
|
|
||||||
|
|
||||||
#[bench]
|
fn symmetric_eigen_decompose_4x4(bh: &mut criterion::Criterion) {
|
||||||
fn symmetric_eigen_decompose_4x4(bh: &mut Bencher) {
|
|
||||||
let m = Matrix4::<f64>::new_random();
|
let m = Matrix4::<f64>::new_random();
|
||||||
bh.iter(|| test::black_box(SymmetricEigen::new(m.clone())))
|
bh.bench_function("symmetric_eigen_decompose_4x4", move |bh| bh.iter(|| test::black_box(SymmetricEigen::new(m.clone()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn symmetric_eigen_decompose_10x10(bh: &mut criterion::Criterion) {
|
||||||
fn symmetric_eigen_decompose_10x10(bh: &mut Bencher) {
|
let m = crate::reproductible_dmatrix(10, 10);
|
||||||
let m = ::reproductible_dmatrix(10, 10);
|
bh.bench_function("symmetric_eigen_decompose_10x10", move |bh| bh.iter(|| test::black_box(SymmetricEigen::new(m.clone()))));
|
||||||
bh.iter(|| test::black_box(SymmetricEigen::new(m.clone())))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn symmetric_eigen_decompose_100x100(bh: &mut criterion::Criterion) {
|
||||||
fn symmetric_eigen_decompose_100x100(bh: &mut Bencher) {
|
let m = crate::reproductible_dmatrix(100, 100);
|
||||||
let m = ::reproductible_dmatrix(100, 100);
|
bh.bench_function("symmetric_eigen_decompose_100x100", move |bh| bh.iter(|| test::black_box(SymmetricEigen::new(m.clone()))));
|
||||||
bh.iter(|| test::black_box(SymmetricEigen::new(m.clone())))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
fn symmetric_eigen_decompose_200x200(bh: &mut criterion::Criterion) {
|
||||||
fn symmetric_eigen_decompose_200x200(bh: &mut Bencher) {
|
let m = crate::reproductible_dmatrix(200, 200);
|
||||||
let m = ::reproductible_dmatrix(200, 200);
|
bh.bench_function("symmetric_eigen_decompose_200x200", move |bh| bh.iter(|| test::black_box(SymmetricEigen::new(m.clone()))));
|
||||||
bh.iter(|| test::black_box(SymmetricEigen::new(m.clone())))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
criterion_group!(symmetric_eigen,
|
||||||
|
symmetric_eigen_decompose_4x4,
|
||||||
|
symmetric_eigen_decompose_10x10,
|
||||||
|
symmetric_eigen_decompose_100x100,
|
||||||
|
symmetric_eigen_decompose_200x200
|
||||||
|
);
|
||||||
|
|
|
@ -6,7 +6,7 @@ if [ -z "$NO_STD" ]; then
|
||||||
if [ -z "$LAPACK" ]; then
|
if [ -z "$LAPACK" ]; then
|
||||||
cargo test --verbose;
|
cargo test --verbose;
|
||||||
cargo test --verbose "arbitrary";
|
cargo test --verbose "arbitrary";
|
||||||
cargo test --verbose "debug arbitrary mint serde-serialize abomonation-serialize";
|
cargo test --verbose --all-features;
|
||||||
cd nalgebra-glm; cargo test --verbose;
|
cd nalgebra-glm; cargo test --verbose;
|
||||||
else
|
else
|
||||||
cd nalgebra-lapack; cargo test --verbose;
|
cd nalgebra-lapack; cargo test --verbose;
|
||||||
|
|
|
@ -4,7 +4,7 @@ extern crate nalgebra as na;
|
||||||
use alga::linear::FiniteDimInnerSpace;
|
use alga::linear::FiniteDimInnerSpace;
|
||||||
use na::allocator::Allocator;
|
use na::allocator::Allocator;
|
||||||
use na::dimension::Dim;
|
use na::dimension::Dim;
|
||||||
use na::{DefaultAllocator, Real, Unit, Vector2, Vector3, VectorN};
|
use na::{DefaultAllocator, RealField, Unit, Vector2, Vector3, VectorN};
|
||||||
|
|
||||||
/// 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_algebraic_genericity<V>(plane_normal: &Unit<V>, vector: &V) -> V
|
fn reflect_wrt_hyperplane_with_algebraic_genericity<V>(plane_normal: &Unit<V>, vector: &V) -> V
|
||||||
|
@ -14,12 +14,12 @@ where V: FiniteDimInnerSpace + Copy {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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: Real, D: Dim>(
|
fn reflect_wrt_hyperplane_with_dimensional_genericity<N: RealField, D: Dim>(
|
||||||
plane_normal: &Unit<VectorN<N, D>>,
|
plane_normal: &Unit<VectorN<N, D>>,
|
||||||
vector: &VectorN<N, D>,
|
vector: &VectorN<N, D>,
|
||||||
) -> VectorN<N, D>
|
) -> VectorN<N, D>
|
||||||
where
|
where
|
||||||
N: Real,
|
N: RealField,
|
||||||
D: Dim,
|
D: Dim,
|
||||||
DefaultAllocator: Allocator<N, D>,
|
DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
|
@ -29,7 +29,7 @@ where
|
||||||
|
|
||||||
/// 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<N>(plane_normal: &Unit<Vector2<N>>, vector: &Vector2<N>) -> Vector2<N>
|
||||||
where N: Real {
|
where N: 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))
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ where N: Real {
|
||||||
/// 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<N>(plane_normal: &Unit<Vector3<N>>, vector: &Vector3<N>) -> Vector3<N>
|
||||||
where N: Real {
|
where N: 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))
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,4 +36,4 @@ fn main() {
|
||||||
// They both return the same result.
|
// They both return the same result.
|
||||||
assert!(result1 == Vector3::new(100001.0, 200002.0, 300003.0));
|
assert!(result1 == Vector3::new(100001.0, 200002.0, 300003.0));
|
||||||
assert!(result2 == Vector3::new(100001.0, 200002.0, 300003.0));
|
assert!(result2 == Vector3::new(100001.0, 200002.0, 300003.0));
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
extern crate alga;
|
extern crate alga;
|
||||||
extern crate nalgebra as na;
|
extern crate nalgebra as na;
|
||||||
|
|
||||||
use alga::general::{Real, RingCommutative};
|
use alga::general::{RealField, RingCommutative};
|
||||||
use na::{Scalar, Vector3};
|
use na::{Scalar, Vector3};
|
||||||
|
|
||||||
fn print_vector<N: Scalar>(m: &Vector3<N>) {
|
fn print_vector<N: Scalar>(m: &Vector3<N>) {
|
||||||
|
@ -14,11 +14,11 @@ fn print_squared_norm<N: Scalar + RingCommutative>(v: &Vector3<N>) {
|
||||||
println!("{:?}", sqnorm);
|
println!("{:?}", sqnorm);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_norm<N: Real>(v: &Vector3<N>) {
|
fn print_norm<N: RealField>(v: &Vector3<N>) {
|
||||||
// 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 Real bound implies that N is Display so we can
|
// The RealField bound implies that N 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.3.0"
|
version = "0.4.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."
|
||||||
|
@ -11,6 +11,7 @@ readme = "../README.md"
|
||||||
categories = [ "science" ]
|
categories = [ "science" ]
|
||||||
keywords = [ "linear", "algebra", "matrix", "vector", "math" ]
|
keywords = [ "linear", "algebra", "matrix", "vector", "math" ]
|
||||||
license = "BSD-3-Clause"
|
license = "BSD-3-Clause"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = [ "std" ]
|
default = [ "std" ]
|
||||||
|
@ -23,5 +24,5 @@ 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.3", default-features = false }
|
approx = { version = "0.3", default-features = false }
|
||||||
alga = { version = "0.8", default-features = false }
|
alga = { version = "0.9", default-features = false }
|
||||||
nalgebra = { path = "..", version = "0.17", default-features = false }
|
nalgebra = { path = "..", version = "0.18", default-features = false }
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use na::{self, DefaultAllocator, Real};
|
use na::{self, DefaultAllocator, RealField};
|
||||||
use num::FromPrimitive;
|
use num::FromPrimitive;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
use aliases::{TMat, TVec};
|
use crate::aliases::{TMat, TVec};
|
||||||
use traits::{Alloc, Dimension, Number};
|
use crate::traits::{Alloc, Dimension, 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`.
|
||||||
///
|
///
|
||||||
|
@ -43,7 +43,7 @@ where DefaultAllocator: Alloc<N, R, C> {
|
||||||
/// * [`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: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn ceil<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
x.map(|x| x.ceil())
|
x.map(|x| x.ceil())
|
||||||
}
|
}
|
||||||
|
@ -222,7 +222,7 @@ where DefaultAllocator: Alloc<f32, D> {
|
||||||
/// * [`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: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn floor<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
x.map(|x| x.floor())
|
x.map(|x| x.floor())
|
||||||
}
|
}
|
||||||
|
@ -249,14 +249,14 @@ where DefaultAllocator: Alloc<N, D> {
|
||||||
/// * [`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: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn fract<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
x.map(|x| x.fract())
|
x.map(|x| x.fract())
|
||||||
}
|
}
|
||||||
|
|
||||||
//// FIXME: should be implemented for TVec/TMat?
|
//// FIXME: 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: Real>(x: N, exp: N) -> (N, N) {
|
//pub fn frexp<N: RealField>(x: N, exp: N) -> (N, N) {
|
||||||
// // FIXME: is there a better approach?
|
// // FIXME: is there a better approach?
|
||||||
// let e = x.log2().ceil();
|
// let e = x.log2().ceil();
|
||||||
// (x * (-e).exp2(), e)
|
// (x * (-e).exp2(), e)
|
||||||
|
@ -310,7 +310,7 @@ where DefaultAllocator: Alloc<f32, D> {
|
||||||
//}
|
//}
|
||||||
|
|
||||||
///// Returns the (significant, exponent) of this float number.
|
///// Returns the (significant, exponent) of this float number.
|
||||||
//pub fn ldexp<N: Real>(x: N, exp: N) -> N {
|
//pub fn ldexp<N: RealField>(x: N, exp: N) -> N {
|
||||||
// // FIXME: is there a better approach?
|
// // FIXME: is there a better approach?
|
||||||
// x * (exp).exp2()
|
// x * (exp).exp2()
|
||||||
//}
|
//}
|
||||||
|
@ -499,7 +499,7 @@ 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: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn round<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
x.map(|x| x.round())
|
x.map(|x| x.round())
|
||||||
}
|
}
|
||||||
|
@ -576,7 +576,7 @@ where DefaultAllocator: Alloc<N, D> {
|
||||||
/// * [`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: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn trunc<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
x.map(|x| x.trunc())
|
x.map(|x| x.trunc())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#![cfg_attr(rustfmt, rustfmt_skip)]
|
#![cfg_attr(rustfmt, rustfmt_skip)]
|
||||||
|
|
||||||
use na::{Scalar, Real, U2, U3, U4};
|
use na::{Scalar, RealField, U2, U3, U4};
|
||||||
use aliases::{TMat, Qua, TVec1, TVec2, TVec3, TVec4, TMat2, TMat2x3, TMat2x4, TMat3, TMat3x2, TMat3x4,
|
use crate::aliases::{TMat, Qua, TVec1, TVec2, TVec3, TVec4, TMat2, TMat2x3, TMat2x4, TMat3, TMat3x2, TMat3x4,
|
||||||
TMat4, TMat4x2, TMat4x3};
|
TMat4, TMat4x2, TMat4x3};
|
||||||
|
|
||||||
|
|
||||||
|
@ -168,6 +168,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: Real>(x: N, y: N, z: N, w: N) -> Qua<N> {
|
pub fn quat<N: RealField>(x: N, y: N, z: N, w: N) -> Qua<N> {
|
||||||
Qua::new(w, x, y, z)
|
Qua::new(w, x, y, z)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
use aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
use na::{DefaultAllocator, Real};
|
use na::{DefaultAllocator, RealField};
|
||||||
use traits::{Alloc, Dimension};
|
use crate::traits::{Alloc, Dimension};
|
||||||
|
|
||||||
/// Component-wise exponential.
|
/// Component-wise exponential.
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`exp2`](fn.exp2.html)
|
/// * [`exp2`](fn.exp2.html)
|
||||||
pub fn exp<N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
pub fn exp<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
v.map(|x| x.exp())
|
v.map(|x| x.exp())
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ where DefaultAllocator: Alloc<N, D> {
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`exp`](fn.exp.html)
|
/// * [`exp`](fn.exp.html)
|
||||||
pub fn exp2<N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
pub fn exp2<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
v.map(|x| x.exp2())
|
v.map(|x| x.exp2())
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ where DefaultAllocator: Alloc<N, D> {
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`sqrt`](fn.sqrt.html)
|
/// * [`sqrt`](fn.sqrt.html)
|
||||||
pub fn inversesqrt<N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
pub fn inversesqrt<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
v.map(|x| N::one() / x.sqrt())
|
v.map(|x| N::one() / x.sqrt())
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ where DefaultAllocator: Alloc<N, D> {
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`log2`](fn.log2.html)
|
/// * [`log2`](fn.log2.html)
|
||||||
pub fn log<N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
pub fn log<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
v.map(|x| x.ln())
|
v.map(|x| x.ln())
|
||||||
}
|
}
|
||||||
|
@ -47,13 +47,13 @@ where DefaultAllocator: Alloc<N, D> {
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`log`](fn.log.html)
|
/// * [`log`](fn.log.html)
|
||||||
pub fn log2<N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
pub fn log2<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, 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: Real, D: Dimension>(base: &TVec<N, D>, exponent: &TVec<N, D>) -> TVec<N, D>
|
pub fn pow<N: RealField, D: Dimension>(base: &TVec<N, D>, exponent: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
base.zip_map(exponent, |b, e| b.powf(e))
|
base.zip_map(exponent, |b, e| b.powf(e))
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ where DefaultAllocator: Alloc<N, D> {
|
||||||
/// * [`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: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
pub fn sqrt<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
v.map(|x| x.sqrt())
|
v.map(|x| x.sqrt())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,55 +1,55 @@
|
||||||
use aliases::TMat4;
|
use crate::aliases::TMat4;
|
||||||
use na::{Real};
|
use na::{RealField};
|
||||||
|
|
||||||
//pub fn frustum<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
//pub fn frustum<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//pub fn frustum_lh<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
//pub fn frustum_lh<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn frustum_lr_no<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
//pub fn frustum_lr_no<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn frustum_lh_zo<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
//pub fn frustum_lh_zo<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn frustum_no<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
//pub fn frustum_no<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn frustum_rh<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
//pub fn frustum_rh<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn frustum_rh_no<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
//pub fn frustum_rh_no<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn frustum_rh_zo<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
//pub fn frustum_rh_zo<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn frustum_zo<N: Real>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
//pub fn frustum_zo<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//pub fn infinite_perspective<N: Real>(fovy: N, aspect: N, near: N) -> TMat4<N> {
|
//pub fn infinite_perspective<N: RealField>(fovy: N, aspect: N, near: N) -> TMat4<N> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn infinite_perspective_lh<N: Real>(fovy: N, aspect: N, near: N) -> TMat4<N> {
|
//pub fn infinite_perspective_lh<N: RealField>(fovy: N, aspect: N, near: N) -> TMat4<N> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn infinite_perspective_rh<N: Real>(fovy: N, aspect: N, near: N) -> TMat4<N> {
|
//pub fn infinite_perspective_rh<N: RealField>(fovy: N, aspect: N, near: N) -> TMat4<N> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn infinite_ortho<N: Real>(left: N, right: N, bottom: N, top: N) -> TMat4<N> {
|
//pub fn infinite_ortho<N: RealField>(left: N, right: N, bottom: N, top: N) -> TMat4<N> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ use na::{Real};
|
||||||
/// * `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: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
pub fn ortho<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
||||||
ortho_rh_no(left, right, bottom, top, znear, zfar)
|
ortho_rh_no(left, right, bottom, top, znear, zfar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ pub fn ortho<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -
|
||||||
/// * `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: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
pub fn ortho_lh<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
||||||
ortho_lh_no(left, right, bottom, top, znear, zfar)
|
ortho_lh_no(left, right, bottom, top, znear, zfar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,8 +94,8 @@ pub fn ortho_lh<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N
|
||||||
/// * `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: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
pub fn ortho_lh_no<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
||||||
let two : N = ::convert(2.0);
|
let two : N = crate::convert(2.0);
|
||||||
let mut mat : TMat4<N> = TMat4::<N>::identity();
|
let mut mat : TMat4<N> = TMat4::<N>::identity();
|
||||||
|
|
||||||
mat[(0, 0)] = two / (right - left);
|
mat[(0, 0)] = two / (right - left);
|
||||||
|
@ -119,9 +119,9 @@ pub fn ortho_lh_no<N: Real>(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_zo<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
pub fn ortho_lh_zo<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
||||||
let one : N = N::one();
|
let one : N = N::one();
|
||||||
let two : N = ::convert(2.0);
|
let two : N = crate::convert(2.0);
|
||||||
let mut mat : TMat4<N> = TMat4::<N>::identity();
|
let mut mat : TMat4<N> = TMat4::<N>::identity();
|
||||||
|
|
||||||
mat[(0, 0)] = two / (right - left);
|
mat[(0, 0)] = two / (right - left);
|
||||||
|
@ -145,7 +145,7 @@ pub fn ortho_lh_zo<N: Real>(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_no<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
pub fn ortho_no<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
||||||
ortho_rh_no(left, right, bottom, top, znear, zfar)
|
ortho_rh_no(left, right, bottom, top, znear, zfar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ pub fn ortho_no<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N
|
||||||
/// * `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: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
pub fn ortho_rh<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
||||||
ortho_rh_no(left, right, bottom, top, znear, zfar)
|
ortho_rh_no(left, right, bottom, top, znear, zfar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,8 +175,8 @@ pub fn ortho_rh<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N
|
||||||
/// * `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: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
pub fn ortho_rh_no<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
||||||
let two : N = ::convert(2.0);
|
let two : N = crate::convert(2.0);
|
||||||
let mut mat : TMat4<N> = TMat4::<N>::identity();
|
let mut mat : TMat4<N> = TMat4::<N>::identity();
|
||||||
|
|
||||||
mat[(0, 0)] = two / (right - left);
|
mat[(0, 0)] = two / (right - left);
|
||||||
|
@ -200,9 +200,9 @@ pub fn ortho_rh_no<N: Real>(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_rh_zo<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
pub fn ortho_rh_zo<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
||||||
let one : N = N::one();
|
let one : N = N::one();
|
||||||
let two : N = ::convert(2.0);
|
let two : N = crate::convert(2.0);
|
||||||
let mut mat : TMat4<N> = TMat4::<N>::identity();
|
let mut mat : TMat4<N> = TMat4::<N>::identity();
|
||||||
|
|
||||||
mat[(0, 0)] = two / (right - left);
|
mat[(0, 0)] = two / (right - left);
|
||||||
|
@ -226,7 +226,7 @@ pub fn ortho_rh_zo<N: Real>(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_zo<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
pub fn ortho_zo<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> {
|
||||||
ortho_rh_zo(left, right, bottom, top, znear, zfar)
|
ortho_rh_zo(left, right, bottom, top, znear, zfar)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +240,7 @@ pub fn ortho_zo<N: Real>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N
|
||||||
/// * `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: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_fov<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
||||||
perspective_fov_rh_no(fov, width, height, near, far)
|
perspective_fov_rh_no(fov, width, height, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +254,7 @@ pub fn perspective_fov<N: Real>(fov: N, width: N, height: N, near: N, far: N) ->
|
||||||
/// * `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: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_fov_lh<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
||||||
perspective_fov_lh_no(fov, width, height, near, far)
|
perspective_fov_lh_no(fov, width, height, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,7 +268,7 @@ pub fn perspective_fov_lh<N: Real>(fov: N, width: N, height: N, near: N, far: N)
|
||||||
/// * `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: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_fov_lh_no<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
||||||
assert!(
|
assert!(
|
||||||
width > N::zero(),
|
width > N::zero(),
|
||||||
"The width must be greater than zero"
|
"The width must be greater than zero"
|
||||||
|
@ -285,13 +285,13 @@ pub fn perspective_fov_lh_no<N: Real>(fov: N, width: N, height: N, near: N, far:
|
||||||
let mut mat = TMat4::zeros();
|
let mut mat = TMat4::zeros();
|
||||||
|
|
||||||
let rad = fov;
|
let rad = fov;
|
||||||
let h = (rad * ::convert(0.5)).cos() / (rad * ::convert(0.5)).sin();
|
let h = (rad * crate::convert(0.5)).cos() / (rad * crate::convert(0.5)).sin();
|
||||||
let w = h * height / width;
|
let w = h * height / width;
|
||||||
|
|
||||||
mat[(0, 0)] = w;
|
mat[(0, 0)] = w;
|
||||||
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 * ::convert(2.0)) / (far - near);
|
mat[(2, 3)] = - (far * near * crate::convert(2.0)) / (far - near);
|
||||||
mat[(3, 2)] = N::one();
|
mat[(3, 2)] = N::one();
|
||||||
|
|
||||||
mat
|
mat
|
||||||
|
@ -307,7 +307,7 @@ pub fn perspective_fov_lh_no<N: Real>(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_zo<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_fov_lh_zo<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
||||||
assert!(
|
assert!(
|
||||||
width > N::zero(),
|
width > N::zero(),
|
||||||
"The width must be greater than zero"
|
"The width must be greater than zero"
|
||||||
|
@ -324,7 +324,7 @@ pub fn perspective_fov_lh_zo<N: Real>(fov: N, width: N, height: N, near: N, far:
|
||||||
let mut mat = TMat4::zeros();
|
let mut mat = TMat4::zeros();
|
||||||
|
|
||||||
let rad = fov;
|
let rad = fov;
|
||||||
let h = (rad * ::convert(0.5)).cos() / (rad * ::convert(0.5)).sin();
|
let h = (rad * crate::convert(0.5)).cos() / (rad * crate::convert(0.5)).sin();
|
||||||
let w = h * height / width;
|
let w = h * height / width;
|
||||||
|
|
||||||
mat[(0, 0)] = w;
|
mat[(0, 0)] = w;
|
||||||
|
@ -346,7 +346,7 @@ pub fn perspective_fov_lh_zo<N: Real>(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_no<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_fov_no<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
||||||
perspective_fov_rh_no(fov, width, height, near, far)
|
perspective_fov_rh_no(fov, width, height, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +360,7 @@ pub fn perspective_fov_no<N: Real>(fov: N, width: N, height: N, near: N, far: N)
|
||||||
/// * `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: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_fov_rh<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
||||||
perspective_fov_rh_no(fov, width, height, near, far)
|
perspective_fov_rh_no(fov, width, height, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,7 +374,7 @@ pub fn perspective_fov_rh<N: Real>(fov: N, width: N, height: N, near: N, far: N)
|
||||||
/// * `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: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_fov_rh_no<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
||||||
assert!(
|
assert!(
|
||||||
width > N::zero(),
|
width > N::zero(),
|
||||||
"The width must be greater than zero"
|
"The width must be greater than zero"
|
||||||
|
@ -391,13 +391,13 @@ pub fn perspective_fov_rh_no<N: Real>(fov: N, width: N, height: N, near: N, far:
|
||||||
let mut mat = TMat4::zeros();
|
let mut mat = TMat4::zeros();
|
||||||
|
|
||||||
let rad = fov;
|
let rad = fov;
|
||||||
let h = (rad * ::convert(0.5)).cos() / (rad * ::convert(0.5)).sin();
|
let h = (rad * crate::convert(0.5)).cos() / (rad * crate::convert(0.5)).sin();
|
||||||
let w = h * height / width;
|
let w = h * height / width;
|
||||||
|
|
||||||
mat[(0, 0)] = w;
|
mat[(0, 0)] = w;
|
||||||
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 * ::convert(2.0)) / (far - near);
|
mat[(2, 3)] = - (far * near * crate::convert(2.0)) / (far - near);
|
||||||
mat[(3, 2)] = -N::one();
|
mat[(3, 2)] = -N::one();
|
||||||
|
|
||||||
mat
|
mat
|
||||||
|
@ -413,7 +413,7 @@ pub fn perspective_fov_rh_no<N: Real>(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_rh_zo<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_fov_rh_zo<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
||||||
assert!(
|
assert!(
|
||||||
width > N::zero(),
|
width > N::zero(),
|
||||||
"The width must be greater than zero"
|
"The width must be greater than zero"
|
||||||
|
@ -430,7 +430,7 @@ pub fn perspective_fov_rh_zo<N: Real>(fov: N, width: N, height: N, near: N, far:
|
||||||
let mut mat = TMat4::zeros();
|
let mut mat = TMat4::zeros();
|
||||||
|
|
||||||
let rad = fov;
|
let rad = fov;
|
||||||
let h = (rad * ::convert(0.5)).cos() / (rad * ::convert(0.5)).sin();
|
let h = (rad * crate::convert(0.5)).cos() / (rad * crate::convert(0.5)).sin();
|
||||||
let w = h * height / width;
|
let w = h * height / width;
|
||||||
|
|
||||||
mat[(0, 0)] = w;
|
mat[(0, 0)] = w;
|
||||||
|
@ -452,7 +452,7 @@ pub fn perspective_fov_rh_zo<N: Real>(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_zo<N: Real>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_fov_zo<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> {
|
||||||
perspective_fov_rh_zo(fov, width, height, near, far)
|
perspective_fov_rh_zo(fov, width, height, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,7 +467,7 @@ pub fn perspective_fov_zo<N: Real>(fov: N, width: N, height: N, near: N, far: 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<N: Real>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
||||||
// 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
|
||||||
|
@ -496,7 +496,7 @@ pub fn perspective<N: Real>(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: Real>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_lh<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
||||||
perspective_lh_no(aspect, fovy, near, far)
|
perspective_lh_no(aspect, fovy, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,7 +511,7 @@ pub fn perspective_lh<N: Real>(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_no<N: Real>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_lh_no<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
||||||
assert!(
|
assert!(
|
||||||
!relative_eq!(far - near, N::zero()),
|
!relative_eq!(far - near, N::zero()),
|
||||||
"The near-plane and far-plane must not be superimposed."
|
"The near-plane and far-plane must not be superimposed."
|
||||||
|
@ -522,7 +522,7 @@ pub fn perspective_lh_no<N: Real>(aspect: N, fovy: N, near: N, far: N) -> TMat4<
|
||||||
);
|
);
|
||||||
|
|
||||||
let one = N::one();
|
let one = N::one();
|
||||||
let two: N = ::convert( 2.0);
|
let two: N = crate::convert( 2.0);
|
||||||
let mut mat : TMat4<N> = TMat4::zeros();
|
let mut mat : TMat4<N> = TMat4::zeros();
|
||||||
|
|
||||||
let tan_half_fovy = (fovy / two).tan();
|
let tan_half_fovy = (fovy / two).tan();
|
||||||
|
@ -547,7 +547,7 @@ pub fn perspective_lh_no<N: Real>(aspect: N, fovy: N, near: N, far: N) -> TMat4<
|
||||||
///
|
///
|
||||||
/// # 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: Real>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_lh_zo<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
||||||
assert!(
|
assert!(
|
||||||
!relative_eq!(far - near, N::zero()),
|
!relative_eq!(far - near, N::zero()),
|
||||||
"The near-plane and far-plane must not be superimposed."
|
"The near-plane and far-plane must not be superimposed."
|
||||||
|
@ -558,7 +558,7 @@ pub fn perspective_lh_zo<N: Real>(aspect: N, fovy: N, near: N, far: N) -> TMat4<
|
||||||
);
|
);
|
||||||
|
|
||||||
let one = N::one();
|
let one = N::one();
|
||||||
let two: N = ::convert( 2.0);
|
let two: N = crate::convert( 2.0);
|
||||||
let mut mat: TMat4<N> = TMat4::zeros();
|
let mut mat: TMat4<N> = TMat4::zeros();
|
||||||
|
|
||||||
let tan_half_fovy = (fovy / two).tan();
|
let tan_half_fovy = (fovy / two).tan();
|
||||||
|
@ -583,7 +583,7 @@ pub fn perspective_lh_zo<N: Real>(aspect: N, fovy: N, near: N, far: N) -> TMat4<
|
||||||
///
|
///
|
||||||
/// # 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: Real>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_no<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
||||||
perspective_rh_no(aspect, fovy, near, far)
|
perspective_rh_no(aspect, fovy, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -598,7 +598,7 @@ pub fn perspective_no<N: Real>(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_rh<N: Real>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_rh<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
||||||
perspective_rh_no(aspect, fovy, near, far)
|
perspective_rh_no(aspect, fovy, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,7 +613,7 @@ pub fn perspective_rh<N: Real>(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_rh_no<N: Real>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_rh_no<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
||||||
assert!(
|
assert!(
|
||||||
!relative_eq!(far - near, N::zero()),
|
!relative_eq!(far - near, N::zero()),
|
||||||
"The near-plane and far-plane must not be superimposed."
|
"The near-plane and far-plane must not be superimposed."
|
||||||
|
@ -625,7 +625,7 @@ pub fn perspective_rh_no<N: Real>(aspect: N, fovy: N, near: N, far: N) -> TMat4<
|
||||||
|
|
||||||
let negone = -N::one();
|
let negone = -N::one();
|
||||||
let one = N::one();
|
let one = N::one();
|
||||||
let two: N = ::convert( 2.0);
|
let two: N = 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();
|
||||||
|
@ -650,7 +650,7 @@ pub fn perspective_rh_no<N: Real>(aspect: N, fovy: N, near: N, far: N) -> TMat4<
|
||||||
///
|
///
|
||||||
/// # 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: Real>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_rh_zo<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
||||||
assert!(
|
assert!(
|
||||||
!relative_eq!(far - near, N::zero()),
|
!relative_eq!(far - near, N::zero()),
|
||||||
"The near-plane and far-plane must not be superimposed."
|
"The near-plane and far-plane must not be superimposed."
|
||||||
|
@ -662,7 +662,7 @@ pub fn perspective_rh_zo<N: Real>(aspect: N, fovy: N, near: N, far: N) -> TMat4<
|
||||||
|
|
||||||
let negone = -N::one();
|
let negone = -N::one();
|
||||||
let one = N::one();
|
let one = N::one();
|
||||||
let two = ::convert( 2.0);
|
let two = 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();
|
||||||
|
@ -687,14 +687,14 @@ pub fn perspective_rh_zo<N: Real>(aspect: N, fovy: N, near: N, far: N) -> TMat4<
|
||||||
///
|
///
|
||||||
/// # 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: Real>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
pub fn perspective_zo<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> {
|
||||||
perspective_rh_zo(aspect, fovy, near, far)
|
perspective_rh_zo(aspect, fovy, near, far)
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn tweaked_infinite_perspective<N: Real>(fovy: N, aspect: N, near: N) -> TMat4<N> {
|
//pub fn tweaked_infinite_perspective<N: RealField>(fovy: N, aspect: N, near: N) -> TMat4<N> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn tweaked_infinite_perspective_ep<N: Real>(fovy: N, aspect: N, near: N, ep: N) -> TMat4<N> {
|
//pub fn tweaked_infinite_perspective_ep<N: RealField>(fovy: N, aspect: N, near: N, ep: N) -> TMat4<N> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use na::{self, Real, U3};
|
use na::{self, RealField, U3};
|
||||||
|
|
||||||
use aliases::{TMat4, TVec2, TVec3, TVec4};
|
use crate::aliases::{TMat4, TVec2, TVec3, TVec4};
|
||||||
|
|
||||||
/// Define a picking region.
|
/// Define a picking region.
|
||||||
///
|
///
|
||||||
|
@ -9,7 +9,7 @@ use 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: Real>(center: &TVec2<N>, delta: &TVec2<N>, viewport: &TVec4<N>) -> TMat4<N> {
|
pub fn pick_matrix<N: RealField>(center: &TVec2<N>, delta: &TVec2<N>, viewport: &TVec4<N>) -> TMat4<N> {
|
||||||
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,
|
||||||
|
@ -41,7 +41,7 @@ pub fn pick_matrix<N: Real>(center: &TVec2<N>, delta: &TVec2<N>, viewport: &TVec
|
||||||
/// * [`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: Real>(
|
pub fn project<N: RealField>(
|
||||||
obj: &TVec3<N>,
|
obj: &TVec3<N>,
|
||||||
model: &TMat4<N>,
|
model: &TMat4<N>,
|
||||||
proj: &TMat4<N>,
|
proj: &TMat4<N>,
|
||||||
|
@ -69,7 +69,7 @@ pub fn project<N: Real>(
|
||||||
/// * [`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: Real>(
|
pub fn project_no<N: RealField>(
|
||||||
obj: &TVec3<N>,
|
obj: &TVec3<N>,
|
||||||
model: &TMat4<N>,
|
model: &TMat4<N>,
|
||||||
proj: &TMat4<N>,
|
proj: &TMat4<N>,
|
||||||
|
@ -98,7 +98,7 @@ pub fn project_no<N: Real>(
|
||||||
/// * [`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: Real>(
|
pub fn project_zo<N: RealField>(
|
||||||
obj: &TVec3<N>,
|
obj: &TVec3<N>,
|
||||||
model: &TMat4<N>,
|
model: &TMat4<N>,
|
||||||
proj: &TMat4<N>,
|
proj: &TMat4<N>,
|
||||||
|
@ -132,7 +132,7 @@ pub fn project_zo<N: Real>(
|
||||||
/// * [`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: Real>(
|
pub fn unproject<N: RealField>(
|
||||||
win: &TVec3<N>,
|
win: &TVec3<N>,
|
||||||
model: &TMat4<N>,
|
model: &TMat4<N>,
|
||||||
proj: &TMat4<N>,
|
proj: &TMat4<N>,
|
||||||
|
@ -160,7 +160,7 @@ pub fn unproject<N: Real>(
|
||||||
/// * [`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: Real>(
|
pub fn unproject_no<N: RealField>(
|
||||||
win: &TVec3<N>,
|
win: &TVec3<N>,
|
||||||
model: &TMat4<N>,
|
model: &TMat4<N>,
|
||||||
proj: &TMat4<N>,
|
proj: &TMat4<N>,
|
||||||
|
@ -198,7 +198,7 @@ pub fn unproject_no<N: Real>(
|
||||||
/// * [`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: Real>(
|
pub fn unproject_zo<N: RealField>(
|
||||||
win: &TVec3<N>,
|
win: &TVec3<N>,
|
||||||
model: &TMat4<N>,
|
model: &TMat4<N>,
|
||||||
proj: &TMat4<N>,
|
proj: &TMat4<N>,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use na::DefaultAllocator;
|
use na::DefaultAllocator;
|
||||||
|
|
||||||
use aliases::{TMat, TVec};
|
use crate::aliases::{TMat, TVec};
|
||||||
use traits::{Alloc, Dimension, Number};
|
use crate::traits::{Alloc, Dimension, Number};
|
||||||
|
|
||||||
/// Perform a component-wise equal-to comparison of two matrices.
|
/// Perform a component-wise equal-to comparison of two matrices.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use na::{DefaultAllocator, Point3, Real, Rotation3, Unit};
|
use na::{DefaultAllocator, Point3, RealField, Rotation3, Unit};
|
||||||
|
|
||||||
use aliases::{TMat, TMat4, TVec, TVec3};
|
use crate::aliases::{TMat, TMat4, TVec, TVec3};
|
||||||
use traits::{Alloc, Dimension, Number};
|
use crate::traits::{Alloc, Dimension, Number};
|
||||||
|
|
||||||
/// The identity matrix.
|
/// The identity matrix.
|
||||||
pub fn identity<N: Number, D: Dimension>() -> TMat<N, D, D>
|
pub fn identity<N: Number, D: Dimension>() -> TMat<N, D, D>
|
||||||
|
@ -21,7 +21,7 @@ where DefaultAllocator: Alloc<N, D, D> {
|
||||||
///
|
///
|
||||||
/// * [`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: Real>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> {
|
pub fn look_at<N: RealField>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> {
|
||||||
look_at_rh(eye, center, up)
|
look_at_rh(eye, center, up)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ pub fn look_at<N: Real>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>) -> TMa
|
||||||
///
|
///
|
||||||
/// * [`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: Real>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> {
|
pub fn look_at_lh<N: RealField>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> {
|
||||||
TMat::look_at_lh(&Point3::from(*eye), &Point3::from(*center), up)
|
TMat::look_at_lh(&Point3::from(*eye), &Point3::from(*center), up)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ pub fn look_at_lh<N: Real>(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: Real>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> {
|
pub fn look_at_rh<N: RealField>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> {
|
||||||
TMat::look_at_rh(&Point3::from(*eye), &Point3::from(*center), up)
|
TMat::look_at_rh(&Point3::from(*eye), &Point3::from(*center), up)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ pub fn look_at_rh<N: Real>(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: Real>(m: &TMat4<N>, angle: N, axis: &TVec3<N>) -> TMat4<N> {
|
pub fn rotate<N: RealField>(m: &TMat4<N>, angle: N, axis: &TVec3<N>) -> TMat4<N> {
|
||||||
m * Rotation3::from_axis_angle(&Unit::new_normalize(*axis), angle).to_homogeneous()
|
m * Rotation3::from_axis_angle(&Unit::new_normalize(*axis), angle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ pub fn rotate<N: Real>(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: Real>(m: &TMat4<N>, angle: N) -> TMat4<N> {
|
pub fn rotate_x<N: RealField>(m: &TMat4<N>, angle: N) -> TMat4<N> {
|
||||||
rotate(m, angle, &TVec::x())
|
rotate(m, angle, &TVec::x())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ pub fn rotate_x<N: Real>(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: Real>(m: &TMat4<N>, angle: N) -> TMat4<N> {
|
pub fn rotate_y<N: RealField>(m: &TMat4<N>, angle: N) -> TMat4<N> {
|
||||||
rotate(m, angle, &TVec::y())
|
rotate(m, angle, &TVec::y())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ pub fn rotate_y<N: Real>(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: Real>(m: &TMat4<N>, angle: N) -> TMat4<N> {
|
pub fn rotate_z<N: RealField>(m: &TMat4<N>, angle: N) -> TMat4<N> {
|
||||||
rotate(m, angle, &TVec::z())
|
rotate(m, angle, &TVec::z())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
use na::{self, Real, Unit};
|
use na::{self, RealField, Unit};
|
||||||
|
|
||||||
use aliases::Qua;
|
use crate::aliases::Qua;
|
||||||
|
|
||||||
/// The conjugate of `q`.
|
/// The conjugate of `q`.
|
||||||
pub fn quat_conjugate<N: Real>(q: &Qua<N>) -> Qua<N> {
|
pub fn quat_conjugate<N: RealField>(q: &Qua<N>) -> Qua<N> {
|
||||||
q.conjugate()
|
q.conjugate()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The inverse of `q`.
|
/// The inverse of `q`.
|
||||||
pub fn quat_inverse<N: Real>(q: &Qua<N>) -> Qua<N> {
|
pub fn quat_inverse<N: RealField>(q: &Qua<N>) -> Qua<N> {
|
||||||
q.try_inverse().unwrap_or_else(na::zero)
|
q.try_inverse().unwrap_or_else(na::zero)
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn quat_isinf<N: Real>(x: &Qua<N>) -> TVec<bool, U4> {
|
//pub fn quat_isinf<N: RealField>(x: &Qua<N>) -> TVec<bool, U4> {
|
||||||
// x.coords.map(|e| e.is_inf())
|
// x.coords.map(|e| e.is_inf())
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//pub fn quat_isnan<N: Real>(x: &Qua<N>) -> TVec<bool, U4> {
|
//pub fn quat_isnan<N: RealField>(x: &Qua<N>) -> 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: Real>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> {
|
pub fn quat_lerp<N: RealField>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> {
|
||||||
x.lerp(y, a)
|
x.lerp(y, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn quat_mix<N: Real>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> {
|
//pub fn quat_mix<N: RealField>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> {
|
||||||
// x * (N::one() - a) + y * a
|
// x * (N::one() - a) + y * a
|
||||||
//}
|
//}
|
||||||
|
|
||||||
/// Interpolate spherically between `x` and `y`.
|
/// Interpolate spherically between `x` and `y`.
|
||||||
pub fn quat_slerp<N: Real>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> {
|
pub fn quat_slerp<N: RealField>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> {
|
||||||
Unit::new_normalize(*x)
|
Unit::new_normalize(*x)
|
||||||
.slerp(&Unit::new_normalize(*y), a)
|
.slerp(&Unit::new_normalize(*y), a)
|
||||||
.into_inner()
|
.into_inner()
|
||||||
|
|
|
@ -1,28 +1,28 @@
|
||||||
use na::Real;
|
use na::RealField;
|
||||||
|
|
||||||
use aliases::Qua;
|
use crate::aliases::Qua;
|
||||||
|
|
||||||
/// Multiplies two quaternions.
|
/// Multiplies two quaternions.
|
||||||
pub fn quat_cross<N: Real>(q1: &Qua<N>, q2: &Qua<N>) -> Qua<N> {
|
pub fn quat_cross<N: RealField>(q1: &Qua<N>, q2: &Qua<N>) -> Qua<N> {
|
||||||
q1 * q2
|
q1 * q2
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The scalar product of two quaternions.
|
/// The scalar product of two quaternions.
|
||||||
pub fn quat_dot<N: Real>(x: &Qua<N>, y: &Qua<N>) -> N {
|
pub fn quat_dot<N: RealField>(x: &Qua<N>, y: &Qua<N>) -> N {
|
||||||
x.dot(y)
|
x.dot(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The magnitude of the quaternion `q`.
|
/// The magnitude of the quaternion `q`.
|
||||||
pub fn quat_length<N: Real>(q: &Qua<N>) -> N {
|
pub fn quat_length<N: RealField>(q: &Qua<N>) -> N {
|
||||||
q.norm()
|
q.norm()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The magnitude of the quaternion `q`.
|
/// The magnitude of the quaternion `q`.
|
||||||
pub fn quat_magnitude<N: Real>(q: &Qua<N>) -> N {
|
pub fn quat_magnitude<N: RealField>(q: &Qua<N>) -> N {
|
||||||
q.norm()
|
q.norm()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Normalizes the quaternion `q`.
|
/// Normalizes the quaternion `q`.
|
||||||
pub fn quat_normalize<N: Real>(q: &Qua<N>) -> Qua<N> {
|
pub fn quat_normalize<N: RealField>(q: &Qua<N>) -> Qua<N> {
|
||||||
q.normalize()
|
q.normalize()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
use na::{Real, U4};
|
use na::{RealField, U4};
|
||||||
|
|
||||||
use 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: Real>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> {
|
pub fn quat_equal<N: RealField>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> {
|
||||||
::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: Real>(x: &Qua<N>, y: &Qua<N>, epsilon: N) -> TVec<bool, U4> {
|
pub fn quat_equal_eps<N: RealField>(x: &Qua<N>, y: &Qua<N>, epsilon: N) -> TVec<bool, U4> {
|
||||||
::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: Real>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> {
|
pub fn quat_not_equal<N: RealField>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> {
|
||||||
::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: Real>(x: &Qua<N>, y: &Qua<N>, epsilon: N) -> TVec<bool, U4> {
|
pub fn quat_not_equal_eps<N: RealField>(x: &Qua<N>, y: &Qua<N>, epsilon: N) -> TVec<bool, U4> {
|
||||||
::not_equal_eps(&x.coords, &y.coords, epsilon)
|
crate::not_equal_eps(&x.coords, &y.coords, epsilon)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
use na::{Real, Unit, UnitQuaternion};
|
use na::{RealField, Unit, UnitQuaternion};
|
||||||
|
|
||||||
use aliases::{Qua, TVec3};
|
use crate::aliases::{Qua, TVec3};
|
||||||
|
|
||||||
/// Computes the quaternion exponential.
|
/// Computes the quaternion exponential.
|
||||||
pub fn quat_exp<N: Real>(q: &Qua<N>) -> Qua<N> {
|
pub fn quat_exp<N: RealField>(q: &Qua<N>) -> Qua<N> {
|
||||||
q.exp()
|
q.exp()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the quaternion logarithm.
|
/// Computes the quaternion logarithm.
|
||||||
pub fn quat_log<N: Real>(q: &Qua<N>) -> Qua<N> {
|
pub fn quat_log<N: RealField>(q: &Qua<N>) -> Qua<N> {
|
||||||
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: Real>(q: &Qua<N>, y: N) -> Qua<N> {
|
pub fn quat_pow<N: RealField>(q: &Qua<N>, y: N) -> Qua<N> {
|
||||||
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: Real>(q: &Qua<N>, angle: N, axis: &TVec3<N>) -> Qua<N> {
|
pub fn quat_rotate<N: RealField>(q: &Qua<N>, angle: N, axis: &TVec3<N>) -> Qua<N> {
|
||||||
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: Real>(q: &Qua<N>) -> Qua<N> {
|
//pub fn quat_sqrt<N: RealField>(q: &Qua<N>) -> Qua<N> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
use na::{Real, Unit, UnitQuaternion};
|
use na::{RealField, Unit, UnitQuaternion};
|
||||||
|
|
||||||
use 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: Real>(x: &Qua<N>) -> N {
|
pub fn quat_angle<N: RealField>(x: &Qua<N>) -> N {
|
||||||
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: Real>(angle: N, axis: &TVec3<N>) -> Qua<N> {
|
pub fn quat_angle_axis<N: RealField>(angle: N, axis: &TVec3<N>) -> Qua<N> {
|
||||||
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: Real>(x: &Qua<N>) -> TVec3<N> {
|
pub fn quat_axis<N: RealField>(x: &Qua<N>) -> TVec3<N> {
|
||||||
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 {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use na;
|
use na;
|
||||||
|
|
||||||
use traits::Number;
|
use crate::traits::Number;
|
||||||
|
|
||||||
/// Returns the maximum among three values.
|
/// Returns the maximum among three values.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use approx::AbsDiffEq;
|
use approx::AbsDiffEq;
|
||||||
use na::Real;
|
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<N: AbsDiffEq<Epsilon = N>>() -> N {
|
||||||
|
@ -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: Real>() -> N {
|
pub fn pi<N: RealField>() -> N {
|
||||||
N::pi()
|
N::pi()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use na::{self, DefaultAllocator};
|
use na::{self, DefaultAllocator};
|
||||||
|
|
||||||
use aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
use traits::{Alloc, Dimension, Number};
|
use crate::traits::{Alloc, Dimension, Number};
|
||||||
|
|
||||||
/// Component-wise maximum between a vector and a scalar.
|
/// Component-wise maximum between a vector and a scalar.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use na::DefaultAllocator;
|
use na::DefaultAllocator;
|
||||||
|
|
||||||
use aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
use traits::{Alloc, Dimension, Number};
|
use crate::traits::{Alloc, Dimension, Number};
|
||||||
|
|
||||||
/// Component-wise approximate equality of two vectors, using a scalar epsilon.
|
/// Component-wise approximate equality of two vectors, using a scalar epsilon.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use na::{DefaultAllocator, Real};
|
use na::{DefaultAllocator, RealField};
|
||||||
|
|
||||||
use aliases::{TVec, TVec3};
|
use crate::aliases::{TVec, TVec3};
|
||||||
use traits::{Alloc, Dimension, Number};
|
use crate::traits::{Alloc, Dimension, Number};
|
||||||
|
|
||||||
/// The cross product of two vectors.
|
/// The cross product of two vectors.
|
||||||
pub fn cross<N: Number, D: Dimension>(x: &TVec3<N>, y: &TVec3<N>) -> TVec3<N> {
|
pub fn cross<N: Number, D: Dimension>(x: &TVec3<N>, y: &TVec3<N>) -> TVec3<N> {
|
||||||
|
@ -13,7 +13,7 @@ pub fn cross<N: Number, D: Dimension>(x: &TVec3<N>, y: &TVec3<N>) -> TVec3<N> {
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`distance2`](fn.distance2.html)
|
/// * [`distance2`](fn.distance2.html)
|
||||||
pub fn distance<N: Real, D: Dimension>(p0: &TVec<N, D>, p1: &TVec<N, D>) -> N
|
pub fn distance<N: RealField, D: Dimension>(p0: &TVec<N, D>, p1: &TVec<N, D>) -> N
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
(p1 - p0).norm()
|
(p1 - p0).norm()
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,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: Real, D: Dimension>(x: &TVec<N, D>) -> N
|
pub fn length<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
x.norm()
|
x.norm()
|
||||||
}
|
}
|
||||||
|
@ -63,13 +63,13 @@ where DefaultAllocator: Alloc<N, D> {
|
||||||
/// * [`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: Real, D: Dimension>(x: &TVec<N, D>) -> N
|
pub fn magnitude<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
x.norm()
|
x.norm()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Normalizes a vector.
|
/// Normalizes a vector.
|
||||||
pub fn normalize<N: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn normalize<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
x.normalize()
|
x.normalize()
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ where DefaultAllocator: Alloc<N, D> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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: Real, D: Dimension>(i: &TVec<N, D>, n: &TVec<N, D>, eta: N) -> TVec<N, D>
|
pub fn refract_vec<N: RealField, D: Dimension>(i: &TVec<N, D>, n: &TVec<N, D>, eta: N) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
let ni = n.dot(i);
|
let ni = n.dot(i);
|
||||||
let k = N::one() - eta * eta * (N::one() - ni * ni);
|
let k = N::one() - eta * eta * (N::one() - ni * ni);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use na::{Scalar, DefaultAllocator};
|
use na::{Scalar, DefaultAllocator};
|
||||||
|
|
||||||
use traits::{Alloc, Dimension};
|
use crate::traits::{Alloc, Dimension};
|
||||||
use aliases::*;
|
use crate::aliases::*;
|
||||||
|
|
||||||
pub fn bitfieldDeinterleave(x: u16) -> U8Vec2 {
|
pub fn bitfieldDeinterleave(x: u16) -> U8Vec2 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
use na::{self, Real};
|
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: Real>() -> N {
|
pub fn e<N: RealField>() -> N {
|
||||||
N::e()
|
N::e()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The Euler constant.
|
/// The Euler constant.
|
||||||
pub fn euler<N: Real>() -> N {
|
pub fn euler<N: RealField>() -> N {
|
||||||
N::e()
|
N::e()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,12 +28,12 @@ pub fn euler<N: Real>() -> 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: Real>() -> N {
|
pub fn four_over_pi<N: RealField>() -> N {
|
||||||
na::convert::<_, N>(4.0) / N::pi()
|
na::convert::<_, N>(4.0) / N::pi()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the golden ratio.
|
/// Returns the golden ratio.
|
||||||
pub fn golden_ratio<N: Real>() -> N {
|
pub fn golden_ratio<N: RealField>() -> N {
|
||||||
(N::one() + root_five()) / na::convert(2.0)
|
(N::one() + root_five()) / na::convert(2.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ pub fn golden_ratio<N: Real>() -> 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: Real>() -> N {
|
pub fn half_pi<N: RealField>() -> N {
|
||||||
N::frac_pi_2()
|
N::frac_pi_2()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ pub fn half_pi<N: Real>() -> 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: Real>() -> N {
|
pub fn ln_ln_two<N: RealField>() -> N {
|
||||||
N::ln_2().ln()
|
N::ln_2().ln()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ pub fn ln_ln_two<N: Real>() -> 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: Real>() -> N {
|
pub fn ln_ten<N: RealField>() -> N {
|
||||||
N::ln_10()
|
N::ln_10()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ pub fn ln_ten<N: Real>() -> 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: Real>() -> N {
|
pub fn ln_two<N: RealField>() -> N {
|
||||||
N::ln_2()
|
N::ln_2()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,12 +106,12 @@ 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: Real>() -> N {
|
pub fn one_over_pi<N: RealField>() -> N {
|
||||||
N::frac_1_pi()
|
N::frac_1_pi()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `1 / sqrt(2)`.
|
/// Returns `1 / sqrt(2)`.
|
||||||
pub fn one_over_root_two<N: Real>() -> N {
|
pub fn one_over_root_two<N: RealField>() -> N {
|
||||||
N::one() / root_two()
|
N::one() / root_two()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ pub fn one_over_root_two<N: Real>() -> 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: Real>() -> N {
|
pub fn one_over_two_pi<N: RealField>() -> N {
|
||||||
N::frac_1_pi() * na::convert(0.5)
|
N::frac_1_pi() * na::convert(0.5)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ pub fn one_over_two_pi<N: Real>() -> 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: Real>() -> N {
|
pub fn quarter_pi<N: RealField>() -> N {
|
||||||
N::frac_pi_4()
|
N::frac_pi_4()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ pub fn quarter_pi<N: Real>() -> 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: Real>() -> N {
|
pub fn root_five<N: RealField>() -> N {
|
||||||
na::convert::<_, N>(5.0).sqrt()
|
na::convert::<_, N>(5.0).sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,12 +181,12 @@ pub fn root_five<N: Real>() -> 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: Real>() -> N {
|
pub fn root_half_pi<N: RealField>() -> N {
|
||||||
(N::pi() / na::convert(2.0)).sqrt()
|
(N::pi() / na::convert(2.0)).sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `sqrt(ln(4))`.
|
/// Returns `sqrt(ln(4))`.
|
||||||
pub fn root_ln_four<N: Real>() -> N {
|
pub fn root_ln_four<N: RealField>() -> N {
|
||||||
na::convert::<_, N>(4.0).ln().sqrt()
|
na::convert::<_, N>(4.0).ln().sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,7 +206,7 @@ pub fn root_ln_four<N: Real>() -> 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: Real>() -> N {
|
pub fn root_pi<N: RealField>() -> N {
|
||||||
N::pi().sqrt()
|
N::pi().sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ pub fn root_pi<N: Real>() -> 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: Real>() -> N {
|
pub fn root_three<N: RealField>() -> N {
|
||||||
na::convert::<_, N>(3.0).sqrt()
|
na::convert::<_, N>(3.0).sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,8 +226,8 @@ pub fn root_three<N: Real>() -> 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: Real>() -> N {
|
pub fn root_two<N: RealField>() -> N {
|
||||||
// FIXME: there should be a ::sqrt_2() on the Real trait.
|
// FIXME: there should be a crate::sqrt_2() on the RealField trait.
|
||||||
na::convert::<_, N>(2.0).sqrt()
|
na::convert::<_, N>(2.0).sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,7 +247,7 @@ pub fn root_two<N: Real>() -> 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: Real>() -> N {
|
pub fn root_two_pi<N: RealField>() -> N {
|
||||||
N::two_pi().sqrt()
|
N::two_pi().sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +256,7 @@ pub fn root_two_pi<N: Real>() -> N {
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`two_thirds`](fn.two_thirds.html)
|
/// * [`two_thirds`](fn.two_thirds.html)
|
||||||
pub fn third<N: Real>() -> N {
|
pub fn third<N: RealField>() -> N {
|
||||||
na::convert(1.0 / 3.0)
|
na::convert(1.0 / 3.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ pub fn third<N: Real>() -> 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: Real>() -> N {
|
pub fn three_over_two_pi<N: RealField>() -> N {
|
||||||
na::convert::<_, N>(3.0) / N::two_pi()
|
na::convert::<_, N>(3.0) / N::two_pi()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +295,7 @@ pub fn three_over_two_pi<N: Real>() -> 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: Real>() -> N {
|
pub fn two_over_pi<N: RealField>() -> N {
|
||||||
N::frac_2_pi()
|
N::frac_2_pi()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +315,7 @@ pub fn two_over_pi<N: Real>() -> 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: Real>() -> N {
|
pub fn two_over_root_pi<N: RealField>() -> N {
|
||||||
N::frac_2_sqrt_pi()
|
N::frac_2_sqrt_pi()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,7 +335,7 @@ pub fn two_over_root_pi<N: Real>() -> 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: Real>() -> N {
|
pub fn two_pi<N: RealField>() -> N {
|
||||||
N::two_pi()
|
N::two_pi()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,7 +344,7 @@ pub fn two_pi<N: Real>() -> N {
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`third`](fn.third.html)
|
/// * [`third`](fn.third.html)
|
||||||
pub fn two_thirds<N: Real>() -> N {
|
pub fn two_thirds<N: RealField>() -> N {
|
||||||
na::convert(2.0 / 3.0)
|
na::convert(2.0 / 3.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
use approx::AbsDiffEq;
|
use approx::AbsDiffEq;
|
||||||
use na::DefaultAllocator;
|
use na::DefaultAllocator;
|
||||||
|
|
||||||
use traits::{Alloc, Number, Dimension};
|
use crate::traits::{Alloc, Number, Dimension};
|
||||||
use 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<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, epsilon: N) -> TVec<bool, D>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//use na::{Scalar, DefaultAllocator};
|
//use na::{Scalar, DefaultAllocator};
|
||||||
//
|
//
|
||||||
//use traits::{Alloc, Dimension};
|
//use crate::traits::{Alloc, Dimension};
|
||||||
//use aliases::TVec;
|
//use crate::aliases::TVec;
|
||||||
|
|
||||||
//pub fn iround<N: Scalar, D: Dimension>(x: &TVec<N, D>) -> TVec<i32, D>
|
//pub fn iround<N: Scalar, D: Dimension>(x: &TVec<N, D>) -> TVec<i32, D>
|
||||||
// where DefaultAllocator: Alloc<N, D> {
|
// where DefaultAllocator: Alloc<N, D> {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use na::{DefaultAllocator, Scalar};
|
use na::{DefaultAllocator, Scalar};
|
||||||
|
|
||||||
use aliases::{TMat, TVec};
|
use crate::aliases::{TMat, TVec};
|
||||||
use traits::{Alloc, Dimension};
|
use crate::traits::{Alloc, Dimension};
|
||||||
|
|
||||||
/// The `index`-th column of the matrix `m`.
|
/// The `index`-th column of the matrix `m`.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
use na::{DefaultAllocator, Real};
|
use na::{DefaultAllocator, RealField};
|
||||||
|
|
||||||
use aliases::TMat;
|
use crate::aliases::TMat;
|
||||||
use traits::{Alloc, Dimension};
|
use crate::traits::{Alloc, Dimension};
|
||||||
|
|
||||||
/// Fast matrix inverse for affine matrix.
|
/// Fast matrix inverse for affine matrix.
|
||||||
pub fn affine_inverse<N: Real, D: Dimension>(m: TMat<N, D, D>) -> TMat<N, D, D>
|
pub fn affine_inverse<N: RealField, D: Dimension>(m: TMat<N, D, D>) -> TMat<N, D, D>
|
||||||
where DefaultAllocator: Alloc<N, D, D> {
|
where DefaultAllocator: Alloc<N, D, D> {
|
||||||
// FIXME: this should be optimized.
|
// FIXME: 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: Real, D: Dimension>(m: TMat<N, D, D>) -> TMat<N, D, D>
|
pub fn inverse_transpose<N: RealField, D: Dimension>(m: TMat<N, D, D>) -> TMat<N, D, D>
|
||||||
where DefaultAllocator: Alloc<N, 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)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use na::{Scalar, Real, DefaultAllocator, U3, U4};
|
use na::{Scalar, RealField, DefaultAllocator, U3, U4};
|
||||||
|
|
||||||
use traits::{Alloc, Dimension};
|
use crate::traits::{Alloc, Dimension};
|
||||||
use aliases::*;
|
use crate::aliases::*;
|
||||||
|
|
||||||
|
|
||||||
pub fn packF2x11_1x10(v: &Vec3) -> i32 {
|
pub fn packF2x11_1x10(v: &Vec3) -> i32 {
|
||||||
|
@ -53,7 +53,7 @@ pub fn packRGBM<N: Scalar>(rgb: &TVec3<N>) -> TVec4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn packSnorm<I: Scalar, N: Real, D: Dimension>(v: TVec<N, D>) -> TVec<I, D>
|
pub fn packSnorm<I: Scalar, N: RealField, D: Dimension>(v: TVec<N, D>) -> TVec<I, D>
|
||||||
where DefaultAllocator: Alloc<N, D> + Alloc<I, D> {
|
where DefaultAllocator: Alloc<N, D> + Alloc<I, D> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ pub fn packUint4x8(v: &U8Vec4) -> i32 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn packUnorm<UI: Scalar, N: Real, D: Dimension>(v: &TVec<N, D>) -> TVec<UI, D>
|
pub fn packUnorm<UI: Scalar, N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<UI, D>
|
||||||
where DefaultAllocator: Alloc<N, D> + Alloc<UI, D> {
|
where DefaultAllocator: Alloc<N, D> + Alloc<UI, D> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ pub fn unpackRGBM<N: Scalar>(rgbm: &TVec4<N>) -> TVec3<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unpackSnorm<I: Scalar, N: Real, D: Dimension>(v: &TVec<I, D>) -> TVec<N, D>
|
pub fn unpackSnorm<I: Scalar, N: RealField, D: Dimension>(v: &TVec<I, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, D> + Alloc<I, D> {
|
where DefaultAllocator: Alloc<N, D> + Alloc<I, D> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
@ -245,7 +245,7 @@ pub fn unpackUint4x8(p: i32) -> U8Vec4 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unpackUnorm<UI: Scalar, N: Real, D: Dimension>(v: &TVec<UI, D>) -> TVec<N, D>
|
pub fn unpackUnorm<UI: Scalar, N: RealField, D: Dimension>(v: &TVec<UI, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, D> + Alloc<UI, D> {
|
where DefaultAllocator: Alloc<N, D> + Alloc<UI, D> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,37 +1,37 @@
|
||||||
use na::{Real, UnitQuaternion, U4};
|
use na::{RealField, UnitQuaternion, U4};
|
||||||
|
|
||||||
use 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: Real>(x: &Qua<N>) -> TVec3<N> {
|
pub fn quat_euler_angles<N: RealField>(x: &Qua<N>) -> TVec3<N> {
|
||||||
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: Real>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> {
|
pub fn quat_greater_than<N: RealField>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> {
|
||||||
::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: Real>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> {
|
pub fn quat_greater_than_equal<N: RealField>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> {
|
||||||
::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: Real>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> {
|
pub fn quat_less_than<N: RealField>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> {
|
||||||
::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: Real>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> {
|
pub fn quat_less_than_equal<N: RealField>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> {
|
||||||
::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: Real>(x: &Qua<N>) -> TMat4<N> {
|
pub fn quat_cast<N: RealField>(x: &Qua<N>) -> TMat4<N> {
|
||||||
::quat_to_mat4(x)
|
crate::quat_to_mat4(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes a right hand look-at quaternion
|
/// Computes a right hand look-at quaternion
|
||||||
|
@ -41,34 +41,34 @@ pub fn quat_cast<N: Real>(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: Real>(direction: &TVec3<N>, up: &TVec3<N>) -> Qua<N> {
|
pub fn quat_look_at<N: RealField>(direction: &TVec3<N>, up: &TVec3<N>) -> Qua<N> {
|
||||||
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: Real>(direction: &TVec3<N>, up: &TVec3<N>) -> Qua<N> {
|
pub fn quat_look_at_lh<N: RealField>(direction: &TVec3<N>, up: &TVec3<N>) -> Qua<N> {
|
||||||
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: Real>(direction: &TVec3<N>, up: &TVec3<N>) -> Qua<N> {
|
pub fn quat_look_at_rh<N: RealField>(direction: &TVec3<N>, up: &TVec3<N>) -> Qua<N> {
|
||||||
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: Real>(x: &Qua<N>) -> N {
|
pub fn quat_roll<N: RealField>(x: &Qua<N>) -> N {
|
||||||
// FIXME: optimize this.
|
// FIXME: 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: Real>(x: &Qua<N>) -> N {
|
pub fn quat_yaw<N: RealField>(x: &Qua<N>) -> N {
|
||||||
// FIXME: optimize this.
|
// FIXME: 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: Real>(x: &Qua<N>) -> N {
|
pub fn quat_pitch<N: RealField>(x: &Qua<N>) -> N {
|
||||||
// FIXME: optimize this.
|
// FIXME: optimize this.
|
||||||
quat_euler_angles(x).x
|
quat_euler_angles(x).x
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use na::{Scalar, Real, U3, DefaultAllocator};
|
use na::{Scalar, RealField, U3, DefaultAllocator};
|
||||||
|
|
||||||
use traits::{Number, Alloc, Dimension};
|
use crate::traits::{Number, Alloc, Dimension};
|
||||||
use aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
|
|
||||||
|
|
||||||
pub fn ceilMultiple<T>(v: T, Multiple: T) -> T {
|
pub fn ceilMultiple<T>(v: T, Multiple: T) -> T {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use na::{DefaultAllocator, Quaternion, Real, Scalar};
|
use na::{DefaultAllocator, Quaternion, RealField, Scalar};
|
||||||
|
|
||||||
use 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 traits::{Alloc, Dimension, Number};
|
use crate::traits::{Alloc, Dimension, 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<N: Scalar>(ptr: &[N]) -> TMat2<N> {
|
||||||
|
@ -112,7 +112,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: Real>(ptr: &[N]) -> Qua<N> {
|
pub fn make_quat<N: RealField>(ptr: &[N]) -> Qua<N> {
|
||||||
Quaternion::from(TVec4::from_column_slice(ptr))
|
Quaternion::from(TVec4::from_column_slice(ptr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use na::{Scalar, U2};
|
use na::{Scalar, U2};
|
||||||
|
|
||||||
use 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 {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use na::{self, DefaultAllocator};
|
use na::{self, DefaultAllocator};
|
||||||
|
|
||||||
use aliases::TMat;
|
use crate::aliases::TMat;
|
||||||
use traits::{Alloc, Dimension, Number};
|
use crate::traits::{Alloc, Dimension, Number};
|
||||||
|
|
||||||
/// The sum of every component of the given matrix or vector.
|
/// The sum of every component of the given matrix or vector.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1,163 +1,163 @@
|
||||||
use na::{Real, U3, U4};
|
use na::{RealField, U3, U4};
|
||||||
|
|
||||||
use aliases::{TVec, TMat};
|
use crate::aliases::{TVec, TMat};
|
||||||
|
|
||||||
pub fn derivedEulerAngleX<N: Real>(angleX: N, angularVelocityX: N) -> TMat4<N> {
|
pub fn derivedEulerAngleX<N: RealField>(angleX: N, angularVelocityX: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn derivedEulerAngleY<N: Real>(angleY: N, angularVelocityY: N) -> TMat4<N> {
|
pub fn derivedEulerAngleY<N: RealField>(angleY: N, angularVelocityY: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn derivedEulerAngleZ<N: Real>(angleZ: N, angularVelocityZ: N) -> TMat4<N> {
|
pub fn derivedEulerAngleZ<N: RealField>(angleZ: N, angularVelocityZ: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleX<N: Real>(angleX: N) -> TMat4<N> {
|
pub fn eulerAngleX<N: RealField>(angleX: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleXY<N: Real>(angleX: N, angleY: N) -> TMat4<N> {
|
pub fn eulerAngleXY<N: RealField>(angleX: N, angleY: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleXYX<N: Real>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleXYX<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleXYZ<N: Real>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleXYZ<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleXZ<N: Real>(angleX: N, angleZ: N) -> TMat4<N> {
|
pub fn eulerAngleXZ<N: RealField>(angleX: N, angleZ: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleXZX<N: Real>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleXZX<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleXZY<N: Real>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleXZY<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleY<N: Real>(angleY: N) -> TMat4<N> {
|
pub fn eulerAngleY<N: RealField>(angleY: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleYX<N: Real>(angleY: N, angleX: N) -> TMat4<N> {
|
pub fn eulerAngleYX<N: RealField>(angleY: N, angleX: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleYXY<N: Real>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleYXY<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleYXZ<N: Real>(yaw: N, pitch: N, roll: N) -> TMat4<N> {
|
pub fn eulerAngleYXZ<N: RealField>(yaw: N, pitch: N, roll: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleYZ<N: Real>(angleY: N, angleZ: N) -> TMat4<N> {
|
pub fn eulerAngleYZ<N: RealField>(angleY: N, angleZ: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleYZX<N: Real>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleYZX<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleYZY<N: Real>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleYZY<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleZ<N: Real>(angleZ: N) -> TMat4<N> {
|
pub fn eulerAngleZ<N: RealField>(angleZ: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleZX<N: Real>(angle: N, angleX: N) -> TMat4<N> {
|
pub fn eulerAngleZX<N: RealField>(angle: N, angleX: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleZXY<N: Real>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleZXY<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleZXZ<N: Real>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleZXZ<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleZY<N: Real>(angleZ: N, angleY: N) -> TMat4<N> {
|
pub fn eulerAngleZY<N: RealField>(angleZ: N, angleY: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleZYX<N: Real>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleZYX<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eulerAngleZYZ<N: Real>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
pub fn eulerAngleZYZ<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleXYX<N: Real>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleXYX<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleXYZ<N: Real>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleXYZ<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleXZX<N: Real>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleXZX<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleXZY<N: Real>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleXZY<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleYXY<N: Real>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleYXY<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleYXZ<N: Real>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleYXZ<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleYZX<N: Real>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleYZX<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleYZY<N: Real>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleYZY<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleZXY<N: Real>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleZXY<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleZXZ<N: Real>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleZXZ<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleZYX<N: Real>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleZYX<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extractEulerAngleZYZ<N: Real>(M: &TMat4<N>) -> (N, N, N) {
|
pub fn extractEulerAngleZYZ<N: RealField>(M: &TMat4<N>) -> (N, N, N) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn orientate2<N: Real>(angle: N) -> TMat3x3<N> {
|
pub fn orientate2<N: RealField>(angle: N) -> TMat3x3<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn orientate3<N: Real>(angles: TVec3<N>) -> TMat3x3<N> {
|
pub fn orientate3<N: RealField>(angles: TVec3<N>) -> TMat3x3<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn orientate4<N: Real>(angles: TVec3<N>) -> TMat4<N> {
|
pub fn orientate4<N: RealField>(angles: TVec3<N>) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn yawPitchRoll<N: Real>(yaw: N, pitch: N, roll: N) -> TMat4<N> {
|
pub fn yawPitchRoll<N: RealField>(yaw: N, pitch: N, roll: N) -> TMat4<N> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use aliases::TVec2;
|
use crate::aliases::TVec2;
|
||||||
use 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<N: Number>(v: &TVec2<N>, u: &TVec2<N>) -> N {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use aliases::TVec3;
|
use crate::aliases::TVec3;
|
||||||
use traits::Number;
|
use crate::traits::Number;
|
||||||
|
|
||||||
/// Returns `true` if `{a, b, c}` forms a left-handed trihedron.
|
/// Returns `true` if `{a, b, c}` forms a left-handed trihedron.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
use na::Real;
|
use na::RealField;
|
||||||
|
|
||||||
use aliases::{TMat3, TMat4, TVec3};
|
use crate::aliases::{TMat3, TMat4, TVec3};
|
||||||
|
|
||||||
/// Builds a 3x3 matrix `m` such that for any `v`: `m * v == cross(x, v)`.
|
/// Builds a 3x3 matrix `m` such that for any `v`: `m * v == cross(x, v)`.
|
||||||
///
|
///
|
||||||
/// # See also:
|
/// # See also:
|
||||||
///
|
///
|
||||||
/// * [`matrix_cross`](fn.matrix_cross.html)
|
/// * [`matrix_cross`](fn.matrix_cross.html)
|
||||||
pub fn matrix_cross3<N: Real>(x: &TVec3<N>) -> TMat3<N> {
|
pub fn matrix_cross3<N: RealField>(x: &TVec3<N>) -> TMat3<N> {
|
||||||
x.cross_matrix()
|
x.cross_matrix()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,6 @@ pub fn matrix_cross3<N: Real>(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: Real>(x: &TVec3<N>) -> TMat4<N> {
|
pub fn matrix_cross<N: RealField>(x: &TVec3<N>) -> TMat4<N> {
|
||||||
::mat3_to_mat4(&x.cross_matrix())
|
crate::mat3_to_mat4(&x.cross_matrix())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use aliases::{
|
use crate::aliases::{
|
||||||
TMat2, TMat2x3, TMat2x4, TMat3, TMat3x2, TMat3x4, TMat4, TMat4x2, TMat4x3, TVec2, TVec3, TVec4,
|
TMat2, TMat2x3, TMat2x4, TMat3, TMat3x2, TMat3x4, TMat4, TMat4x2, TMat4x3, TVec2, TVec3, TVec4,
|
||||||
};
|
};
|
||||||
use traits::Number;
|
use crate::traits::Number;
|
||||||
|
|
||||||
/// Builds a 2x2 diagonal matrix.
|
/// Builds a 2x2 diagonal matrix.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
use na::{DefaultAllocator, Real};
|
use na::{DefaultAllocator, RealField};
|
||||||
|
|
||||||
use aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
use traits::{Alloc, Dimension};
|
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: Real, D: Dimension>(p0: &TVec<N, D>, p1: &TVec<N, D>) -> N
|
pub fn distance2<N: RealField, D: Dimension>(p0: &TVec<N, D>, p1: &TVec<N, D>) -> N
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
(p1 - p0).norm_squared()
|
(p1 - p0).norm_squared()
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ where DefaultAllocator: Alloc<N, D> {
|
||||||
/// * [`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: Real, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
|
pub fn l1_distance<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
l1_norm(&(y - x))
|
l1_norm(&(y - x))
|
||||||
}
|
}
|
||||||
|
@ -35,9 +35,9 @@ where DefaultAllocator: Alloc<N, D> {
|
||||||
/// * [`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: Real, D: Dimension>(v: &TVec<N, D>) -> N
|
pub fn l1_norm<N: RealField, D: Dimension>(v: &TVec<N, D>) -> N
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
::comp_add(&v.abs())
|
crate::comp_add(&v.abs())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The l2-norm of `x - y`.
|
/// The l2-norm of `x - y`.
|
||||||
|
@ -54,7 +54,7 @@ where DefaultAllocator: Alloc<N, D> {
|
||||||
/// * [`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: Real, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
|
pub fn l2_distance<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
l2_norm(&(y - x))
|
l2_norm(&(y - x))
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ where DefaultAllocator: Alloc<N, D> {
|
||||||
/// * [`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: Real, D: Dimension>(x: &TVec<N, D>) -> N
|
pub fn l2_norm<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
x.norm()
|
x.norm()
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ where DefaultAllocator: Alloc<N, D> {
|
||||||
/// * [`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: Real, D: Dimension>(x: &TVec<N, D>) -> N
|
pub fn length2<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
x.norm_squared()
|
x.norm_squared()
|
||||||
}
|
}
|
||||||
|
@ -107,17 +107,17 @@ where DefaultAllocator: Alloc<N, D> {
|
||||||
/// * [`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: Real, D: Dimension>(x: &TVec<N, D>) -> N
|
pub fn magnitude2<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
x.norm_squared()
|
x.norm_squared()
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn lxNorm<N: Real, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, unsigned int Depth) -> N
|
//pub fn lxNorm<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, unsigned int Depth) -> N
|
||||||
// where DefaultAllocator: Alloc<N, D> {
|
// where DefaultAllocator: Alloc<N, D> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn lxNorm<N: Real, D: Dimension>(x: &TVec<N, D>, unsigned int Depth) -> N
|
//pub fn lxNorm<N: RealField, D: Dimension>(x: &TVec<N, D>, unsigned int Depth) -> N
|
||||||
// where DefaultAllocator: Alloc<N, D> {
|
// where DefaultAllocator: Alloc<N, D> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use na::Real;
|
use na::RealField;
|
||||||
|
|
||||||
use aliases::TVec3;
|
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: Real>(p1: &TVec3<N>, p2: &TVec3<N>, p3: &TVec3<N>) -> TVec3<N> {
|
pub fn triangle_normal<N: RealField>(p1: &TVec3<N>, p2: &TVec3<N>, p3: &TVec3<N>) -> TVec3<N> {
|
||||||
(p2 - p1).cross(&(p3 - p1)).normalize()
|
(p2 - p1).cross(&(p3 - p1)).normalize()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use na::{DefaultAllocator, Real};
|
use na::{DefaultAllocator, RealField};
|
||||||
|
|
||||||
use aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
use traits::{Alloc, Dimension};
|
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,7 +10,7 @@ use 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: Real, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
|
pub fn fast_normalize_dot<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
// XXX: improve those.
|
// XXX: improve those.
|
||||||
x.normalize().dot(&y.normalize())
|
x.normalize().dot(&y.normalize())
|
||||||
|
@ -21,7 +21,7 @@ where DefaultAllocator: Alloc<N, D> {
|
||||||
/// # 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: Real, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
|
pub fn normalize_dot<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
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::{Real, Rotation3, Unit, UnitQuaternion, U3};
|
use na::{RealField, Rotation3, Unit, UnitQuaternion, U3};
|
||||||
|
|
||||||
use 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: Real>(q: &Qua<N>, v: &TVec3<N>) -> TVec3<N> {
|
pub fn quat_cross_vec<N: RealField>(q: &Qua<N>, v: &TVec3<N>) -> TVec3<N> {
|
||||||
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: Real>(v: &TVec3<N>, q: &Qua<N>) -> TVec3<N> {
|
pub fn quat_inv_cross_vec<N: RealField>(v: &TVec3<N>, q: &Qua<N>) -> TVec3<N> {
|
||||||
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: Real>(q: &Qua<N>) -> N {
|
pub fn quat_extract_real_component<N: RealField>(q: &Qua<N>) -> N {
|
||||||
q.w
|
q.w
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Normalized linear interpolation between two quaternions.
|
/// Normalized linear interpolation between two quaternions.
|
||||||
pub fn quat_fast_mix<N: Real>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> {
|
pub fn quat_fast_mix<N: RealField>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> {
|
||||||
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: Real>(prev: &Qua<N>, curr: &Qua<N>, next: &Qua<N>) -> Qua<N> {
|
//pub fn quat_intermediate<N: RealField>(prev: &Qua<N>, curr: &Qua<N>, next: &Qua<N>) -> Qua<N> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
/// The squared magnitude of a quaternion `q`.
|
/// The squared magnitude of a quaternion `q`.
|
||||||
pub fn quat_length2<N: Real>(q: &Qua<N>) -> N {
|
pub fn quat_length2<N: RealField>(q: &Qua<N>) -> N {
|
||||||
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: Real>(q: &Qua<N>) -> N {
|
pub fn quat_magnitude2<N: RealField>(q: &Qua<N>) -> N {
|
||||||
q.norm_squared()
|
q.norm_squared()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The quaternion representing the identity rotation.
|
/// The quaternion representing the identity rotation.
|
||||||
pub fn quat_identity<N: Real>() -> Qua<N> {
|
pub fn quat_identity<N: RealField>() -> Qua<N> {
|
||||||
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: Real>(q: &Qua<N>, v: &TVec3<N>) -> TVec3<N> {
|
pub fn quat_rotate_vec3<N: RealField>(q: &Qua<N>, v: &TVec3<N>) -> TVec3<N> {
|
||||||
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: Real>(q: &Qua<N>, v: &TVec4<N>) -> TVec4<N> {
|
pub fn quat_rotate_vec<N: RealField>(q: &Qua<N>, v: &TVec4<N>) -> TVec4<N> {
|
||||||
let rotated = Unit::new_unchecked(*q) * v.fixed_rows::<U3>(0);
|
let rotated = Unit::new_unchecked(*q) * v.fixed_rows::<U3>(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: Real>(orig: &TVec3<N>, dest: &TVec3<N>) -> Qua<N> {
|
pub fn quat_rotation<N: RealField>(orig: &TVec3<N>, dest: &TVec3<N>) -> Qua<N> {
|
||||||
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: Real>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> {
|
pub fn quat_short_mix<N: RealField>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> {
|
||||||
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: Real>(q1: &Qua<N>, q2: &Qua<N>, s1: &Qua<N>, s2: &Qua<N>, h: N) -> Qua<N> {
|
//pub fn quat_squad<N: RealField>(q1: &Qua<N>, q2: &Qua<N>, s1: &Qua<N>, s2: &Qua<N>, h: N) -> Qua<N> {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
||||||
/// Converts a quaternion to a rotation matrix.
|
/// Converts a quaternion to a rotation matrix.
|
||||||
pub fn quat_to_mat3<N: Real>(x: &Qua<N>) -> TMat3<N> {
|
pub fn quat_to_mat3<N: RealField>(x: &Qua<N>) -> TMat3<N> {
|
||||||
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: Real>(x: &Qua<N>) -> TMat4<N> {
|
pub fn quat_to_mat4<N: RealField>(x: &Qua<N>) -> TMat4<N> {
|
||||||
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: Real>(x: &TMat3<N>) -> Qua<N> {
|
pub fn mat3_to_quat<N: RealField>(x: &TMat3<N>) -> Qua<N> {
|
||||||
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: Real>(x: &TMat4<N>) -> Qua<N> {
|
pub fn to_quat<N: RealField>(x: &TMat4<N>) -> Qua<N> {
|
||||||
let rot = x.fixed_slice::<U3, U3>(0, 0).into_owned();
|
let rot = x.fixed_slice::<U3, U3>(0, 0).into_owned();
|
||||||
mat3_to_quat(&rot)
|
mat3_to_quat(&rot)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use na::{Real, Rotation3, Unit, UnitQuaternion};
|
use na::{RealField, Rotation3, Unit, UnitQuaternion};
|
||||||
|
|
||||||
use aliases::{Qua, TMat4, TVec3};
|
use crate::aliases::{Qua, TMat4, TVec3};
|
||||||
|
|
||||||
/// Builds a rotation 4 * 4 matrix created from a normalized axis and an angle.
|
/// Builds a rotation 4 * 4 matrix created from a normalized axis and an angle.
|
||||||
///
|
///
|
||||||
|
@ -9,7 +9,7 @@ use 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: Real>(m: &TMat4<N>, angle: N, axis: &TVec3<N>) -> TMat4<N> {
|
pub fn rotate_normalized_axis<N: RealField>(m: &TMat4<N>, angle: N, axis: &TVec3<N>) -> TMat4<N> {
|
||||||
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: Real>(m: &TMat4<N>, angle: N, axis: &TVec3<N>)
|
||||||
/// * `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: Real>(q: &Qua<N>, angle: N, axis: &TVec3<N>) -> Qua<N> {
|
pub fn quat_rotate_normalized_axis<N: RealField>(q: &Qua<N>, angle: N, axis: &TVec3<N>) -> Qua<N> {
|
||||||
q * UnitQuaternion::from_axis_angle(&Unit::new_unchecked(*axis), angle).into_inner()
|
q * UnitQuaternion::from_axis_angle(&Unit::new_unchecked(*axis), angle).into_inner()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use na::{Real, Rotation3, Unit, UnitComplex};
|
use na::{RealField, Rotation3, Unit, UnitComplex};
|
||||||
|
|
||||||
use 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: Real>(normal: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> {
|
pub fn orientation<N: RealField>(normal: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> {
|
||||||
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: Real>(normal: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate a two dimensional vector.
|
/// Rotate a two dimensional vector.
|
||||||
pub fn rotate_vec2<N: Real>(v: &TVec2<N>, angle: N) -> TVec2<N> {
|
pub fn rotate_vec2<N: RealField>(v: &TVec2<N>, angle: N) -> TVec2<N> {
|
||||||
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: Real>(v: &TVec3<N>, angle: N, normal: &TVec3<N>) -> TVec3<N> {
|
pub fn rotate_vec3<N: RealField>(v: &TVec3<N>, angle: N, normal: &TVec3<N>) -> TVec3<N> {
|
||||||
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: Real>(v: &TVec4<N>, angle: N, normal: &TVec3<N>) -> TVec4<N> {
|
pub fn rotate_vec4<N: RealField>(v: &TVec4<N>, angle: N, normal: &TVec3<N>) -> TVec4<N> {
|
||||||
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: Real>(v: &TVec3<N>, angle: N) -> TVec3<N> {
|
pub fn rotate_x_vec3<N: RealField>(v: &TVec3<N>, angle: N) -> TVec3<N> {
|
||||||
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: Real>(v: &TVec4<N>, angle: N) -> TVec4<N> {
|
pub fn rotate_x_vec4<N: RealField>(v: &TVec4<N>, angle: N) -> TVec4<N> {
|
||||||
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: Real>(v: &TVec3<N>, angle: N) -> TVec3<N> {
|
pub fn rotate_y_vec3<N: RealField>(v: &TVec3<N>, angle: N) -> TVec3<N> {
|
||||||
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: Real>(v: &TVec4<N>, angle: N) -> TVec4<N> {
|
pub fn rotate_y_vec4<N: RealField>(v: &TVec4<N>, angle: N) -> TVec4<N> {
|
||||||
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: Real>(v: &TVec3<N>, angle: N) -> TVec3<N> {
|
pub fn rotate_z_vec3<N: RealField>(v: &TVec3<N>, angle: N) -> TVec3<N> {
|
||||||
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: Real>(v: &TVec4<N>, angle: N) -> TVec4<N> {
|
pub fn rotate_z_vec4<N: RealField>(v: &TVec4<N>, angle: N) -> TVec4<N> {
|
||||||
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: Real>(x: &TVec3<N>, y: &TVec3<N>, a: N) -> TVec3<N> {
|
pub fn slerp<N: RealField>(x: &TVec3<N>, y: &TVec3<N>, a: N) -> TVec3<N> {
|
||||||
Unit::new_unchecked(*x)
|
Unit::new_unchecked(*x)
|
||||||
.slerp(&Unit::new_unchecked(*y), a)
|
.slerp(&Unit::new_unchecked(*y), a)
|
||||||
.into_inner()
|
.into_inner()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use na::{Real, Rotation2, Rotation3, Unit};
|
use na::{RealField, Rotation2, Rotation3, Unit};
|
||||||
|
|
||||||
use aliases::{TMat3, TMat4, TVec2, TVec3};
|
use crate::aliases::{TMat3, TMat4, TVec2, TVec3};
|
||||||
use traits::Number;
|
use crate::traits::Number;
|
||||||
|
|
||||||
/// A rotation 4 * 4 matrix created from an axis of 3 scalars and an angle expressed in radians.
|
/// A rotation 4 * 4 matrix created from an axis of 3 scalars and an angle expressed in radians.
|
||||||
///
|
///
|
||||||
|
@ -12,7 +12,7 @@ use 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: Real>(angle: N, v: &TVec3<N>) -> TMat4<N> {
|
pub fn rotation<N: RealField>(angle: N, v: &TVec3<N>) -> TMat4<N> {
|
||||||
Rotation3::from_axis_angle(&Unit::new_normalize(*v), angle).to_homogeneous()
|
Rotation3::from_axis_angle(&Unit::new_normalize(*v), angle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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: Real>(angle: N) -> TMat3<N> {
|
pub fn rotation2d<N: RealField>(angle: N) -> TMat3<N> {
|
||||||
Rotation2::new(angle).to_homogeneous()
|
Rotation2::new(angle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use na::{U2, U3};
|
use na::{U2, U3};
|
||||||
|
|
||||||
use aliases::{TMat3, TMat4, TVec2, TVec3};
|
use crate::aliases::{TMat3, TMat4, TVec2, TVec3};
|
||||||
use 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<N: Number>(m: &TMat3<N>, normal: &TVec2<N>) -> TMat3<N> {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use na::{Real, UnitComplex};
|
use na::{RealField, UnitComplex};
|
||||||
|
|
||||||
use aliases::{TMat3, TVec2};
|
use crate::aliases::{TMat3, TVec2};
|
||||||
use traits::Number;
|
use crate::traits::Number;
|
||||||
|
|
||||||
/// Builds a 2D rotation matrix from an angle and right-multiply it to `m`.
|
/// Builds a 2D rotation matrix from an angle and right-multiply it to `m`.
|
||||||
///
|
///
|
||||||
|
@ -12,7 +12,7 @@ use 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: Real>(m: &TMat3<N>, angle: N) -> TMat3<N> {
|
pub fn rotate2d<N: RealField>(m: &TMat3<N>, angle: N) -> TMat3<N> {
|
||||||
m * UnitComplex::new(angle).to_homogeneous()
|
m * UnitComplex::new(angle).to_homogeneous()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
use na::{DefaultAllocator, Real};
|
use na::{DefaultAllocator, RealField};
|
||||||
|
|
||||||
use aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
use traits::{Alloc, Dimension};
|
use crate::traits::{Alloc, Dimension};
|
||||||
|
|
||||||
/// The angle between two vectors.
|
/// The angle between two vectors.
|
||||||
pub fn angle<N: Real, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
|
pub fn angle<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
x.angle(y)
|
x.angle(y)
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub fn oriented_angle<N: Real>(x: &TVec2<N>, y: &TVec2<N>) -> N {
|
//pub fn oriented_angle<N: RealField>(x: &TVec2<N>, y: &TVec2<N>) -> N {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//pub fn oriented_angle_ref<N: Real>(x: &TVec3<N>, y: &TVec3<N>, refv: &TVec3<N>) -> N {
|
//pub fn oriented_angle_ref<N: RealField>(x: &TVec3<N>, y: &TVec3<N>, refv: &TVec3<N>) -> N {
|
||||||
// unimplemented!()
|
// unimplemented!()
|
||||||
//}
|
//}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use na::{DefaultAllocator, Real};
|
use na::{DefaultAllocator, RealField};
|
||||||
|
|
||||||
use aliases::{TVec, TVec2, TVec3};
|
use crate::aliases::{TVec, TVec2, TVec3};
|
||||||
use traits::{Alloc, Dimension, Number};
|
use crate::traits::{Alloc, Dimension, Number};
|
||||||
|
|
||||||
/// Returns `true` if two vectors are collinear (up to an epsilon).
|
/// Returns `true` if two vectors are collinear (up to an epsilon).
|
||||||
///
|
///
|
||||||
|
@ -45,7 +45,7 @@ where DefaultAllocator: Alloc<N, D> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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: Real, D: Dimension>(v: &TVec<N, D>, epsilon: N) -> bool
|
pub fn is_normalized<N: RealField, D: Dimension>(v: &TVec<N, D>, epsilon: N) -> bool
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
abs_diff_eq!(v.norm_squared(), N::one(), epsilon = epsilon * epsilon)
|
abs_diff_eq!(v.norm_squared(), N::one(), epsilon = epsilon * epsilon)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use na::{Scalar, Real, U3, DefaultAllocator};
|
use na::{Scalar, RealField, U3, DefaultAllocator};
|
||||||
|
|
||||||
use traits::{Number, Alloc, Dimension};
|
use crate::traits::{Number, Alloc, Dimension};
|
||||||
use aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
|
|
||||||
pub fn bitCount<T>(v: T) -> i32 {
|
pub fn bitCount<T>(v: T) -> i32 {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
|
|
|
@ -119,7 +119,7 @@ extern crate approx;
|
||||||
extern crate alga;
|
extern crate alga;
|
||||||
extern crate nalgebra as na;
|
extern crate nalgebra as na;
|
||||||
|
|
||||||
pub use aliases::*;
|
pub use crate::aliases::*;
|
||||||
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,
|
||||||
|
@ -133,7 +133,7 @@ pub use geometric::{
|
||||||
cross, distance, dot, faceforward, length, magnitude, normalize, reflect_vec, refract_vec,
|
cross, distance, dot, faceforward, length, magnitude, normalize, reflect_vec, refract_vec,
|
||||||
};
|
};
|
||||||
pub use matrix::{determinant, inverse, matrix_comp_mult, outer_product, transpose};
|
pub use matrix::{determinant, inverse, matrix_comp_mult, outer_product, transpose};
|
||||||
pub use traits::{Alloc, Dimension, Number};
|
pub use crate::traits::{Alloc, Dimension, Number};
|
||||||
pub use trigonometric::{
|
pub use trigonometric::{
|
||||||
acos, acosh, asin, asinh, atan, atan2, atanh, cos, cosh, degrees, radians, sin, sinh, tan, tanh,
|
acos, acosh, asin, asinh, atan, atan2, atanh, cos, cosh, degrees, radians, sin, sinh, tan, tanh,
|
||||||
};
|
};
|
||||||
|
@ -191,7 +191,7 @@ pub use gtx::{
|
||||||
pub use na::{
|
pub use na::{
|
||||||
convert, convert_ref, convert_ref_unchecked, convert_unchecked, try_convert, try_convert_ref,
|
convert, convert_ref, convert_ref_unchecked, convert_unchecked, try_convert, try_convert_ref,
|
||||||
};
|
};
|
||||||
pub use na::{DefaultAllocator, Real, Scalar, U1, U2, U3, U4};
|
pub use na::{DefaultAllocator, RealField, Scalar, U1, U2, U3, U4};
|
||||||
|
|
||||||
mod aliases;
|
mod aliases;
|
||||||
mod common;
|
mod common;
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
use na::{DefaultAllocator, Real, Scalar};
|
use na::{DefaultAllocator, RealField, Scalar};
|
||||||
|
|
||||||
use aliases::{TMat, TVec};
|
use crate::aliases::{TMat, TVec};
|
||||||
use traits::{Alloc, Dimension, Number};
|
use crate::traits::{Alloc, Dimension, Number};
|
||||||
|
|
||||||
/// The determinant of the matrix `m`.
|
/// The determinant of the matrix `m`.
|
||||||
pub fn determinant<N: Real, D: Dimension>(m: &TMat<N, D, D>) -> N
|
pub fn determinant<N: RealField, D: Dimension>(m: &TMat<N, D, D>) -> N
|
||||||
where DefaultAllocator: Alloc<N, D, D> {
|
where DefaultAllocator: Alloc<N, D, D> {
|
||||||
m.determinant()
|
m.determinant()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The inverse of the matrix `m`.
|
/// The inverse of the matrix `m`.
|
||||||
pub fn inverse<N: Real, D: Dimension>(m: &TMat<N, D, D>) -> TMat<N, D, D>
|
pub fn inverse<N: RealField, D: Dimension>(m: &TMat<N, D, D>) -> TMat<N, D, D>
|
||||||
where DefaultAllocator: Alloc<N, D, D> {
|
where DefaultAllocator: Alloc<N, D, D> {
|
||||||
m.clone()
|
m.clone()
|
||||||
.try_inverse()
|
.try_inverse()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use na::Scalar;
|
use na::Scalar;
|
||||||
|
|
||||||
use aliases::{Vec2, Vec4, UVec2};
|
use crate::aliases::{Vec2, Vec4, UVec2};
|
||||||
|
|
||||||
|
|
||||||
pub fn packDouble2x32<N: Scalar>(v: &UVec2) -> f64 {
|
pub fn packDouble2x32<N: Scalar>(v: &UVec2) -> f64 {
|
||||||
|
|
|
@ -1,94 +1,94 @@
|
||||||
use na::{self, DefaultAllocator, Real};
|
use na::{self, DefaultAllocator, RealField};
|
||||||
|
|
||||||
use aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
use traits::{Alloc, Dimension};
|
use crate::traits::{Alloc, Dimension};
|
||||||
|
|
||||||
/// Component-wise arc-cosinus.
|
/// Component-wise arc-cosinus.
|
||||||
pub fn acos<N: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn acos<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, 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: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn acosh<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, 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: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn asin<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, 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: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn asinh<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, 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: Real, D: Dimension>(y: &TVec<N, D>, x: &TVec<N, D>) -> TVec<N, D>
|
pub fn atan2<N: RealField, D: Dimension>(y: &TVec<N, D>, x: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, 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: Real, D: Dimension>(y_over_x: &TVec<N, D>) -> TVec<N, D>
|
pub fn atan<N: RealField, D: Dimension>(y_over_x: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, 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: Real, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
pub fn atanh<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, 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: Real, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
|
pub fn cos<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, 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: Real, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
|
pub fn cosh<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, 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: Real, D: Dimension>(radians: &TVec<N, D>) -> TVec<N, D>
|
pub fn degrees<N: RealField, D: Dimension>(radians: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
radians.map(|e| e * na::convert(180.0) / N::pi())
|
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: Real, D: Dimension>(degrees: &TVec<N, D>) -> TVec<N, D>
|
pub fn radians<N: RealField, D: Dimension>(degrees: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
degrees.map(|e| e * N::pi() / na::convert(180.0))
|
degrees.map(|e| e * N::pi() / na::convert(180.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Component-wise sinus.
|
/// Component-wise sinus.
|
||||||
pub fn sin<N: Real, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
|
pub fn sin<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, 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: Real, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
|
pub fn sinh<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, 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: Real, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
|
pub fn tan<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, 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: Real, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
|
pub fn tanh<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D>
|
||||||
where DefaultAllocator: Alloc<N, D> {
|
where DefaultAllocator: Alloc<N, D> {
|
||||||
angle.map(|e| e.tanh())
|
angle.map(|e| e.tanh())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use na::DefaultAllocator;
|
use na::DefaultAllocator;
|
||||||
|
|
||||||
use aliases::TVec;
|
use crate::aliases::TVec;
|
||||||
use traits::{Alloc, Dimension, Number};
|
use crate::traits::{Alloc, Dimension, Number};
|
||||||
|
|
||||||
/// Checks that all the vector components are `true`.
|
/// Checks that all the vector components are `true`.
|
||||||
///
|
///
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "nalgebra-lapack"
|
name = "nalgebra-lapack"
|
||||||
version = "0.9.0"
|
version = "0.10.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 = "Linear algebra library with transformations and satically-sized or dynamically-sized matrices."
|
description = "Linear algebra library with transformations and satically-sized or dynamically-sized matrices."
|
||||||
|
@ -10,6 +10,7 @@ repository = "https://github.com/rustsim/nalgebra"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
keywords = [ "linear", "algebra", "matrix", "vector" ]
|
keywords = [ "linear", "algebra", "matrix", "vector" ]
|
||||||
license = "BSD-3-Clause"
|
license = "BSD-3-Clause"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
serde-serialize = [ "serde", "serde_derive" ]
|
serde-serialize = [ "serde", "serde_derive" ]
|
||||||
|
@ -22,10 +23,10 @@ accelerate = ["lapack-src/accelerate"]
|
||||||
intel-mkl = ["lapack-src/intel-mkl"]
|
intel-mkl = ["lapack-src/intel-mkl"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nalgebra = { version = "0.17", path = ".." }
|
nalgebra = { version = "0.18", path = ".." }
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
num-complex = { version = "0.2", default-features = false }
|
num-complex = { version = "0.2", default-features = false }
|
||||||
alga = { version = "0.8", default-features = false }
|
alga = { version = "0.9", default-features = false }
|
||||||
serde = { version = "1.0", optional = true }
|
serde = { version = "1.0", optional = true }
|
||||||
serde_derive = { version = "1.0", optional = true }
|
serde_derive = { version = "1.0", optional = true }
|
||||||
lapack = { version = "0.16", default-features = false }
|
lapack = { version = "0.16", default-features = false }
|
||||||
|
@ -33,7 +34,7 @@ lapack-src = { version = "0.2", default-features = false }
|
||||||
# clippy = "*"
|
# clippy = "*"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
nalgebra = { version = "0.17", path = "..", features = [ "arbitrary" ] }
|
nalgebra = { version = "0.18", path = "..", features = [ "arbitrary" ] }
|
||||||
quickcheck = "0.8"
|
quickcheck = "0.8"
|
||||||
approx = "0.3"
|
approx = "0.3"
|
||||||
rand = "0.6"
|
rand = "0.6"
|
||||||
|
|
|
@ -4,13 +4,13 @@ use serde::{Deserialize, Serialize};
|
||||||
use num::Zero;
|
use num::Zero;
|
||||||
use num_complex::Complex;
|
use num_complex::Complex;
|
||||||
|
|
||||||
use alga::general::Real;
|
use alga::general::RealField;
|
||||||
|
|
||||||
use na::allocator::Allocator;
|
use na::allocator::Allocator;
|
||||||
use na::dimension::{Dim, U1};
|
use na::dimension::{Dim, U1};
|
||||||
use na::storage::Storage;
|
use na::storage::Storage;
|
||||||
use na::{DefaultAllocator, Matrix, MatrixN, Scalar, VectorN};
|
use na::{DefaultAllocator, Matrix, MatrixN, Scalar, VectorN};
|
||||||
use ComplexHelper;
|
use crate::ComplexHelper;
|
||||||
|
|
||||||
use lapack;
|
use lapack;
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ where
|
||||||
MatrixN<N, D>: Copy,
|
MatrixN<N, D>: Copy,
|
||||||
{}
|
{}
|
||||||
|
|
||||||
impl<N: EigenScalar + Real, D: Dim> Eigen<N, D>
|
impl<N: EigenScalar + RealField, D: Dim> Eigen<N, D>
|
||||||
where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>
|
where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>
|
||||||
{
|
{
|
||||||
/// Computes the eigenvalues and eigenvectors of the square matrix `m`.
|
/// Computes the eigenvalues and eigenvectors of the square matrix `m`.
|
||||||
|
@ -101,7 +101,7 @@ where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>
|
||||||
|
|
||||||
lapack_check!(info);
|
lapack_check!(info);
|
||||||
|
|
||||||
let mut work = unsafe { ::uninitialized_vec(lwork as usize) };
|
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
|
||||||
|
|
||||||
match (left_eigenvectors, eigenvectors) {
|
match (left_eigenvectors, eigenvectors) {
|
||||||
(true, true) => {
|
(true, true) => {
|
||||||
|
@ -263,7 +263,7 @@ where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>
|
||||||
|
|
||||||
lapack_panic!(info);
|
lapack_panic!(info);
|
||||||
|
|
||||||
let mut work = unsafe { ::uninitialized_vec(lwork as usize) };
|
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
|
||||||
|
|
||||||
N::xgeev(
|
N::xgeev(
|
||||||
b'N',
|
b'N',
|
||||||
|
|
|
@ -5,7 +5,7 @@ use na::allocator::Allocator;
|
||||||
use na::dimension::{DimDiff, DimSub, U1};
|
use na::dimension::{DimDiff, DimSub, U1};
|
||||||
use na::storage::Storage;
|
use na::storage::Storage;
|
||||||
use na::{DefaultAllocator, Matrix, MatrixN, Scalar, VectorN};
|
use na::{DefaultAllocator, Matrix, MatrixN, Scalar, VectorN};
|
||||||
use ComplexHelper;
|
use crate::ComplexHelper;
|
||||||
|
|
||||||
use lapack;
|
use lapack;
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ where DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimDiff<D, U1>>
|
||||||
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);
|
N::xgehrd_work_size(n, 1, n, m.as_mut_slice(), n, tau.as_mut_slice(), &mut info);
|
||||||
let mut work = unsafe { ::uninitialized_vec(lwork as usize) };
|
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
|
||||||
|
|
||||||
lapack_panic!(info);
|
lapack_panic!(info);
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ pub use self::eigen::Eigen;
|
||||||
pub use self::hessenberg::Hessenberg;
|
pub use self::hessenberg::Hessenberg;
|
||||||
pub use self::lu::{LUScalar, LU};
|
pub use self::lu::{LUScalar, LU};
|
||||||
pub use self::qr::QR;
|
pub use self::qr::QR;
|
||||||
pub use self::schur::RealSchur;
|
pub use self::schur::Schur;
|
||||||
pub use self::svd::SVD;
|
pub use self::svd::SVD;
|
||||||
pub use self::symmetric_eigen::SymmetricEigen;
|
pub use self::symmetric_eigen::SymmetricEigen;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ use na::allocator::Allocator;
|
||||||
use na::dimension::{Dim, DimMin, DimMinimum, U1};
|
use na::dimension::{Dim, DimMin, DimMinimum, U1};
|
||||||
use na::storage::Storage;
|
use na::storage::Storage;
|
||||||
use na::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Scalar, VectorN};
|
use na::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Scalar, VectorN};
|
||||||
use ComplexHelper;
|
use crate::ComplexHelper;
|
||||||
|
|
||||||
use lapack;
|
use lapack;
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Solves the linear system `self.conjugate_transpose() * x = b`, where `x` is the unknown to
|
/// Solves the linear system `self.adjoint() * x = b`, where `x` is the unknown to
|
||||||
/// 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,
|
||||||
|
@ -249,11 +249,11 @@ where
|
||||||
self.generic_solve_mut(b'T', b)
|
self.generic_solve_mut(b'T', b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Solves in-place the linear system `self.conjugate_transpose() * x = b`, where `x` is the unknown to
|
/// Solves in-place the linear system `self.adjoint() * x = b`, where `x` is the unknown to
|
||||||
/// 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_conjugate_transpose_mut<R2: Dim, C2: Dim>(
|
pub fn solve_adjoint_mut<R2: Dim, C2: Dim>(
|
||||||
&self,
|
&self,
|
||||||
b: &mut MatrixMN<N, R2, C2>,
|
b: &mut MatrixMN<N, R2, C2>,
|
||||||
) -> bool
|
) -> bool
|
||||||
|
@ -283,7 +283,7 @@ where
|
||||||
);
|
);
|
||||||
lapack_check!(info);
|
lapack_check!(info);
|
||||||
|
|
||||||
let mut work = unsafe { ::uninitialized_vec(lwork as usize) };
|
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
|
||||||
|
|
||||||
N::xgetri(
|
N::xgetri(
|
||||||
dim,
|
dim,
|
||||||
|
|
|
@ -8,7 +8,7 @@ use na::allocator::Allocator;
|
||||||
use na::dimension::{Dim, DimMin, DimMinimum, U1};
|
use na::dimension::{Dim, DimMin, DimMinimum, U1};
|
||||||
use na::storage::Storage;
|
use na::storage::Storage;
|
||||||
use na::{DefaultAllocator, Matrix, MatrixMN, Scalar, VectorN};
|
use na::{DefaultAllocator, Matrix, MatrixMN, Scalar, VectorN};
|
||||||
use ComplexHelper;
|
use crate::ComplexHelper;
|
||||||
|
|
||||||
use lapack;
|
use lapack;
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ where DefaultAllocator: Allocator<N, R, C>
|
||||||
&mut info,
|
&mut info,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut work = unsafe { ::uninitialized_vec(lwork as usize) };
|
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
|
||||||
|
|
||||||
N::xgeqrf(
|
N::xgeqrf(
|
||||||
nrows.value() as i32,
|
nrows.value() as i32,
|
||||||
|
|
|
@ -4,13 +4,13 @@ use serde::{Deserialize, Serialize};
|
||||||
use num::Zero;
|
use num::Zero;
|
||||||
use num_complex::Complex;
|
use num_complex::Complex;
|
||||||
|
|
||||||
use alga::general::Real;
|
use alga::general::RealField;
|
||||||
|
|
||||||
use na::allocator::Allocator;
|
use na::allocator::Allocator;
|
||||||
use na::dimension::{Dim, U1};
|
use na::dimension::{Dim, U1};
|
||||||
use na::storage::Storage;
|
use na::storage::Storage;
|
||||||
use na::{DefaultAllocator, Matrix, MatrixN, Scalar, VectorN};
|
use na::{DefaultAllocator, Matrix, MatrixN, Scalar, VectorN};
|
||||||
use ComplexHelper;
|
use crate::ComplexHelper;
|
||||||
|
|
||||||
use lapack;
|
use lapack;
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ use lapack;
|
||||||
))
|
))
|
||||||
)]
|
)]
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct RealSchur<N: Scalar, D: Dim>
|
pub struct Schur<N: Scalar, D: Dim>
|
||||||
where DefaultAllocator: Allocator<N, D> + Allocator<N, D, D>
|
where DefaultAllocator: Allocator<N, D> + Allocator<N, D, D>
|
||||||
{
|
{
|
||||||
re: VectorN<N, D>,
|
re: VectorN<N, D>,
|
||||||
|
@ -42,21 +42,21 @@ where DefaultAllocator: Allocator<N, D> + Allocator<N, D, D>
|
||||||
q: MatrixN<N, D>,
|
q: MatrixN<N, D>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar, D: Dim> Copy for RealSchur<N, D>
|
impl<N: Scalar, D: Dim> Copy for Schur<N, D>
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
|
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>,
|
||||||
MatrixN<N, D>: Copy,
|
MatrixN<N, D>: Copy,
|
||||||
VectorN<N, D>: Copy,
|
VectorN<N, D>: Copy,
|
||||||
{}
|
{}
|
||||||
|
|
||||||
impl<N: RealSchurScalar + Real, D: Dim> RealSchur<N, D>
|
impl<N: SchurScalar + RealField, D: Dim> Schur<N, D>
|
||||||
where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>
|
where DefaultAllocator: Allocator<N, D, D> + Allocator<N, 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: MatrixN<N, D>) -> Self {
|
||||||
Self::try_new(m).expect("RealSchur 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`.
|
||||||
|
@ -98,7 +98,7 @@ where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>
|
||||||
);
|
);
|
||||||
lapack_check!(info);
|
lapack_check!(info);
|
||||||
|
|
||||||
let mut work = unsafe { ::uninitialized_vec(lwork as usize) };
|
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
|
||||||
|
|
||||||
N::xgees(
|
N::xgees(
|
||||||
b'V',
|
b'V',
|
||||||
|
@ -118,7 +118,7 @@ where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>
|
||||||
);
|
);
|
||||||
lapack_check!(info);
|
lapack_check!(info);
|
||||||
|
|
||||||
Some(RealSchur {
|
Some(Schur {
|
||||||
re: wr,
|
re: wr,
|
||||||
im: wi,
|
im: wi,
|
||||||
t: m,
|
t: m,
|
||||||
|
@ -161,8 +161,8 @@ where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>
|
||||||
* Lapack functions dispatch.
|
* Lapack functions dispatch.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/// Trait implemented by scalars for which Lapack implements the Real Schur decomposition.
|
/// Trait implemented by scalars for which Lapack implements the RealField Schur decomposition.
|
||||||
pub trait RealSchurScalar: Scalar {
|
pub trait SchurScalar: Scalar {
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
fn xgees(
|
fn xgees(
|
||||||
jobvs: u8,
|
jobvs: u8,
|
||||||
|
@ -202,7 +202,7 @@ pub trait RealSchurScalar: Scalar {
|
||||||
|
|
||||||
macro_rules! real_eigensystem_scalar_impl (
|
macro_rules! real_eigensystem_scalar_impl (
|
||||||
($N: ty, $xgees: path) => (
|
($N: ty, $xgees: path) => (
|
||||||
impl RealSchurScalar for $N {
|
impl SchurScalar for $N {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn xgees(jobvs: u8,
|
fn xgees(jobvs: u8,
|
||||||
sort: u8,
|
sort: u8,
|
||||||
|
|
|
@ -109,7 +109,7 @@ macro_rules! svd_impl(
|
||||||
let mut work = [ 0.0 ];
|
let mut work = [ 0.0 ];
|
||||||
let mut lwork = -1 as i32;
|
let mut lwork = -1 as i32;
|
||||||
let mut info = 0;
|
let mut info = 0;
|
||||||
let mut iwork = unsafe { ::uninitialized_vec(8 * cmp::min(nrows.value(), ncols.value())) };
|
let mut iwork = unsafe { crate::uninitialized_vec(8 * cmp::min(nrows.value(), ncols.value())) };
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
$lapack_func(job, nrows.value() as i32, ncols.value() as i32, m.as_mut_slice(),
|
$lapack_func(job, nrows.value() as i32, ncols.value() as i32, m.as_mut_slice(),
|
||||||
|
@ -119,7 +119,7 @@ macro_rules! svd_impl(
|
||||||
lapack_check!(info);
|
lapack_check!(info);
|
||||||
|
|
||||||
lwork = work[0] as i32;
|
lwork = work[0] as i32;
|
||||||
let mut work = unsafe { ::uninitialized_vec(lwork as usize) };
|
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
$lapack_func(job, nrows.value() as i32, ncols.value() as i32, m.as_mut_slice(),
|
$lapack_func(job, nrows.value() as i32, ncols.value() as i32, m.as_mut_slice(),
|
||||||
|
|
|
@ -4,13 +4,13 @@ use serde::{Deserialize, Serialize};
|
||||||
use num::Zero;
|
use num::Zero;
|
||||||
use std::ops::MulAssign;
|
use std::ops::MulAssign;
|
||||||
|
|
||||||
use alga::general::Real;
|
use alga::general::RealField;
|
||||||
|
|
||||||
use na::allocator::Allocator;
|
use na::allocator::Allocator;
|
||||||
use na::dimension::{Dim, U1};
|
use na::dimension::{Dim, U1};
|
||||||
use na::storage::Storage;
|
use na::storage::Storage;
|
||||||
use na::{DefaultAllocator, Matrix, MatrixN, Scalar, VectorN};
|
use na::{DefaultAllocator, Matrix, MatrixN, Scalar, VectorN};
|
||||||
use ComplexHelper;
|
use crate::ComplexHelper;
|
||||||
|
|
||||||
use lapack;
|
use lapack;
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ where
|
||||||
VectorN<N, D>: Copy,
|
VectorN<N, D>: Copy,
|
||||||
{}
|
{}
|
||||||
|
|
||||||
impl<N: SymmetricEigenScalar + Real, D: Dim> SymmetricEigen<N, D>
|
impl<N: SymmetricEigenScalar + RealField, D: Dim> SymmetricEigen<N, D>
|
||||||
where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>
|
where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>
|
||||||
{
|
{
|
||||||
/// Computes the eigenvalues and eigenvectors of the symmetric matrix `m`.
|
/// Computes the eigenvalues and eigenvectors of the symmetric matrix `m`.
|
||||||
|
@ -102,7 +102,7 @@ where DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>
|
||||||
let lwork = N::xsyev_work_size(jobz, b'L', n as i32, m.as_mut_slice(), lda, &mut info);
|
let lwork = N::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 { ::uninitialized_vec(lwork as usize) };
|
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
|
||||||
|
|
||||||
N::xsyev(
|
N::xsyev(
|
||||||
jobz,
|
jobz,
|
||||||
|
|
|
@ -2,6 +2,6 @@ mod cholesky;
|
||||||
mod lu;
|
mod lu;
|
||||||
mod qr;
|
mod qr;
|
||||||
mod real_eigensystem;
|
mod real_eigensystem;
|
||||||
mod real_schur;
|
mod schur;
|
||||||
mod svd;
|
mod svd;
|
||||||
mod symmetric_eigen;
|
mod symmetric_eigen;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use na::{DMatrix, Matrix4};
|
use na::{DMatrix, Matrix4};
|
||||||
use nl::RealSchur;
|
use nl::Schur;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
|
|
||||||
quickcheck! {
|
quickcheck! {
|
||||||
|
@ -7,13 +7,13 @@ quickcheck! {
|
||||||
let n = cmp::max(1, cmp::min(n, 10));
|
let n = cmp::max(1, cmp::min(n, 10));
|
||||||
let m = DMatrix::<f64>::new_random(n, n);
|
let m = DMatrix::<f64>::new_random(n, n);
|
||||||
|
|
||||||
let (vecs, vals) = RealSchur::new(m.clone()).unpack();
|
let (vecs, vals) = Schur::new(m.clone()).unpack();
|
||||||
|
|
||||||
relative_eq!(&vecs * vals * vecs.transpose(), m, epsilon = 1.0e-7)
|
relative_eq!(&vecs * vals * vecs.transpose(), m, epsilon = 1.0e-7)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn schur_static(m: Matrix4<f64>) -> bool {
|
fn schur_static(m: Matrix4<f64>) -> bool {
|
||||||
let (vecs, vals) = RealSchur::new(m.clone()).unpack();
|
let (vecs, vals) = Schur::new(m.clone()).unpack();
|
||||||
|
|
||||||
relative_eq!(vecs * vals * vecs.transpose(), m, epsilon = 1.0e-7)
|
relative_eq!(vecs * vals * vecs.transpose(), m, epsilon = 1.0e-7)
|
||||||
}
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
#[cfg(any(feature = "alloc", feature = "std"))]
|
#[cfg(any(feature = "alloc", feature = "std"))]
|
||||||
use base::dimension::Dynamic;
|
use crate::base::dimension::Dynamic;
|
||||||
use base::dimension::{U1, U2, U3, U4, U5, U6};
|
use crate::base::dimension::{U1, U2, U3, U4, U5, U6};
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
use base::vec_storage::VecStorage;
|
use crate::base::vec_storage::VecStorage;
|
||||||
use base::storage::Owned;
|
use crate::base::storage::Owned;
|
||||||
use base::Matrix;
|
use crate::base::Matrix;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use base::dimension::{Dynamic, U1, U2, U3, U4, U5, U6};
|
use crate::base::dimension::{Dynamic, U1, U2, U3, U4, U5, U6};
|
||||||
use base::matrix_slice::{SliceStorage, SliceStorageMut};
|
use crate::base::matrix_slice::{SliceStorage, SliceStorageMut};
|
||||||
use base::Matrix;
|
use crate::base::Matrix;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
|
|
||||||
use base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
|
use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
|
||||||
use base::dimension::{Dim, U1};
|
use crate::base::dimension::{Dim, U1};
|
||||||
use base::storage::ContiguousStorageMut;
|
use crate::base::storage::ContiguousStorageMut;
|
||||||
use 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 `N`.
|
||||||
|
|
|
@ -21,11 +21,11 @@ use abomonation::Abomonation;
|
||||||
use generic_array::{ArrayLength, GenericArray};
|
use generic_array::{ArrayLength, GenericArray};
|
||||||
use typenum::Prod;
|
use typenum::Prod;
|
||||||
|
|
||||||
use base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use base::default_allocator::DefaultAllocator;
|
use crate::base::default_allocator::DefaultAllocator;
|
||||||
use base::dimension::{DimName, U1};
|
use crate::base::dimension::{DimName, U1};
|
||||||
use base::storage::{ContiguousStorage, ContiguousStorageMut, Owned, Storage, StorageMut};
|
use crate::base::storage::{ContiguousStorage, ContiguousStorageMut, Owned, Storage, StorageMut};
|
||||||
use base::Scalar;
|
use crate::base::Scalar;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
@ -330,7 +330,7 @@ where
|
||||||
let mut out: Self::Value = unsafe { mem::uninitialized() };
|
let mut out: Self::Value = unsafe { mem::uninitialized() };
|
||||||
let mut curr = 0;
|
let mut curr = 0;
|
||||||
|
|
||||||
while let Some(value) = try!(visitor.next_element()) {
|
while let Some(value) = visitor.next_element()? {
|
||||||
*out.get_mut(curr).ok_or_else(|| V::Error::invalid_length(curr, &self))? = value;
|
*out.get_mut(curr).ok_or_else(|| V::Error::invalid_length(curr, &self))? = value;
|
||||||
curr += 1;
|
curr += 1;
|
||||||
}
|
}
|
||||||
|
|
724
src/base/blas.rs
724
src/base/blas.rs
|
@ -1,17 +1,52 @@
|
||||||
use alga::general::{ClosedAdd, ClosedMul};
|
use alga::general::{ClosedAdd, ClosedMul, ComplexField};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use matrixmultiply;
|
use matrixmultiply;
|
||||||
use num::{One, Signed, Zero};
|
use num::{One, Signed, Zero};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
use base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use base::constraint::{
|
use crate::base::constraint::{
|
||||||
AreMultipliable, DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint,
|
AreMultipliable, DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint,
|
||||||
};
|
};
|
||||||
use base::dimension::{Dim, Dynamic, U1, U2, U3, U4};
|
use crate::base::dimension::{Dim, Dynamic, U1, U2, U3, U4};
|
||||||
use base::storage::{Storage, StorageMut};
|
use crate::base::storage::{Storage, StorageMut};
|
||||||
use base::{DefaultAllocator, Matrix, Scalar, SquareMatrix, Vector};
|
use crate::base::{DefaultAllocator, Matrix, Scalar, SquareMatrix, Vector, DVectorSlice, VectorSliceN};
|
||||||
|
|
||||||
|
|
||||||
|
// FIXME: find a way to avoid code duplication just for complex number support.
|
||||||
|
impl<N: ComplexField, D: Dim, S: Storage<N, D>> Vector<N, D, S> {
|
||||||
|
/// Computes the index of the vector component with the largest complex or real absolute value.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # extern crate num_complex;
|
||||||
|
/// # extern crate nalgebra;
|
||||||
|
/// # use num_complex::Complex;
|
||||||
|
/// # use nalgebra::Vector3;
|
||||||
|
/// let vec = Vector3::new(Complex::new(11.0, 3.0), Complex::new(-15.0, 0.0), Complex::new(13.0, 5.0));
|
||||||
|
/// assert_eq!(vec.icamax(), 2);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub fn icamax(&self) -> usize {
|
||||||
|
assert!(!self.is_empty(), "The input vector must not be empty.");
|
||||||
|
|
||||||
|
let mut the_max = unsafe { self.vget_unchecked(0).norm1() };
|
||||||
|
let mut the_i = 0;
|
||||||
|
|
||||||
|
for i in 1..self.nrows() {
|
||||||
|
let val = unsafe { self.vget_unchecked(i).norm1() };
|
||||||
|
|
||||||
|
if val > the_max {
|
||||||
|
the_max = val;
|
||||||
|
the_i = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
the_i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<N: Scalar + PartialOrd, D: Dim, S: Storage<N, D>> Vector<N, D, S> {
|
impl<N: Scalar + PartialOrd, D: Dim, S: Storage<N, D>> Vector<N, D, S> {
|
||||||
/// Computes the index and value of the vector component with the largest value.
|
/// Computes the index and value of the vector component with the largest value.
|
||||||
|
@ -157,6 +192,44 @@ impl<N: Scalar + PartialOrd, D: Dim, S: Storage<N, D>> Vector<N, D, S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: find a way to avoid code duplication just for complex number support.
|
||||||
|
impl<N: ComplexField, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||||
|
/// Computes the index of the matrix component with the largest absolute value.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # extern crate num_complex;
|
||||||
|
/// # extern crate nalgebra;
|
||||||
|
/// # use num_complex::Complex;
|
||||||
|
/// # use nalgebra::Matrix2x3;
|
||||||
|
/// let mat = Matrix2x3::new(Complex::new(11.0, 1.0), Complex::new(-12.0, 2.0), Complex::new(13.0, 3.0),
|
||||||
|
/// Complex::new(21.0, 43.0), Complex::new(22.0, 5.0), Complex::new(-23.0, 0.0));
|
||||||
|
/// assert_eq!(mat.icamax_full(), (1, 0));
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub fn icamax_full(&self) -> (usize, usize) {
|
||||||
|
assert!(!self.is_empty(), "The input matrix must not be empty.");
|
||||||
|
|
||||||
|
let mut the_max = unsafe { self.get_unchecked((0, 0)).norm1() };
|
||||||
|
let mut the_ij = (0, 0);
|
||||||
|
|
||||||
|
for j in 0..self.ncols() {
|
||||||
|
for i in 0..self.nrows() {
|
||||||
|
let val = unsafe { self.get_unchecked((i, j)).norm1() };
|
||||||
|
|
||||||
|
if val > the_max {
|
||||||
|
the_max = val;
|
||||||
|
the_ij = (i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
the_ij
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<N: Scalar + PartialOrd + Signed, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
impl<N: Scalar + PartialOrd + Signed, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||||
/// Computes the index of the matrix component with the largest absolute value.
|
/// Computes the index of the matrix component with the largest absolute value.
|
||||||
///
|
///
|
||||||
|
@ -193,30 +266,11 @@ impl<N: Scalar + PartialOrd + Signed, R: Dim, C: Dim, S: Storage<N, R, C>> Matri
|
||||||
impl<N, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S>
|
impl<N, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S>
|
||||||
where N: Scalar + Zero + ClosedAdd + ClosedMul
|
where N: Scalar + Zero + ClosedAdd + ClosedMul
|
||||||
{
|
{
|
||||||
/// The dot product between two vectors or matrices (seen as vectors).
|
#[inline(always)]
|
||||||
///
|
fn dotx<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<N, R2, C2, SB>, conjugate: impl Fn(N) -> N) -> N
|
||||||
/// Note that this is **not** the matrix multiplication as in, e.g., numpy. For matrix
|
where
|
||||||
/// multiplication, use one of: `.gemm`, `.mul_to`, `.mul`, the `*` operator.
|
SB: Storage<N, R2, C2>,
|
||||||
///
|
ShapeConstraint: DimEq<R, R2> + DimEq<C, C2>,
|
||||||
/// # Examples:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// # use nalgebra::{Vector3, Matrix2x3};
|
|
||||||
/// let vec1 = Vector3::new(1.0, 2.0, 3.0);
|
|
||||||
/// let vec2 = Vector3::new(0.1, 0.2, 0.3);
|
|
||||||
/// assert_eq!(vec1.dot(&vec2), 1.4);
|
|
||||||
///
|
|
||||||
/// let mat1 = Matrix2x3::new(1.0, 2.0, 3.0,
|
|
||||||
/// 4.0, 5.0, 6.0);
|
|
||||||
/// let mat2 = Matrix2x3::new(0.1, 0.2, 0.3,
|
|
||||||
/// 0.4, 0.5, 0.6);
|
|
||||||
/// assert_eq!(mat1.dot(&mat2), 9.1);
|
|
||||||
/// ```
|
|
||||||
#[inline]
|
|
||||||
pub fn dot<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> N
|
|
||||||
where
|
|
||||||
SB: Storage<N, R2, C2>,
|
|
||||||
ShapeConstraint: DimEq<R, R2> + DimEq<C, C2>,
|
|
||||||
{
|
{
|
||||||
assert!(
|
assert!(
|
||||||
self.nrows() == rhs.nrows(),
|
self.nrows() == rhs.nrows(),
|
||||||
|
@ -227,27 +281,27 @@ where N: Scalar + Zero + ClosedAdd + ClosedMul
|
||||||
// because the `for` loop below won't be very efficient on those.
|
// because the `for` loop below won't be very efficient on those.
|
||||||
if (R::is::<U2>() || R2::is::<U2>()) && (C::is::<U1>() || C2::is::<U1>()) {
|
if (R::is::<U2>() || R2::is::<U2>()) && (C::is::<U1>() || C2::is::<U1>()) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let a = *self.get_unchecked((0, 0)) * *rhs.get_unchecked((0, 0));
|
let a = conjugate(*self.get_unchecked((0, 0))) * *rhs.get_unchecked((0, 0));
|
||||||
let b = *self.get_unchecked((1, 0)) * *rhs.get_unchecked((1, 0));
|
let b = conjugate(*self.get_unchecked((1, 0))) * *rhs.get_unchecked((1, 0));
|
||||||
|
|
||||||
return a + b;
|
return a + b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (R::is::<U3>() || R2::is::<U3>()) && (C::is::<U1>() || C2::is::<U1>()) {
|
if (R::is::<U3>() || R2::is::<U3>()) && (C::is::<U1>() || C2::is::<U1>()) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let a = *self.get_unchecked((0, 0)) * *rhs.get_unchecked((0, 0));
|
let a = conjugate(*self.get_unchecked((0, 0))) * *rhs.get_unchecked((0, 0));
|
||||||
let b = *self.get_unchecked((1, 0)) * *rhs.get_unchecked((1, 0));
|
let b = conjugate(*self.get_unchecked((1, 0))) * *rhs.get_unchecked((1, 0));
|
||||||
let c = *self.get_unchecked((2, 0)) * *rhs.get_unchecked((2, 0));
|
let c = conjugate(*self.get_unchecked((2, 0))) * *rhs.get_unchecked((2, 0));
|
||||||
|
|
||||||
return a + b + c;
|
return a + b + c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (R::is::<U4>() || R2::is::<U4>()) && (C::is::<U1>() || C2::is::<U1>()) {
|
if (R::is::<U4>() || R2::is::<U4>()) && (C::is::<U1>() || C2::is::<U1>()) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut a = *self.get_unchecked((0, 0)) * *rhs.get_unchecked((0, 0));
|
let mut a = conjugate(*self.get_unchecked((0, 0))) * *rhs.get_unchecked((0, 0));
|
||||||
let mut b = *self.get_unchecked((1, 0)) * *rhs.get_unchecked((1, 0));
|
let mut b = conjugate(*self.get_unchecked((1, 0))) * *rhs.get_unchecked((1, 0));
|
||||||
let c = *self.get_unchecked((2, 0)) * *rhs.get_unchecked((2, 0));
|
let c = conjugate(*self.get_unchecked((2, 0))) * *rhs.get_unchecked((2, 0));
|
||||||
let d = *self.get_unchecked((3, 0)) * *rhs.get_unchecked((3, 0));
|
let d = conjugate(*self.get_unchecked((3, 0))) * *rhs.get_unchecked((3, 0));
|
||||||
|
|
||||||
a += c;
|
a += c;
|
||||||
b += d;
|
b += d;
|
||||||
|
@ -287,14 +341,14 @@ where N: Scalar + Zero + ClosedAdd + ClosedMul
|
||||||
acc7 = N::zero();
|
acc7 = N::zero();
|
||||||
|
|
||||||
while self.nrows() - i >= 8 {
|
while self.nrows() - i >= 8 {
|
||||||
acc0 += unsafe { *self.get_unchecked((i + 0, j)) * *rhs.get_unchecked((i + 0, j)) };
|
acc0 += unsafe { conjugate(*self.get_unchecked((i + 0, j))) * *rhs.get_unchecked((i + 0, j)) };
|
||||||
acc1 += unsafe { *self.get_unchecked((i + 1, j)) * *rhs.get_unchecked((i + 1, j)) };
|
acc1 += unsafe { conjugate(*self.get_unchecked((i + 1, j))) * *rhs.get_unchecked((i + 1, j)) };
|
||||||
acc2 += unsafe { *self.get_unchecked((i + 2, j)) * *rhs.get_unchecked((i + 2, j)) };
|
acc2 += unsafe { conjugate(*self.get_unchecked((i + 2, j))) * *rhs.get_unchecked((i + 2, j)) };
|
||||||
acc3 += unsafe { *self.get_unchecked((i + 3, j)) * *rhs.get_unchecked((i + 3, j)) };
|
acc3 += unsafe { conjugate(*self.get_unchecked((i + 3, j))) * *rhs.get_unchecked((i + 3, j)) };
|
||||||
acc4 += unsafe { *self.get_unchecked((i + 4, j)) * *rhs.get_unchecked((i + 4, j)) };
|
acc4 += unsafe { conjugate(*self.get_unchecked((i + 4, j))) * *rhs.get_unchecked((i + 4, j)) };
|
||||||
acc5 += unsafe { *self.get_unchecked((i + 5, j)) * *rhs.get_unchecked((i + 5, j)) };
|
acc5 += unsafe { conjugate(*self.get_unchecked((i + 5, j))) * *rhs.get_unchecked((i + 5, j)) };
|
||||||
acc6 += unsafe { *self.get_unchecked((i + 6, j)) * *rhs.get_unchecked((i + 6, j)) };
|
acc6 += unsafe { conjugate(*self.get_unchecked((i + 6, j))) * *rhs.get_unchecked((i + 6, j)) };
|
||||||
acc7 += unsafe { *self.get_unchecked((i + 7, j)) * *rhs.get_unchecked((i + 7, j)) };
|
acc7 += unsafe { conjugate(*self.get_unchecked((i + 7, j))) * *rhs.get_unchecked((i + 7, j)) };
|
||||||
i += 8;
|
i += 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,13 +358,75 @@ where N: Scalar + Zero + ClosedAdd + ClosedMul
|
||||||
res += acc3 + acc7;
|
res += acc3 + acc7;
|
||||||
|
|
||||||
for k in i..self.nrows() {
|
for k in i..self.nrows() {
|
||||||
res += unsafe { *self.get_unchecked((k, j)) * *rhs.get_unchecked((k, j)) }
|
res += unsafe { conjugate(*self.get_unchecked((k, j))) * *rhs.get_unchecked((k, j)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// The dot product between two vectors or matrices (seen as vectors).
|
||||||
|
///
|
||||||
|
/// This is equal to `self.transpose() * rhs`. For the sesquilinear complex dot product, use
|
||||||
|
/// `self.dotc(rhs)`.
|
||||||
|
///
|
||||||
|
/// Note that this is **not** the matrix multiplication as in, e.g., numpy. For matrix
|
||||||
|
/// multiplication, use one of: `.gemm`, `.mul_to`, `.mul`, the `*` operator.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra::{Vector3, Matrix2x3};
|
||||||
|
/// let vec1 = Vector3::new(1.0, 2.0, 3.0);
|
||||||
|
/// let vec2 = Vector3::new(0.1, 0.2, 0.3);
|
||||||
|
/// assert_eq!(vec1.dot(&vec2), 1.4);
|
||||||
|
///
|
||||||
|
/// let mat1 = Matrix2x3::new(1.0, 2.0, 3.0,
|
||||||
|
/// 4.0, 5.0, 6.0);
|
||||||
|
/// let mat2 = Matrix2x3::new(0.1, 0.2, 0.3,
|
||||||
|
/// 0.4, 0.5, 0.6);
|
||||||
|
/// assert_eq!(mat1.dot(&mat2), 9.1);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
#[inline]
|
||||||
|
pub fn dot<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> N
|
||||||
|
where
|
||||||
|
SB: Storage<N, R2, C2>,
|
||||||
|
ShapeConstraint: DimEq<R, R2> + DimEq<C, C2>,
|
||||||
|
{
|
||||||
|
self.dotx(rhs, |e| e)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The conjugate-linear dot product between two vectors or matrices (seen as vectors).
|
||||||
|
///
|
||||||
|
/// This is equal to `self.adjoint() * rhs`.
|
||||||
|
/// For real vectors, this is identical to `self.dot(&rhs)`.
|
||||||
|
/// Note that this is **not** the matrix multiplication as in, e.g., numpy. For matrix
|
||||||
|
/// multiplication, use one of: `.gemm`, `.mul_to`, `.mul`, the `*` operator.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra::{Vector2, Complex};
|
||||||
|
/// let vec1 = Vector2::new(Complex::new(1.0, 2.0), Complex::new(3.0, 4.0));
|
||||||
|
/// let vec2 = Vector2::new(Complex::new(0.4, 0.3), Complex::new(0.2, 0.1));
|
||||||
|
/// assert_eq!(vec1.dotc(&vec2), Complex::new(2.0, -1.0));
|
||||||
|
///
|
||||||
|
/// // Note that for complex vectors, we generally have:
|
||||||
|
/// // vec1.dotc(&vec2) != vec2.dot(&vec2)
|
||||||
|
/// assert_ne!(vec1.dotc(&vec2), vec1.dot(&vec2));
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub fn dotc<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> N
|
||||||
|
where
|
||||||
|
N: ComplexField,
|
||||||
|
SB: Storage<N, R2, C2>,
|
||||||
|
ShapeConstraint: DimEq<R, R2> + DimEq<C, C2>,
|
||||||
|
{
|
||||||
|
self.dotx(rhs, ComplexField::conjugate)
|
||||||
|
}
|
||||||
|
|
||||||
/// The dot product between the transpose of `self` and `rhs`.
|
/// The dot product between the transpose of `self` and `rhs`.
|
||||||
///
|
///
|
||||||
/// # Examples:
|
/// # Examples:
|
||||||
|
@ -378,7 +494,7 @@ where
|
||||||
{
|
{
|
||||||
/// Computes `self = a * x + b * self`.
|
/// Computes `self = a * x + b * self`.
|
||||||
///
|
///
|
||||||
/// If be is zero, `self` is never read from.
|
/// If `b` is zero, `self` is never read from.
|
||||||
///
|
///
|
||||||
/// # Examples:
|
/// # Examples:
|
||||||
///
|
///
|
||||||
|
@ -465,40 +581,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes `self = alpha * a * x + beta * self`, where `a` is a **symmetric** matrix, `x` a
|
|
||||||
/// vector, and `alpha, beta` two scalars.
|
#[inline(always)]
|
||||||
///
|
fn xxgemv<D2: Dim, D3: Dim, SB, SC>(
|
||||||
/// If `beta` is zero, `self` is never read. If `self` is read, only its lower-triangular part
|
|
||||||
/// (including the diagonal) is actually read.
|
|
||||||
///
|
|
||||||
/// # Examples:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// # use nalgebra::{Matrix2, Vector2};
|
|
||||||
/// let mat = Matrix2::new(1.0, 2.0,
|
|
||||||
/// 2.0, 4.0);
|
|
||||||
/// let mut vec1 = Vector2::new(1.0, 2.0);
|
|
||||||
/// let vec2 = Vector2::new(0.1, 0.2);
|
|
||||||
/// vec1.gemv_symm(10.0, &mat, &vec2, 5.0);
|
|
||||||
/// assert_eq!(vec1, Vector2::new(10.0, 20.0));
|
|
||||||
///
|
|
||||||
///
|
|
||||||
/// // The matrix upper-triangular elements can be garbage because it is never
|
|
||||||
/// // read by this method. Therefore, it is not necessary for the caller to
|
|
||||||
/// // fill the matrix struct upper-triangle.
|
|
||||||
/// let mat = Matrix2::new(1.0, 9999999.9999999,
|
|
||||||
/// 2.0, 4.0);
|
|
||||||
/// let mut vec1 = Vector2::new(1.0, 2.0);
|
|
||||||
/// vec1.gemv_symm(10.0, &mat, &vec2, 5.0);
|
|
||||||
/// assert_eq!(vec1, Vector2::new(10.0, 20.0));
|
|
||||||
/// ```
|
|
||||||
#[inline]
|
|
||||||
pub fn gemv_symm<D2: Dim, D3: Dim, SB, SC>(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
alpha: N,
|
alpha: N,
|
||||||
a: &SquareMatrix<N, D2, SB>,
|
a: &SquareMatrix<N, D2, SB>,
|
||||||
x: &Vector<N, D3, SC>,
|
x: &Vector<N, D3, SC>,
|
||||||
beta: N,
|
beta: N,
|
||||||
|
dot: impl Fn(&DVectorSlice<N, SB::RStride, SB::CStride>, &DVectorSlice<N, SC::RStride, SC::CStride>) -> N,
|
||||||
) where
|
) where
|
||||||
N: One,
|
N: One,
|
||||||
SB: Storage<N, D2, D2>,
|
SB: Storage<N, D2, D2>,
|
||||||
|
@ -511,11 +602,11 @@ where
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
a.is_square(),
|
a.is_square(),
|
||||||
"Syetric gemv: the input matrix must be square."
|
"Symmetric cgemv: the input matrix must be square."
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
dim2 == dim3 && dim1 == dim2,
|
dim2 == dim3 && dim1 == dim2,
|
||||||
"Symmetric gemv: dimensions mismatch."
|
"Symmetric cgemv: dimensions mismatch."
|
||||||
);
|
);
|
||||||
|
|
||||||
if dim2 == 0 {
|
if dim2 == 0 {
|
||||||
|
@ -526,11 +617,11 @@ where
|
||||||
let col2 = a.column(0);
|
let col2 = a.column(0);
|
||||||
let val = unsafe { *x.vget_unchecked(0) };
|
let val = unsafe { *x.vget_unchecked(0) };
|
||||||
self.axpy(alpha * val, &col2, beta);
|
self.axpy(alpha * val, &col2, beta);
|
||||||
self[0] += alpha * x.rows_range(1..).dot(&a.slice_range(1.., 0));
|
self[0] += alpha * dot(&a.slice_range(1.., 0), &x.rows_range(1..));
|
||||||
|
|
||||||
for j in 1..dim2 {
|
for j in 1..dim2 {
|
||||||
let col2 = a.column(j);
|
let col2 = a.column(j);
|
||||||
let dot = x.rows_range(j..).dot(&col2.rows_range(j..));
|
let dot = dot(&col2.rows_range(j..), &x.rows_range(j..));
|
||||||
|
|
||||||
let val;
|
let val;
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -542,6 +633,156 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Computes `self = alpha * a * x + beta * self`, where `a` is a **symmetric** matrix, `x` a
|
||||||
|
/// vector, and `alpha, beta` two scalars. DEPRECATED: use `sygemv` instead.
|
||||||
|
#[inline]
|
||||||
|
#[deprecated(note = "This is renamed `sygemv` to match the original BLAS terminology.")]
|
||||||
|
pub fn gemv_symm<D2: Dim, D3: Dim, SB, SC>(
|
||||||
|
&mut self,
|
||||||
|
alpha: N,
|
||||||
|
a: &SquareMatrix<N, D2, SB>,
|
||||||
|
x: &Vector<N, D3, SC>,
|
||||||
|
beta: N,
|
||||||
|
) where
|
||||||
|
N: One,
|
||||||
|
SB: Storage<N, D2, D2>,
|
||||||
|
SC: Storage<N, D3>,
|
||||||
|
ShapeConstraint: DimEq<D, D2> + AreMultipliable<D2, D2, D3, U1>,
|
||||||
|
{
|
||||||
|
self.sygemv(alpha, a, x, beta)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Computes `self = alpha * a * x + beta * self`, where `a` is a **symmetric** matrix, `x` a
|
||||||
|
/// vector, and `alpha, beta` two scalars.
|
||||||
|
///
|
||||||
|
/// For hermitian matrices, use `.hegemv` instead.
|
||||||
|
/// If `beta` is zero, `self` is never read. If `self` is read, only its lower-triangular part
|
||||||
|
/// (including the diagonal) is actually read.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra::{Matrix2, Vector2};
|
||||||
|
/// let mat = Matrix2::new(1.0, 2.0,
|
||||||
|
/// 2.0, 4.0);
|
||||||
|
/// let mut vec1 = Vector2::new(1.0, 2.0);
|
||||||
|
/// let vec2 = Vector2::new(0.1, 0.2);
|
||||||
|
/// vec1.sygemv(10.0, &mat, &vec2, 5.0);
|
||||||
|
/// assert_eq!(vec1, Vector2::new(10.0, 20.0));
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// // The matrix upper-triangular elements can be garbage because it is never
|
||||||
|
/// // read by this method. Therefore, it is not necessary for the caller to
|
||||||
|
/// // fill the matrix struct upper-triangle.
|
||||||
|
/// let mat = Matrix2::new(1.0, 9999999.9999999,
|
||||||
|
/// 2.0, 4.0);
|
||||||
|
/// let mut vec1 = Vector2::new(1.0, 2.0);
|
||||||
|
/// vec1.sygemv(10.0, &mat, &vec2, 5.0);
|
||||||
|
/// assert_eq!(vec1, Vector2::new(10.0, 20.0));
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub fn sygemv<D2: Dim, D3: Dim, SB, SC>(
|
||||||
|
&mut self,
|
||||||
|
alpha: N,
|
||||||
|
a: &SquareMatrix<N, D2, SB>,
|
||||||
|
x: &Vector<N, D3, SC>,
|
||||||
|
beta: N,
|
||||||
|
) where
|
||||||
|
N: One,
|
||||||
|
SB: Storage<N, D2, D2>,
|
||||||
|
SC: Storage<N, D3>,
|
||||||
|
ShapeConstraint: DimEq<D, D2> + AreMultipliable<D2, D2, D3, U1>,
|
||||||
|
{
|
||||||
|
self.xxgemv(alpha, a, x, beta, |a, b| a.dot(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Computes `self = alpha * a * x + beta * self`, where `a` is an **hermitian** matrix, `x` a
|
||||||
|
/// vector, and `alpha, beta` two scalars.
|
||||||
|
///
|
||||||
|
/// If `beta` is zero, `self` is never read. If `self` is read, only its lower-triangular part
|
||||||
|
/// (including the diagonal) is actually read.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra::{Matrix2, Vector2, Complex};
|
||||||
|
/// let mat = Matrix2::new(Complex::new(1.0, 0.0), Complex::new(2.0, -0.1),
|
||||||
|
/// Complex::new(2.0, 1.0), Complex::new(4.0, 0.0));
|
||||||
|
/// let mut vec1 = Vector2::new(Complex::new(1.0, 2.0), Complex::new(3.0, 4.0));
|
||||||
|
/// let vec2 = Vector2::new(Complex::new(0.1, 0.2), Complex::new(0.3, 0.4));
|
||||||
|
/// vec1.sygemv(Complex::new(10.0, 20.0), &mat, &vec2, Complex::new(5.0, 15.0));
|
||||||
|
/// assert_eq!(vec1, Vector2::new(Complex::new(-48.0, 44.0), Complex::new(-75.0, 110.0)));
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// // The matrix upper-triangular elements can be garbage because it is never
|
||||||
|
/// // read by this method. Therefore, it is not necessary for the caller to
|
||||||
|
/// // fill the matrix struct upper-triangle.
|
||||||
|
///
|
||||||
|
/// let mat = Matrix2::new(Complex::new(1.0, 0.0), Complex::new(99999999.9, 999999999.9),
|
||||||
|
/// Complex::new(2.0, 1.0), Complex::new(4.0, 0.0));
|
||||||
|
/// let mut vec1 = Vector2::new(Complex::new(1.0, 2.0), Complex::new(3.0, 4.0));
|
||||||
|
/// let vec2 = Vector2::new(Complex::new(0.1, 0.2), Complex::new(0.3, 0.4));
|
||||||
|
/// vec1.sygemv(Complex::new(10.0, 20.0), &mat, &vec2, Complex::new(5.0, 15.0));
|
||||||
|
/// assert_eq!(vec1, Vector2::new(Complex::new(-48.0, 44.0), Complex::new(-75.0, 110.0)));
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub fn hegemv<D2: Dim, D3: Dim, SB, SC>(
|
||||||
|
&mut self,
|
||||||
|
alpha: N,
|
||||||
|
a: &SquareMatrix<N, D2, SB>,
|
||||||
|
x: &Vector<N, D3, SC>,
|
||||||
|
beta: N,
|
||||||
|
) where
|
||||||
|
N: ComplexField,
|
||||||
|
SB: Storage<N, D2, D2>,
|
||||||
|
SC: Storage<N, D3>,
|
||||||
|
ShapeConstraint: DimEq<D, D2> + AreMultipliable<D2, D2, D3, U1>,
|
||||||
|
{
|
||||||
|
self.xxgemv(alpha, a, x, beta, |a, b| a.dotc(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn gemv_xx<R2: Dim, C2: Dim, D3: Dim, SB, SC>(
|
||||||
|
&mut self,
|
||||||
|
alpha: N,
|
||||||
|
a: &Matrix<N, R2, C2, SB>,
|
||||||
|
x: &Vector<N, D3, SC>,
|
||||||
|
beta: N,
|
||||||
|
dot: impl Fn(&VectorSliceN<N, R2, SB::RStride, SB::CStride>, &Vector<N, D3, SC>) -> N,
|
||||||
|
) where
|
||||||
|
N: One,
|
||||||
|
SB: Storage<N, R2, C2>,
|
||||||
|
SC: Storage<N, D3>,
|
||||||
|
ShapeConstraint: DimEq<D, C2> + AreMultipliable<C2, R2, D3, U1>,
|
||||||
|
{
|
||||||
|
let dim1 = self.nrows();
|
||||||
|
let (nrows2, ncols2) = a.shape();
|
||||||
|
let dim3 = x.nrows();
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
nrows2 == dim3 && dim1 == ncols2,
|
||||||
|
"Gemv: dimensions mismatch."
|
||||||
|
);
|
||||||
|
|
||||||
|
if ncols2 == 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if beta.is_zero() {
|
||||||
|
for j in 0..ncols2 {
|
||||||
|
let val = unsafe { self.vget_unchecked_mut(j) };
|
||||||
|
*val = alpha * dot(&a.column(j), x)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for j in 0..ncols2 {
|
||||||
|
let val = unsafe { self.vget_unchecked_mut(j) };
|
||||||
|
*val = alpha * dot(&a.column(j), x) + beta * *val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Computes `self = alpha * a.transpose() * x + beta * self`, where `a` is a matrix, `x` a vector, and
|
/// Computes `self = alpha * a.transpose() * x + beta * self`, where `a` is a matrix, `x` a vector, and
|
||||||
/// `alpha, beta` two scalars.
|
/// `alpha, beta` two scalars.
|
||||||
///
|
///
|
||||||
|
@ -573,36 +814,78 @@ where
|
||||||
SC: Storage<N, D3>,
|
SC: Storage<N, D3>,
|
||||||
ShapeConstraint: DimEq<D, C2> + AreMultipliable<C2, R2, D3, U1>,
|
ShapeConstraint: DimEq<D, C2> + AreMultipliable<C2, R2, D3, U1>,
|
||||||
{
|
{
|
||||||
let dim1 = self.nrows();
|
self.gemv_xx(alpha, a, x, beta, |a, b| a.dot(b))
|
||||||
let (nrows2, ncols2) = a.shape();
|
}
|
||||||
let dim3 = x.nrows();
|
|
||||||
|
|
||||||
assert!(
|
/// Computes `self = alpha * a.adjoint() * x + beta * self`, where `a` is a matrix, `x` a vector, and
|
||||||
nrows2 == dim3 && dim1 == ncols2,
|
/// `alpha, beta` two scalars.
|
||||||
"Gemv: dimensions mismatch."
|
///
|
||||||
);
|
/// For real matrices, this is the same as `.gemv_tr`.
|
||||||
|
/// If `beta` is zero, `self` is never read.
|
||||||
if ncols2 == 0 {
|
///
|
||||||
return;
|
/// # Examples:
|
||||||
}
|
///
|
||||||
|
/// ```
|
||||||
if beta.is_zero() {
|
/// # use nalgebra::{Matrix2, Vector2, Complex};
|
||||||
for j in 0..ncols2 {
|
/// let mat = Matrix2::new(Complex::new(1.0, 2.0), Complex::new(3.0, 4.0),
|
||||||
let val = unsafe { self.vget_unchecked_mut(j) };
|
/// Complex::new(5.0, 6.0), Complex::new(7.0, 8.0));
|
||||||
*val = alpha * a.column(j).dot(x)
|
/// let mut vec1 = Vector2::new(Complex::new(1.0, 2.0), Complex::new(3.0, 4.0));
|
||||||
}
|
/// let vec2 = Vector2::new(Complex::new(0.1, 0.2), Complex::new(0.3, 0.4));
|
||||||
} else {
|
/// let expected = mat.adjoint() * vec2 * Complex::new(10.0, 20.0) + vec1 * Complex::new(5.0, 15.0);
|
||||||
for j in 0..ncols2 {
|
///
|
||||||
let val = unsafe { self.vget_unchecked_mut(j) };
|
/// vec1.gemv_ad(Complex::new(10.0, 20.0), &mat, &vec2, Complex::new(5.0, 15.0));
|
||||||
*val = alpha * a.column(j).dot(x) + beta * *val;
|
/// assert_eq!(vec1, expected);
|
||||||
}
|
/// ```
|
||||||
}
|
#[inline]
|
||||||
|
pub fn gemv_ad<R2: Dim, C2: Dim, D3: Dim, SB, SC>(
|
||||||
|
&mut self,
|
||||||
|
alpha: N,
|
||||||
|
a: &Matrix<N, R2, C2, SB>,
|
||||||
|
x: &Vector<N, D3, SC>,
|
||||||
|
beta: N,
|
||||||
|
) where
|
||||||
|
N: ComplexField,
|
||||||
|
SB: Storage<N, R2, C2>,
|
||||||
|
SC: Storage<N, D3>,
|
||||||
|
ShapeConstraint: DimEq<D, C2> + AreMultipliable<C2, R2, D3, U1>,
|
||||||
|
{
|
||||||
|
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<N, R1: Dim, C1: Dim, S: StorageMut<N, R1, C1>> Matrix<N, R1, C1, S>
|
||||||
where N: Scalar + Zero + ClosedAdd + ClosedMul
|
where N: Scalar + Zero + ClosedAdd + ClosedMul
|
||||||
{
|
{
|
||||||
|
#[inline(always)]
|
||||||
|
fn gerx<D2: Dim, D3: Dim, SB, SC>(
|
||||||
|
&mut self,
|
||||||
|
alpha: N,
|
||||||
|
x: &Vector<N, D2, SB>,
|
||||||
|
y: &Vector<N, D3, SC>,
|
||||||
|
beta: N,
|
||||||
|
conjugate: impl Fn(N) -> N,
|
||||||
|
) where
|
||||||
|
N: One,
|
||||||
|
SB: Storage<N, D2>,
|
||||||
|
SC: Storage<N, D3>,
|
||||||
|
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
||||||
|
{
|
||||||
|
let (nrows1, ncols1) = self.shape();
|
||||||
|
let dim2 = x.nrows();
|
||||||
|
let dim3 = y.nrows();
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
nrows1 == dim2 && ncols1 == dim3,
|
||||||
|
"ger: dimensions mismatch."
|
||||||
|
);
|
||||||
|
|
||||||
|
for j in 0..ncols1 {
|
||||||
|
// FIXME: avoid bound checks.
|
||||||
|
let val = unsafe { conjugate(*y.vget_unchecked(j)) };
|
||||||
|
self.column_mut(j).axpy(alpha * val, x, beta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Computes `self = alpha * x * y.transpose() + beta * self`.
|
/// Computes `self = alpha * x * y.transpose() + beta * self`.
|
||||||
///
|
///
|
||||||
/// If `beta` is zero, `self` is never read.
|
/// If `beta` is zero, `self` is never read.
|
||||||
|
@ -632,20 +915,40 @@ where N: Scalar + Zero + ClosedAdd + ClosedMul
|
||||||
SC: Storage<N, D3>,
|
SC: Storage<N, D3>,
|
||||||
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
||||||
{
|
{
|
||||||
let (nrows1, ncols1) = self.shape();
|
self.gerx(alpha, x, y, beta, |e| e)
|
||||||
let dim2 = x.nrows();
|
}
|
||||||
let dim3 = y.nrows();
|
|
||||||
|
|
||||||
assert!(
|
/// Computes `self = alpha * x * y.adjoint() + beta * self`.
|
||||||
nrows1 == dim2 && ncols1 == dim3,
|
///
|
||||||
"ger: dimensions mismatch."
|
/// If `beta` is zero, `self` is never read.
|
||||||
);
|
///
|
||||||
|
/// # Examples:
|
||||||
for j in 0..ncols1 {
|
///
|
||||||
// FIXME: avoid bound checks.
|
/// ```
|
||||||
let val = unsafe { *y.vget_unchecked(j) };
|
/// # #[macro_use] extern crate approx;
|
||||||
self.column_mut(j).axpy(alpha * val, x, beta);
|
/// # use nalgebra::{Matrix2x3, Vector2, Vector3, Complex};
|
||||||
}
|
/// let mut mat = Matrix2x3::repeat(Complex::new(4.0, 5.0));
|
||||||
|
/// let vec1 = Vector2::new(Complex::new(1.0, 2.0), Complex::new(3.0, 4.0));
|
||||||
|
/// let vec2 = Vector3::new(Complex::new(0.6, 0.5), Complex::new(0.4, 0.5), Complex::new(0.2, 0.1));
|
||||||
|
/// let expected = vec1 * vec2.adjoint() * Complex::new(10.0, 20.0) + mat * Complex::new(5.0, 15.0);
|
||||||
|
///
|
||||||
|
/// mat.gerc(Complex::new(10.0, 20.0), &vec1, &vec2, Complex::new(5.0, 15.0));
|
||||||
|
/// assert_eq!(mat, expected);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub fn gerc<D2: Dim, D3: Dim, SB, SC>(
|
||||||
|
&mut self,
|
||||||
|
alpha: N,
|
||||||
|
x: &Vector<N, D2, SB>,
|
||||||
|
y: &Vector<N, D3, SC>,
|
||||||
|
beta: N,
|
||||||
|
) where
|
||||||
|
N: ComplexField,
|
||||||
|
SB: Storage<N, D2>,
|
||||||
|
SC: Storage<N, D3>,
|
||||||
|
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
||||||
|
{
|
||||||
|
self.gerx(alpha, x, y, beta, ComplexField::conjugate)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes `self = alpha * a * b + beta * self`, where `a, b, self` are matrices.
|
/// Computes `self = alpha * a * b + beta * self`, where `a, b, self` are matrices.
|
||||||
|
@ -800,7 +1103,7 @@ where N: Scalar + Zero + ClosedAdd + ClosedMul
|
||||||
/// let expected = mat2.transpose() * mat3 * 10.0 + mat1 * 5.0;
|
/// let expected = mat2.transpose() * mat3 * 10.0 + mat1 * 5.0;
|
||||||
///
|
///
|
||||||
/// mat1.gemm_tr(10.0, &mat2, &mat3, 5.0);
|
/// mat1.gemm_tr(10.0, &mat2, &mat3, 5.0);
|
||||||
/// assert_relative_eq!(mat1, expected);
|
/// assert_eq!(mat1, expected);
|
||||||
/// ```
|
/// ```
|
||||||
#[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>(
|
||||||
|
@ -836,11 +1139,105 @@ where N: Scalar + Zero + ClosedAdd + ClosedMul
|
||||||
self.column_mut(j1).gemv_tr(alpha, a, &b.column(j1), beta);
|
self.column_mut(j1).gemv_tr(alpha, a, &b.column(j1), beta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Computes `self = alpha * a.adjoint() * b + beta * self`, where `a, b, self` are matrices.
|
||||||
|
/// `alpha` and `beta` are scalar.
|
||||||
|
///
|
||||||
|
/// If `beta` is zero, `self` is never read.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # #[macro_use] extern crate approx;
|
||||||
|
/// # use nalgebra::{Matrix3x2, Matrix3x4, Matrix2x4, Complex};
|
||||||
|
/// let mut mat1 = Matrix2x4::identity();
|
||||||
|
/// let mat2 = Matrix3x2::new(Complex::new(1.0, 4.0), Complex::new(7.0, 8.0),
|
||||||
|
/// Complex::new(2.0, 5.0), Complex::new(9.0, 10.0),
|
||||||
|
/// Complex::new(3.0, 6.0), Complex::new(11.0, 12.0));
|
||||||
|
/// let mat3 = Matrix3x4::new(Complex::new(0.1, 1.3), Complex::new(0.2, 1.4), Complex::new(0.3, 1.5), Complex::new(0.4, 1.6),
|
||||||
|
/// Complex::new(0.5, 1.7), Complex::new(0.6, 1.8), Complex::new(0.7, 1.9), Complex::new(0.8, 2.0),
|
||||||
|
/// Complex::new(0.9, 2.1), Complex::new(1.0, 2.2), Complex::new(1.1, 2.3), Complex::new(1.2, 2.4));
|
||||||
|
/// let expected = mat2.adjoint() * mat3 * Complex::new(10.0, 20.0) + mat1 * Complex::new(5.0, 15.0);
|
||||||
|
///
|
||||||
|
/// mat1.gemm_ad(Complex::new(10.0, 20.0), &mat2, &mat3, Complex::new(5.0, 15.0));
|
||||||
|
/// assert_eq!(mat1, expected);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub fn gemm_ad<R2: Dim, C2: Dim, R3: Dim, C3: Dim, SB, SC>(
|
||||||
|
&mut self,
|
||||||
|
alpha: N,
|
||||||
|
a: &Matrix<N, R2, C2, SB>,
|
||||||
|
b: &Matrix<N, R3, C3, SC>,
|
||||||
|
beta: N,
|
||||||
|
) where
|
||||||
|
N: ComplexField,
|
||||||
|
SB: Storage<N, R2, C2>,
|
||||||
|
SC: Storage<N, R3, C3>,
|
||||||
|
ShapeConstraint: SameNumberOfRows<R1, C2>
|
||||||
|
+ SameNumberOfColumns<C1, C3>
|
||||||
|
+ AreMultipliable<C2, R2, R3, C3>,
|
||||||
|
{
|
||||||
|
let (nrows1, ncols1) = self.shape();
|
||||||
|
let (nrows2, ncols2) = a.shape();
|
||||||
|
let (nrows3, ncols3) = b.shape();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
nrows2, nrows3,
|
||||||
|
"gemm: dimensions mismatch for multiplication."
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
(nrows1, ncols1),
|
||||||
|
(ncols2, ncols3),
|
||||||
|
"gemm: dimensions mismatch for addition."
|
||||||
|
);
|
||||||
|
|
||||||
|
for j1 in 0..ncols1 {
|
||||||
|
// FIXME: avoid bound checks.
|
||||||
|
self.column_mut(j1).gemv_ad(alpha, a, &b.column(j1), beta);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, R1: Dim, C1: Dim, S: StorageMut<N, R1, C1>> Matrix<N, R1, C1, S>
|
impl<N, R1: Dim, C1: Dim, S: StorageMut<N, R1, C1>> Matrix<N, R1, C1, S>
|
||||||
where N: Scalar + Zero + ClosedAdd + ClosedMul
|
where N: Scalar + Zero + ClosedAdd + ClosedMul
|
||||||
{
|
{
|
||||||
|
#[inline(always)]
|
||||||
|
fn xxgerx<D2: Dim, D3: Dim, SB, SC>(
|
||||||
|
&mut self,
|
||||||
|
alpha: N,
|
||||||
|
x: &Vector<N, D2, SB>,
|
||||||
|
y: &Vector<N, D3, SC>,
|
||||||
|
beta: N,
|
||||||
|
conjugate: impl Fn(N) -> N,
|
||||||
|
) where
|
||||||
|
N: One,
|
||||||
|
SB: Storage<N, D2>,
|
||||||
|
SC: Storage<N, D3>,
|
||||||
|
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
||||||
|
{
|
||||||
|
let dim1 = self.nrows();
|
||||||
|
let dim2 = x.nrows();
|
||||||
|
let dim3 = y.nrows();
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
self.is_square(),
|
||||||
|
"Symmetric ger: the input matrix must be square."
|
||||||
|
);
|
||||||
|
assert!(dim1 == dim2 && dim1 == dim3, "ger: dimensions mismatch.");
|
||||||
|
|
||||||
|
for j in 0..dim1 {
|
||||||
|
let val = unsafe { conjugate(*y.vget_unchecked(j)) };
|
||||||
|
let subdim = Dynamic::new(dim1 - j);
|
||||||
|
// FIXME: avoid bound checks.
|
||||||
|
self.generic_slice_mut((j, j), (subdim, U1)).axpy(
|
||||||
|
alpha * val,
|
||||||
|
&x.rows_range(j..),
|
||||||
|
beta,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Computes `self = alpha * x * y.transpose() + beta * self`, where `self` is a **symmetric**
|
/// Computes `self = alpha * x * y.transpose() + beta * self`, where `self` is a **symmetric**
|
||||||
/// matrix.
|
/// matrix.
|
||||||
///
|
///
|
||||||
|
@ -861,6 +1258,7 @@ where N: Scalar + Zero + ClosedAdd + ClosedMul
|
||||||
/// assert_eq!(mat.lower_triangle(), expected.lower_triangle());
|
/// assert_eq!(mat.lower_triangle(), expected.lower_triangle());
|
||||||
/// assert_eq!(mat.m12, 99999.99999); // This was untouched.
|
/// assert_eq!(mat.m12, 99999.99999); // This was untouched.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[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: N,
|
||||||
|
@ -873,26 +1271,78 @@ where N: Scalar + Zero + ClosedAdd + ClosedMul
|
||||||
SC: Storage<N, D3>,
|
SC: Storage<N, D3>,
|
||||||
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
||||||
{
|
{
|
||||||
let dim1 = self.nrows();
|
self.syger(alpha, x, y, beta)
|
||||||
let dim2 = x.nrows();
|
}
|
||||||
let dim3 = y.nrows();
|
|
||||||
|
|
||||||
assert!(
|
/// Computes `self = alpha * x * y.transpose() + beta * self`, where `self` is a **symmetric**
|
||||||
self.is_square(),
|
/// matrix.
|
||||||
"Symmetric ger: the input matrix must be square."
|
///
|
||||||
);
|
/// For hermitian complex matrices, use `.hegerc` instead.
|
||||||
assert!(dim1 == dim2 && dim1 == dim3, "ger: dimensions mismatch.");
|
/// If `beta` is zero, `self` is never read. The result is symmetric. Only the lower-triangular
|
||||||
|
/// (including the diagonal) part of `self` is read/written.
|
||||||
|
///
|
||||||
|
/// # Examples:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use nalgebra::{Matrix2, Vector2};
|
||||||
|
/// let mut mat = Matrix2::identity();
|
||||||
|
/// let vec1 = Vector2::new(1.0, 2.0);
|
||||||
|
/// let vec2 = Vector2::new(0.1, 0.2);
|
||||||
|
/// let expected = vec1 * vec2.transpose() * 10.0 + mat * 5.0;
|
||||||
|
/// mat.m12 = 99999.99999; // This component is on the upper-triangular part and will not be read/written.
|
||||||
|
///
|
||||||
|
/// mat.syger(10.0, &vec1, &vec2, 5.0);
|
||||||
|
/// assert_eq!(mat.lower_triangle(), expected.lower_triangle());
|
||||||
|
/// assert_eq!(mat.m12, 99999.99999); // This was untouched.
|
||||||
|
#[inline]
|
||||||
|
pub fn syger<D2: Dim, D3: Dim, SB, SC>(
|
||||||
|
&mut self,
|
||||||
|
alpha: N,
|
||||||
|
x: &Vector<N, D2, SB>,
|
||||||
|
y: &Vector<N, D3, SC>,
|
||||||
|
beta: N,
|
||||||
|
) where
|
||||||
|
N: One,
|
||||||
|
SB: Storage<N, D2>,
|
||||||
|
SC: Storage<N, D3>,
|
||||||
|
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
||||||
|
{
|
||||||
|
self.xxgerx(alpha, x, y, beta, |e| e)
|
||||||
|
}
|
||||||
|
|
||||||
for j in 0..dim1 {
|
/// Computes `self = alpha * x * y.adjoint() + beta * self`, where `self` is an **hermitian**
|
||||||
let val = unsafe { *y.vget_unchecked(j) };
|
/// matrix.
|
||||||
let subdim = Dynamic::new(dim1 - j);
|
///
|
||||||
// FIXME: avoid bound checks.
|
/// If `beta` is zero, `self` is never read. The result is symmetric. Only the lower-triangular
|
||||||
self.generic_slice_mut((j, j), (subdim, U1)).axpy(
|
/// (including the diagonal) part of `self` is read/written.
|
||||||
alpha * val,
|
///
|
||||||
&x.rows_range(j..),
|
/// # Examples:
|
||||||
beta,
|
///
|
||||||
);
|
/// ```
|
||||||
}
|
/// # use nalgebra::{Matrix2, Vector2, Complex};
|
||||||
|
/// let mut mat = Matrix2::identity();
|
||||||
|
/// let vec1 = Vector2::new(Complex::new(1.0, 3.0), Complex::new(2.0, 4.0));
|
||||||
|
/// let vec2 = Vector2::new(Complex::new(0.2, 0.4), Complex::new(0.1, 0.3));
|
||||||
|
/// let expected = vec1 * vec2.adjoint() * Complex::new(10.0, 20.0) + mat * Complex::new(5.0, 15.0);
|
||||||
|
/// mat.m12 = Complex::new(99999.99999, 88888.88888); // This component is on the upper-triangular part and will not be read/written.
|
||||||
|
///
|
||||||
|
/// mat.hegerc(Complex::new(10.0, 20.0), &vec1, &vec2, Complex::new(5.0, 15.0));
|
||||||
|
/// assert_eq!(mat.lower_triangle(), expected.lower_triangle());
|
||||||
|
/// assert_eq!(mat.m12, Complex::new(99999.99999, 88888.88888)); // This was untouched.
|
||||||
|
#[inline]
|
||||||
|
pub fn hegerc<D2: Dim, D3: Dim, SB, SC>(
|
||||||
|
&mut self,
|
||||||
|
alpha: N,
|
||||||
|
x: &Vector<N, D2, SB>,
|
||||||
|
y: &Vector<N, D3, SC>,
|
||||||
|
beta: N,
|
||||||
|
) where
|
||||||
|
N: ComplexField,
|
||||||
|
SB: Storage<N, D2>,
|
||||||
|
SC: Storage<N, D3>,
|
||||||
|
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
|
||||||
|
{
|
||||||
|
self.xxgerx(alpha, x, y, beta, ComplexField::conjugate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,18 +7,18 @@
|
||||||
|
|
||||||
use num::One;
|
use num::One;
|
||||||
|
|
||||||
use base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use base::dimension::{DimName, DimNameDiff, DimNameSub, U1};
|
use crate::base::dimension::{DimName, DimNameDiff, DimNameSub, U1};
|
||||||
use base::storage::{Storage, StorageMut};
|
use crate::base::storage::{Storage, StorageMut};
|
||||||
use base::{
|
use crate::base::{
|
||||||
DefaultAllocator, Matrix3, Matrix4, MatrixN, Scalar, SquareMatrix, Unit, Vector, Vector3,
|
DefaultAllocator, Matrix3, Matrix4, MatrixN, Scalar, SquareMatrix, Unit, Vector, Vector3,
|
||||||
VectorN,
|
VectorN,
|
||||||
};
|
};
|
||||||
use geometry::{
|
use crate::geometry::{
|
||||||
Isometry, IsometryMatrix3, Orthographic3, Perspective3, Point, Point3, Rotation2, Rotation3,
|
Isometry, IsometryMatrix3, Orthographic3, Perspective3, Point, Point3, Rotation2, Rotation3,
|
||||||
};
|
};
|
||||||
|
|
||||||
use alga::general::{Real, Ring};
|
use alga::general::{RealField, Ring};
|
||||||
use alga::linear::Transformation;
|
use alga::linear::Transformation;
|
||||||
|
|
||||||
impl<N, D: DimName> MatrixN<N, D>
|
impl<N, D: DimName> MatrixN<N, D>
|
||||||
|
@ -65,7 +65,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Real> Matrix3<N> {
|
impl<N: RealField> Matrix3<N> {
|
||||||
/// 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: N) -> Self {
|
||||||
|
@ -73,7 +73,7 @@ impl<N: Real> Matrix3<N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Real> Matrix4<N> {
|
impl<N: RealField> Matrix4<N> {
|
||||||
/// 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.
|
||||||
|
@ -321,7 +321,7 @@ impl<N: Scalar + Ring, D: DimName, S: StorageMut<N, D, D>> SquareMatrix<N, D, S>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Real, D: DimNameSub<U1>, S: Storage<N, D, D>> SquareMatrix<N, D, S>
|
impl<N: RealField, D: DimNameSub<U1>, S: Storage<N, D, D>> SquareMatrix<N, D, S>
|
||||||
where DefaultAllocator: Allocator<N, D, D>
|
where DefaultAllocator: Allocator<N, D, D>
|
||||||
+ Allocator<N, DimNameDiff<D, U1>>
|
+ Allocator<N, DimNameDiff<D, U1>>
|
||||||
+ Allocator<N, DimNameDiff<D, U1>, DimNameDiff<D, U1>>
|
+ Allocator<N, DimNameDiff<D, U1>, DimNameDiff<D, U1>>
|
||||||
|
@ -365,7 +365,7 @@ where DefaultAllocator: Allocator<N, D, D>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Real, D: DimNameSub<U1>> Transformation<Point<N, DimNameDiff<D, U1>>> for MatrixN<N, D>
|
impl<N: RealField, D: DimNameSub<U1>> Transformation<Point<N, DimNameDiff<D, U1>>> for MatrixN<N, D>
|
||||||
where DefaultAllocator: Allocator<N, D, D>
|
where DefaultAllocator: Allocator<N, D, D>
|
||||||
+ Allocator<N, DimNameDiff<D, U1>>
|
+ Allocator<N, DimNameDiff<D, U1>>
|
||||||
+ Allocator<N, DimNameDiff<D, U1>, DimNameDiff<D, U1>>
|
+ Allocator<N, DimNameDiff<D, U1>, DimNameDiff<D, U1>>
|
||||||
|
|
|
@ -5,11 +5,11 @@ use std::ops::{Add, Mul};
|
||||||
|
|
||||||
use alga::general::{ClosedDiv, ClosedMul};
|
use alga::general::{ClosedDiv, ClosedMul};
|
||||||
|
|
||||||
use base::allocator::{Allocator, SameShapeAllocator};
|
use crate::base::allocator::{Allocator, SameShapeAllocator};
|
||||||
use base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
|
use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
|
||||||
use base::dimension::Dim;
|
use crate::base::dimension::Dim;
|
||||||
use base::storage::{Storage, StorageMut};
|
use crate::base::storage::{Storage, StorageMut};
|
||||||
use base::{DefaultAllocator, Matrix, MatrixMN, MatrixSum, Scalar};
|
use crate::base::{DefaultAllocator, Matrix, MatrixMN, MatrixSum, Scalar};
|
||||||
|
|
||||||
/// 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<N, R1, C1, R2, C2> = MatrixSum<N, R1, C1, R2, C2>;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! Compatibility constraints between matrix shapes, e.g., for addition or multiplication.
|
//! Compatibility constraints between matrix shapes, e.g., for addition or multiplication.
|
||||||
|
|
||||||
use base::dimension::{Dim, DimName, Dynamic};
|
use crate::base::dimension::{Dim, DimName, Dynamic};
|
||||||
|
|
||||||
/// A type used in `where` clauses for enforcing constraints.
|
/// A type used in `where` clauses for enforcing constraints.
|
||||||
pub struct ShapeConstraint;
|
pub struct ShapeConstraint;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#[cfg(feature = "arbitrary")]
|
#[cfg(feature = "arbitrary")]
|
||||||
use base::storage::Owned;
|
use crate::base::storage::Owned;
|
||||||
#[cfg(feature = "arbitrary")]
|
#[cfg(feature = "arbitrary")]
|
||||||
use quickcheck::{Arbitrary, Gen};
|
use quickcheck::{Arbitrary, Gen};
|
||||||
|
|
||||||
|
@ -12,13 +12,13 @@ use std::iter;
|
||||||
use typenum::{self, Cmp, Greater};
|
use typenum::{self, Cmp, Greater};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use alga::general::Real;
|
use alga::general::RealField;
|
||||||
use alga::general::{ClosedAdd, ClosedMul};
|
use alga::general::{ClosedAdd, ClosedMul};
|
||||||
|
|
||||||
use base::allocator::Allocator;
|
use crate::base::allocator::Allocator;
|
||||||
use base::dimension::{Dim, DimName, Dynamic, U1, U2, U3, U4, U5, U6};
|
use crate::base::dimension::{Dim, DimName, Dynamic, U1, U2, U3, U4, U5, U6};
|
||||||
use base::storage::Storage;
|
use crate::base::storage::Storage;
|
||||||
use base::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Scalar, Unit, Vector, VectorN};
|
use crate::base::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Scalar, Unit, Vector, VectorN};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
@ -131,7 +131,7 @@ where DefaultAllocator: Allocator<N, R, C>
|
||||||
where N: Zero + One {
|
where N: Zero + One {
|
||||||
let mut res = Self::zeros_generic(nrows, ncols);
|
let mut res = Self::zeros_generic(nrows, ncols);
|
||||||
|
|
||||||
for i in 0..::min(nrows.value(), ncols.value()) {
|
for i in 0..crate::min(nrows.value(), ncols.value()) {
|
||||||
unsafe { *res.get_unchecked_mut((i, i)) = elt }
|
unsafe { *res.get_unchecked_mut((i, i)) = elt }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ where DefaultAllocator: Allocator<N, R, C>
|
||||||
where N: Zero {
|
where N: Zero {
|
||||||
let mut res = Self::zeros_generic(nrows, ncols);
|
let mut res = Self::zeros_generic(nrows, ncols);
|
||||||
assert!(
|
assert!(
|
||||||
elts.len() <= ::min(nrows.value(), ncols.value()),
|
elts.len() <= crate::min(nrows.value(), ncols.value()),
|
||||||
"Too many diagonal elements provided."
|
"Too many diagonal elements provided."
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -795,7 +795,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<N: Real, D: DimName> Distribution<Unit<VectorN<N, D>>> for Standard
|
impl<N: RealField, D: DimName> Distribution<Unit<VectorN<N, D>>> for Standard
|
||||||
where
|
where
|
||||||
DefaultAllocator: Allocator<N, D>,
|
DefaultAllocator: Allocator<N, D>,
|
||||||
StandardNormal: Distribution<N>,
|
StandardNormal: Distribution<N>,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use base::dimension::{Dim, DimName, Dynamic, U1};
|
use crate::base::dimension::{Dim, DimName, Dynamic, U1};
|
||||||
use base::matrix_slice::{SliceStorage, SliceStorageMut};
|
use crate::base::matrix_slice::{SliceStorage, SliceStorageMut};
|
||||||
use base::{MatrixSliceMN, MatrixSliceMutMN, Scalar};
|
use crate::base::{MatrixSliceMN, MatrixSliceMutMN, Scalar};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
|
|
@ -9,18 +9,18 @@ use generic_array::ArrayLength;
|
||||||
use std::ops::Mul;
|
use std::ops::Mul;
|
||||||
use typenum::Prod;
|
use typenum::Prod;
|
||||||
|
|
||||||
use base::allocator::{Allocator, SameShapeAllocator};
|
use crate::base::allocator::{Allocator, SameShapeAllocator};
|
||||||
use base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
|
use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
|
||||||
use base::dimension::{
|
use crate::base::dimension::{
|
||||||
Dim, DimName, U1, U10, U11, U12, U13, U14, U15, U16, U2, U3, U4, U5, U6, U7, U8, U9,
|
Dim, DimName, U1, U10, U11, U12, U13, U14, U15, U16, U2, U3, U4, U5, U6, U7, U8, U9,
|
||||||
};
|
};
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
use base::dimension::Dynamic;
|
use crate::base::dimension::Dynamic;
|
||||||
use base::iter::{MatrixIter, MatrixIterMut};
|
use crate::base::iter::{MatrixIter, MatrixIterMut};
|
||||||
use base::storage::{ContiguousStorage, ContiguousStorageMut, Storage, StorageMut};
|
use crate::base::storage::{ContiguousStorage, ContiguousStorageMut, Storage, StorageMut};
|
||||||
#[cfg(any(feature = "std", feature = "alloc"))]
|
#[cfg(any(feature = "std", feature = "alloc"))]
|
||||||
use base::VecStorage;
|
use crate::base::VecStorage;
|
||||||
use base::{DefaultAllocator, Matrix, ArrayStorage, MatrixMN, MatrixSlice, MatrixSliceMut, Scalar};
|
use crate::base::{DefaultAllocator, Matrix, ArrayStorage, MatrixMN, MatrixSlice, MatrixSliceMut, Scalar};
|
||||||
|
|
||||||
// FIXME: too bad this won't work allo slice conversions.
|
// FIXME: 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<N1, N2, R1, C1, R2, C2> SubsetOf<MatrixMN<N2, R2, C2>> for MatrixMN<N1, R1, C1>
|
||||||
|
@ -331,9 +331,9 @@ macro_rules! impl_from_into_mint_2D(
|
||||||
#[cfg(feature = "mint")]
|
#[cfg(feature = "mint")]
|
||||||
impl_from_into_mint_2D!(
|
impl_from_into_mint_2D!(
|
||||||
(U2, U2) => ColumnMatrix2{x, y}[2];
|
(U2, U2) => ColumnMatrix2{x, y}[2];
|
||||||
(U2, U3) => ColumnMatrix2x3{x, y}[2];
|
(U2, U3) => ColumnMatrix2x3{x, y, z}[2];
|
||||||
(U3, U3) => ColumnMatrix3{x, y, z}[3];
|
(U3, U3) => ColumnMatrix3{x, y, z}[3];
|
||||||
(U3, U4) => ColumnMatrix3x4{x, y, z}[3];
|
(U3, U4) => ColumnMatrix3x4{x, y, z, w}[3];
|
||||||
(U4, U4) => ColumnMatrix4{x, y, z, w}[4];
|
(U4, U4) => ColumnMatrix4{x, y, z, w}[4];
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
use base::dimension::{U1, U2, U3, U4, U5, U6};
|
use crate::base::dimension::{U1, U2, U3, U4, U5, U6};
|
||||||
use base::storage::{ContiguousStorage, ContiguousStorageMut};
|
use crate::base::storage::{ContiguousStorage, ContiguousStorageMut};
|
||||||
use base::{Matrix, Scalar};
|
use crate::base::{Matrix, Scalar};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue