Rename generic parameter N -> T

This commit is contained in:
Crozet Sébastien 2021-04-11 11:00:38 +02:00
parent 23a7d7475b
commit 24d546d3b6
217 changed files with 8542 additions and 8952 deletions

View File

@ -36,7 +36,7 @@ no_unsound_assume_init = [ ]
# Conversion # Conversion
convert-mint = [ "mint" ] convert-mint = [ "mint" ]
convert-glam = [ "glam" ] convert-glam = [ "glam" ]
convert-glam-unchecked = [ "convert-glam" ] # Unable edgy conversions like Mat4 -> Isometry3 convert-glam-unchecked = [ "convert-glam" ] # Enable edgy conversions like Mat4 -> Isometry3
convert-bytemuck = [ "bytemuck" ] convert-bytemuck = [ "bytemuck" ]
# Serialization # Serialization

View File

@ -1,4 +1,4 @@
use na::{DMatrix, DVector, Matrix2, Matrix3, Matrix4, MatrixN, Vector2, Vector3, Vector4, U10}; use na::{DMatrix, DVector, Matrix2, Matrix3, Matrix4, OMatrix, Vector2, Vector3, Vector4, U10};
use rand::Rng; use rand::Rng;
use rand_isaac::IsaacRng; use rand_isaac::IsaacRng;
use std::ops::{Add, Div, Mul, Sub}; use std::ops::{Add, Div, Mul, Sub};
@ -116,8 +116,8 @@ fn mat10_mul_mat10(bench: &mut criterion::Criterion) {
} }
fn mat10_mul_mat10_static(bench: &mut criterion::Criterion) { fn mat10_mul_mat10_static(bench: &mut criterion::Criterion) {
let a = MatrixN::<f64, U10>::new_random(); let a = OMatrix::<f64, U10>::new_random();
let b = MatrixN::<f64, U10>::new_random(); let b = OMatrix::<f64, U10>::new_random();
bench.bench_function("mat10_mul_mat10_static", move |bh| bh.iter(|| &a * &b)); bench.bench_function("mat10_mul_mat10_static", move |bh| bh.iter(|| &a * &b));
} }

View File

@ -1,4 +1,4 @@
use na::{DVector, Vector2, Vector3, Vector4, VectorN}; use na::{DVector, OVector, Vector2, Vector3, Vector4};
use rand::Rng; use rand::Rng;
use rand_isaac::IsaacRng; use rand_isaac::IsaacRng;
use std::ops::{Add, Div, Mul, Sub}; use std::ops::{Add, Div, Mul, Sub};
@ -45,8 +45,8 @@ bench_unop!(vec2_normalize, Vector2<f32>, normalize);
bench_unop!(vec3_normalize, Vector3<f32>, normalize); bench_unop!(vec3_normalize, Vector3<f32>, normalize);
bench_unop!(vec4_normalize, Vector4<f32>, normalize); bench_unop!(vec4_normalize, Vector4<f32>, normalize);
bench_binop_ref!(vec10000_dot_f64, VectorN<f64, U10000>, VectorN<f64, U10000>, dot); bench_binop_ref!(vec10000_dot_f64, OVector<f64, U10000>, OVector<f64, U10000>, dot);
bench_binop_ref!(vec10000_dot_f32, VectorN<f32, U10000>, VectorN<f32, U10000>, dot); bench_binop_ref!(vec10000_dot_f32, OVector<f32, U10000>, OVector<f32, U10000>, dot);
fn vec10000_axpy_f64(bh: &mut criterion::Criterion) { fn vec10000_axpy_f64(bh: &mut criterion::Criterion) {
use rand::SeedableRng; use rand::SeedableRng;
@ -93,11 +93,11 @@ fn vec10000_axpy_f64_slice(bh: &mut criterion::Criterion) {
fn vec10000_axpy_f64_static(bh: &mut criterion::Criterion) { fn vec10000_axpy_f64_static(bh: &mut criterion::Criterion) {
use rand::SeedableRng; use rand::SeedableRng;
let mut rng = IsaacRng::seed_from_u64(0); let mut rng = IsaacRng::seed_from_u64(0);
let mut a = VectorN::<f64, U10000>::new_random(); let mut a = OVector::<f64, U10000>::new_random();
let b = VectorN::<f64, U10000>::new_random(); let b = OVector::<f64, U10000>::new_random();
let n = rng.gen::<f64>(); let n = rng.gen::<f64>();
// NOTE: for some reasons, it is much faster if the arument are boxed (Box::new(VectorN...)). // NOTE: for some reasons, it is much faster if the arument are boxed (Box::new(OVector...)).
bh.bench_function("vec10000_axpy_f64_static", move |bh| { bh.bench_function("vec10000_axpy_f64_static", move |bh| {
bh.iter(|| a.axpy(n, &b, 1.0)) bh.iter(|| a.axpy(n, &b, 1.0))
}); });

View File

@ -2,26 +2,26 @@ extern crate nalgebra as na;
use na::allocator::Allocator; use na::allocator::Allocator;
use na::dimension::Dim; use na::dimension::Dim;
use na::{DefaultAllocator, RealField, Unit, Vector2, Vector3, VectorN}; use na::{DefaultAllocator, OVector, RealField, Unit, Vector2, Vector3};
/// Reflects a vector wrt. the hyperplane with normal `plane_normal`. /// Reflects a vector wrt. the hyperplane with normal `plane_normal`.
fn reflect_wrt_hyperplane_with_dimensional_genericity<N: RealField, D: Dim>( fn reflect_wrt_hyperplane_with_dimensional_genericity<T: RealField, D: Dim>(
plane_normal: &Unit<VectorN<N, D>>, plane_normal: &Unit<OVector<T, D>>,
vector: &VectorN<N, D>, vector: &OVector<T, D>,
) -> VectorN<N, D> ) -> OVector<T, D>
where where
N: RealField, T: RealField,
D: Dim, D: Dim,
DefaultAllocator: Allocator<N, D>, DefaultAllocator: Allocator<T, D>,
{ {
let n = plane_normal.as_ref(); // Get the underlying V. let n = plane_normal.as_ref(); // Get the underlying V.
vector - n * (n.dot(vector) * na::convert(2.0)) vector - n * (n.dot(vector) * na::convert(2.0))
} }
/// Reflects a 2D vector wrt. the 2D line with normal `plane_normal`. /// Reflects a 2D vector wrt. the 2D line with normal `plane_normal`.
fn reflect_wrt_hyperplane2<N>(plane_normal: &Unit<Vector2<N>>, vector: &Vector2<N>) -> Vector2<N> fn reflect_wrt_hyperplane2<T>(plane_normal: &Unit<Vector2<T>>, vector: &Vector2<T>) -> Vector2<T>
where where
N: RealField, T: RealField,
{ {
let n = plane_normal.as_ref(); // Get the underlying Vector2 let n = plane_normal.as_ref(); // Get the underlying Vector2
vector - n * (n.dot(vector) * na::convert(2.0)) vector - n * (n.dot(vector) * na::convert(2.0))
@ -29,9 +29,9 @@ where
/// Reflects a 3D vector wrt. the 3D plane with normal `plane_normal`. /// Reflects a 3D vector wrt. the 3D plane with normal `plane_normal`.
/// /!\ This is an exact replicate of `reflect_wrt_hyperplane2, but for 3D. /// /!\ This is an exact replicate of `reflect_wrt_hyperplane2, but for 3D.
fn reflect_wrt_hyperplane3<N>(plane_normal: &Unit<Vector3<N>>, vector: &Vector3<N>) -> Vector3<N> fn reflect_wrt_hyperplane3<T>(plane_normal: &Unit<Vector3<T>>, vector: &Vector3<T>) -> Vector3<T>
where where
N: RealField, T: RealField,
{ {
let n = plane_normal.as_ref(); // Get the underlying Vector3 let n = plane_normal.as_ref(); // Get the underlying Vector3
vector - n * (n.dot(vector) * na::convert(2.0)) vector - n * (n.dot(vector) * na::convert(2.0))

View File

@ -2,20 +2,20 @@ extern crate nalgebra as na;
use matrixcompare::comparators::{AbsoluteElementwiseComparator, ExactElementwiseComparator}; use matrixcompare::comparators::{AbsoluteElementwiseComparator, ExactElementwiseComparator};
use matrixcompare::compare_matrices; use matrixcompare::compare_matrices;
use na::{MatrixMN, U3, U4}; use na::{OMatrix, U3, U4};
fn compare_integers_fail() { fn compare_integers_fail() {
println!("Comparing two integer matrices."); println!("Comparing two integer matrices.");
#[rustfmt::skip] #[rustfmt::skip]
let a = MatrixMN::<_, U3, U4>::from_row_slice(&[ let a = OMatrix::<_, U3, U4>::from_row_slice(&[
0, 1, 2, 3, 0, 1, 2, 3,
4, 5, 6, 7, 4, 5, 6, 7,
8, 9, -2, 11 8, 9, -2, 11
]); ]);
#[rustfmt::skip] #[rustfmt::skip]
let b = MatrixMN::<_, U3, U4>::from_row_slice(&[ let b = OMatrix::<_, U3, U4>::from_row_slice(&[
0, 1, 2, 3, 0, 1, 2, 3,
4, 5, 6, 7, 4, 5, 6, 7,
8, 9, 10, 11 8, 9, 10, 11
@ -29,14 +29,14 @@ fn compare_integers_fail() {
fn compare_different_size() { fn compare_different_size() {
println!("Comparing matrices of different size."); println!("Comparing matrices of different size.");
#[rustfmt::skip] #[rustfmt::skip]
let a = MatrixMN::<_, U3, U3>::from_row_slice(&[ let a = OMatrix::<_, U3, U3>::from_row_slice(&[
0, 1, 2, 0, 1, 2,
4, 5, 6, 4, 5, 6,
8, 9, 10, 8, 9, 10,
]); ]);
#[rustfmt::skip] #[rustfmt::skip]
let b = MatrixMN::<_, U3, U4>::from_row_slice(&[ let b = OMatrix::<_, U3, U4>::from_row_slice(&[
0, 1, 2, 3, 0, 1, 2, 3,
4, 5, 6, 7, 4, 5, 6, 7,
8, 9, 10, 11 8, 9, 10, 11
@ -51,14 +51,14 @@ fn compare_f64_abs_tol_fail() {
println!("Comparing two f64 matrices."); println!("Comparing two f64 matrices.");
#[rustfmt::skip] #[rustfmt::skip]
let a = MatrixMN::<f64, U3, U3>::from_row_slice(&[ let a = OMatrix::<f64, U3, U3>::from_row_slice(&[
0.0, 1.0, 2.0 + 1e-10, 0.0, 1.0, 2.0 + 1e-10,
4.0, 5.0, 6.0, 4.0, 5.0, 6.0,
8.0, 9.0, 10.0, 8.0, 9.0, 10.0,
]); ]);
#[rustfmt::skip] #[rustfmt::skip]
let b = MatrixMN::<_, U3, U3>::from_row_slice(&[ let b = OMatrix::<_, U3, U3>::from_row_slice(&[
0.0, 1.0, 2.0, 0.0, 1.0, 2.0,
4.0, 5.0, 6.0, 4.0, 5.0, 6.0,
8.0, 9.0, 10.0 8.0, 9.0, 10.0

View File

@ -3,15 +3,15 @@ extern crate nalgebra as na;
use na::{Scalar, Vector3}; use na::{Scalar, Vector3};
use simba::scalar::RealField; use simba::scalar::RealField;
fn print_vector<N: Scalar>(m: &Vector3<N>) { fn print_vector<T: Scalar>(m: &Vector3<T>) {
println!("{:?}", m) println!("{:?}", m)
} }
fn print_norm<N: RealField>(v: &Vector3<N>) { fn print_norm<T: RealField>(v: &Vector3<T>) {
// NOTE: alternatively, nalgebra already defines `v.norm()`. // NOTE: alternatively, nalgebra already defines `v.norm()`.
let norm = v.dot(v).sqrt(); let norm = v.dot(v).sqrt();
// The RealField bound implies that N is Display so we can // The RealField bound implies that T is Display so we can
// use "{}" instead of "{:?}" for the format string. // use "{}" instead of "{:?}" for the format string.
println!("{}", norm) println!("{}", norm)
} }

View File

@ -1,9 +1,9 @@
use na::{ use na::{
Matrix2, Matrix2x3, Matrix2x4, Matrix3, Matrix3x2, Matrix3x4, Matrix4, Matrix4x2, Matrix4x3, Matrix2, Matrix2x3, Matrix2x4, Matrix3, Matrix3x2, Matrix3x4, Matrix4, Matrix4x2, Matrix4x3,
MatrixMN, Quaternion, VectorN, U1, U2, U3, U4, Quaternion, SMatrix, SVector,
}; };
/// A matrix with components of type `N`. It has `R` rows, and `C` columns. /// A matrix with components of type `T`. It has `R` rows, and `C` columns.
/// ///
/// In this library, vectors, represented as [`TVec`](type.TVec.html) and /// In this library, vectors, represented as [`TVec`](type.TVec.html) and
/// friends, are also matrices. Operations that operate on a matrix will /// friends, are also matrices. Operations that operate on a matrix will
@ -24,8 +24,8 @@ use na::{
/// * [`TMat4x3`](type.TMat4x3.html) /// * [`TMat4x3`](type.TMat4x3.html)
/// * [`TMat4x4`](type.TMat4x4.html) /// * [`TMat4x4`](type.TMat4x4.html)
/// * [`TVec`](type.TVec.html) /// * [`TVec`](type.TVec.html)
pub type TMat<N, R, C> = MatrixMN<N, R, C>; pub type TMat<T, const R: usize, const C: usize> = SMatrix<T, R, C>;
/// A column vector with components of type `N`. It has `D` rows (and one column). /// A column vector with components of type `T`. It has `D` rows (and one column).
/// ///
/// In this library, vectors are represented as a single column matrix, so /// In this library, vectors are represented as a single column matrix, so
/// operations on [`TMat`](type.TMat.html) are also valid on vectors. /// operations on [`TMat`](type.TMat.html) are also valid on vectors.
@ -37,11 +37,11 @@ pub type TMat<N, R, C> = MatrixMN<N, R, C>;
/// * [`TVec2`](type.TVec2.html) /// * [`TVec2`](type.TVec2.html)
/// * [`TVec3`](type.TVec3.html) /// * [`TVec3`](type.TVec3.html)
/// * [`TVec4`](type.TVec4.html) /// * [`TVec4`](type.TVec4.html)
pub type TVec<N, R> = VectorN<N, R>; pub type TVec<T, const R: usize> = SVector<T, R>;
/// A quaternion with components of type `N`. /// A quaternion with components of type `T`.
pub type Qua<N> = Quaternion<N>; pub type Qua<T> = Quaternion<T>;
/// A 1D vector with components of type `N`. /// A 1D vector with components of type `T`.
/// ///
/// # See also: /// # See also:
/// ///
@ -69,8 +69,8 @@ pub type Qua<N> = Quaternion<N>;
/// * [`U64Vec1`](type.U64Vec1.html) /// * [`U64Vec1`](type.U64Vec1.html)
/// * [`U8Vec1`](type.U8Vec1.html) /// * [`U8Vec1`](type.U8Vec1.html)
/// * [`Vec1`](type.Vec1.html) /// * [`Vec1`](type.Vec1.html)
pub type TVec1<N> = TVec<N, U1>; pub type TVec1<T> = TVec<T, 1>;
/// A 2D vector with components of type `N`. /// A 2D vector with components of type `T`.
/// ///
/// # See also: /// # See also:
/// ///
@ -99,8 +99,8 @@ pub type TVec1<N> = TVec<N, U1>;
/// * [`U64Vec2`](type.U64Vec2.html) /// * [`U64Vec2`](type.U64Vec2.html)
/// * [`U8Vec2`](type.U8Vec2.html) /// * [`U8Vec2`](type.U8Vec2.html)
/// * [`Vec2`](type.Vec2.html) /// * [`Vec2`](type.Vec2.html)
pub type TVec2<N> = TVec<N, U2>; pub type TVec2<T> = TVec<T, 2>;
/// A 3D vector with components of type `N`. /// A 3D vector with components of type `T`.
/// ///
/// # See also: /// # See also:
/// ///
@ -129,8 +129,8 @@ pub type TVec2<N> = TVec<N, U2>;
/// * [`U64Vec3`](type.U64Vec3.html) /// * [`U64Vec3`](type.U64Vec3.html)
/// * [`U8Vec3`](type.U8Vec3.html) /// * [`U8Vec3`](type.U8Vec3.html)
/// * [`Vec3`](type.Vec3.html) /// * [`Vec3`](type.Vec3.html)
pub type TVec3<N> = TVec<N, U3>; pub type TVec3<T> = TVec<T, 3>;
/// A 4D vector with components of type `N`. /// A 4D vector with components of type `T`.
/// ///
/// # See also: /// # See also:
/// ///
@ -158,7 +158,7 @@ pub type TVec3<N> = TVec<N, U3>;
/// * [`U64Vec4`](type.U64Vec4.html) /// * [`U64Vec4`](type.U64Vec4.html)
/// * [`U8Vec4`](type.U8Vec4.html) /// * [`U8Vec4`](type.U8Vec4.html)
/// * [`Vec4`](type.Vec4.html) /// * [`Vec4`](type.Vec4.html)
pub type TVec4<N> = TVec<N, U4>; pub type TVec4<T> = TVec<T, 4>;
/// A 1D vector with boolean components. /// A 1D vector with boolean components.
pub type BVec1 = TVec1<bool>; pub type BVec1 = TVec1<bool>;
/// A 2D vector with boolean components. /// A 2D vector with boolean components.
@ -268,31 +268,31 @@ pub type I8Vec3 = TVec3<i8>;
/// A 4D vector with `i8` components. /// A 4D vector with `i8` components.
pub type I8Vec4 = TVec4<i8>; pub type I8Vec4 = TVec4<i8>;
/// A 2x2 matrix with components of type `N`. /// A 2x2 matrix with components of type `T`.
pub type TMat2<N> = Matrix2<N>; pub type TMat2<T> = Matrix2<T>;
/// A 2x2 matrix with components of type `N`. /// A 2x2 matrix with components of type `T`.
pub type TMat2x2<N> = Matrix2<N>; pub type TMat2x2<T> = Matrix2<T>;
/// A 2x3 matrix with components of type `N`. /// A 2x3 matrix with components of type `T`.
pub type TMat2x3<N> = Matrix2x3<N>; pub type TMat2x3<T> = Matrix2x3<T>;
/// A 2x4 matrix with components of type `N`. /// A 2x4 matrix with components of type `T`.
pub type TMat2x4<N> = Matrix2x4<N>; pub type TMat2x4<T> = Matrix2x4<T>;
/// A 3x3 matrix with components of type `N`. /// A 3x3 matrix with components of type `T`.
pub type TMat3<N> = Matrix3<N>; pub type TMat3<T> = Matrix3<T>;
/// A 3x2 matrix with components of type `N`. /// A 3x2 matrix with components of type `T`.
pub type TMat3x2<N> = Matrix3x2<N>; pub type TMat3x2<T> = Matrix3x2<T>;
/// A 3x3 matrix with components of type `N`. /// A 3x3 matrix with components of type `T`.
pub type TMat3x3<N> = Matrix3<N>; pub type TMat3x3<T> = Matrix3<T>;
/// A 3x4 matrix with components of type `N`. /// A 3x4 matrix with components of type `T`.
pub type TMat3x4<N> = Matrix3x4<N>; pub type TMat3x4<T> = Matrix3x4<T>;
/// A 4x4 matrix with components of type `N`. /// A 4x4 matrix with components of type `T`.
pub type TMat4<N> = Matrix4<N>; pub type TMat4<T> = Matrix4<T>;
/// A 4x2 matrix with components of type `N`. /// A 4x2 matrix with components of type `T`.
pub type TMat4x2<N> = Matrix4x2<N>; pub type TMat4x2<T> = Matrix4x2<T>;
/// A 4x3 matrix with components of type `N`. /// A 4x3 matrix with components of type `T`.
pub type TMat4x3<N> = Matrix4x3<N>; pub type TMat4x3<T> = Matrix4x3<T>;
/// A 4x4 matrix with components of type `N`. /// A 4x4 matrix with components of type `T`.
pub type TMat4x4<N> = Matrix4<N>; pub type TMat4x4<T> = Matrix4<T>;
/// A 2x2 matrix with components of type `N`. /// A 2x2 matrix with components of type `T`.
pub type DMat2 = Matrix2<f64>; pub type DMat2 = Matrix2<f64>;
/// A 2x2 matrix with `f64` components. /// A 2x2 matrix with `f64` components.
pub type DMat2x2 = Matrix2<f64>; pub type DMat2x2 = Matrix2<f64>;

View File

@ -1,9 +1,9 @@
use core::mem; use core::mem;
use na::{self, DefaultAllocator, RealField}; use na::{self, RealField};
use num::FromPrimitive; use num::FromPrimitive;
use crate::aliases::{TMat, TVec}; use crate::aliases::{TMat, TVec};
use crate::traits::{Alloc, Dimension, Number}; use crate::traits::Number;
/// For each matrix or vector component `x` if `x >= 0`; otherwise, it returns `-x`. /// For each matrix or vector component `x` if `x >= 0`; otherwise, it returns `-x`.
/// ///
@ -21,10 +21,7 @@ use crate::traits::{Alloc, Dimension, Number};
/// # See also: /// # See also:
/// ///
/// * [`sign`](fn.sign.html) /// * [`sign`](fn.sign.html)
pub fn abs<N: Number, R: Dimension, C: Dimension>(x: &TMat<N, R, C>) -> TMat<N, R, C> pub fn abs<T: Number, const R: usize, const C: usize>(x: &TMat<T, R, C>) -> TMat<T, R, C> {
where
DefaultAllocator: Alloc<N, R, C>,
{
x.abs() x.abs()
} }
@ -45,10 +42,7 @@ where
/// * [`fract`](fn.fract.html) /// * [`fract`](fn.fract.html)
/// * [`round`](fn.round.html) /// * [`round`](fn.round.html)
/// * [`trunc`](fn.trunc.html) /// * [`trunc`](fn.trunc.html)
pub fn ceil<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn ceil<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.map(|x| x.ceil()) x.map(|x| x.ceil())
} }
@ -73,7 +67,7 @@ where
/// ///
/// * [`clamp`](fn.clamp.html) /// * [`clamp`](fn.clamp.html)
/// * [`clamp_vec`](fn.clamp_vec.html) /// * [`clamp_vec`](fn.clamp_vec.html)
pub fn clamp_scalar<N: Number>(x: N, min_val: N, max_val: N) -> N { pub fn clamp_scalar<T: Number>(x: T, min_val: T, max_val: T) -> T {
na::clamp(x, min_val, max_val) na::clamp(x, min_val, max_val)
} }
@ -97,10 +91,7 @@ pub fn clamp_scalar<N: Number>(x: N, min_val: N, max_val: N) -> N {
/// ///
/// * [`clamp_scalar`](fn.clamp_scalar.html) /// * [`clamp_scalar`](fn.clamp_scalar.html)
/// * [`clamp_vec`](fn.clamp_vec.html) /// * [`clamp_vec`](fn.clamp_vec.html)
pub fn clamp<N: Number, D: Dimension>(x: &TVec<N, D>, min_val: N, max_val: N) -> TVec<N, D> pub fn clamp<T: Number, const D: usize>(x: &TVec<T, D>, min_val: T, max_val: T) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.map(|x| na::clamp(x, min_val, max_val)) x.map(|x| na::clamp(x, min_val, max_val))
} }
@ -131,14 +122,11 @@ where
/// ///
/// * [`clamp_scalar`](fn.clamp_scalar.html) /// * [`clamp_scalar`](fn.clamp_scalar.html)
/// * [`clamp`](fn.clamp.html) /// * [`clamp`](fn.clamp.html)
pub fn clamp_vec<N: Number, D: Dimension>( pub fn clamp_vec<T: Number, const D: usize>(
x: &TVec<N, D>, x: &TVec<T, D>,
min_val: &TVec<N, D>, min_val: &TVec<T, D>,
max_val: &TVec<N, D>, max_val: &TVec<T, D>,
) -> TVec<N, D> ) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.zip_zip_map(min_val, max_val, |a, min, max| na::clamp(a, min, max)) x.zip_zip_map(min_val, max_val, |a, min, max| na::clamp(a, min, max))
} }
@ -172,10 +160,7 @@ pub fn float_bits_to_int(v: f32) -> i32 {
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html) /// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html) /// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html) /// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
pub fn float_bits_to_int_vec<D: Dimension>(v: &TVec<f32, D>) -> TVec<i32, D> pub fn float_bits_to_int_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<i32, D> {
where
DefaultAllocator: Alloc<f32, D>,
{
v.map(float_bits_to_int) v.map(float_bits_to_int)
} }
@ -209,10 +194,7 @@ pub fn float_bits_to_uint(v: f32) -> u32 {
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html) /// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html) /// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html) /// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
pub fn float_bits_to_uint_vec<D: Dimension>(v: &TVec<f32, D>) -> TVec<u32, D> pub fn float_bits_to_uint_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<u32, D> {
where
DefaultAllocator: Alloc<f32, D>,
{
v.map(float_bits_to_uint) v.map(float_bits_to_uint)
} }
@ -232,15 +214,12 @@ where
/// * [`fract`](fn.fract.html) /// * [`fract`](fn.fract.html)
/// * [`round`](fn.round.html) /// * [`round`](fn.round.html)
/// * [`trunc`](fn.trunc.html) /// * [`trunc`](fn.trunc.html)
pub fn floor<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn floor<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.map(|x| x.floor()) x.map(|x| x.floor())
} }
//// TODO: should be implemented for TVec/TMat? //// TODO: should be implemented for TVec/TMat?
//pub fn fma<N: Number>(a: N, b: N, c: N) -> N { //pub fn fma<T: Number>(a: T, b: T, c: T) -> T {
// // TODO: use an actual FMA // // TODO: use an actual FMA
// a * b + c // a * b + c
//} //}
@ -261,16 +240,13 @@ where
/// * [`floor`](fn.floor.html) /// * [`floor`](fn.floor.html)
/// * [`round`](fn.round.html) /// * [`round`](fn.round.html)
/// * [`trunc`](fn.trunc.html) /// * [`trunc`](fn.trunc.html)
pub fn fract<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn fract<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.map(|x| x.fract()) x.map(|x| x.fract())
} }
//// TODO: should be implemented for TVec/TMat? //// TODO: should be implemented for TVec/TMat?
///// Returns the (significant, exponent) of this float number. ///// Returns the (significant, exponent) of this float number.
//pub fn frexp<N: RealField>(x: N, exp: N) -> (N, N) { //pub fn frexp<T: RealField>(x: T, exp: T) -> (T, T) {
// // TODO: is there a better approach? // // TODO: is there a better approach?
// let e = x.log2().ceil(); // let e = x.log2().ceil();
// (x * (-e).exp2(), e) // (x * (-e).exp2(), e)
@ -306,27 +282,22 @@ pub fn int_bits_to_float(v: i32) -> f32 {
/// * [`int_bits_to_float`](fn.int_bits_to_float.html) /// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`uint_bits_to_float`](fn.uint_bits_to_float.html) /// * [`uint_bits_to_float`](fn.uint_bits_to_float.html)
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html) /// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
pub fn int_bits_to_float_vec<D: Dimension>(v: &TVec<i32, D>) -> TVec<f32, D> pub fn int_bits_to_float_vec<const D: usize>(v: &TVec<i32, D>) -> TVec<f32, D> {
where
DefaultAllocator: Alloc<f32, D>,
{
v.map(int_bits_to_float) v.map(int_bits_to_float)
} }
//pub fn isinf<N: Scalar, D: Dimension>(x: &TVec<N, D>) -> TVec<bool, D> //pub fn isinf<T: Scalar, const D: usize>(x: &TVec<T, D>) -> TVec<bool, D> {
// where DefaultAllocator: Alloc<N, D> {
// unimplemented!() // unimplemented!()
// //
//} //}
// //
//pub fn isnan<N: Scalar, D: Dimension>(x: &TVec<N, D>) -> TVec<bool, D> //pub fn isnan<T: Scalar, const D: usize>(x: &TVec<T, D>) -> TVec<bool, D> {
// where DefaultAllocator: Alloc<N, D> {
// unimplemented!() // unimplemented!()
// //
//} //}
///// Returns the (significant, exponent) of this float number. ///// Returns the (significant, exponent) of this float number.
//pub fn ldexp<N: RealField>(x: N, exp: N) -> N { //pub fn ldexp<T: RealField>(x: T, exp: T) -> T {
// // TODO: is there a better approach? // // TODO: is there a better approach?
// x * (exp).exp2() // x * (exp).exp2()
//} //}
@ -346,8 +317,8 @@ where
/// ///
/// * [`mix`](fn.mix.html) /// * [`mix`](fn.mix.html)
/// * [`mix_vec`](fn.mix_vec.html) /// * [`mix_vec`](fn.mix_vec.html)
pub fn mix_scalar<N: Number>(x: N, y: N, a: N) -> N { pub fn mix_scalar<T: Number>(x: T, y: T, a: T) -> T {
x * (N::one() - a) + y * a x * (T::one() - a) + y * a
} }
/// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the vectors x and y using the scalar value a. /// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the vectors x and y using the scalar value a.
@ -367,11 +338,8 @@ pub fn mix_scalar<N: Number>(x: N, y: N, a: N) -> N {
/// ///
/// * [`mix_scalar`](fn.mix_scalar.html) /// * [`mix_scalar`](fn.mix_scalar.html)
/// * [`mix_vec`](fn.mix_vec.html) /// * [`mix_vec`](fn.mix_vec.html)
pub fn mix<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, a: N) -> TVec<N, D> pub fn mix<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) -> TVec<T, D> {
where x * (T::one() - a) + y * a
DefaultAllocator: Alloc<N, D>,
{
x * (N::one() - a) + y * a
} }
/// Returns `x * (1.0 - a) + y * a`, i.e., the component-wise linear blend of `x` and `y` using the components of /// Returns `x * (1.0 - a) + y * a`, i.e., the component-wise linear blend of `x` and `y` using the components of
@ -393,15 +361,12 @@ where
/// ///
/// * [`mix_scalar`](fn.mix_scalar.html) /// * [`mix_scalar`](fn.mix_scalar.html)
/// * [`mix`](fn.mix.html) /// * [`mix`](fn.mix.html)
pub fn mix_vec<N: Number, D: Dimension>( pub fn mix_vec<T: Number, const D: usize>(
x: &TVec<N, D>, x: &TVec<T, D>,
y: &TVec<N, D>, y: &TVec<T, D>,
a: &TVec<N, D>, a: &TVec<T, D>,
) -> TVec<N, D> ) -> TVec<T, D> {
where x.component_mul(&(TVec::<T, D>::repeat(T::one()) - a)) + y.component_mul(&a)
DefaultAllocator: Alloc<N, D>,
{
x.component_mul(&(TVec::<N, D>::repeat(N::one()) - a)) + y.component_mul(&a)
} }
/// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the scalars x and y using the scalar value a. /// Returns `x * (1.0 - a) + y * a`, i.e., the linear blend of the scalars x and y using the scalar value a.
@ -420,7 +385,7 @@ where
/// ///
/// * [`lerp`](fn.lerp.html) /// * [`lerp`](fn.lerp.html)
/// * [`lerp_vec`](fn.lerp_vec.html) /// * [`lerp_vec`](fn.lerp_vec.html)
pub fn lerp_scalar<N: Number>(x: N, y: N, a: N) -> N { pub fn lerp_scalar<T: Number>(x: T, y: T, a: T) -> T {
mix_scalar(x, y, a) mix_scalar(x, y, a)
} }
@ -442,10 +407,7 @@ pub fn lerp_scalar<N: Number>(x: N, y: N, a: N) -> N {
/// ///
/// * [`lerp_scalar`](fn.lerp_scalar.html) /// * [`lerp_scalar`](fn.lerp_scalar.html)
/// * [`lerp_vec`](fn.lerp_vec.html) /// * [`lerp_vec`](fn.lerp_vec.html)
pub fn lerp<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, a: N) -> TVec<N, D> pub fn lerp<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, a: T) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
mix(x, y, a) mix(x, y, a)
} }
@ -469,14 +431,11 @@ where
/// ///
/// * [`lerp_scalar`](fn.lerp_scalar.html) /// * [`lerp_scalar`](fn.lerp_scalar.html)
/// * [`lerp`](fn.lerp.html) /// * [`lerp`](fn.lerp.html)
pub fn lerp_vec<N: Number, D: Dimension>( pub fn lerp_vec<T: Number, const D: usize>(
x: &TVec<N, D>, x: &TVec<T, D>,
y: &TVec<N, D>, y: &TVec<T, D>,
a: &TVec<N, D>, a: &TVec<T, D>,
) -> TVec<N, D> ) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
mix_vec(x, y, a) mix_vec(x, y, a)
} }
@ -487,10 +446,7 @@ where
/// # See also: /// # See also:
/// ///
/// * [`modf`](fn.modf.html) /// * [`modf`](fn.modf.html)
pub fn modf_vec<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<N, D> pub fn modf_vec<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| x % y) x.zip_map(y, |x, y| x % y)
} }
@ -499,7 +455,7 @@ where
/// # See also: /// # See also:
/// ///
/// * [`modf_vec`](fn.modf_vec.html) /// * [`modf_vec`](fn.modf_vec.html)
pub fn modf<N: Number>(x: N, i: N) -> N { pub fn modf<T: Number>(x: T, i: T) -> T {
x % i x % i
} }
@ -521,15 +477,11 @@ pub fn modf<N: Number>(x: N, i: N) -> N {
/// * [`floor`](fn.floor.html) /// * [`floor`](fn.floor.html)
/// * [`fract`](fn.fract.html) /// * [`fract`](fn.fract.html)
/// * [`trunc`](fn.trunc.html) /// * [`trunc`](fn.trunc.html)
pub fn round<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn round<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.map(|x| x.round()) x.map(|x| x.round())
} }
//pub fn roundEven<N: Scalar, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> //pub fn roundEven<T: Scalar, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
// where DefaultAllocator: Alloc<N, D> {
// unimplemented!() // unimplemented!()
//} //}
@ -547,46 +499,37 @@ where
/// ///
/// * [`abs`](fn.abs.html) /// * [`abs`](fn.abs.html)
/// ///
pub fn sign<N: Number, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn sign<T: Number, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
where x.map(|x| if x.is_zero() { T::zero() } else { x.signum() })
DefaultAllocator: Alloc<N, D>,
{
x.map(|x| if x.is_zero() { N::zero() } else { x.signum() })
} }
/// Returns 0.0 if `x <= edge0` and `1.0 if x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`. /// Returns 0.0 if `x <= edge0` and `1.0 if x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.
/// ///
/// This is useful in cases where you would want a threshold function with a smooth transition. /// This is useful in cases where you would want a threshold function with a smooth transition.
/// This is equivalent to: `let result = clamp((x - edge0) / (edge1 - edge0), 0, 1); return t * t * (3 - 2 * t);` Results are undefined if `edge0 >= edge1`. /// This is equivalent to: `let result = clamp((x - edge0) / (edge1 - edge0), 0, 1); return t * t * (3 - 2 * t);` Results are undefined if `edge0 >= edge1`.
pub fn smoothstep<N: Number>(edge0: N, edge1: N, x: N) -> N { pub fn smoothstep<T: Number>(edge0: T, edge1: T, x: T) -> T {
let _3: N = FromPrimitive::from_f64(3.0).unwrap(); let _3: T = FromPrimitive::from_f64(3.0).unwrap();
let _2: N = FromPrimitive::from_f64(2.0).unwrap(); let _2: T = FromPrimitive::from_f64(2.0).unwrap();
let t = na::clamp((x - edge0) / (edge1 - edge0), N::zero(), N::one()); let t = na::clamp((x - edge0) / (edge1 - edge0), T::zero(), T::one());
t * t * (_3 - t * _2) t * t * (_3 - t * _2)
} }
/// Returns 0.0 if `x < edge`, otherwise it returns 1.0. /// Returns 0.0 if `x < edge`, otherwise it returns 1.0.
pub fn step_scalar<N: Number>(edge: N, x: N) -> N { pub fn step_scalar<T: Number>(edge: T, x: T) -> T {
if edge > x { if edge > x {
N::zero() T::zero()
} else { } else {
N::one() T::one()
} }
} }
/// Returns 0.0 if `x[i] < edge`, otherwise it returns 1.0. /// Returns 0.0 if `x[i] < edge`, otherwise it returns 1.0.
pub fn step<N: Number, D: Dimension>(edge: N, x: &TVec<N, D>) -> TVec<N, D> pub fn step<T: Number, const D: usize>(edge: T, x: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.map(|x| step_scalar(edge, x)) x.map(|x| step_scalar(edge, x))
} }
/// Returns 0.0 if `x[i] < edge[i]`, otherwise it returns 1.0. /// Returns 0.0 if `x[i] < edge[i]`, otherwise it returns 1.0.
pub fn step_vec<N: Number, D: Dimension>(edge: &TVec<N, D>, x: &TVec<N, D>) -> TVec<N, D> pub fn step_vec<T: Number, const D: usize>(edge: &TVec<T, D>, x: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
edge.zip_map(x, step_scalar) edge.zip_map(x, step_scalar)
} }
@ -606,10 +549,7 @@ where
/// * [`floor`](fn.floor.html) /// * [`floor`](fn.floor.html)
/// * [`fract`](fn.fract.html) /// * [`fract`](fn.fract.html)
/// * [`round`](fn.round.html) /// * [`round`](fn.round.html)
pub fn trunc<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn trunc<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.map(|x| x.trunc()) x.map(|x| x.trunc())
} }
@ -643,9 +583,6 @@ pub fn uint_bits_to_float_scalar(v: u32) -> f32 {
/// * [`int_bits_to_float`](fn.int_bits_to_float.html) /// * [`int_bits_to_float`](fn.int_bits_to_float.html)
/// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html) /// * [`int_bits_to_float_vec`](fn.int_bits_to_float_vec.html)
/// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html) /// * [`uint_bits_to_float_scalar`](fn.uint_bits_to_float_scalar.html)
pub fn uint_bits_to_float<D: Dimension>(v: &TVec<u32, D>) -> TVec<f32, D> pub fn uint_bits_to_float<const D: usize>(v: &TVec<u32, D>) -> TVec<f32, D> {
where
DefaultAllocator: Alloc<f32, D>,
{
v.map(uint_bits_to_float_scalar) v.map(uint_bits_to_float_scalar)
} }

View File

@ -2,7 +2,7 @@ use crate::aliases::{
Qua, TMat, TMat2, TMat2x3, TMat2x4, TMat3, TMat3x2, TMat3x4, TMat4, TMat4x2, TMat4x3, TVec1, Qua, TMat, TMat2, TMat2x3, TMat2x4, TMat3, TMat3x2, TMat3x4, TMat4, TMat4x2, TMat4x3, TVec1,
TVec2, TVec3, TVec4, TVec2, TVec3, TVec4,
}; };
use na::{RealField, Scalar, U2, U3, U4}; use na::{RealField, Scalar};
/// Creates a new 1D vector. /// Creates a new 1D vector.
/// ///
@ -14,30 +14,30 @@ use na::{RealField, Scalar, U2, U3, U4};
/// # use nalgebra_glm as glm; /// # use nalgebra_glm as glm;
/// let v = glm::vec1(true); /// let v = glm::vec1(true);
/// ``` /// ```
pub fn vec1<N: Scalar>(x: N) -> TVec1<N> { pub fn vec1<T: Scalar>(x: T) -> TVec1<T> {
TVec1::new(x) TVec1::new(x)
} }
/// Creates a new 2D vector. /// Creates a new 2D vector.
pub fn vec2<N: Scalar>(x: N, y: N) -> TVec2<N> { pub fn vec2<T: Scalar>(x: T, y: T) -> TVec2<T> {
TVec2::new(x, y) TVec2::new(x, y)
} }
/// Creates a new 3D vector. /// Creates a new 3D vector.
pub fn vec3<N: Scalar>(x: N, y: N, z: N) -> TVec3<N> { pub fn vec3<T: Scalar>(x: T, y: T, z: T) -> TVec3<T> {
TVec3::new(x, y, z) TVec3::new(x, y, z)
} }
/// Creates a new 4D vector. /// Creates a new 4D vector.
pub fn vec4<N: Scalar>(x: N, y: N, z: N, w: N) -> TVec4<N> { pub fn vec4<T: Scalar>(x: T, y: T, z: T, w: T) -> TVec4<T> {
TVec4::new(x, y, z, w) TVec4::new(x, y, z, w)
} }
/// Create a new 2x2 matrix. /// Create a new 2x2 matrix.
#[rustfmt::skip] #[rustfmt::skip]
pub fn mat2<N: Scalar>(m11: N, m12: N, pub fn mat2<T: Scalar>(m11: T, m12: T,
m21: N, m22: N) -> TMat2<N> { m21: T, m22: T) -> TMat2<T> {
TMat::<N, U2, U2>::new( TMat::<T, 2, 2>::new(
m11, m12, m11, m12,
m21, m22, m21, m22,
) )
@ -45,9 +45,9 @@ pub fn mat2<N: Scalar>(m11: N, m12: N,
/// Create a new 2x2 matrix. /// Create a new 2x2 matrix.
#[rustfmt::skip] #[rustfmt::skip]
pub fn mat2x2<N: Scalar>(m11: N, m12: N, pub fn mat2x2<T: Scalar>(m11: T, m12: T,
m21: N, m22: N) -> TMat2<N> { m21: T, m22: T) -> TMat2<T> {
TMat::<N, U2, U2>::new( TMat::<T, 2, 2>::new(
m11, m12, m11, m12,
m21, m22, m21, m22,
) )
@ -55,9 +55,9 @@ pub fn mat2x2<N: Scalar>(m11: N, m12: N,
/// Create a new 2x3 matrix. /// Create a new 2x3 matrix.
#[rustfmt::skip] #[rustfmt::skip]
pub fn mat2x3<N: Scalar>(m11: N, m12: N, m13: N, pub fn mat2x3<T: Scalar>(m11: T, m12: T, m13: T,
m21: N, m22: N, m23: N) -> TMat2x3<N> { m21: T, m22: T, m23: T) -> TMat2x3<T> {
TMat::<N, U2, U3>::new( TMat::<T, 2, 3>::new(
m11, m12, m13, m11, m12, m13,
m21, m22, m23, m21, m22, m23,
) )
@ -65,9 +65,9 @@ pub fn mat2x3<N: Scalar>(m11: N, m12: N, m13: N,
/// Create a new 2x4 matrix. /// Create a new 2x4 matrix.
#[rustfmt::skip] #[rustfmt::skip]
pub fn mat2x4<N: Scalar>(m11: N, m12: N, m13: N, m14: N, pub fn mat2x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
m21: N, m22: N, m23: N, m24: N) -> TMat2x4<N> { m21: T, m22: T, m23: T, m24: T) -> TMat2x4<T> {
TMat::<N, U2, U4>::new( TMat::<T, 2, 4>::new(
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
) )
@ -75,10 +75,10 @@ pub fn mat2x4<N: Scalar>(m11: N, m12: N, m13: N, m14: N,
/// Create a new 3x3 matrix. /// Create a new 3x3 matrix.
#[rustfmt::skip] #[rustfmt::skip]
pub fn mat3<N: Scalar>(m11: N, m12: N, m13: N, pub fn mat3<T: Scalar>(m11: T, m12: T, m13: T,
m21: N, m22: N, m23: N, m21: T, m22: T, m23: T,
m31: N, m32: N, m33: N) -> TMat3<N> { m31: T, m32: T, m33: T) -> TMat3<T> {
TMat::<N, U3, U3>::new( TMat::<T, 3, 3>::new(
m11, m12, m13, m11, m12, m13,
m21, m22, m23, m21, m22, m23,
m31, m32, m33, m31, m32, m33,
@ -87,10 +87,10 @@ pub fn mat3<N: Scalar>(m11: N, m12: N, m13: N,
/// Create a new 3x2 matrix. /// Create a new 3x2 matrix.
#[rustfmt::skip] #[rustfmt::skip]
pub fn mat3x2<N: Scalar>(m11: N, m12: N, pub fn mat3x2<T: Scalar>(m11: T, m12: T,
m21: N, m22: N, m21: T, m22: T,
m31: N, m32: N) -> TMat3x2<N> { m31: T, m32: T) -> TMat3x2<T> {
TMat::<N, U3, U2>::new( TMat::<T, 3, 2>::new(
m11, m12, m11, m12,
m21, m22, m21, m22,
m31, m32, m31, m32,
@ -99,10 +99,10 @@ pub fn mat3x2<N: Scalar>(m11: N, m12: N,
/// Create a new 3x3 matrix. /// Create a new 3x3 matrix.
#[rustfmt::skip] #[rustfmt::skip]
pub fn mat3x3<N: Scalar>(m11: N, m12: N, m13: N, pub fn mat3x3<T: Scalar>(m11: T, m12: T, m13: T,
m21: N, m22: N, m23: N, m21: T, m22: T, m23: T,
m31: N, m32: N, m33: N) -> TMat3<N> { m31: T, m32: T, m33: T) -> TMat3<T> {
TMat::<N, U3, U3>::new( TMat::<T, 3, 3>::new(
m11, m12, m13, m11, m12, m13,
m31, m32, m33, m31, m32, m33,
m21, m22, m23, m21, m22, m23,
@ -111,10 +111,10 @@ pub fn mat3x3<N: Scalar>(m11: N, m12: N, m13: N,
/// Create a new 3x4 matrix. /// Create a new 3x4 matrix.
#[rustfmt::skip] #[rustfmt::skip]
pub fn mat3x4<N: Scalar>(m11: N, m12: N, m13: N, m14: N, pub fn mat3x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
m21: N, m22: N, m23: N, m24: N, m21: T, m22: T, m23: T, m24: T,
m31: N, m32: N, m33: N, m34: N) -> TMat3x4<N> { m31: T, m32: T, m33: T, m34: T) -> TMat3x4<T> {
TMat::<N, U3, U4>::new( TMat::<T, 3, 4>::new(
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
m31, m32, m33, m34, m31, m32, m33, m34,
@ -123,11 +123,11 @@ pub fn mat3x4<N: Scalar>(m11: N, m12: N, m13: N, m14: N,
/// Create a new 4x2 matrix. /// Create a new 4x2 matrix.
#[rustfmt::skip] #[rustfmt::skip]
pub fn mat4x2<N: Scalar>(m11: N, m12: N, pub fn mat4x2<T: Scalar>(m11: T, m12: T,
m21: N, m22: N, m21: T, m22: T,
m31: N, m32: N, m31: T, m32: T,
m41: N, m42: N) -> TMat4x2<N> { m41: T, m42: T) -> TMat4x2<T> {
TMat::<N, U4, U2>::new( TMat::<T, 4, 2>::new(
m11, m12, m11, m12,
m21, m22, m21, m22,
m31, m32, m31, m32,
@ -137,11 +137,11 @@ pub fn mat4x2<N: Scalar>(m11: N, m12: N,
/// Create a new 4x3 matrix. /// Create a new 4x3 matrix.
#[rustfmt::skip] #[rustfmt::skip]
pub fn mat4x3<N: Scalar>(m11: N, m12: N, m13: N, pub fn mat4x3<T: Scalar>(m11: T, m12: T, m13: T,
m21: N, m22: N, m23: N, m21: T, m22: T, m23: T,
m31: N, m32: N, m33: N, m31: T, m32: T, m33: T,
m41: N, m42: N, m43: N) -> TMat4x3<N> { m41: T, m42: T, m43: T) -> TMat4x3<T> {
TMat::<N, U4, U3>::new( TMat::<T, 4, 3>::new(
m11, m12, m13, m11, m12, m13,
m21, m22, m23, m21, m22, m23,
m31, m32, m33, m31, m32, m33,
@ -151,11 +151,11 @@ pub fn mat4x3<N: Scalar>(m11: N, m12: N, m13: N,
/// Create a new 4x4 matrix. /// Create a new 4x4 matrix.
#[rustfmt::skip] #[rustfmt::skip]
pub fn mat4x4<N: Scalar>(m11: N, m12: N, m13: N, m14: N, pub fn mat4x4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
m21: N, m22: N, m23: N, m24: N, m21: T, m22: T, m23: T, m24: T,
m31: N, m32: N, m33: N, m34: N, m31: T, m32: T, m33: T, m34: T,
m41: N, m42: N, m43: N, m44: N) -> TMat4<N> { m41: T, m42: T, m43: T, m44: T) -> TMat4<T> {
TMat::<N, U4, U4>::new( TMat::<T, 4, 4>::new(
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
m31, m32, m33, m34, m31, m32, m33, m34,
@ -165,11 +165,11 @@ pub fn mat4x4<N: Scalar>(m11: N, m12: N, m13: N, m14: N,
/// Create a new 4x4 matrix. /// Create a new 4x4 matrix.
#[rustfmt::skip] #[rustfmt::skip]
pub fn mat4<N: Scalar>(m11: N, m12: N, m13: N, m14: N, pub fn mat4<T: Scalar>(m11: T, m12: T, m13: T, m14: T,
m21: N, m22: N, m23: N, m24: N, m21: T, m22: T, m23: T, m24: T,
m31: N, m32: N, m33: N, m34: N, m31: T, m32: T, m33: T, m34: T,
m41: N, m42: N, m43: N, m44: N) -> TMat4<N> { m41: T, m42: T, m43: T, m44: T) -> TMat4<T> {
TMat::<N, U4, U4>::new( TMat::<T, 4, 4>::new(
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
m31, m32, m33, m34, m31, m32, m33, m34,
@ -178,6 +178,6 @@ pub fn mat4<N: Scalar>(m11: N, m12: N, m13: N, m14: N,
} }
/// Creates a new quaternion. /// Creates a new quaternion.
pub fn quat<N: RealField>(x: N, y: N, z: N, w: N) -> Qua<N> { pub fn quat<T: RealField>(x: T, y: T, z: T, w: T) -> Qua<T> {
Qua::new(w, x, y, z) Qua::new(w, x, y, z)
} }

View File

@ -1,16 +1,12 @@
use crate::aliases::TVec; use crate::aliases::TVec;
use crate::traits::{Alloc, Dimension}; use na::RealField;
use na::{DefaultAllocator, RealField};
/// Component-wise exponential. /// Component-wise exponential.
/// ///
/// # See also: /// # See also:
/// ///
/// * [`exp2`](fn.exp2.html) /// * [`exp2`](fn.exp2.html)
pub fn exp<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn exp<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
v.map(|x| x.exp()) v.map(|x| x.exp())
} }
@ -19,10 +15,7 @@ where
/// # See also: /// # See also:
/// ///
/// * [`exp`](fn.exp.html) /// * [`exp`](fn.exp.html)
pub fn exp2<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn exp2<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
v.map(|x| x.exp2()) v.map(|x| x.exp2())
} }
@ -31,11 +24,8 @@ where
/// # See also: /// # See also:
/// ///
/// * [`sqrt`](fn.sqrt.html) /// * [`sqrt`](fn.sqrt.html)
pub fn inversesqrt<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn inversesqrt<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
where v.map(|x| T::one() / x.sqrt())
DefaultAllocator: Alloc<N, D>,
{
v.map(|x| N::one() / x.sqrt())
} }
/// Component-wise logarithm. /// Component-wise logarithm.
@ -43,10 +33,7 @@ where
/// # See also: /// # See also:
/// ///
/// * [`log2`](fn.log2.html) /// * [`log2`](fn.log2.html)
pub fn log<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn log<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
v.map(|x| x.ln()) v.map(|x| x.ln())
} }
@ -55,18 +42,12 @@ where
/// # See also: /// # See also:
/// ///
/// * [`log`](fn.log.html) /// * [`log`](fn.log.html)
pub fn log2<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn log2<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
v.map(|x| x.log2()) v.map(|x| x.log2())
} }
/// Component-wise power. /// Component-wise power.
pub fn pow<N: RealField, D: Dimension>(base: &TVec<N, D>, exponent: &TVec<N, D>) -> TVec<N, D> pub fn pow<T: RealField, const D: usize>(base: &TVec<T, D>, exponent: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
base.zip_map(exponent, |b, e| b.powf(e)) base.zip_map(exponent, |b, e| b.powf(e))
} }
@ -78,9 +59,6 @@ where
/// * [`exp2`](fn.exp2.html) /// * [`exp2`](fn.exp2.html)
/// * [`inversesqrt`](fn.inversesqrt.html) /// * [`inversesqrt`](fn.inversesqrt.html)
/// * [`pow`](fn.pow.html) /// * [`pow`](fn.pow.html)
pub fn sqrt<N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn sqrt<T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
v.map(|x| x.sqrt()) v.map(|x| x.sqrt())
} }

View File

@ -1,51 +1,51 @@
use crate::aliases::TMat4; use crate::aliases::TMat4;
use na::RealField; use na::RealField;
//pub fn frustum<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> { //pub fn frustum<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
// unimplemented!() // unimplemented!()
//} //}
//pub fn frustum_lh<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> { //pub fn frustum_lh<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
// unimplemented!() // unimplemented!()
//} //}
// //
//pub fn frustum_lr_no<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> { //pub fn frustum_lr_no<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
// unimplemented!() // unimplemented!()
//} //}
// //
//pub fn frustum_lh_zo<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> { //pub fn frustum_lh_zo<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
// unimplemented!() // unimplemented!()
//} //}
// //
//pub fn frustum_no<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> { //pub fn frustum_no<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
// unimplemented!() // unimplemented!()
//} //}
// //
//pub fn frustum_rh<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> { //pub fn frustum_rh<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
// unimplemented!() // unimplemented!()
//} //}
// //
//pub fn frustum_rh_no<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> { //pub fn frustum_rh_no<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
// unimplemented!() // unimplemented!()
//} //}
// //
//pub fn frustum_rh_zo<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> { //pub fn frustum_rh_zo<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
// unimplemented!() // unimplemented!()
//} //}
// //
//pub fn frustum_zo<N: RealField>(left: N, right: N, bottom: N, top: N, near: N, far: N) -> TMat4<N> { //pub fn frustum_zo<T: RealField>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> TMat4<T> {
// unimplemented!() // unimplemented!()
//} //}
//pub fn infinite_perspective<N: RealField>(fovy: N, aspect: N, near: N) -> TMat4<N> { //pub fn infinite_perspective<T: RealField>(fovy: T, aspect: T, near: T) -> TMat4<T> {
// unimplemented!() // unimplemented!()
//} //}
// //
//pub fn infinite_perspective_lh<N: RealField>(fovy: N, aspect: N, near: N) -> TMat4<N> { //pub fn infinite_perspective_lh<T: RealField>(fovy: T, aspect: T, near: T) -> TMat4<T> {
// unimplemented!() // unimplemented!()
//} //}
// //
//pub fn infinite_ortho<N: RealField>(left: N, right: N, bottom: N, top: N) -> TMat4<N> { //pub fn infinite_ortho<T: RealField>(left: T, right: T, bottom: T, top: T) -> TMat4<T> {
// unimplemented!() // unimplemented!()
//} //}
@ -60,7 +60,7 @@ use na::RealField;
/// * `znear` - Distance from the viewer to the near clipping plane /// * `znear` - Distance from the viewer to the near clipping plane
/// * `zfar` - Distance from the viewer to the far clipping plane /// * `zfar` - Distance from the viewer to the far clipping plane
/// ///
pub fn ortho<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> { pub fn ortho<T: RealField>(left: T, right: T, bottom: T, top: T, znear: T, zfar: T) -> TMat4<T> {
ortho_rh_no(left, right, bottom, top, znear, zfar) ortho_rh_no(left, right, bottom, top, znear, zfar)
} }
@ -75,7 +75,7 @@ pub fn ortho<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar:
/// * `znear` - Distance from the viewer to the near clipping plane /// * `znear` - Distance from the viewer to the near clipping plane
/// * `zfar` - Distance from the viewer to the far clipping plane /// * `zfar` - Distance from the viewer to the far clipping plane
/// ///
pub fn ortho_lh<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> { pub fn ortho_lh<T: RealField>(left: T, right: T, bottom: T, top: T, znear: T, zfar: T) -> TMat4<T> {
ortho_lh_no(left, right, bottom, top, znear, zfar) ortho_lh_no(left, right, bottom, top, znear, zfar)
} }
@ -90,16 +90,16 @@ pub fn ortho_lh<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zf
/// * `znear` - Distance from the viewer to the near clipping plane /// * `znear` - Distance from the viewer to the near clipping plane
/// * `zfar` - Distance from the viewer to the far clipping plane /// * `zfar` - Distance from the viewer to the far clipping plane
/// ///
pub fn ortho_lh_no<N: RealField>( pub fn ortho_lh_no<T: RealField>(
left: N, left: T,
right: N, right: T,
bottom: N, bottom: T,
top: N, top: T,
znear: N, znear: T,
zfar: N, zfar: T,
) -> TMat4<N> { ) -> TMat4<T> {
let two: N = crate::convert(2.0); let two: T = crate::convert(2.0);
let mut mat: TMat4<N> = TMat4::<N>::identity(); let mut mat: TMat4<T> = TMat4::<T>::identity();
mat[(0, 0)] = two / (right - left); mat[(0, 0)] = two / (right - left);
mat[(0, 3)] = -(right + left) / (right - left); mat[(0, 3)] = -(right + left) / (right - left);
@ -122,17 +122,17 @@ pub fn ortho_lh_no<N: RealField>(
/// * `znear` - Distance from the viewer to the near clipping plane /// * `znear` - Distance from the viewer to the near clipping plane
/// * `zfar` - Distance from the viewer to the far clipping plane /// * `zfar` - Distance from the viewer to the far clipping plane
/// ///
pub fn ortho_lh_zo<N: RealField>( pub fn ortho_lh_zo<T: RealField>(
left: N, left: T,
right: N, right: T,
bottom: N, bottom: T,
top: N, top: T,
znear: N, znear: T,
zfar: N, zfar: T,
) -> TMat4<N> { ) -> TMat4<T> {
let one: N = N::one(); let one: T = T::one();
let two: N = crate::convert(2.0); let two: T = crate::convert(2.0);
let mut mat: TMat4<N> = TMat4::<N>::identity(); let mut mat: TMat4<T> = TMat4::<T>::identity();
mat[(0, 0)] = two / (right - left); mat[(0, 0)] = two / (right - left);
mat[(0, 3)] = -(right + left) / (right - left); mat[(0, 3)] = -(right + left) / (right - left);
@ -155,7 +155,7 @@ pub fn ortho_lh_zo<N: RealField>(
/// * `znear` - Distance from the viewer to the near clipping plane /// * `znear` - Distance from the viewer to the near clipping plane
/// * `zfar` - Distance from the viewer to the far clipping plane /// * `zfar` - Distance from the viewer to the far clipping plane
/// ///
pub fn ortho_no<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> { pub fn ortho_no<T: RealField>(left: T, right: T, bottom: T, top: T, znear: T, zfar: T) -> TMat4<T> {
ortho_rh_no(left, right, bottom, top, znear, zfar) ortho_rh_no(left, right, bottom, top, znear, zfar)
} }
@ -170,7 +170,7 @@ pub fn ortho_no<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zf
/// * `znear` - Distance from the viewer to the near clipping plane /// * `znear` - Distance from the viewer to the near clipping plane
/// * `zfar` - Distance from the viewer to the far clipping plane /// * `zfar` - Distance from the viewer to the far clipping plane
/// ///
pub fn ortho_rh<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> { pub fn ortho_rh<T: RealField>(left: T, right: T, bottom: T, top: T, znear: T, zfar: T) -> TMat4<T> {
ortho_rh_no(left, right, bottom, top, znear, zfar) ortho_rh_no(left, right, bottom, top, znear, zfar)
} }
@ -185,16 +185,16 @@ pub fn ortho_rh<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zf
/// * `znear` - Distance from the viewer to the near clipping plane /// * `znear` - Distance from the viewer to the near clipping plane
/// * `zfar` - Distance from the viewer to the far clipping plane /// * `zfar` - Distance from the viewer to the far clipping plane
/// ///
pub fn ortho_rh_no<N: RealField>( pub fn ortho_rh_no<T: RealField>(
left: N, left: T,
right: N, right: T,
bottom: N, bottom: T,
top: N, top: T,
znear: N, znear: T,
zfar: N, zfar: T,
) -> TMat4<N> { ) -> TMat4<T> {
let two: N = crate::convert(2.0); let two: T = crate::convert(2.0);
let mut mat: TMat4<N> = TMat4::<N>::identity(); let mut mat: TMat4<T> = TMat4::<T>::identity();
mat[(0, 0)] = two / (right - left); mat[(0, 0)] = two / (right - left);
mat[(0, 3)] = -(right + left) / (right - left); mat[(0, 3)] = -(right + left) / (right - left);
@ -217,17 +217,17 @@ pub fn ortho_rh_no<N: RealField>(
/// * `znear` - Distance from the viewer to the near clipping plane /// * `znear` - Distance from the viewer to the near clipping plane
/// * `zfar` - Distance from the viewer to the far clipping plane /// * `zfar` - Distance from the viewer to the far clipping plane
/// ///
pub fn ortho_rh_zo<N: RealField>( pub fn ortho_rh_zo<T: RealField>(
left: N, left: T,
right: N, right: T,
bottom: N, bottom: T,
top: N, top: T,
znear: N, znear: T,
zfar: N, zfar: T,
) -> TMat4<N> { ) -> TMat4<T> {
let one: N = N::one(); let one: T = T::one();
let two: N = crate::convert(2.0); let two: T = crate::convert(2.0);
let mut mat: TMat4<N> = TMat4::<N>::identity(); let mut mat: TMat4<T> = TMat4::<T>::identity();
mat[(0, 0)] = two / (right - left); mat[(0, 0)] = two / (right - left);
mat[(0, 3)] = -(right + left) / (right - left); mat[(0, 3)] = -(right + left) / (right - left);
@ -250,7 +250,7 @@ pub fn ortho_rh_zo<N: RealField>(
/// * `znear` - Distance from the viewer to the near clipping plane /// * `znear` - Distance from the viewer to the near clipping plane
/// * `zfar` - Distance from the viewer to the far clipping plane /// * `zfar` - Distance from the viewer to the far clipping plane
/// ///
pub fn ortho_zo<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> TMat4<N> { pub fn ortho_zo<T: RealField>(left: T, right: T, bottom: T, top: T, znear: T, zfar: T) -> TMat4<T> {
ortho_rh_zo(left, right, bottom, top, znear, zfar) ortho_rh_zo(left, right, bottom, top, znear, zfar)
} }
@ -264,7 +264,7 @@ pub fn ortho_zo<N: RealField>(left: N, right: N, bottom: N, top: N, znear: N, zf
/// * `near` - Distance from the viewer to the near clipping plane /// * `near` - Distance from the viewer to the near clipping plane
/// * `far` - Distance from the viewer to the far clipping plane /// * `far` - Distance from the viewer to the far clipping plane
/// ///
pub fn perspective_fov<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> { pub fn perspective_fov<T: RealField>(fov: T, width: T, height: T, near: T, far: T) -> TMat4<T> {
perspective_fov_rh_no(fov, width, height, near, far) perspective_fov_rh_no(fov, width, height, near, far)
} }
@ -278,7 +278,7 @@ pub fn perspective_fov<N: RealField>(fov: N, width: N, height: N, near: N, far:
/// * `near` - Distance from the viewer to the near clipping plane /// * `near` - Distance from the viewer to the near clipping plane
/// * `far` - Distance from the viewer to the far clipping plane /// * `far` - Distance from the viewer to the far clipping plane
/// ///
pub fn perspective_fov_lh<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> { pub fn perspective_fov_lh<T: RealField>(fov: T, width: T, height: T, near: T, far: T) -> TMat4<T> {
perspective_fov_lh_no(fov, width, height, near, far) perspective_fov_lh_no(fov, width, height, near, far)
} }
@ -292,16 +292,16 @@ pub fn perspective_fov_lh<N: RealField>(fov: N, width: N, height: N, near: N, fa
/// * `near` - Distance from the viewer to the near clipping plane /// * `near` - Distance from the viewer to the near clipping plane
/// * `far` - Distance from the viewer to the far clipping plane /// * `far` - Distance from the viewer to the far clipping plane
/// ///
pub fn perspective_fov_lh_no<N: RealField>( pub fn perspective_fov_lh_no<T: RealField>(
fov: N, fov: T,
width: N, width: T,
height: N, height: T,
near: N, near: T,
far: N, far: T,
) -> TMat4<N> { ) -> TMat4<T> {
assert!(width > N::zero(), "The width must be greater than zero"); assert!(width > T::zero(), "The width must be greater than zero");
assert!(height > N::zero(), "The height must be greater than zero."); assert!(height > T::zero(), "The height must be greater than zero.");
assert!(fov > N::zero(), "The fov must be greater than zero"); assert!(fov > T::zero(), "The fov must be greater than zero");
let mut mat = TMat4::zeros(); let mut mat = TMat4::zeros();
@ -313,7 +313,7 @@ pub fn perspective_fov_lh_no<N: RealField>(
mat[(1, 1)] = h; mat[(1, 1)] = h;
mat[(2, 2)] = (far + near) / (far - near); mat[(2, 2)] = (far + near) / (far - near);
mat[(2, 3)] = -(far * near * crate::convert(2.0)) / (far - near); mat[(2, 3)] = -(far * near * crate::convert(2.0)) / (far - near);
mat[(3, 2)] = N::one(); mat[(3, 2)] = T::one();
mat mat
} }
@ -328,16 +328,16 @@ pub fn perspective_fov_lh_no<N: RealField>(
/// * `near` - Distance from the viewer to the near clipping plane /// * `near` - Distance from the viewer to the near clipping plane
/// * `far` - Distance from the viewer to the far clipping plane /// * `far` - Distance from the viewer to the far clipping plane
/// ///
pub fn perspective_fov_lh_zo<N: RealField>( pub fn perspective_fov_lh_zo<T: RealField>(
fov: N, fov: T,
width: N, width: T,
height: N, height: T,
near: N, near: T,
far: N, far: T,
) -> TMat4<N> { ) -> TMat4<T> {
assert!(width > N::zero(), "The width must be greater than zero"); assert!(width > T::zero(), "The width must be greater than zero");
assert!(height > N::zero(), "The height must be greater than zero."); assert!(height > T::zero(), "The height must be greater than zero.");
assert!(fov > N::zero(), "The fov must be greater than zero"); assert!(fov > T::zero(), "The fov must be greater than zero");
let mut mat = TMat4::zeros(); let mut mat = TMat4::zeros();
@ -349,7 +349,7 @@ pub fn perspective_fov_lh_zo<N: RealField>(
mat[(1, 1)] = h; mat[(1, 1)] = h;
mat[(2, 2)] = far / (far - near); mat[(2, 2)] = far / (far - near);
mat[(2, 3)] = -(far * near) / (far - near); mat[(2, 3)] = -(far * near) / (far - near);
mat[(3, 2)] = N::one(); mat[(3, 2)] = T::one();
mat mat
} }
@ -364,7 +364,7 @@ pub fn perspective_fov_lh_zo<N: RealField>(
/// * `near` - Distance from the viewer to the near clipping plane /// * `near` - Distance from the viewer to the near clipping plane
/// * `far` - Distance from the viewer to the far clipping plane /// * `far` - Distance from the viewer to the far clipping plane
/// ///
pub fn perspective_fov_no<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> { pub fn perspective_fov_no<T: RealField>(fov: T, width: T, height: T, near: T, far: T) -> TMat4<T> {
perspective_fov_rh_no(fov, width, height, near, far) perspective_fov_rh_no(fov, width, height, near, far)
} }
@ -378,7 +378,7 @@ pub fn perspective_fov_no<N: RealField>(fov: N, width: N, height: N, near: N, fa
/// * `near` - Distance from the viewer to the near clipping plane /// * `near` - Distance from the viewer to the near clipping plane
/// * `far` - Distance from the viewer to the far clipping plane /// * `far` - Distance from the viewer to the far clipping plane
/// ///
pub fn perspective_fov_rh<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> { pub fn perspective_fov_rh<T: RealField>(fov: T, width: T, height: T, near: T, far: T) -> TMat4<T> {
perspective_fov_rh_no(fov, width, height, near, far) perspective_fov_rh_no(fov, width, height, near, far)
} }
@ -392,16 +392,16 @@ pub fn perspective_fov_rh<N: RealField>(fov: N, width: N, height: N, near: N, fa
/// * `near` - Distance from the viewer to the near clipping plane /// * `near` - Distance from the viewer to the near clipping plane
/// * `far` - Distance from the viewer to the far clipping plane /// * `far` - Distance from the viewer to the far clipping plane
/// ///
pub fn perspective_fov_rh_no<N: RealField>( pub fn perspective_fov_rh_no<T: RealField>(
fov: N, fov: T,
width: N, width: T,
height: N, height: T,
near: N, near: T,
far: N, far: T,
) -> TMat4<N> { ) -> TMat4<T> {
assert!(width > N::zero(), "The width must be greater than zero"); assert!(width > T::zero(), "The width must be greater than zero");
assert!(height > N::zero(), "The height must be greater than zero."); assert!(height > T::zero(), "The height must be greater than zero.");
assert!(fov > N::zero(), "The fov must be greater than zero"); assert!(fov > T::zero(), "The fov must be greater than zero");
let mut mat = TMat4::zeros(); let mut mat = TMat4::zeros();
@ -413,7 +413,7 @@ pub fn perspective_fov_rh_no<N: RealField>(
mat[(1, 1)] = h; mat[(1, 1)] = h;
mat[(2, 2)] = -(far + near) / (far - near); mat[(2, 2)] = -(far + near) / (far - near);
mat[(2, 3)] = -(far * near * crate::convert(2.0)) / (far - near); mat[(2, 3)] = -(far * near * crate::convert(2.0)) / (far - near);
mat[(3, 2)] = -N::one(); mat[(3, 2)] = -T::one();
mat mat
} }
@ -428,16 +428,16 @@ pub fn perspective_fov_rh_no<N: RealField>(
/// * `near` - Distance from the viewer to the near clipping plane /// * `near` - Distance from the viewer to the near clipping plane
/// * `far` - Distance from the viewer to the far clipping plane /// * `far` - Distance from the viewer to the far clipping plane
/// ///
pub fn perspective_fov_rh_zo<N: RealField>( pub fn perspective_fov_rh_zo<T: RealField>(
fov: N, fov: T,
width: N, width: T,
height: N, height: T,
near: N, near: T,
far: N, far: T,
) -> TMat4<N> { ) -> TMat4<T> {
assert!(width > N::zero(), "The width must be greater than zero"); assert!(width > T::zero(), "The width must be greater than zero");
assert!(height > N::zero(), "The height must be greater than zero."); assert!(height > T::zero(), "The height must be greater than zero.");
assert!(fov > N::zero(), "The fov must be greater than zero"); assert!(fov > T::zero(), "The fov must be greater than zero");
let mut mat = TMat4::zeros(); let mut mat = TMat4::zeros();
@ -449,7 +449,7 @@ pub fn perspective_fov_rh_zo<N: RealField>(
mat[(1, 1)] = h; mat[(1, 1)] = h;
mat[(2, 2)] = far / (near - far); mat[(2, 2)] = far / (near - far);
mat[(2, 3)] = -(far * near) / (far - near); mat[(2, 3)] = -(far * near) / (far - near);
mat[(3, 2)] = -N::one(); mat[(3, 2)] = -T::one();
mat mat
} }
@ -464,7 +464,7 @@ pub fn perspective_fov_rh_zo<N: RealField>(
/// * `near` - Distance from the viewer to the near clipping plane /// * `near` - Distance from the viewer to the near clipping plane
/// * `far` - Distance from the viewer to the far clipping plane /// * `far` - Distance from the viewer to the far clipping plane
/// ///
pub fn perspective_fov_zo<N: RealField>(fov: N, width: N, height: N, near: N, far: N) -> TMat4<N> { pub fn perspective_fov_zo<T: RealField>(fov: T, width: T, height: T, near: T, far: T) -> TMat4<T> {
perspective_fov_rh_zo(fov, width, height, near, far) perspective_fov_rh_zo(fov, width, height, near, far)
} }
@ -479,7 +479,7 @@ pub fn perspective_fov_zo<N: RealField>(fov: N, width: N, height: N, near: N, fa
/// ///
/// # Important note /// # Important note
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API. /// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
pub fn perspective<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> { pub fn perspective<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
// TODO: Breaking change - revert back to proper glm conventions? // TODO: Breaking change - revert back to proper glm conventions?
// //
// Prior to changes to support configuring the behaviour of this function it was simply // Prior to changes to support configuring the behaviour of this function it was simply
@ -508,7 +508,7 @@ pub fn perspective<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N
/// ///
/// # Important note /// # Important note
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API. /// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
pub fn perspective_lh<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> { pub fn perspective_lh<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
perspective_lh_no(aspect, fovy, near, far) perspective_lh_no(aspect, fovy, near, far)
} }
@ -523,19 +523,19 @@ pub fn perspective_lh<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat
/// ///
/// # Important note /// # Important note
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API. /// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
pub fn perspective_lh_no<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> { pub fn perspective_lh_no<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
assert!( assert!(
!relative_eq!(far - near, N::zero()), !relative_eq!(far - near, T::zero()),
"The near-plane and far-plane must not be superimposed." "The near-plane and far-plane must not be superimposed."
); );
assert!( assert!(
!relative_eq!(aspect, N::zero()), !relative_eq!(aspect, T::zero()),
"The aspect ratio must not be zero." "The aspect ratio must not be zero."
); );
let one = N::one(); let one = T::one();
let two: N = crate::convert(2.0); let two: T = crate::convert(2.0);
let mut mat: TMat4<N> = TMat4::zeros(); let mut mat: TMat4<T> = TMat4::zeros();
let tan_half_fovy = (fovy / two).tan(); let tan_half_fovy = (fovy / two).tan();
@ -559,19 +559,19 @@ pub fn perspective_lh_no<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> T
/// ///
/// # Important note /// # Important note
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API. /// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
pub fn perspective_lh_zo<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> { pub fn perspective_lh_zo<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
assert!( assert!(
!relative_eq!(far - near, N::zero()), !relative_eq!(far - near, T::zero()),
"The near-plane and far-plane must not be superimposed." "The near-plane and far-plane must not be superimposed."
); );
assert!( assert!(
!relative_eq!(aspect, N::zero()), !relative_eq!(aspect, T::zero()),
"The aspect ratio must not be zero." "The aspect ratio must not be zero."
); );
let one = N::one(); let one = T::one();
let two: N = crate::convert(2.0); let two: T = crate::convert(2.0);
let mut mat: TMat4<N> = TMat4::zeros(); let mut mat: TMat4<T> = TMat4::zeros();
let tan_half_fovy = (fovy / two).tan(); let tan_half_fovy = (fovy / two).tan();
@ -595,7 +595,7 @@ pub fn perspective_lh_zo<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> T
/// ///
/// # Important note /// # Important note
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API. /// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
pub fn perspective_no<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> { pub fn perspective_no<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
perspective_rh_no(aspect, fovy, near, far) perspective_rh_no(aspect, fovy, near, far)
} }
@ -610,7 +610,7 @@ pub fn perspective_no<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat
/// ///
/// # Important note /// # Important note
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API. /// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
pub fn perspective_rh<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> { pub fn perspective_rh<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
perspective_rh_no(aspect, fovy, near, far) perspective_rh_no(aspect, fovy, near, far)
} }
@ -625,19 +625,19 @@ pub fn perspective_rh<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat
/// ///
/// # Important note /// # Important note
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API. /// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
pub fn perspective_rh_no<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> { pub fn perspective_rh_no<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
assert!( assert!(
!relative_eq!(far - near, N::zero()), !relative_eq!(far - near, T::zero()),
"The near-plane and far-plane must not be superimposed." "The near-plane and far-plane must not be superimposed."
); );
assert!( assert!(
!relative_eq!(aspect, N::zero()), !relative_eq!(aspect, T::zero()),
"The aspect ratio must not be zero." "The aspect ratio must not be zero."
); );
let negone = -N::one(); let negone = -T::one();
let one = N::one(); let one = T::one();
let two: N = crate::convert(2.0); let two: T = crate::convert(2.0);
let mut mat = TMat4::zeros(); let mut mat = TMat4::zeros();
let tan_half_fovy = (fovy / two).tan(); let tan_half_fovy = (fovy / two).tan();
@ -662,18 +662,18 @@ pub fn perspective_rh_no<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> T
/// ///
/// # Important note /// # Important note
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API. /// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
pub fn perspective_rh_zo<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> { pub fn perspective_rh_zo<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
assert!( assert!(
!relative_eq!(far - near, N::zero()), !relative_eq!(far - near, T::zero()),
"The near-plane and far-plane must not be superimposed." "The near-plane and far-plane must not be superimposed."
); );
assert!( assert!(
!relative_eq!(aspect, N::zero()), !relative_eq!(aspect, T::zero()),
"The aspect ratio must not be zero." "The aspect ratio must not be zero."
); );
let negone = -N::one(); let negone = -T::one();
let one = N::one(); let one = T::one();
let two = crate::convert(2.0); let two = crate::convert(2.0);
let mut mat = TMat4::zeros(); let mut mat = TMat4::zeros();
@ -699,7 +699,7 @@ pub fn perspective_rh_zo<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> T
/// ///
/// # Important note /// # Important note
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API. /// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
pub fn perspective_zo<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> { pub fn perspective_zo<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
perspective_rh_zo(aspect, fovy, near, far) perspective_rh_zo(aspect, fovy, near, far)
} }
@ -713,15 +713,15 @@ pub fn perspective_zo<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat
/// ///
/// # Important note /// # Important note
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API. /// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
pub fn infinite_perspective_rh_no<N: RealField>(aspect: N, fovy: N, near: N) -> TMat4<N> { pub fn infinite_perspective_rh_no<T: RealField>(aspect: T, fovy: T, near: T) -> TMat4<T> {
let f = N::one() / (fovy * na::convert(0.5)).tan(); let f = T::one() / (fovy * na::convert(0.5)).tan();
let mut mat = TMat4::zeros(); let mut mat = TMat4::zeros();
mat[(0, 0)] = f / aspect; mat[(0, 0)] = f / aspect;
mat[(1, 1)] = f; mat[(1, 1)] = f;
mat[(2, 2)] = -N::one(); mat[(2, 2)] = -T::one();
mat[(2, 3)] = -near * na::convert(2.0); mat[(2, 3)] = -near * na::convert(2.0);
mat[(3, 2)] = -N::one(); mat[(3, 2)] = -T::one();
mat mat
} }
@ -738,15 +738,15 @@ pub fn infinite_perspective_rh_no<N: RealField>(aspect: N, fovy: N, near: N) ->
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API. /// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
/// ///
// https://discourse.nphysics.org/t/reversed-z-and-infinite-zfar-in-projections/341/2 // https://discourse.nphysics.org/t/reversed-z-and-infinite-zfar-in-projections/341/2
pub fn infinite_perspective_rh_zo<N: RealField>(aspect: N, fovy: N, near: N) -> TMat4<N> { pub fn infinite_perspective_rh_zo<T: RealField>(aspect: T, fovy: T, near: T) -> TMat4<T> {
let f = N::one() / (fovy * na::convert(0.5)).tan(); let f = T::one() / (fovy * na::convert(0.5)).tan();
let mut mat = TMat4::zeros(); let mut mat = TMat4::zeros();
mat[(0, 0)] = f / aspect; mat[(0, 0)] = f / aspect;
mat[(1, 1)] = f; mat[(1, 1)] = f;
mat[(2, 2)] = -N::one(); mat[(2, 2)] = -T::one();
mat[(2, 3)] = -near; mat[(2, 3)] = -near;
mat[(3, 2)] = -N::one(); mat[(3, 2)] = -T::one();
mat mat
} }
@ -763,8 +763,8 @@ pub fn infinite_perspective_rh_zo<N: RealField>(aspect: N, fovy: N, near: N) ->
/// # Important note /// # Important note
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API. /// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
// NOTE: The variants `_no` of reversed perspective are not useful. // NOTE: The variants `_no` of reversed perspective are not useful.
pub fn reversed_perspective_rh_zo<N: RealField>(aspect: N, fovy: N, near: N, far: N) -> TMat4<N> { pub fn reversed_perspective_rh_zo<T: RealField>(aspect: T, fovy: T, near: T, far: T) -> TMat4<T> {
let one = N::one(); let one = T::one();
let two = crate::convert(2.0); let two = crate::convert(2.0);
let mut mat = TMat4::zeros(); let mut mat = TMat4::zeros();
@ -791,22 +791,22 @@ pub fn reversed_perspective_rh_zo<N: RealField>(aspect: N, fovy: N, near: N, far
/// The `aspect` and `fovy` argument are interchanged compared to the original GLM API. /// The `aspect` and `fovy` argument are interchanged compared to the original GLM API.
// Credit: https://discourse.nphysics.org/t/reversed-z-and-infinite-zfar-in-projections/341/2 // Credit: https://discourse.nphysics.org/t/reversed-z-and-infinite-zfar-in-projections/341/2
// NOTE: The variants `_no` of reversed perspective are not useful. // NOTE: The variants `_no` of reversed perspective are not useful.
pub fn reversed_infinite_perspective_rh_zo<N: RealField>(aspect: N, fovy: N, near: N) -> TMat4<N> { pub fn reversed_infinite_perspective_rh_zo<T: RealField>(aspect: T, fovy: T, near: T) -> TMat4<T> {
let f = N::one() / (fovy * na::convert(0.5)).tan(); let f = T::one() / (fovy * na::convert(0.5)).tan();
let mut mat = TMat4::zeros(); let mut mat = TMat4::zeros();
mat[(0, 0)] = f / aspect; mat[(0, 0)] = f / aspect;
mat[(1, 1)] = f; mat[(1, 1)] = f;
mat[(2, 3)] = near; mat[(2, 3)] = near;
mat[(3, 2)] = -N::one(); mat[(3, 2)] = -T::one();
mat mat
} }
//pub fn tweaked_infinite_perspective<N: RealField>(fovy: N, aspect: N, near: N) -> TMat4<N> { //pub fn tweaked_infinite_perspective<T: RealField>(fovy: T, aspect: T, near: T) -> TMat4<T> {
// unimplemented!() // unimplemented!()
//} //}
// //
//pub fn tweaked_infinite_perspective_ep<N: RealField>(fovy: N, aspect: N, near: N, ep: N) -> TMat4<N> { //pub fn tweaked_infinite_perspective_ep<T: RealField>(fovy: T, aspect: T, near: T, ep: T) -> TMat4<T> {
// unimplemented!() // unimplemented!()
//} //}

View File

@ -1,4 +1,4 @@
use na::{self, RealField, U3}; use na::{self, RealField};
use crate::aliases::{TMat4, TVec2, TVec3, TVec4}; use crate::aliases::{TMat4, TVec2, TVec3, TVec4};
@ -9,22 +9,22 @@ use crate::aliases::{TMat4, TVec2, TVec3, TVec4};
/// * `center` - Specify the center of a picking region in window coordinates. /// * `center` - Specify the center of a picking region in window coordinates.
/// * `delta` - Specify the width and height, respectively, of the picking region in window coordinates. /// * `delta` - Specify the width and height, respectively, of the picking region in window coordinates.
/// * `viewport` - Rendering viewport. /// * `viewport` - Rendering viewport.
pub fn pick_matrix<N: RealField>( pub fn pick_matrix<T: RealField>(
center: &TVec2<N>, center: &TVec2<T>,
delta: &TVec2<N>, delta: &TVec2<T>,
viewport: &TVec4<N>, viewport: &TVec4<T>,
) -> TMat4<N> { ) -> TMat4<T> {
let shift = TVec3::new( let shift = TVec3::new(
(viewport.z - (center.x - viewport.x) * na::convert(2.0)) / delta.x, (viewport.z - (center.x - viewport.x) * na::convert(2.0)) / delta.x,
(viewport.w - (center.y - viewport.y) * na::convert(2.0)) / delta.y, (viewport.w - (center.y - viewport.y) * na::convert(2.0)) / delta.y,
N::zero(), T::zero(),
); );
let result = TMat4::new_translation(&shift); let result = TMat4::new_translation(&shift);
result.prepend_nonuniform_scaling(&TVec3::new( result.prepend_nonuniform_scaling(&TVec3::new(
viewport.z / delta.x, viewport.z / delta.x,
viewport.w / delta.y, viewport.w / delta.y,
N::one(), T::one(),
)) ))
} }
@ -45,12 +45,12 @@ pub fn pick_matrix<N: RealField>(
/// * [`unproject`](fn.unproject.html) /// * [`unproject`](fn.unproject.html)
/// * [`unproject_no`](fn.unproject_no.html) /// * [`unproject_no`](fn.unproject_no.html)
/// * [`unproject_zo`](fn.unproject_zo.html) /// * [`unproject_zo`](fn.unproject_zo.html)
pub fn project<N: RealField>( pub fn project<T: RealField>(
obj: &TVec3<N>, obj: &TVec3<T>,
model: &TMat4<N>, model: &TMat4<T>,
proj: &TMat4<N>, proj: &TMat4<T>,
viewport: TVec4<N>, viewport: TVec4<T>,
) -> TVec3<N> { ) -> TVec3<T> {
project_no(obj, model, proj, viewport) project_no(obj, model, proj, viewport)
} }
@ -72,12 +72,12 @@ pub fn project<N: RealField>(
/// * [`unproject`](fn.unproject.html) /// * [`unproject`](fn.unproject.html)
/// * [`unproject_no`](fn.unproject_no.html) /// * [`unproject_no`](fn.unproject_no.html)
/// * [`unproject_zo`](fn.unproject_zo.html) /// * [`unproject_zo`](fn.unproject_zo.html)
pub fn project_no<N: RealField>( pub fn project_no<T: RealField>(
obj: &TVec3<N>, obj: &TVec3<T>,
model: &TMat4<N>, model: &TMat4<T>,
proj: &TMat4<N>, proj: &TMat4<T>,
viewport: TVec4<N>, viewport: TVec4<T>,
) -> TVec3<N> { ) -> TVec3<T> {
let proj = project_zo(obj, model, proj, viewport); let proj = project_zo(obj, model, proj, viewport);
TVec3::new(proj.x, proj.y, proj.z * na::convert(0.5) + na::convert(0.5)) TVec3::new(proj.x, proj.y, proj.z * na::convert(0.5) + na::convert(0.5))
} }
@ -100,18 +100,18 @@ pub fn project_no<N: RealField>(
/// * [`unproject`](fn.unproject.html) /// * [`unproject`](fn.unproject.html)
/// * [`unproject_no`](fn.unproject_no.html) /// * [`unproject_no`](fn.unproject_no.html)
/// * [`unproject_zo`](fn.unproject_zo.html) /// * [`unproject_zo`](fn.unproject_zo.html)
pub fn project_zo<N: RealField>( pub fn project_zo<T: RealField>(
obj: &TVec3<N>, obj: &TVec3<T>,
model: &TMat4<N>, model: &TMat4<T>,
proj: &TMat4<N>, proj: &TMat4<T>,
viewport: TVec4<N>, viewport: TVec4<T>,
) -> TVec3<N> { ) -> TVec3<T> {
let normalized = proj * model * TVec4::new(obj.x, obj.y, obj.z, N::one()); let normalized = proj * model * TVec4::new(obj.x, obj.y, obj.z, T::one());
let scale = N::one() / normalized.w; let scale = T::one() / normalized.w;
TVec3::new( TVec3::new(
viewport.x + (viewport.z * (normalized.x * scale + N::one()) * na::convert(0.5)), viewport.x + (viewport.z * (normalized.x * scale + T::one()) * na::convert(0.5)),
viewport.y + (viewport.w * (normalized.y * scale + N::one()) * na::convert(0.5)), viewport.y + (viewport.w * (normalized.y * scale + T::one()) * na::convert(0.5)),
normalized.z * scale, normalized.z * scale,
) )
} }
@ -133,12 +133,12 @@ pub fn project_zo<N: RealField>(
/// * [`project_zo`](fn.project_zo.html) /// * [`project_zo`](fn.project_zo.html)
/// * [`unproject_no`](fn.unproject_no.html) /// * [`unproject_no`](fn.unproject_no.html)
/// * [`unproject_zo`](fn.unproject_zo.html) /// * [`unproject_zo`](fn.unproject_zo.html)
pub fn unproject<N: RealField>( pub fn unproject<T: RealField>(
win: &TVec3<N>, win: &TVec3<T>,
model: &TMat4<N>, model: &TMat4<T>,
proj: &TMat4<N>, proj: &TMat4<T>,
viewport: TVec4<N>, viewport: TVec4<T>,
) -> TVec3<N> { ) -> TVec3<T> {
unproject_no(win, model, proj, viewport) unproject_no(win, model, proj, viewport)
} }
@ -160,23 +160,23 @@ pub fn unproject<N: RealField>(
/// * [`project_zo`](fn.project_zo.html) /// * [`project_zo`](fn.project_zo.html)
/// * [`unproject`](fn.unproject.html) /// * [`unproject`](fn.unproject.html)
/// * [`unproject_zo`](fn.unproject_zo.html) /// * [`unproject_zo`](fn.unproject_zo.html)
pub fn unproject_no<N: RealField>( pub fn unproject_no<T: RealField>(
win: &TVec3<N>, win: &TVec3<T>,
model: &TMat4<N>, model: &TMat4<T>,
proj: &TMat4<N>, proj: &TMat4<T>,
viewport: TVec4<N>, viewport: TVec4<T>,
) -> TVec3<N> { ) -> TVec3<T> {
let _2: N = na::convert(2.0); let _2: T = na::convert(2.0);
let transform = (proj * model).try_inverse().unwrap_or_else(TMat4::zeros); let transform = (proj * model).try_inverse().unwrap_or_else(TMat4::zeros);
let pt = TVec4::new( let pt = TVec4::new(
_2 * (win.x - viewport.x) / viewport.z - N::one(), _2 * (win.x - viewport.x) / viewport.z - T::one(),
_2 * (win.y - viewport.y) / viewport.w - N::one(), _2 * (win.y - viewport.y) / viewport.w - T::one(),
_2 * win.z - N::one(), _2 * win.z - T::one(),
N::one(), T::one(),
); );
let result = transform * pt; let result = transform * pt;
result.fixed_rows::<U3>(0) / result.w result.fixed_rows::<3>(0) / result.w
} }
/// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates. /// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates.
@ -197,21 +197,21 @@ pub fn unproject_no<N: RealField>(
/// * [`project_zo`](fn.project_zo.html) /// * [`project_zo`](fn.project_zo.html)
/// * [`unproject`](fn.unproject.html) /// * [`unproject`](fn.unproject.html)
/// * [`unproject_no`](fn.unproject_no.html) /// * [`unproject_no`](fn.unproject_no.html)
pub fn unproject_zo<N: RealField>( pub fn unproject_zo<T: RealField>(
win: &TVec3<N>, win: &TVec3<T>,
model: &TMat4<N>, model: &TMat4<T>,
proj: &TMat4<N>, proj: &TMat4<T>,
viewport: TVec4<N>, viewport: TVec4<T>,
) -> TVec3<N> { ) -> TVec3<T> {
let _2: N = na::convert(2.0); let _2: T = na::convert(2.0);
let transform = (proj * model).try_inverse().unwrap_or_else(TMat4::zeros); let transform = (proj * model).try_inverse().unwrap_or_else(TMat4::zeros);
let pt = TVec4::new( let pt = TVec4::new(
_2 * (win.x - viewport.x) / viewport.z - N::one(), _2 * (win.x - viewport.x) / viewport.z - T::one(),
_2 * (win.y - viewport.y) / viewport.w - N::one(), _2 * (win.y - viewport.y) / viewport.w - T::one(),
win.z, win.z,
N::one(), T::one(),
); );
let result = transform * pt; let result = transform * pt;
result.fixed_rows::<U3>(0) / result.w result.fixed_rows::<3>(0) / result.w
} }

View File

@ -1,21 +1,16 @@
use na::DefaultAllocator;
use crate::aliases::{TMat, TVec}; use crate::aliases::{TMat, TVec};
use crate::traits::{Alloc, Dimension, Number}; use crate::traits::Number;
/// Perform a component-wise equal-to comparison of two matrices. /// Perform a component-wise equal-to comparison of two matrices.
/// ///
/// Return a boolean vector which components value is True if this expression is satisfied per column of the matrices. /// Return a boolean vector which components value is True if this expression is satisfied per column of the matrices.
pub fn equal_columns<N: Number, R: Dimension, C: Dimension>( pub fn equal_columns<T: Number, const R: usize, const C: usize>(
x: &TMat<N, R, C>, x: &TMat<T, R, C>,
y: &TMat<N, R, C>, y: &TMat<T, R, C>,
) -> TVec<bool, C> ) -> TVec<bool, C> {
where
DefaultAllocator: Alloc<N, R, C>,
{
let mut res = TVec::<_, C>::repeat(false); let mut res = TVec::<_, C>::repeat(false);
for i in 0..C::dim() { for i in 0..C {
res[i] = x.column(i) == y.column(i) res[i] = x.column(i) == y.column(i)
} }
@ -25,31 +20,25 @@ where
/// Returns the component-wise comparison of `|x - y| < epsilon`. /// Returns the component-wise comparison of `|x - y| < epsilon`.
/// ///
/// True if this expression is satisfied. /// True if this expression is satisfied.
pub fn equal_columns_eps<N: Number, R: Dimension, C: Dimension>( pub fn equal_columns_eps<T: Number, const R: usize, const C: usize>(
x: &TMat<N, R, C>, x: &TMat<T, R, C>,
y: &TMat<N, R, C>, y: &TMat<T, R, C>,
epsilon: N, epsilon: T,
) -> TVec<bool, C> ) -> TVec<bool, C> {
where
DefaultAllocator: Alloc<N, R, C>,
{
equal_columns_eps_vec(x, y, &TVec::<_, C>::repeat(epsilon)) equal_columns_eps_vec(x, y, &TVec::<_, C>::repeat(epsilon))
} }
/// Returns the component-wise comparison on each matrix column `|x - y| < epsilon`. /// Returns the component-wise comparison on each matrix column `|x - y| < epsilon`.
/// ///
/// True if this expression is satisfied. /// True if this expression is satisfied.
pub fn equal_columns_eps_vec<N: Number, R: Dimension, C: Dimension>( pub fn equal_columns_eps_vec<T: Number, const R: usize, const C: usize>(
x: &TMat<N, R, C>, x: &TMat<T, R, C>,
y: &TMat<N, R, C>, y: &TMat<T, R, C>,
epsilon: &TVec<N, C>, epsilon: &TVec<T, C>,
) -> TVec<bool, C> ) -> TVec<bool, C> {
where
DefaultAllocator: Alloc<N, R, C>,
{
let mut res = TVec::<_, C>::repeat(false); let mut res = TVec::<_, C>::repeat(false);
for i in 0..C::dim() { for i in 0..C {
res[i] = (x.column(i) - y.column(i)).abs() < TVec::<_, R>::repeat(epsilon[i]) res[i] = (x.column(i) - y.column(i)).abs() < TVec::<_, R>::repeat(epsilon[i])
} }
@ -59,16 +48,13 @@ where
/// Perform a component-wise not-equal-to comparison of two matrices. /// Perform a component-wise not-equal-to comparison of two matrices.
/// ///
/// Return a boolean vector which components value is True if this expression is satisfied per column of the matrices. /// Return a boolean vector which components value is True if this expression is satisfied per column of the matrices.
pub fn not_equal_columns<N: Number, R: Dimension, C: Dimension>( pub fn not_equal_columns<T: Number, const R: usize, const C: usize>(
x: &TMat<N, R, C>, x: &TMat<T, R, C>,
y: &TMat<N, R, C>, y: &TMat<T, R, C>,
) -> TVec<bool, C> ) -> TVec<bool, C> {
where
DefaultAllocator: Alloc<N, R, C>,
{
let mut res = TVec::<_, C>::repeat(false); let mut res = TVec::<_, C>::repeat(false);
for i in 0..C::dim() { for i in 0..C {
res[i] = x.column(i) != y.column(i) res[i] = x.column(i) != y.column(i)
} }
@ -78,31 +64,25 @@ where
/// Returns the component-wise comparison of `|x - y| < epsilon`. /// Returns the component-wise comparison of `|x - y| < epsilon`.
/// ///
/// True if this expression is not satisfied. /// True if this expression is not satisfied.
pub fn not_equal_columns_eps<N: Number, R: Dimension, C: Dimension>( pub fn not_equal_columns_eps<T: Number, const R: usize, const C: usize>(
x: &TMat<N, R, C>, x: &TMat<T, R, C>,
y: &TMat<N, R, C>, y: &TMat<T, R, C>,
epsilon: N, epsilon: T,
) -> TVec<bool, C> ) -> TVec<bool, C> {
where
DefaultAllocator: Alloc<N, R, C>,
{
not_equal_columns_eps_vec(x, y, &TVec::<_, C>::repeat(epsilon)) not_equal_columns_eps_vec(x, y, &TVec::<_, C>::repeat(epsilon))
} }
/// Returns the component-wise comparison of `|x - y| >= epsilon`. /// Returns the component-wise comparison of `|x - y| >= epsilon`.
/// ///
/// True if this expression is not satisfied. /// True if this expression is not satisfied.
pub fn not_equal_columns_eps_vec<N: Number, R: Dimension, C: Dimension>( pub fn not_equal_columns_eps_vec<T: Number, const R: usize, const C: usize>(
x: &TMat<N, R, C>, x: &TMat<T, R, C>,
y: &TMat<N, R, C>, y: &TMat<T, R, C>,
epsilon: &TVec<N, C>, epsilon: &TVec<T, C>,
) -> TVec<bool, C> ) -> TVec<bool, C> {
where
DefaultAllocator: Alloc<N, R, C>,
{
let mut res = TVec::<_, C>::repeat(false); let mut res = TVec::<_, C>::repeat(false);
for i in 0..C::dim() { for i in 0..C {
res[i] = (x.column(i) - y.column(i)).abs() >= TVec::<_, R>::repeat(epsilon[i]) res[i] = (x.column(i) - y.column(i)).abs() >= TVec::<_, R>::repeat(epsilon[i])
} }

View File

@ -1,14 +1,11 @@
use na::{DefaultAllocator, Point3, RealField, Rotation3, Unit}; use na::{Point3, RealField, Rotation3, Unit};
use crate::aliases::{TMat, TMat4, TVec, TVec3}; use crate::aliases::{TMat, TMat4, TVec, TVec3};
use crate::traits::{Alloc, Dimension, Number}; use crate::traits::Number;
/// The identity matrix. /// The identity matrix.
pub fn identity<N: Number, D: Dimension>() -> TMat<N, D, D> pub fn identity<T: Number, const D: usize>() -> TMat<T, D, D> {
where TMat::<T, D, D>::identity()
DefaultAllocator: Alloc<N, D, D>,
{
TMat::<N, D, D>::identity()
} }
/// Build a look at view matrix based on the right handedness. /// Build a look at view matrix based on the right handedness.
@ -23,7 +20,7 @@ where
/// ///
/// * [`look_at_lh`](fn.look_at_lh.html) /// * [`look_at_lh`](fn.look_at_lh.html)
/// * [`look_at_rh`](fn.look_at_rh.html) /// * [`look_at_rh`](fn.look_at_rh.html)
pub fn look_at<N: RealField>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> { pub fn look_at<T: RealField>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
look_at_rh(eye, center, up) look_at_rh(eye, center, up)
} }
@ -39,7 +36,7 @@ pub fn look_at<N: RealField>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>) -
/// ///
/// * [`look_at`](fn.look_at.html) /// * [`look_at`](fn.look_at.html)
/// * [`look_at_rh`](fn.look_at_rh.html) /// * [`look_at_rh`](fn.look_at_rh.html)
pub fn look_at_lh<N: RealField>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> { pub fn look_at_lh<T: RealField>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
TMat::look_at_lh(&Point3::from(*eye), &Point3::from(*center), up) TMat::look_at_lh(&Point3::from(*eye), &Point3::from(*center), up)
} }
@ -55,7 +52,7 @@ pub fn look_at_lh<N: RealField>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>
/// ///
/// * [`look_at`](fn.look_at.html) /// * [`look_at`](fn.look_at.html)
/// * [`look_at_lh`](fn.look_at_lh.html) /// * [`look_at_lh`](fn.look_at_lh.html)
pub fn look_at_rh<N: RealField>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> { pub fn look_at_rh<T: RealField>(eye: &TVec3<T>, center: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
TMat::look_at_rh(&Point3::from(*eye), &Point3::from(*center), up) TMat::look_at_rh(&Point3::from(*eye), &Point3::from(*center), up)
} }
@ -74,7 +71,7 @@ pub fn look_at_rh<N: RealField>(eye: &TVec3<N>, center: &TVec3<N>, up: &TVec3<N>
/// * [`rotate_z`](fn.rotate_z.html) /// * [`rotate_z`](fn.rotate_z.html)
/// * [`scale`](fn.scale.html) /// * [`scale`](fn.scale.html)
/// * [`translate`](fn.translate.html) /// * [`translate`](fn.translate.html)
pub fn rotate<N: RealField>(m: &TMat4<N>, angle: N, axis: &TVec3<N>) -> TMat4<N> { pub fn rotate<T: RealField>(m: &TMat4<T>, angle: T, axis: &TVec3<T>) -> TMat4<T> {
m * Rotation3::from_axis_angle(&Unit::new_normalize(*axis), angle).to_homogeneous() m * Rotation3::from_axis_angle(&Unit::new_normalize(*axis), angle).to_homogeneous()
} }
@ -92,7 +89,7 @@ pub fn rotate<N: RealField>(m: &TMat4<N>, angle: N, axis: &TVec3<N>) -> TMat4<N>
/// * [`rotate_z`](fn.rotate_z.html) /// * [`rotate_z`](fn.rotate_z.html)
/// * [`scale`](fn.scale.html) /// * [`scale`](fn.scale.html)
/// * [`translate`](fn.translate.html) /// * [`translate`](fn.translate.html)
pub fn rotate_x<N: RealField>(m: &TMat4<N>, angle: N) -> TMat4<N> { pub fn rotate_x<T: RealField>(m: &TMat4<T>, angle: T) -> TMat4<T> {
rotate(m, angle, &TVec::x()) rotate(m, angle, &TVec::x())
} }
@ -110,7 +107,7 @@ pub fn rotate_x<N: RealField>(m: &TMat4<N>, angle: N) -> TMat4<N> {
/// * [`rotate_z`](fn.rotate_z.html) /// * [`rotate_z`](fn.rotate_z.html)
/// * [`scale`](fn.scale.html) /// * [`scale`](fn.scale.html)
/// * [`translate`](fn.translate.html) /// * [`translate`](fn.translate.html)
pub fn rotate_y<N: RealField>(m: &TMat4<N>, angle: N) -> TMat4<N> { pub fn rotate_y<T: RealField>(m: &TMat4<T>, angle: T) -> TMat4<T> {
rotate(m, angle, &TVec::y()) rotate(m, angle, &TVec::y())
} }
@ -128,7 +125,7 @@ pub fn rotate_y<N: RealField>(m: &TMat4<N>, angle: N) -> TMat4<N> {
/// * [`rotate_y`](fn.rotate_y.html) /// * [`rotate_y`](fn.rotate_y.html)
/// * [`scale`](fn.scale.html) /// * [`scale`](fn.scale.html)
/// * [`translate`](fn.translate.html) /// * [`translate`](fn.translate.html)
pub fn rotate_z<N: RealField>(m: &TMat4<N>, angle: N) -> TMat4<N> { pub fn rotate_z<T: RealField>(m: &TMat4<T>, angle: T) -> TMat4<T> {
rotate(m, angle, &TVec::z()) rotate(m, angle, &TVec::z())
} }
@ -146,7 +143,7 @@ pub fn rotate_z<N: RealField>(m: &TMat4<N>, angle: N) -> TMat4<N> {
/// * [`rotate_y`](fn.rotate_y.html) /// * [`rotate_y`](fn.rotate_y.html)
/// * [`rotate_z`](fn.rotate_z.html) /// * [`rotate_z`](fn.rotate_z.html)
/// * [`translate`](fn.translate.html) /// * [`translate`](fn.translate.html)
pub fn scale<N: Number>(m: &TMat4<N>, v: &TVec3<N>) -> TMat4<N> { pub fn scale<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> {
m.prepend_nonuniform_scaling(v) m.prepend_nonuniform_scaling(v)
} }
@ -164,6 +161,6 @@ pub fn scale<N: Number>(m: &TMat4<N>, v: &TVec3<N>) -> TMat4<N> {
/// * [`rotate_y`](fn.rotate_y.html) /// * [`rotate_y`](fn.rotate_y.html)
/// * [`rotate_z`](fn.rotate_z.html) /// * [`rotate_z`](fn.rotate_z.html)
/// * [`scale`](fn.scale.html) /// * [`scale`](fn.scale.html)
pub fn translate<N: Number>(m: &TMat4<N>, v: &TVec3<N>) -> TMat4<N> { pub fn translate<T: Number>(m: &TMat4<T>, v: &TVec3<T>) -> TMat4<T> {
m.prepend_translation(v) m.prepend_translation(v)
} }

View File

@ -3,34 +3,34 @@ use na::{self, RealField, Unit};
use crate::aliases::Qua; use crate::aliases::Qua;
/// The conjugate of `q`. /// The conjugate of `q`.
pub fn quat_conjugate<N: RealField>(q: &Qua<N>) -> Qua<N> { pub fn quat_conjugate<T: RealField>(q: &Qua<T>) -> Qua<T> {
q.conjugate() q.conjugate()
} }
/// The inverse of `q`. /// The inverse of `q`.
pub fn quat_inverse<N: RealField>(q: &Qua<N>) -> Qua<N> { pub fn quat_inverse<T: RealField>(q: &Qua<T>) -> Qua<T> {
q.try_inverse().unwrap_or_else(na::zero) q.try_inverse().unwrap_or_else(na::zero)
} }
//pub fn quat_isinf<N: RealField>(x: &Qua<N>) -> TVec<bool, U4> { //pub fn quat_isinf<T: RealField>(x: &Qua<T>) -> TVec<bool, U4> {
// x.coords.map(|e| e.is_inf()) // x.coords.map(|e| e.is_inf())
//} //}
//pub fn quat_isnan<N: RealField>(x: &Qua<N>) -> TVec<bool, U4> { //pub fn quat_isnan<T: RealField>(x: &Qua<T>) -> TVec<bool, U4> {
// x.coords.map(|e| e.is_nan()) // x.coords.map(|e| e.is_nan())
//} //}
/// Interpolate linearly between `x` and `y`. /// Interpolate linearly between `x` and `y`.
pub fn quat_lerp<N: RealField>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> { pub fn quat_lerp<T: RealField>(x: &Qua<T>, y: &Qua<T>, a: T) -> Qua<T> {
x.lerp(y, a) x.lerp(y, a)
} }
//pub fn quat_mix<N: RealField>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> { //pub fn quat_mix<T: RealField>(x: &Qua<T>, y: &Qua<T>, a: T) -> Qua<T> {
// x * (N::one() - a) + y * a // x * (T::one() - a) + y * a
//} //}
/// Interpolate spherically between `x` and `y`. /// Interpolate spherically between `x` and `y`.
pub fn quat_slerp<N: RealField>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> { pub fn quat_slerp<T: RealField>(x: &Qua<T>, y: &Qua<T>, a: T) -> Qua<T> {
Unit::new_normalize(*x) Unit::new_normalize(*x)
.slerp(&Unit::new_normalize(*y), a) .slerp(&Unit::new_normalize(*y), a)
.into_inner() .into_inner()

View File

@ -3,26 +3,26 @@ use na::RealField;
use crate::aliases::Qua; use crate::aliases::Qua;
/// Multiplies two quaternions. /// Multiplies two quaternions.
pub fn quat_cross<N: RealField>(q1: &Qua<N>, q2: &Qua<N>) -> Qua<N> { pub fn quat_cross<T: RealField>(q1: &Qua<T>, q2: &Qua<T>) -> Qua<T> {
q1 * q2 q1 * q2
} }
/// The scalar product of two quaternions. /// The scalar product of two quaternions.
pub fn quat_dot<N: RealField>(x: &Qua<N>, y: &Qua<N>) -> N { pub fn quat_dot<T: RealField>(x: &Qua<T>, y: &Qua<T>) -> T {
x.dot(y) x.dot(y)
} }
/// The magnitude of the quaternion `q`. /// The magnitude of the quaternion `q`.
pub fn quat_length<N: RealField>(q: &Qua<N>) -> N { pub fn quat_length<T: RealField>(q: &Qua<T>) -> T {
q.norm() q.norm()
} }
/// The magnitude of the quaternion `q`. /// The magnitude of the quaternion `q`.
pub fn quat_magnitude<N: RealField>(q: &Qua<N>) -> N { pub fn quat_magnitude<T: RealField>(q: &Qua<T>) -> T {
q.norm() q.norm()
} }
/// Normalizes the quaternion `q`. /// Normalizes the quaternion `q`.
pub fn quat_normalize<N: RealField>(q: &Qua<N>) -> Qua<N> { pub fn quat_normalize<T: RealField>(q: &Qua<T>) -> Qua<T> {
q.normalize() q.normalize()
} }

View File

@ -1,23 +1,23 @@
use na::{RealField, U4}; use na::RealField;
use crate::aliases::{Qua, TVec}; use crate::aliases::{Qua, TVec};
/// Component-wise equality comparison between two quaternions. /// Component-wise equality comparison between two quaternions.
pub fn quat_equal<N: RealField>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> { pub fn quat_equal<T: RealField>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
crate::equal(&x.coords, &y.coords) crate::equal(&x.coords, &y.coords)
} }
/// Component-wise approximate equality comparison between two quaternions. /// Component-wise approximate equality comparison between two quaternions.
pub fn quat_equal_eps<N: RealField>(x: &Qua<N>, y: &Qua<N>, epsilon: N) -> TVec<bool, U4> { pub fn quat_equal_eps<T: RealField>(x: &Qua<T>, y: &Qua<T>, epsilon: T) -> TVec<bool, 4> {
crate::equal_eps(&x.coords, &y.coords, epsilon) crate::equal_eps(&x.coords, &y.coords, epsilon)
} }
/// Component-wise non-equality comparison between two quaternions. /// Component-wise non-equality comparison between two quaternions.
pub fn quat_not_equal<N: RealField>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> { pub fn quat_not_equal<T: RealField>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
crate::not_equal(&x.coords, &y.coords) crate::not_equal(&x.coords, &y.coords)
} }
/// Component-wise approximate non-equality comparison between two quaternions. /// Component-wise approximate non-equality comparison between two quaternions.
pub fn quat_not_equal_eps<N: RealField>(x: &Qua<N>, y: &Qua<N>, epsilon: N) -> TVec<bool, U4> { pub fn quat_not_equal_eps<T: RealField>(x: &Qua<T>, y: &Qua<T>, epsilon: T) -> TVec<bool, 4> {
crate::not_equal_eps(&x.coords, &y.coords, epsilon) crate::not_equal_eps(&x.coords, &y.coords, epsilon)
} }

View File

@ -3,25 +3,25 @@ use na::{RealField, Unit, UnitQuaternion};
use crate::aliases::{Qua, TVec3}; use crate::aliases::{Qua, TVec3};
/// Computes the quaternion exponential. /// Computes the quaternion exponential.
pub fn quat_exp<N: RealField>(q: &Qua<N>) -> Qua<N> { pub fn quat_exp<T: RealField>(q: &Qua<T>) -> Qua<T> {
q.exp() q.exp()
} }
/// Computes the quaternion logarithm. /// Computes the quaternion logarithm.
pub fn quat_log<N: RealField>(q: &Qua<N>) -> Qua<N> { pub fn quat_log<T: RealField>(q: &Qua<T>) -> Qua<T> {
q.ln() q.ln()
} }
/// Raises the quaternion `q` to the power `y`. /// Raises the quaternion `q` to the power `y`.
pub fn quat_pow<N: RealField>(q: &Qua<N>, y: N) -> Qua<N> { pub fn quat_pow<T: RealField>(q: &Qua<T>, y: T) -> Qua<T> {
q.powf(y) q.powf(y)
} }
/// Builds a quaternion from an axis and an angle, and right-multiply it to the quaternion `q`. /// Builds a quaternion from an axis and an angle, and right-multiply it to the quaternion `q`.
pub fn quat_rotate<N: RealField>(q: &Qua<N>, angle: N, axis: &TVec3<N>) -> Qua<N> { pub fn quat_rotate<T: RealField>(q: &Qua<T>, angle: T, axis: &TVec3<T>) -> Qua<T> {
q * UnitQuaternion::from_axis_angle(&Unit::new_normalize(*axis), angle).into_inner() q * UnitQuaternion::from_axis_angle(&Unit::new_normalize(*axis), angle).into_inner()
} }
//pub fn quat_sqrt<N: RealField>(q: &Qua<N>) -> Qua<N> { //pub fn quat_sqrt<T: RealField>(q: &Qua<T>) -> Qua<T> {
// unimplemented!() // unimplemented!()
//} //}

View File

@ -3,17 +3,17 @@ use na::{RealField, Unit, UnitQuaternion};
use crate::aliases::{Qua, TVec3}; use crate::aliases::{Qua, TVec3};
/// The rotation angle of this quaternion assumed to be normalized. /// The rotation angle of this quaternion assumed to be normalized.
pub fn quat_angle<N: RealField>(x: &Qua<N>) -> N { pub fn quat_angle<T: RealField>(x: &Qua<T>) -> T {
UnitQuaternion::from_quaternion(*x).angle() UnitQuaternion::from_quaternion(*x).angle()
} }
/// Creates a quaternion from an axis and an angle. /// Creates a quaternion from an axis and an angle.
pub fn quat_angle_axis<N: RealField>(angle: N, axis: &TVec3<N>) -> Qua<N> { pub fn quat_angle_axis<T: RealField>(angle: T, axis: &TVec3<T>) -> Qua<T> {
UnitQuaternion::from_axis_angle(&Unit::new_normalize(*axis), angle).into_inner() UnitQuaternion::from_axis_angle(&Unit::new_normalize(*axis), angle).into_inner()
} }
/// The rotation axis of a quaternion assumed to be normalized. /// The rotation axis of a quaternion assumed to be normalized.
pub fn quat_axis<N: RealField>(x: &Qua<N>) -> TVec3<N> { pub fn quat_axis<T: RealField>(x: &Qua<T>) -> TVec3<T> {
if let Some(a) = UnitQuaternion::from_quaternion(*x).axis() { if let Some(a) = UnitQuaternion::from_quaternion(*x).axis() {
a.into_inner() a.into_inner()
} else { } else {

View File

@ -15,7 +15,7 @@ use crate::traits::Number;
/// * [`max4_scalar`](fn.max4_scalar.html) /// * [`max4_scalar`](fn.max4_scalar.html)
/// * [`min3_scalar`](fn.min3_scalar.html) /// * [`min3_scalar`](fn.min3_scalar.html)
/// * [`min4_scalar`](fn.min4_scalar.html) /// * [`min4_scalar`](fn.min4_scalar.html)
pub fn max2_scalar<N: Number>(a: N, b: N) -> N { pub fn max2_scalar<T: Number>(a: T, b: T) -> T {
if a >= b { if a >= b {
a a
} else { } else {
@ -38,7 +38,7 @@ pub fn max2_scalar<N: Number>(a: N, b: N) -> N {
/// * [`max4_scalar`](fn.max4_scalar.html) /// * [`max4_scalar`](fn.max4_scalar.html)
/// * [`min3_scalar`](fn.min3_scalar.html) /// * [`min3_scalar`](fn.min3_scalar.html)
/// * [`min4_scalar`](fn.min4_scalar.html) /// * [`min4_scalar`](fn.min4_scalar.html)
pub fn min2_scalar<N: Number>(a: N, b: N) -> N { pub fn min2_scalar<T: Number>(a: T, b: T) -> T {
if a <= b { if a <= b {
a a
} else { } else {
@ -61,7 +61,7 @@ pub fn min2_scalar<N: Number>(a: N, b: N) -> N {
/// * [`max4_scalar`](fn.max4_scalar.html) /// * [`max4_scalar`](fn.max4_scalar.html)
/// * [`min3_scalar`](fn.min3_scalar.html) /// * [`min3_scalar`](fn.min3_scalar.html)
/// * [`min4_scalar`](fn.min4_scalar.html) /// * [`min4_scalar`](fn.min4_scalar.html)
pub fn max3_scalar<N: Number>(a: N, b: N, c: N) -> N { pub fn max3_scalar<T: Number>(a: T, b: T, c: T) -> T {
max2_scalar(max2_scalar(a, b), c) max2_scalar(max2_scalar(a, b), c)
} }
@ -80,7 +80,7 @@ pub fn max3_scalar<N: Number>(a: N, b: N, c: N) -> N {
/// * [`max3_scalar`](fn.max3_scalar.html) /// * [`max3_scalar`](fn.max3_scalar.html)
/// * [`min3_scalar`](fn.min3_scalar.html) /// * [`min3_scalar`](fn.min3_scalar.html)
/// * [`min4_scalar`](fn.min4_scalar.html) /// * [`min4_scalar`](fn.min4_scalar.html)
pub fn max4_scalar<N: Number>(a: N, b: N, c: N, d: N) -> N { pub fn max4_scalar<T: Number>(a: T, b: T, c: T, d: T) -> T {
max2_scalar(max2_scalar(a, b), max2_scalar(c, d)) max2_scalar(max2_scalar(a, b), max2_scalar(c, d))
} }
@ -99,7 +99,7 @@ pub fn max4_scalar<N: Number>(a: N, b: N, c: N, d: N) -> N {
/// * [`max3_scalar`](fn.max3_scalar.html) /// * [`max3_scalar`](fn.max3_scalar.html)
/// * [`max4_scalar`](fn.max4_scalar.html) /// * [`max4_scalar`](fn.max4_scalar.html)
/// * [`min4_scalar`](fn.min4_scalar.html) /// * [`min4_scalar`](fn.min4_scalar.html)
pub fn min3_scalar<N: Number>(a: N, b: N, c: N) -> N { pub fn min3_scalar<T: Number>(a: T, b: T, c: T) -> T {
min2_scalar(min2_scalar(a, b), c) min2_scalar(min2_scalar(a, b), c)
} }
@ -118,6 +118,6 @@ pub fn min3_scalar<N: Number>(a: N, b: N, c: N) -> N {
/// * [`max3_scalar`](fn.max3_scalar.html) /// * [`max3_scalar`](fn.max3_scalar.html)
/// * [`max4_scalar`](fn.max4_scalar.html) /// * [`max4_scalar`](fn.max4_scalar.html)
/// * [`min3_scalar`](fn.min3_scalar.html) /// * [`min3_scalar`](fn.min3_scalar.html)
pub fn min4_scalar<N: Number>(a: N, b: N, c: N, d: N) -> N { pub fn min4_scalar<T: Number>(a: T, b: T, c: T, d: T) -> T {
min2_scalar(min2_scalar(a, b), min2_scalar(c, d)) min2_scalar(min2_scalar(a, b), min2_scalar(c, d))
} }

View File

@ -2,8 +2,8 @@ use approx::AbsDiffEq;
use na::RealField; use na::RealField;
/// Default epsilon value used for approximate comparison. /// Default epsilon value used for approximate comparison.
pub fn epsilon<N: AbsDiffEq<Epsilon = N>>() -> N { pub fn epsilon<T: AbsDiffEq<Epsilon = T>>() -> T {
N::default_epsilon() T::default_epsilon()
} }
/// The value of PI. /// The value of PI.
@ -22,6 +22,6 @@ pub fn epsilon<N: AbsDiffEq<Epsilon = N>>() -> N {
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi`](fn.two_pi.html)
pub fn pi<N: RealField>() -> N { pub fn pi<T: RealField>() -> T {
N::pi() T::pi()
} }

View File

@ -1,7 +1,5 @@
use na::{self, DefaultAllocator};
use crate::aliases::TVec; use crate::aliases::TVec;
use crate::traits::{Alloc, Dimension, Number}; use crate::traits::Number;
/// Component-wise maximum between a vector and a scalar. /// Component-wise maximum between a vector and a scalar.
/// ///
@ -16,10 +14,7 @@ use crate::traits::{Alloc, Dimension, Number};
/// * [`min2`](fn.min2.html) /// * [`min2`](fn.min2.html)
/// * [`min3`](fn.min3.html) /// * [`min3`](fn.min3.html)
/// * [`min4`](fn.min4.html) /// * [`min4`](fn.min4.html)
pub fn max<N: Number, D: Dimension>(a: &TVec<N, D>, b: N) -> TVec<N, D> pub fn max<T: Number, const D: usize>(a: &TVec<T, D>, b: T) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
a.map(|a| crate::max2_scalar(a, b)) a.map(|a| crate::max2_scalar(a, b))
} }
@ -36,10 +31,7 @@ where
/// * [`min2`](fn.min2.html) /// * [`min2`](fn.min2.html)
/// * [`min3`](fn.min3.html) /// * [`min3`](fn.min3.html)
/// * [`min4`](fn.min4.html) /// * [`min4`](fn.min4.html)
pub fn max2<N: Number, D: Dimension>(a: &TVec<N, D>, b: &TVec<N, D>) -> TVec<N, D> pub fn max2<T: Number, const D: usize>(a: &TVec<T, D>, b: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
a.zip_map(b, |a, b| crate::max2_scalar(a, b)) a.zip_map(b, |a, b| crate::max2_scalar(a, b))
} }
@ -56,10 +48,11 @@ where
/// * [`min2`](fn.min2.html) /// * [`min2`](fn.min2.html)
/// * [`min3`](fn.min3.html) /// * [`min3`](fn.min3.html)
/// * [`min4`](fn.min4.html) /// * [`min4`](fn.min4.html)
pub fn max3<N: Number, D: Dimension>(a: &TVec<N, D>, b: &TVec<N, D>, c: &TVec<N, D>) -> TVec<N, D> pub fn max3<T: Number, const D: usize>(
where a: &TVec<T, D>,
DefaultAllocator: Alloc<N, D>, b: &TVec<T, D>,
{ c: &TVec<T, D>,
) -> TVec<T, D> {
max2(&max2(a, b), c) max2(&max2(a, b), c)
} }
@ -76,15 +69,12 @@ where
/// * [`min2`](fn.min2.html) /// * [`min2`](fn.min2.html)
/// * [`min3`](fn.min3.html) /// * [`min3`](fn.min3.html)
/// * [`min4`](fn.min4.html) /// * [`min4`](fn.min4.html)
pub fn max4<N: Number, D: Dimension>( pub fn max4<T: Number, const D: usize>(
a: &TVec<N, D>, a: &TVec<T, D>,
b: &TVec<N, D>, b: &TVec<T, D>,
c: &TVec<N, D>, c: &TVec<T, D>,
d: &TVec<N, D>, d: &TVec<T, D>,
) -> TVec<N, D> ) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
max2(&max2(a, b), &max2(c, d)) max2(&max2(a, b), &max2(c, d))
} }
@ -101,10 +91,7 @@ where
/// * [`min2`](fn.min2.html) /// * [`min2`](fn.min2.html)
/// * [`min3`](fn.min3.html) /// * [`min3`](fn.min3.html)
/// * [`min4`](fn.min4.html) /// * [`min4`](fn.min4.html)
pub fn min<N: Number, D: Dimension>(x: &TVec<N, D>, y: N) -> TVec<N, D> pub fn min<T: Number, const D: usize>(x: &TVec<T, D>, y: T) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.map(|x| crate::min2_scalar(x, y)) x.map(|x| crate::min2_scalar(x, y))
} }
@ -121,10 +108,7 @@ where
/// * [`min`](fn.min.html) /// * [`min`](fn.min.html)
/// * [`min3`](fn.min3.html) /// * [`min3`](fn.min3.html)
/// * [`min4`](fn.min4.html) /// * [`min4`](fn.min4.html)
pub fn min2<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<N, D> pub fn min2<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |a, b| crate::min2_scalar(a, b)) x.zip_map(y, |a, b| crate::min2_scalar(a, b))
} }
@ -141,10 +125,11 @@ where
/// * [`min`](fn.min.html) /// * [`min`](fn.min.html)
/// * [`min2`](fn.min2.html) /// * [`min2`](fn.min2.html)
/// * [`min4`](fn.min4.html) /// * [`min4`](fn.min4.html)
pub fn min3<N: Number, D: Dimension>(a: &TVec<N, D>, b: &TVec<N, D>, c: &TVec<N, D>) -> TVec<N, D> pub fn min3<T: Number, const D: usize>(
where a: &TVec<T, D>,
DefaultAllocator: Alloc<N, D>, b: &TVec<T, D>,
{ c: &TVec<T, D>,
) -> TVec<T, D> {
min2(&min2(a, b), c) min2(&min2(a, b), c)
} }
@ -161,14 +146,11 @@ where
/// * [`min`](fn.min.html) /// * [`min`](fn.min.html)
/// * [`min2`](fn.min2.html) /// * [`min2`](fn.min2.html)
/// * [`min3`](fn.min3.html) /// * [`min3`](fn.min3.html)
pub fn min4<N: Number, D: Dimension>( pub fn min4<T: Number, const D: usize>(
a: &TVec<N, D>, a: &TVec<T, D>,
b: &TVec<N, D>, b: &TVec<T, D>,
c: &TVec<N, D>, c: &TVec<T, D>,
d: &TVec<N, D>, d: &TVec<T, D>,
) -> TVec<N, D> ) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
min2(&min2(a, b), &min2(c, d)) min2(&min2(a, b), &min2(c, d))
} }

View File

@ -1,7 +1,5 @@
use na::DefaultAllocator;
use crate::aliases::TVec; use crate::aliases::TVec;
use crate::traits::{Alloc, Dimension, Number}; use crate::traits::Number;
/// Component-wise approximate equality of two vectors, using a scalar epsilon. /// Component-wise approximate equality of two vectors, using a scalar epsilon.
/// ///
@ -10,14 +8,11 @@ use crate::traits::{Alloc, Dimension, Number};
/// * [`equal_eps_vec`](fn.equal_eps_vec.html) /// * [`equal_eps_vec`](fn.equal_eps_vec.html)
/// * [`not_equal_eps`](fn.not_equal_eps.html) /// * [`not_equal_eps`](fn.not_equal_eps.html)
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html) /// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
pub fn equal_eps<N: Number, D: Dimension>( pub fn equal_eps<T: Number, const D: usize>(
x: &TVec<N, D>, x: &TVec<T, D>,
y: &TVec<N, D>, y: &TVec<T, D>,
epsilon: N, epsilon: T,
) -> TVec<bool, D> ) -> TVec<bool, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| abs_diff_eq!(x, y, epsilon = epsilon)) x.zip_map(y, |x, y| abs_diff_eq!(x, y, epsilon = epsilon))
} }
@ -28,14 +23,11 @@ where
/// * [`equal_eps`](fn.equal_eps.html) /// * [`equal_eps`](fn.equal_eps.html)
/// * [`not_equal_eps`](fn.not_equal_eps.html) /// * [`not_equal_eps`](fn.not_equal_eps.html)
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html) /// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
pub fn equal_eps_vec<N: Number, D: Dimension>( pub fn equal_eps_vec<T: Number, const D: usize>(
x: &TVec<N, D>, x: &TVec<T, D>,
y: &TVec<N, D>, y: &TVec<T, D>,
epsilon: &TVec<N, D>, epsilon: &TVec<T, D>,
) -> TVec<bool, D> ) -> TVec<bool, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.zip_zip_map(y, epsilon, |x, y, eps| abs_diff_eq!(x, y, epsilon = eps)) x.zip_zip_map(y, epsilon, |x, y, eps| abs_diff_eq!(x, y, epsilon = eps))
} }
@ -46,14 +38,11 @@ where
/// * [`equal_eps`](fn.equal_eps.html) /// * [`equal_eps`](fn.equal_eps.html)
/// * [`equal_eps_vec`](fn.equal_eps_vec.html) /// * [`equal_eps_vec`](fn.equal_eps_vec.html)
/// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html) /// * [`not_equal_eps_vec`](fn.not_equal_eps_vec.html)
pub fn not_equal_eps<N: Number, D: Dimension>( pub fn not_equal_eps<T: Number, const D: usize>(
x: &TVec<N, D>, x: &TVec<T, D>,
y: &TVec<N, D>, y: &TVec<T, D>,
epsilon: N, epsilon: T,
) -> TVec<bool, D> ) -> TVec<bool, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| abs_diff_ne!(x, y, epsilon = epsilon)) x.zip_map(y, |x, y| abs_diff_ne!(x, y, epsilon = epsilon))
} }
@ -64,13 +53,10 @@ where
/// * [`equal_eps`](fn.equal_eps.html) /// * [`equal_eps`](fn.equal_eps.html)
/// * [`equal_eps_vec`](fn.equal_eps_vec.html) /// * [`equal_eps_vec`](fn.equal_eps_vec.html)
/// * [`not_equal_eps`](fn.not_equal_eps.html) /// * [`not_equal_eps`](fn.not_equal_eps.html)
pub fn not_equal_eps_vec<N: Number, D: Dimension>( pub fn not_equal_eps_vec<T: Number, const D: usize>(
x: &TVec<N, D>, x: &TVec<T, D>,
y: &TVec<N, D>, y: &TVec<T, D>,
epsilon: &TVec<N, D>, epsilon: &TVec<T, D>,
) -> TVec<bool, D> ) -> TVec<bool, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.zip_zip_map(y, epsilon, |x, y, eps| abs_diff_ne!(x, y, epsilon = eps)) x.zip_zip_map(y, epsilon, |x, y, eps| abs_diff_ne!(x, y, epsilon = eps))
} }

View File

@ -1,10 +1,10 @@
use na::{DefaultAllocator, RealField}; use na::RealField;
use crate::aliases::{TVec, TVec3}; use crate::aliases::{TVec, TVec3};
use crate::traits::{Alloc, Dimension, Number}; use crate::traits::Number;
/// The cross product of two vectors. /// The cross product of two vectors.
pub fn cross<N: Number>(x: &TVec3<N>, y: &TVec3<N>) -> TVec3<N> { pub fn cross<T: Number>(x: &TVec3<T>, y: &TVec3<T>) -> TVec3<T> {
x.cross(y) x.cross(y)
} }
@ -13,31 +13,22 @@ pub fn cross<N: Number>(x: &TVec3<N>, y: &TVec3<N>) -> TVec3<N> {
/// # See also: /// # See also:
/// ///
/// * [`distance2`](fn.distance2.html) /// * [`distance2`](fn.distance2.html)
pub fn distance<N: RealField, D: Dimension>(p0: &TVec<N, D>, p1: &TVec<N, D>) -> N pub fn distance<T: RealField, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T {
where
DefaultAllocator: Alloc<N, D>,
{
(p1 - p0).norm() (p1 - p0).norm()
} }
/// The dot product of two vectors. /// The dot product of two vectors.
pub fn dot<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N pub fn dot<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
where
DefaultAllocator: Alloc<N, D>,
{
x.dot(y) x.dot(y)
} }
/// If `dot(nref, i) < 0.0`, return `n`, otherwise, return `-n`. /// If `dot(nref, i) < 0.0`, return `n`, otherwise, return `-n`.
pub fn faceforward<N: Number, D: Dimension>( pub fn faceforward<T: Number, const D: usize>(
n: &TVec<N, D>, n: &TVec<T, D>,
i: &TVec<N, D>, i: &TVec<T, D>,
nref: &TVec<N, D>, nref: &TVec<T, D>,
) -> TVec<N, D> ) -> TVec<T, D> {
where if nref.dot(i) < T::zero() {
DefaultAllocator: Alloc<N, D>,
{
if nref.dot(i) < N::zero() {
n.clone() n.clone()
} else { } else {
-n.clone() -n.clone()
@ -53,10 +44,7 @@ where
/// * [`length2`](fn.length2.html) /// * [`length2`](fn.length2.html)
/// * [`magnitude`](fn.magnitude.html) /// * [`magnitude`](fn.magnitude.html)
/// * [`magnitude2`](fn.magnitude2.html) /// * [`magnitude2`](fn.magnitude2.html)
pub fn length<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N pub fn length<T: RealField, const D: usize>(x: &TVec<T, D>) -> T {
where
DefaultAllocator: Alloc<N, D>,
{
x.norm() x.norm()
} }
@ -69,39 +57,31 @@ where
/// * [`length`](fn.length.html) /// * [`length`](fn.length.html)
/// * [`magnitude2`](fn.magnitude2.html) /// * [`magnitude2`](fn.magnitude2.html)
/// * [`nalgebra::norm`](../nalgebra/fn.norm.html) /// * [`nalgebra::norm`](../nalgebra/fn.norm.html)
pub fn magnitude<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N pub fn magnitude<T: RealField, const D: usize>(x: &TVec<T, D>) -> T {
where
DefaultAllocator: Alloc<N, D>,
{
x.norm() x.norm()
} }
/// Normalizes a vector. /// Normalizes a vector.
pub fn normalize<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn normalize<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.normalize() x.normalize()
} }
/// For the incident vector `i` and surface orientation `n`, returns the reflection direction : `result = i - 2.0 * dot(n, i) * n`. /// For the incident vector `i` and surface orientation `n`, returns the reflection direction : `result = i - 2.0 * dot(n, i) * n`.
pub fn reflect_vec<N: Number, D: Dimension>(i: &TVec<N, D>, n: &TVec<N, D>) -> TVec<N, D> pub fn reflect_vec<T: Number, const D: usize>(i: &TVec<T, D>, n: &TVec<T, D>) -> TVec<T, D> {
where let _2 = T::one() + T::one();
DefaultAllocator: Alloc<N, D>,
{
let _2 = N::one() + N::one();
i - n * (n.dot(i) * _2) i - n * (n.dot(i) * _2)
} }
/// For the incident vector `i` and surface normal `n`, and the ratio of indices of refraction `eta`, return the refraction vector. /// For the incident vector `i` and surface normal `n`, and the ratio of indices of refraction `eta`, return the refraction vector.
pub fn refract_vec<N: RealField, D: Dimension>(i: &TVec<N, D>, n: &TVec<N, D>, eta: N) -> TVec<N, D> pub fn refract_vec<T: RealField, const D: usize>(
where i: &TVec<T, D>,
DefaultAllocator: Alloc<N, D>, n: &TVec<T, D>,
{ eta: T,
) -> TVec<T, D> {
let ni = n.dot(i); let ni = n.dot(i);
let k = N::one() - eta * eta * (N::one() - ni * ni); let k = T::one() - eta * eta * (T::one() - ni * ni);
if k < N::zero() { if k < T::zero() {
TVec::<_, D>::zeros() TVec::<_, D>::zeros()
} else { } else {
i * eta - n * (eta * dot(n, i) + k.sqrt()) i * eta - n * (eta * dot(n, i) + k.sqrt())

View File

@ -1,6 +1,5 @@
use na::{Scalar, DefaultAllocator}; use na::{DefaultAllocator, Scalar};
use crate::traits::{Alloc, Dimension};
use crate::aliases::*; use crate::aliases::*;
pub fn bitfieldDeinterleave(x: u16) -> U8Vec2 { pub fn bitfieldDeinterleave(x: u16) -> U8Vec2 {
@ -19,8 +18,11 @@ pub fn bitfieldFillOne<IU>(Value: IU, FirstBit: i32, BitCount: i32) -> IU {
unimplemented!() unimplemented!()
} }
pub fn bitfieldFillOne2<N: Scalar, D: Dimension>(Value: &TVec<N, D>, FirstBit: i32, BitCount: i32) -> TVec<N, D> pub fn bitfieldFillOne2<T: Scalar, const D: usize>(
where DefaultAllocator: Alloc<N, D> { Value: &TVec<T, D>,
FirstBit: i32,
BitCount: i32,
) -> TVec<T, D> {
unimplemented!() unimplemented!()
} }
@ -28,8 +30,11 @@ pub fn bitfieldFillZero<IU>(Value: IU, FirstBit: i32, BitCount: i32) -> IU {
unimplemented!() unimplemented!()
} }
pub fn bitfieldFillZero2<N: Scalar, D: Dimension>(Value: &TVec<N, D>, FirstBit: i32, BitCount: i32) -> TVec<N, D> pub fn bitfieldFillZero2<T: Scalar, const D: usize>(
where DefaultAllocator: Alloc<N, D> { Value: &TVec<T, D>,
FirstBit: i32,
BitCount: i32,
) -> TVec<T, D> {
unimplemented!() unimplemented!()
} }
@ -113,8 +118,7 @@ pub fn bitfieldRotateLeft<IU>(In: IU, Shift: i32) -> IU {
unimplemented!() unimplemented!()
} }
pub fn bitfieldRotateLeft2<N: Scalar, D: Dimension>(In: &TVec<N, D>, Shift: i32) -> TVec<N, D> pub fn bitfieldRotateLeft2<T: Scalar, const D: usize>(In: &TVec<T, D>, Shift: i32) -> TVec<T, D> {
where DefaultAllocator: Alloc<N, D> {
unimplemented!() unimplemented!()
} }
@ -122,8 +126,7 @@ pub fn bitfieldRotateRight<IU>(In: IU, Shift: i32) -> IU {
unimplemented!() unimplemented!()
} }
pub fn bitfieldRotateRight2<N: Scalar, D: Dimension>(In: &TVec<N, D>, Shift: i32) -> TVec<N, D> pub fn bitfieldRotateRight2<T: Scalar, const D: usize>(In: &TVec<T, D>, Shift: i32) -> TVec<T, D> {
where DefaultAllocator: Alloc<N, D> {
unimplemented!() unimplemented!()
} }
@ -131,7 +134,6 @@ pub fn mask<IU>(Bits: IU) -> IU {
unimplemented!() unimplemented!()
} }
pub fn mask2<N: Scalar, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn mask2<T: Scalar, const D: usize>(v: &TVec<T, D>) -> TVec<T, D> {
where DefaultAllocator: Alloc<N, D> {
unimplemented!() unimplemented!()
} }

View File

@ -3,13 +3,13 @@ use na::{self, RealField};
/// The Euler constant. /// The Euler constant.
/// ///
/// This is a shorthand alias for [`euler`](fn.euler.html). /// This is a shorthand alias for [`euler`](fn.euler.html).
pub fn e<N: RealField>() -> N { pub fn e<T: RealField>() -> T {
N::e() T::e()
} }
/// The Euler constant. /// The Euler constant.
pub fn euler<N: RealField>() -> N { pub fn euler<T: RealField>() -> T {
N::e() T::e()
} }
/// Returns `4 / pi`. /// Returns `4 / pi`.
@ -28,13 +28,13 @@ pub fn euler<N: RealField>() -> N {
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi`](fn.two_pi.html)
pub fn four_over_pi<N: RealField>() -> N { pub fn four_over_pi<T: RealField>() -> T {
na::convert::<_, N>(4.0) / N::pi() na::convert::<_, T>(4.0) / T::pi()
} }
/// Returns the golden ratio. /// Returns the golden ratio.
pub fn golden_ratio<N: RealField>() -> N { pub fn golden_ratio<T: RealField>() -> T {
(N::one() + root_five()) / na::convert(2.0) (T::one() + root_five()) / na::convert(2.0)
} }
/// Returns `pi / 2`. /// Returns `pi / 2`.
@ -53,8 +53,8 @@ pub fn golden_ratio<N: RealField>() -> N {
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi`](fn.two_pi.html)
pub fn half_pi<N: RealField>() -> N { pub fn half_pi<T: RealField>() -> T {
N::frac_pi_2() T::frac_pi_2()
} }
/// Returns `ln(ln(2))`. /// Returns `ln(ln(2))`.
@ -63,8 +63,8 @@ pub fn half_pi<N: RealField>() -> N {
/// ///
/// * [`ln_ten`](fn.ln_ten.html) /// * [`ln_ten`](fn.ln_ten.html)
/// * [`ln_two`](fn.ln_two.html) /// * [`ln_two`](fn.ln_two.html)
pub fn ln_ln_two<N: RealField>() -> N { pub fn ln_ln_two<T: RealField>() -> T {
N::ln_2().ln() T::ln_2().ln()
} }
/// Returns `ln(10)`. /// Returns `ln(10)`.
@ -73,8 +73,8 @@ pub fn ln_ln_two<N: RealField>() -> N {
/// ///
/// * [`ln_ln_two`](fn.ln_ln_two.html) /// * [`ln_ln_two`](fn.ln_ln_two.html)
/// * [`ln_two`](fn.ln_two.html) /// * [`ln_two`](fn.ln_two.html)
pub fn ln_ten<N: RealField>() -> N { pub fn ln_ten<T: RealField>() -> T {
N::ln_10() T::ln_10()
} }
/// Returns `ln(2)`. /// Returns `ln(2)`.
@ -83,8 +83,8 @@ pub fn ln_ten<N: RealField>() -> N {
/// ///
/// * [`ln_ln_two`](fn.ln_ln_two.html) /// * [`ln_ln_two`](fn.ln_ln_two.html)
/// * [`ln_ten`](fn.ln_ten.html) /// * [`ln_ten`](fn.ln_ten.html)
pub fn ln_two<N: RealField>() -> N { pub fn ln_two<T: RealField>() -> T {
N::ln_2() T::ln_2()
} }
/// Returns `1`. /// Returns `1`.
@ -106,13 +106,13 @@ pub use na::one;
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi`](fn.two_pi.html)
pub fn one_over_pi<N: RealField>() -> N { pub fn one_over_pi<T: RealField>() -> T {
N::frac_1_pi() T::frac_1_pi()
} }
/// Returns `1 / sqrt(2)`. /// Returns `1 / sqrt(2)`.
pub fn one_over_root_two<N: RealField>() -> N { pub fn one_over_root_two<T: RealField>() -> T {
N::one() / root_two() T::one() / root_two()
} }
/// Returns `1 / (2pi)`. /// Returns `1 / (2pi)`.
@ -131,8 +131,8 @@ pub fn one_over_root_two<N: RealField>() -> N {
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi`](fn.two_pi.html)
pub fn one_over_two_pi<N: RealField>() -> N { pub fn one_over_two_pi<T: RealField>() -> T {
N::frac_1_pi() * na::convert(0.5) T::frac_1_pi() * na::convert(0.5)
} }
/// Returns `pi / 4`. /// Returns `pi / 4`.
@ -151,8 +151,8 @@ pub fn one_over_two_pi<N: RealField>() -> N {
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi`](fn.two_pi.html)
pub fn quarter_pi<N: RealField>() -> N { pub fn quarter_pi<T: RealField>() -> T {
N::frac_pi_4() T::frac_pi_4()
} }
/// Returns `sqrt(5)`. /// Returns `sqrt(5)`.
@ -161,8 +161,8 @@ pub fn quarter_pi<N: RealField>() -> N {
/// ///
/// * [`root_three`](fn.root_three.html) /// * [`root_three`](fn.root_three.html)
/// * [`root_two`](fn.root_two.html) /// * [`root_two`](fn.root_two.html)
pub fn root_five<N: RealField>() -> N { pub fn root_five<T: RealField>() -> T {
na::convert::<_, N>(5.0).sqrt() na::convert::<_, T>(5.0).sqrt()
} }
/// Returns `sqrt(pi / 2)`. /// Returns `sqrt(pi / 2)`.
@ -181,13 +181,13 @@ pub fn root_five<N: RealField>() -> N {
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi`](fn.two_pi.html)
pub fn root_half_pi<N: RealField>() -> N { pub fn root_half_pi<T: RealField>() -> T {
(N::pi() / na::convert(2.0)).sqrt() (T::pi() / na::convert(2.0)).sqrt()
} }
/// Returns `sqrt(ln(4))`. /// Returns `sqrt(ln(4))`.
pub fn root_ln_four<N: RealField>() -> N { pub fn root_ln_four<T: RealField>() -> T {
na::convert::<_, N>(4.0).ln().sqrt() na::convert::<_, T>(4.0).ln().sqrt()
} }
/// Returns the square root of pi. /// Returns the square root of pi.
@ -206,8 +206,8 @@ pub fn root_ln_four<N: RealField>() -> N {
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi`](fn.two_pi.html)
pub fn root_pi<N: RealField>() -> N { pub fn root_pi<T: RealField>() -> T {
N::pi().sqrt() T::pi().sqrt()
} }
/// Returns the square root of 3. /// Returns the square root of 3.
@ -216,8 +216,8 @@ pub fn root_pi<N: RealField>() -> N {
/// ///
/// * [`root_five`](fn.root_five.html) /// * [`root_five`](fn.root_five.html)
/// * [`root_two`](fn.root_two.html) /// * [`root_two`](fn.root_two.html)
pub fn root_three<N: RealField>() -> N { pub fn root_three<T: RealField>() -> T {
na::convert::<_, N>(3.0).sqrt() na::convert::<_, T>(3.0).sqrt()
} }
/// Returns the square root of 2. /// Returns the square root of 2.
@ -226,9 +226,9 @@ pub fn root_three<N: RealField>() -> N {
/// ///
/// * [`root_five`](fn.root_five.html) /// * [`root_five`](fn.root_five.html)
/// * [`root_three`](fn.root_three.html) /// * [`root_three`](fn.root_three.html)
pub fn root_two<N: RealField>() -> N { pub fn root_two<T: RealField>() -> T {
// TODO: there should be a crate::sqrt_2() on the RealField trait. // TODO: there should be a crate::sqrt_2() on the RealField trait.
na::convert::<_, N>(2.0).sqrt() na::convert::<_, T>(2.0).sqrt()
} }
/// Returns the square root of 2pi. /// Returns the square root of 2pi.
@ -247,8 +247,8 @@ pub fn root_two<N: RealField>() -> N {
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi`](fn.two_pi.html)
pub fn root_two_pi<N: RealField>() -> N { pub fn root_two_pi<T: RealField>() -> T {
N::two_pi().sqrt() T::two_pi().sqrt()
} }
/// Returns `1 / 3`. /// Returns `1 / 3`.
@ -256,7 +256,7 @@ pub fn root_two_pi<N: RealField>() -> N {
/// # See also: /// # See also:
/// ///
/// * [`two_thirds`](fn.two_thirds.html) /// * [`two_thirds`](fn.two_thirds.html)
pub fn third<N: RealField>() -> N { pub fn third<T: RealField>() -> T {
na::convert(1.0 / 3.0) na::convert(1.0 / 3.0)
} }
@ -276,8 +276,8 @@ pub fn third<N: RealField>() -> N {
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi`](fn.two_pi.html)
pub fn three_over_two_pi<N: RealField>() -> N { pub fn three_over_two_pi<T: RealField>() -> T {
na::convert::<_, N>(3.0) / N::two_pi() na::convert::<_, T>(3.0) / T::two_pi()
} }
/// Returns `2 / pi`. /// Returns `2 / pi`.
@ -295,8 +295,8 @@ pub fn three_over_two_pi<N: RealField>() -> N {
/// * [`three_over_two_pi`](fn.three_over_two_pi.html) /// * [`three_over_two_pi`](fn.three_over_two_pi.html)
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi`](fn.two_pi.html)
pub fn two_over_pi<N: RealField>() -> N { pub fn two_over_pi<T: RealField>() -> T {
N::frac_2_pi() T::frac_2_pi()
} }
/// Returns `2 / sqrt(pi)`. /// Returns `2 / sqrt(pi)`.
@ -315,8 +315,8 @@ pub fn two_over_pi<N: RealField>() -> N {
/// * [`three_over_two_pi`](fn.three_over_two_pi.html) /// * [`three_over_two_pi`](fn.three_over_two_pi.html)
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_pi`](fn.two_pi.html) /// * [`two_pi`](fn.two_pi.html)
pub fn two_over_root_pi<N: RealField>() -> N { pub fn two_over_root_pi<T: RealField>() -> T {
N::frac_2_sqrt_pi() T::frac_2_sqrt_pi()
} }
/// Returns `2pi`. /// Returns `2pi`.
@ -335,8 +335,8 @@ pub fn two_over_root_pi<N: RealField>() -> N {
/// * [`three_over_two_pi`](fn.three_over_two_pi.html) /// * [`three_over_two_pi`](fn.three_over_two_pi.html)
/// * [`two_over_pi`](fn.two_over_pi.html) /// * [`two_over_pi`](fn.two_over_pi.html)
/// * [`two_over_root_pi`](fn.two_over_root_pi.html) /// * [`two_over_root_pi`](fn.two_over_root_pi.html)
pub fn two_pi<N: RealField>() -> N { pub fn two_pi<T: RealField>() -> T {
N::two_pi() T::two_pi()
} }
/// Returns `2 / 3`. /// Returns `2 / 3`.
@ -344,7 +344,7 @@ pub fn two_pi<N: RealField>() -> N {
/// # See also: /// # See also:
/// ///
/// * [`third`](fn.third.html) /// * [`third`](fn.third.html)
pub fn two_thirds<N: RealField>() -> N { pub fn two_thirds<T: RealField>() -> T {
na::convert(2.0 / 3.0) na::convert(2.0 / 3.0)
} }

View File

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

View File

@ -1,10 +1,9 @@
//use na::{Scalar, DefaultAllocator}; //use na::Scalar;
//
// //
//use crate::traits::{Alloc, Dimension};
//use crate::aliases::TVec; //use crate::aliases::TVec;
//pub fn iround<N: Scalar, D: Dimension>(x: &TVec<N, D>) -> TVec<i32, D> //pub fn iround<T: Scalar, const D: usize>(x: &TVec<T, D>) -> TVec<i32, D> {
// where DefaultAllocator: Alloc<N, D> {
// x.map(|x| x.round()) // x.map(|x| x.round())
//} //}
// //
@ -12,7 +11,6 @@
// unimplemented!() // unimplemented!()
//} //}
// //
//pub fn uround<N: Scalar, D: Dimension>(x: &TVec<N, D>) -> TVec<u32, D> //pub fn uround<T: Scalar, const D: usize>(x: &TVec<T, D>) -> TVec<u32, D> {
// where DefaultAllocator: Alloc<N, D> {
// unimplemented!() // unimplemented!()
//} //}

View File

@ -1,7 +1,6 @@
use na::{DefaultAllocator, Scalar}; use na::Scalar;
use crate::aliases::{TMat, TVec}; use crate::aliases::{TMat, TVec};
use crate::traits::{Alloc, Dimension};
/// The `index`-th column of the matrix `m`. /// The `index`-th column of the matrix `m`.
/// ///
@ -10,10 +9,10 @@ use crate::traits::{Alloc, Dimension};
/// * [`row`](fn.row.html) /// * [`row`](fn.row.html)
/// * [`set_column`](fn.set_column.html) /// * [`set_column`](fn.set_column.html)
/// * [`set_row`](fn.set_row.html) /// * [`set_row`](fn.set_row.html)
pub fn column<N: Scalar, R: Dimension, C: Dimension>(m: &TMat<N, R, C>, index: usize) -> TVec<N, R> pub fn column<T: Scalar, const R: usize, const C: usize>(
where m: &TMat<T, R, C>,
DefaultAllocator: Alloc<N, R, C>, index: usize,
{ ) -> TVec<T, R> {
m.column(index).into_owned() m.column(index).into_owned()
} }
@ -24,14 +23,11 @@ where
/// * [`column`](fn.column.html) /// * [`column`](fn.column.html)
/// * [`row`](fn.row.html) /// * [`row`](fn.row.html)
/// * [`set_row`](fn.set_row.html) /// * [`set_row`](fn.set_row.html)
pub fn set_column<N: Scalar, R: Dimension, C: Dimension>( pub fn set_column<T: Scalar, const R: usize, const C: usize>(
m: &TMat<N, R, C>, m: &TMat<T, R, C>,
index: usize, index: usize,
x: &TVec<N, R>, x: &TVec<T, R>,
) -> TMat<N, R, C> ) -> TMat<T, R, C> {
where
DefaultAllocator: Alloc<N, R, C>,
{
let mut res = m.clone(); let mut res = m.clone();
res.set_column(index, x); res.set_column(index, x);
res res
@ -44,10 +40,10 @@ where
/// * [`column`](fn.column.html) /// * [`column`](fn.column.html)
/// * [`set_column`](fn.set_column.html) /// * [`set_column`](fn.set_column.html)
/// * [`set_row`](fn.set_row.html) /// * [`set_row`](fn.set_row.html)
pub fn row<N: Scalar, R: Dimension, C: Dimension>(m: &TMat<N, R, C>, index: usize) -> TVec<N, C> pub fn row<T: Scalar, const R: usize, const C: usize>(
where m: &TMat<T, R, C>,
DefaultAllocator: Alloc<N, R, C>, index: usize,
{ ) -> TVec<T, C> {
m.row(index).into_owned().transpose() m.row(index).into_owned().transpose()
} }
@ -58,14 +54,11 @@ where
/// * [`column`](fn.column.html) /// * [`column`](fn.column.html)
/// * [`row`](fn.row.html) /// * [`row`](fn.row.html)
/// * [`set_column`](fn.set_column.html) /// * [`set_column`](fn.set_column.html)
pub fn set_row<N: Scalar, R: Dimension, C: Dimension>( pub fn set_row<T: Scalar, const R: usize, const C: usize>(
m: &TMat<N, R, C>, m: &TMat<T, R, C>,
index: usize, index: usize,
x: &TVec<N, C>, x: &TVec<T, C>,
) -> TMat<N, R, C> ) -> TMat<T, R, C> {
where
DefaultAllocator: Alloc<N, R, C>,
{
let mut res = m.clone(); let mut res = m.clone();
res.set_row(index, &x.transpose()); res.set_row(index, &x.transpose());
res res

View File

@ -1,22 +1,15 @@
use na::{DefaultAllocator, RealField}; use na::RealField;
use crate::aliases::TMat; use crate::aliases::TMat;
use crate::traits::{Alloc, Dimension};
/// Fast matrix inverse for affine matrix. /// Fast matrix inverse for affine matrix.
pub fn affine_inverse<N: RealField, D: Dimension>(m: TMat<N, D, D>) -> TMat<N, D, D> pub fn affine_inverse<T: RealField, const D: usize>(m: TMat<T, D, D>) -> TMat<T, D, D> {
where
DefaultAllocator: Alloc<N, D, D>,
{
// TODO: this should be optimized. // TODO: this should be optimized.
m.try_inverse().unwrap_or_else(TMat::<_, D, D>::zeros) m.try_inverse().unwrap_or_else(TMat::<_, D, D>::zeros)
} }
/// Compute the transpose of the inverse of a matrix. /// Compute the transpose of the inverse of a matrix.
pub fn inverse_transpose<N: RealField, D: Dimension>(m: TMat<N, D, D>) -> TMat<N, D, D> pub fn inverse_transpose<T: RealField, const D: usize>(m: TMat<T, D, D>) -> TMat<T, D, D> {
where
DefaultAllocator: Alloc<N, D, D>,
{
m.try_inverse() m.try_inverse()
.unwrap_or_else(TMat::<_, D, D>::zeros) .unwrap_or_else(TMat::<_, D, D>::zeros)
.transpose() .transpose()

View File

@ -1,9 +1,7 @@
use na::{Scalar, RealField, DefaultAllocator, U3, U4}; use na::{DefaultAllocator, RealField, Scalar, U3, U4};
use crate::traits::{Alloc, Dimension};
use crate::aliases::*; use crate::aliases::*;
pub fn packF2x11_1x10(v: &Vec3) -> i32 { pub fn packF2x11_1x10(v: &Vec3) -> i32 {
unimplemented!() unimplemented!()
} }
@ -12,8 +10,10 @@ pub fn packF3x9_E1x5(v: &Vec3) -> i32 {
unimplemented!() unimplemented!()
} }
pub fn packHalf<D: Dimension>(v: &TVec<f32, D>) -> TVec<u16, D> pub fn packHalf<const D: usize>(v: &TVec<f32, D>) -> TVec<u16, D>
where DefaultAllocator: Alloc<u16, D> { where
DefaultAllocator: Alloc<u16, D>,
{
unimplemented!() unimplemented!()
} }
@ -49,12 +49,14 @@ pub fn packInt4x8(v: &I8Vec4) -> i32 {
unimplemented!() unimplemented!()
} }
pub fn packRGBM<N: Scalar>(rgb: &TVec3<N>) -> TVec4<N> { pub fn packRGBM<T: Scalar>(rgb: &TVec3<T>) -> TVec4<T> {
unimplemented!() unimplemented!()
} }
pub fn packSnorm<I: Scalar, N: RealField, D: Dimension>(v: TVec<N, D>) -> TVec<I, D> pub fn packSnorm<I: Scalar, T: RealField, const D: usize>(v: TVec<T, D>) -> TVec<I, D>
where DefaultAllocator: Alloc<N, D> + Alloc<I, D> { where
DefaultAllocator: Alloc<T, D> + Alloc<I, D>,
{
unimplemented!() unimplemented!()
} }
@ -102,8 +104,10 @@ pub fn packUint4x8(v: &U8Vec4) -> i32 {
unimplemented!() unimplemented!()
} }
pub fn packUnorm<UI: Scalar, N: RealField, D: Dimension>(v: &TVec<N, D>) -> TVec<UI, D> pub fn packUnorm<UI: Scalar, T: RealField, const D: usize>(v: &TVec<T, D>) -> TVec<UI, D>
where DefaultAllocator: Alloc<N, D> + Alloc<UI, D> { where
DefaultAllocator: Alloc<T, D> + Alloc<UI, D>,
{
unimplemented!() unimplemented!()
} }
@ -155,8 +159,7 @@ pub fn unpackF3x9_E1x5(p: i32) -> Vec3 {
unimplemented!() unimplemented!()
} }
pub fn unpackHalf<N: Scalar, D: Dimension>(p: TVec<i16, D>) -> TVec<N, D> pub fn unpackHalf<T: Scalar, const D: usize>(p: TVec<i16, D>) -> TVec<T, D> {
where DefaultAllocator: Alloc<N, D> {
unimplemented!() unimplemented!()
} }
@ -192,12 +195,14 @@ pub fn unpackInt4x8(p: i32) -> I8Vec4 {
unimplemented!() unimplemented!()
} }
pub fn unpackRGBM<N: Scalar>(rgbm: &TVec4<N>) -> TVec3<N> { pub fn unpackRGBM<T: Scalar>(rgbm: &TVec4<T>) -> TVec3<T> {
unimplemented!() unimplemented!()
} }
pub fn unpackSnorm<I: Scalar, N: RealField, D: Dimension>(v: &TVec<I, D>) -> TVec<N, D> pub fn unpackSnorm<I: Scalar, T: RealField, const D: usize>(v: &TVec<I, D>) -> TVec<T, D>
where DefaultAllocator: Alloc<N, D> + Alloc<I, D> { where
DefaultAllocator: Alloc<T, D> + Alloc<I, D>,
{
unimplemented!() unimplemented!()
} }
@ -245,8 +250,10 @@ pub fn unpackUint4x8(p: i32) -> U8Vec4 {
unimplemented!() unimplemented!()
} }
pub fn unpackUnorm<UI: Scalar, N: RealField, D: Dimension>(v: &TVec<UI, D>) -> TVec<N, D> pub fn unpackUnorm<UI: Scalar, T: RealField, const D: usize>(v: &TVec<UI, D>) -> TVec<T, D>
where DefaultAllocator: Alloc<N, D> + Alloc<UI, D> { where
DefaultAllocator: Alloc<T, D> + Alloc<UI, D>,
{
unimplemented!() unimplemented!()
} }

View File

@ -1,36 +1,36 @@
use na::{RealField, UnitQuaternion, U4}; use na::{RealField, UnitQuaternion};
use crate::aliases::{Qua, TMat4, TVec, TVec3}; use crate::aliases::{Qua, TMat4, TVec, TVec3};
/// Euler angles of the quaternion `q` as (pitch, yaw, roll). /// Euler angles of the quaternion `q` as (pitch, yaw, roll).
pub fn quat_euler_angles<N: RealField>(x: &Qua<N>) -> TVec3<N> { pub fn quat_euler_angles<T: RealField>(x: &Qua<T>) -> TVec3<T> {
let q = UnitQuaternion::new_unchecked(*x); let q = UnitQuaternion::new_unchecked(*x);
let a = q.euler_angles(); let a = q.euler_angles();
TVec3::new(a.2, a.1, a.0) TVec3::new(a.2, a.1, a.0)
} }
/// Component-wise `>` comparison between two quaternions. /// Component-wise `>` comparison between two quaternions.
pub fn quat_greater_than<N: RealField>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> { pub fn quat_greater_than<T: RealField>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
crate::greater_than(&x.coords, &y.coords) crate::greater_than(&x.coords, &y.coords)
} }
/// Component-wise `>=` comparison between two quaternions. /// Component-wise `>=` comparison between two quaternions.
pub fn quat_greater_than_equal<N: RealField>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> { pub fn quat_greater_than_equal<T: RealField>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
crate::greater_than_equal(&x.coords, &y.coords) crate::greater_than_equal(&x.coords, &y.coords)
} }
/// Component-wise `<` comparison between two quaternions. /// Component-wise `<` comparison between two quaternions.
pub fn quat_less_than<N: RealField>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> { pub fn quat_less_than<T: RealField>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
crate::less_than(&x.coords, &y.coords) crate::less_than(&x.coords, &y.coords)
} }
/// Component-wise `<=` comparison between two quaternions. /// Component-wise `<=` comparison between two quaternions.
pub fn quat_less_than_equal<N: RealField>(x: &Qua<N>, y: &Qua<N>) -> TVec<bool, U4> { pub fn quat_less_than_equal<T: RealField>(x: &Qua<T>, y: &Qua<T>) -> TVec<bool, 4> {
crate::less_than_equal(&x.coords, &y.coords) crate::less_than_equal(&x.coords, &y.coords)
} }
/// Convert a quaternion to a rotation matrix in homogeneous coordinates. /// Convert a quaternion to a rotation matrix in homogeneous coordinates.
pub fn quat_cast<N: RealField>(x: &Qua<N>) -> TMat4<N> { pub fn quat_cast<T: RealField>(x: &Qua<T>) -> TMat4<T> {
crate::quat_to_mat4(x) crate::quat_to_mat4(x)
} }
@ -41,34 +41,34 @@ pub fn quat_cast<N: RealField>(x: &Qua<N>) -> TMat4<N> {
/// * `direction` - Direction vector point at where to look /// * `direction` - Direction vector point at where to look
/// * `up` - Object up vector /// * `up` - Object up vector
/// ///
pub fn quat_look_at<N: RealField>(direction: &TVec3<N>, up: &TVec3<N>) -> Qua<N> { pub fn quat_look_at<T: RealField>(direction: &TVec3<T>, up: &TVec3<T>) -> Qua<T> {
quat_look_at_rh(direction, up) quat_look_at_rh(direction, up)
} }
/// Computes a left-handed look-at quaternion (equivalent to a left-handed look-at matrix). /// Computes a left-handed look-at quaternion (equivalent to a left-handed look-at matrix).
pub fn quat_look_at_lh<N: RealField>(direction: &TVec3<N>, up: &TVec3<N>) -> Qua<N> { pub fn quat_look_at_lh<T: RealField>(direction: &TVec3<T>, up: &TVec3<T>) -> Qua<T> {
UnitQuaternion::look_at_lh(direction, up).into_inner() UnitQuaternion::look_at_lh(direction, up).into_inner()
} }
/// Computes a right-handed look-at quaternion (equivalent to a right-handed look-at matrix). /// Computes a right-handed look-at quaternion (equivalent to a right-handed look-at matrix).
pub fn quat_look_at_rh<N: RealField>(direction: &TVec3<N>, up: &TVec3<N>) -> Qua<N> { pub fn quat_look_at_rh<T: RealField>(direction: &TVec3<T>, up: &TVec3<T>) -> Qua<T> {
UnitQuaternion::look_at_rh(direction, up).into_inner() UnitQuaternion::look_at_rh(direction, up).into_inner()
} }
/// The "roll" Euler angle of the quaternion `x` assumed to be normalized. /// The "roll" Euler angle of the quaternion `x` assumed to be normalized.
pub fn quat_roll<N: RealField>(x: &Qua<N>) -> N { pub fn quat_roll<T: RealField>(x: &Qua<T>) -> T {
// TODO: optimize this. // TODO: optimize this.
quat_euler_angles(x).z quat_euler_angles(x).z
} }
/// The "yaw" Euler angle of the quaternion `x` assumed to be normalized. /// The "yaw" Euler angle of the quaternion `x` assumed to be normalized.
pub fn quat_yaw<N: RealField>(x: &Qua<N>) -> N { pub fn quat_yaw<T: RealField>(x: &Qua<T>) -> T {
// TODO: optimize this. // TODO: optimize this.
quat_euler_angles(x).y quat_euler_angles(x).y
} }
/// The "pitch" Euler angle of the quaternion `x` assumed to be normalized. /// The "pitch" Euler angle of the quaternion `x` assumed to be normalized.
pub fn quat_pitch<N: RealField>(x: &Qua<N>) -> N { pub fn quat_pitch<T: RealField>(x: &Qua<T>) -> T {
// TODO: optimize this. // TODO: optimize this.
quat_euler_angles(x).x quat_euler_angles(x).x
} }

View File

@ -1,15 +1,16 @@
use na::{Scalar, RealField, U3, DefaultAllocator}; use na::{DefaultAllocator, RealField, Scalar, U3};
use crate::traits::{Number, Alloc, Dimension};
use crate::aliases::TVec; use crate::aliases::TVec;
use crate::traits::{Alloc, Dimension, Number};
pub fn ceilMultiple<T>(v: T, Multiple: T) -> T { pub fn ceilMultiple<T>(v: T, Multiple: T) -> T {
unimplemented!() unimplemented!()
} }
pub fn ceilMultiple2<N: Scalar, D: Dimension>(v: &TVec<N, D>, Multiple: &TVec<N, D>) -> TVec<N, D> pub fn ceilMultiple2<T: Scalar, const D: usize>(v: &TVec<T, D>, Multiple: &TVec<T, D>) -> TVec<T, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<T, D>,
{
unimplemented!() unimplemented!()
} }
@ -17,8 +18,10 @@ pub fn ceilPowerOfTwo<IU>(v: IU) -> IU {
unimplemented!() unimplemented!()
} }
pub fn ceilPowerOfTwo2<N: Scalar, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn ceilPowerOfTwo2<T: Scalar, const D: usize>(v: &TVec<T, D>) -> TVec<T, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<T, D>,
{
unimplemented!() unimplemented!()
} }
@ -26,8 +29,13 @@ pub fn floorMultiple<T>(v: T, Multiple: T) -> T {
unimplemented!() unimplemented!()
} }
pub fn floorMultiple2<N: Scalar, D: Dimension>(v: &TVec<N, D>, Multiple: &TVec<N, D>) -> TVec<N, D> pub fn floorMultiple2<T: Scalar, const D: usize>(
where DefaultAllocator: Alloc<N, D> { v: &TVec<T, D>,
Multiple: &TVec<T, D>,
) -> TVec<T, D>
where
DefaultAllocator: Alloc<T, D>,
{
unimplemented!() unimplemented!()
} }
@ -35,8 +43,10 @@ pub fn floorPowerOfTwo<IU>(v: IU) -> IU {
unimplemented!() unimplemented!()
} }
pub fn floorPowerOfTwo2<N: Scalar, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn floorPowerOfTwo2<T: Scalar, const D: usize>(v: &TVec<T, D>) -> TVec<T, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<T, D>,
{
unimplemented!() unimplemented!()
} }
@ -44,13 +54,20 @@ pub fn isMultiple<IU>(v: IU, Multiple: IU) -> bool {
unimplemented!() unimplemented!()
} }
pub fn isMultiple2<N: Scalar, D: Dimension>(v: &TVec<N, D>,Multiple: N) -> TVec<bool, D> pub fn isMultiple2<T: Scalar, const D: usize>(v: &TVec<T, D>, Multiple: T) -> TVec<bool, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<T, D>,
{
unimplemented!() unimplemented!()
} }
pub fn isMultiple3<N: Scalar, D: Dimension>(v: &TVec<N, D>, Multiple: &TVec<N, D>) -> TVec<bool, D> pub fn isMultiple3<T: Scalar, const D: usize>(
where DefaultAllocator: Alloc<N, D> { v: &TVec<T, D>,
Multiple: &TVec<T, D>,
) -> TVec<bool, D>
where
DefaultAllocator: Alloc<T, D>,
{
unimplemented!() unimplemented!()
} }
@ -58,8 +75,10 @@ pub fn isPowerOfTwo2<IU>(v: IU) -> bool {
unimplemented!() unimplemented!()
} }
pub fn isPowerOfTwo<N: Scalar, D: Dimension>(v: &TVec<N, D>) -> TVec<bool, D> pub fn isPowerOfTwo<T: Scalar, const D: usize>(v: &TVec<T, D>) -> TVec<bool, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<T, D>,
{
unimplemented!() unimplemented!()
} }
@ -67,8 +86,13 @@ pub fn roundMultiple<T>(v: T, Multiple: T) -> T {
unimplemented!() unimplemented!()
} }
pub fn roundMultiple2<N: Scalar, D: Dimension>(v: &TVec<N, D>, Multiple: &TVec<N, D>) -> TVec<N, D> pub fn roundMultiple2<T: Scalar, const D: usize>(
where DefaultAllocator: Alloc<N, D> { v: &TVec<T, D>,
Multiple: &TVec<T, D>,
) -> TVec<T, D>
where
DefaultAllocator: Alloc<T, D>,
{
unimplemented!() unimplemented!()
} }
@ -76,7 +100,9 @@ pub fn roundPowerOfTwo<IU>(v: IU) -> IU {
unimplemented!() unimplemented!()
} }
pub fn roundPowerOfTwo2<N: Scalar, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn roundPowerOfTwo2<T: Scalar, const D: usize>(v: &TVec<T, D>) -> TVec<T, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<T, D>,
{
unimplemented!() unimplemented!()
} }

View File

@ -1,81 +1,81 @@
use na::{DefaultAllocator, Quaternion, RealField, Scalar}; use na::{Quaternion, RealField, Scalar};
use crate::aliases::{ use crate::aliases::{
Qua, TMat, TMat2, TMat2x3, TMat2x4, TMat3, TMat3x2, TMat3x4, TMat4, TMat4x2, TMat4x3, TVec1, Qua, TMat, TMat2, TMat2x3, TMat2x4, TMat3, TMat3x2, TMat3x4, TMat4, TMat4x2, TMat4x3, TVec1,
TVec2, TVec3, TVec4, TVec2, TVec3, TVec4,
}; };
use crate::traits::{Alloc, Dimension, Number}; use crate::traits::Number;
/// Creates a 2x2 matrix from a slice arranged in column-major order. /// Creates a 2x2 matrix from a slice arranged in column-major order.
pub fn make_mat2<N: Scalar>(ptr: &[N]) -> TMat2<N> { pub fn make_mat2<T: Scalar>(ptr: &[T]) -> TMat2<T> {
TMat2::from_column_slice(ptr) TMat2::from_column_slice(ptr)
} }
/// Creates a 2x2 matrix from a slice arranged in column-major order. /// Creates a 2x2 matrix from a slice arranged in column-major order.
pub fn make_mat2x2<N: Scalar>(ptr: &[N]) -> TMat2<N> { pub fn make_mat2x2<T: Scalar>(ptr: &[T]) -> TMat2<T> {
TMat2::from_column_slice(ptr) TMat2::from_column_slice(ptr)
} }
/// Creates a 2x3 matrix from a slice arranged in column-major order. /// Creates a 2x3 matrix from a slice arranged in column-major order.
pub fn make_mat2x3<N: Scalar>(ptr: &[N]) -> TMat2x3<N> { pub fn make_mat2x3<T: Scalar>(ptr: &[T]) -> TMat2x3<T> {
TMat2x3::from_column_slice(ptr) TMat2x3::from_column_slice(ptr)
} }
/// Creates a 2x4 matrix from a slice arranged in column-major order. /// Creates a 2x4 matrix from a slice arranged in column-major order.
pub fn make_mat2x4<N: Scalar>(ptr: &[N]) -> TMat2x4<N> { pub fn make_mat2x4<T: Scalar>(ptr: &[T]) -> TMat2x4<T> {
TMat2x4::from_column_slice(ptr) TMat2x4::from_column_slice(ptr)
} }
/// Creates a 3 matrix from a slice arranged in column-major order. /// Creates a 3 matrix from a slice arranged in column-major order.
pub fn make_mat3<N: Scalar>(ptr: &[N]) -> TMat3<N> { pub fn make_mat3<T: Scalar>(ptr: &[T]) -> TMat3<T> {
TMat3::from_column_slice(ptr) TMat3::from_column_slice(ptr)
} }
/// Creates a 3x2 matrix from a slice arranged in column-major order. /// Creates a 3x2 matrix from a slice arranged in column-major order.
pub fn make_mat3x2<N: Scalar>(ptr: &[N]) -> TMat3x2<N> { pub fn make_mat3x2<T: Scalar>(ptr: &[T]) -> TMat3x2<T> {
TMat3x2::from_column_slice(ptr) TMat3x2::from_column_slice(ptr)
} }
/// Creates a 3x3 matrix from a slice arranged in column-major order. /// Creates a 3x3 matrix from a slice arranged in column-major order.
pub fn make_mat3x3<N: Scalar>(ptr: &[N]) -> TMat3<N> { pub fn make_mat3x3<T: Scalar>(ptr: &[T]) -> TMat3<T> {
TMat3::from_column_slice(ptr) TMat3::from_column_slice(ptr)
} }
/// Creates a 3x4 matrix from a slice arranged in column-major order. /// Creates a 3x4 matrix from a slice arranged in column-major order.
pub fn make_mat3x4<N: Scalar>(ptr: &[N]) -> TMat3x4<N> { pub fn make_mat3x4<T: Scalar>(ptr: &[T]) -> TMat3x4<T> {
TMat3x4::from_column_slice(ptr) TMat3x4::from_column_slice(ptr)
} }
/// Creates a 4x4 matrix from a slice arranged in column-major order. /// Creates a 4x4 matrix from a slice arranged in column-major order.
pub fn make_mat4<N: Scalar>(ptr: &[N]) -> TMat4<N> { pub fn make_mat4<T: Scalar>(ptr: &[T]) -> TMat4<T> {
TMat4::from_column_slice(ptr) TMat4::from_column_slice(ptr)
} }
/// Creates a 4x2 matrix from a slice arranged in column-major order. /// Creates a 4x2 matrix from a slice arranged in column-major order.
pub fn make_mat4x2<N: Scalar>(ptr: &[N]) -> TMat4x2<N> { pub fn make_mat4x2<T: Scalar>(ptr: &[T]) -> TMat4x2<T> {
TMat4x2::from_column_slice(ptr) TMat4x2::from_column_slice(ptr)
} }
/// Creates a 4x3 matrix from a slice arranged in column-major order. /// Creates a 4x3 matrix from a slice arranged in column-major order.
pub fn make_mat4x3<N: Scalar>(ptr: &[N]) -> TMat4x3<N> { pub fn make_mat4x3<T: Scalar>(ptr: &[T]) -> TMat4x3<T> {
TMat4x3::from_column_slice(ptr) TMat4x3::from_column_slice(ptr)
} }
/// Creates a 4x4 matrix from a slice arranged in column-major order. /// Creates a 4x4 matrix from a slice arranged in column-major order.
pub fn make_mat4x4<N: Scalar>(ptr: &[N]) -> TMat4<N> { pub fn make_mat4x4<T: Scalar>(ptr: &[T]) -> TMat4<T> {
TMat4::from_column_slice(ptr) TMat4::from_column_slice(ptr)
} }
/// Converts a 2x2 matrix to a 3x3 matrix. /// Converts a 2x2 matrix to a 3x3 matrix.
pub fn mat2_to_mat3<N: Number>(m: &TMat2<N>) -> TMat3<N> { pub fn mat2_to_mat3<T: Number>(m: &TMat2<T>) -> TMat3<T> {
let _0 = N::zero(); let _0 = T::zero();
let _1 = N::one(); let _1 = T::one();
TMat3::new(m.m11, m.m12, _0, m.m21, m.m22, _0, _0, _0, _1) TMat3::new(m.m11, m.m12, _0, m.m21, m.m22, _0, _0, _0, _1)
} }
/// Converts a 3x3 matrix to a 2x2 matrix. /// Converts a 3x3 matrix to a 2x2 matrix.
pub fn mat3_to_mat2<N: Scalar>(m: &TMat3<N>) -> TMat2<N> { pub fn mat3_to_mat2<T: Scalar>(m: &TMat3<T>) -> TMat2<T> {
TMat2::new( TMat2::new(
m.m11.inlined_clone(), m.m11.inlined_clone(),
m.m12.inlined_clone(), m.m12.inlined_clone(),
@ -85,9 +85,9 @@ pub fn mat3_to_mat2<N: Scalar>(m: &TMat3<N>) -> TMat2<N> {
} }
/// Converts a 3x3 matrix to a 4x4 matrix. /// Converts a 3x3 matrix to a 4x4 matrix.
pub fn mat3_to_mat4<N: Number>(m: &TMat3<N>) -> TMat4<N> { pub fn mat3_to_mat4<T: Number>(m: &TMat3<T>) -> TMat4<T> {
let _0 = N::zero(); let _0 = T::zero();
let _1 = N::one(); let _1 = T::one();
TMat4::new( TMat4::new(
m.m11, m.m12, m.m13, _0, m.m21, m.m22, m.m23, _0, m.m31, m.m32, m.m33, _0, _0, _0, _0, _1, m.m11, m.m12, m.m13, _0, m.m21, m.m22, m.m23, _0, m.m31, m.m32, m.m33, _0, _0, _0, _0, _1,
@ -95,7 +95,7 @@ pub fn mat3_to_mat4<N: Number>(m: &TMat3<N>) -> TMat4<N> {
} }
/// Converts a 4x4 matrix to a 3x3 matrix. /// Converts a 4x4 matrix to a 3x3 matrix.
pub fn mat4_to_mat3<N: Scalar>(m: &TMat4<N>) -> TMat3<N> { pub fn mat4_to_mat3<T: Scalar>(m: &TMat4<T>) -> TMat3<T> {
TMat3::new( TMat3::new(
m.m11.inlined_clone(), m.m11.inlined_clone(),
m.m12.inlined_clone(), m.m12.inlined_clone(),
@ -110,9 +110,9 @@ pub fn mat4_to_mat3<N: Scalar>(m: &TMat4<N>) -> TMat3<N> {
} }
/// Converts a 2x2 matrix to a 4x4 matrix. /// Converts a 2x2 matrix to a 4x4 matrix.
pub fn mat2_to_mat4<N: Number>(m: &TMat2<N>) -> TMat4<N> { pub fn mat2_to_mat4<T: Number>(m: &TMat2<T>) -> TMat4<T> {
let _0 = N::zero(); let _0 = T::zero();
let _1 = N::one(); let _1 = T::one();
TMat4::new( TMat4::new(
m.m11, m.m12, _0, _0, m.m21, m.m22, _0, _0, _0, _0, _1, _0, _0, _0, _0, _1, m.m11, m.m12, _0, _0, m.m21, m.m22, _0, _0, _0, _0, _1, _0, _0, _0, _0, _1,
@ -120,7 +120,7 @@ pub fn mat2_to_mat4<N: Number>(m: &TMat2<N>) -> TMat4<N> {
} }
/// Converts a 4x4 matrix to a 2x2 matrix. /// Converts a 4x4 matrix to a 2x2 matrix.
pub fn mat4_to_mat2<N: Scalar>(m: &TMat4<N>) -> TMat2<N> { pub fn mat4_to_mat2<T: Scalar>(m: &TMat4<T>) -> TMat2<T> {
TMat2::new( TMat2::new(
m.m11.inlined_clone(), m.m11.inlined_clone(),
m.m12.inlined_clone(), m.m12.inlined_clone(),
@ -130,7 +130,7 @@ pub fn mat4_to_mat2<N: Scalar>(m: &TMat4<N>) -> TMat2<N> {
} }
/// Creates a quaternion from a slice arranged as `[x, y, z, w]`. /// Creates a quaternion from a slice arranged as `[x, y, z, w]`.
pub fn make_quat<N: RealField>(ptr: &[N]) -> Qua<N> { pub fn make_quat<T: RealField>(ptr: &[T]) -> Qua<T> {
Quaternion::from(TVec4::from_column_slice(ptr)) Quaternion::from(TVec4::from_column_slice(ptr))
} }
@ -141,7 +141,7 @@ pub fn make_quat<N: RealField>(ptr: &[N]) -> Qua<N> {
/// * [`make_vec2`](fn.make_vec2.html) /// * [`make_vec2`](fn.make_vec2.html)
/// * [`make_vec3`](fn.make_vec3.html) /// * [`make_vec3`](fn.make_vec3.html)
/// * [`make_vec4`](fn.make_vec4.html) /// * [`make_vec4`](fn.make_vec4.html)
pub fn make_vec1<N: Scalar>(v: &TVec1<N>) -> TVec1<N> { pub fn make_vec1<T: Scalar>(v: &TVec1<T>) -> TVec1<T> {
v.clone() v.clone()
} }
@ -155,7 +155,7 @@ pub fn make_vec1<N: Scalar>(v: &TVec1<N>) -> TVec1<N> {
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html) /// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html) /// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html) /// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
pub fn vec2_to_vec1<N: Scalar>(v: &TVec2<N>) -> TVec1<N> { pub fn vec2_to_vec1<T: Scalar>(v: &TVec2<T>) -> TVec1<T> {
TVec1::new(v.x.inlined_clone()) TVec1::new(v.x.inlined_clone())
} }
@ -169,7 +169,7 @@ pub fn vec2_to_vec1<N: Scalar>(v: &TVec2<N>) -> TVec1<N> {
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html) /// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html) /// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html) /// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
pub fn vec3_to_vec1<N: Scalar>(v: &TVec3<N>) -> TVec1<N> { pub fn vec3_to_vec1<T: Scalar>(v: &TVec3<T>) -> TVec1<T> {
TVec1::new(v.x.inlined_clone()) TVec1::new(v.x.inlined_clone())
} }
@ -183,7 +183,7 @@ pub fn vec3_to_vec1<N: Scalar>(v: &TVec3<N>) -> TVec1<N> {
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html) /// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html) /// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html) /// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
pub fn vec4_to_vec1<N: Scalar>(v: &TVec4<N>) -> TVec1<N> { pub fn vec4_to_vec1<T: Scalar>(v: &TVec4<T>) -> TVec1<T> {
TVec1::new(v.x.inlined_clone()) TVec1::new(v.x.inlined_clone())
} }
@ -199,8 +199,8 @@ pub fn vec4_to_vec1<N: Scalar>(v: &TVec4<N>) -> TVec1<N> {
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html) /// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html) /// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html) /// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
pub fn vec1_to_vec2<N: Number>(v: &TVec1<N>) -> TVec2<N> { pub fn vec1_to_vec2<T: Number>(v: &TVec1<T>) -> TVec2<T> {
TVec2::new(v.x.inlined_clone(), N::zero()) TVec2::new(v.x.inlined_clone(), T::zero())
} }
/// Creates a 2D vector from another vector. /// Creates a 2D vector from another vector.
@ -214,7 +214,7 @@ pub fn vec1_to_vec2<N: Number>(v: &TVec1<N>) -> TVec2<N> {
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html) /// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html) /// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html) /// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
pub fn vec2_to_vec2<N: Scalar>(v: &TVec2<N>) -> TVec2<N> { pub fn vec2_to_vec2<T: Scalar>(v: &TVec2<T>) -> TVec2<T> {
v.clone() v.clone()
} }
@ -228,7 +228,7 @@ pub fn vec2_to_vec2<N: Scalar>(v: &TVec2<N>) -> TVec2<N> {
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html) /// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html) /// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html) /// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
pub fn vec3_to_vec2<N: Scalar>(v: &TVec3<N>) -> TVec2<N> { pub fn vec3_to_vec2<T: Scalar>(v: &TVec3<T>) -> TVec2<T> {
TVec2::new(v.x.inlined_clone(), v.y.inlined_clone()) TVec2::new(v.x.inlined_clone(), v.y.inlined_clone())
} }
@ -242,7 +242,7 @@ pub fn vec3_to_vec2<N: Scalar>(v: &TVec3<N>) -> TVec2<N> {
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html) /// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html) /// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
/// * [`vec2_to_vec4`](fn.vec2_to_vec4.html) /// * [`vec2_to_vec4`](fn.vec2_to_vec4.html)
pub fn vec4_to_vec2<N: Scalar>(v: &TVec4<N>) -> TVec2<N> { pub fn vec4_to_vec2<T: Scalar>(v: &TVec4<T>) -> TVec2<T> {
TVec2::new(v.x.inlined_clone(), v.y.inlined_clone()) TVec2::new(v.x.inlined_clone(), v.y.inlined_clone())
} }
@ -253,7 +253,7 @@ pub fn vec4_to_vec2<N: Scalar>(v: &TVec4<N>) -> TVec2<N> {
/// * [`make_vec1`](fn.make_vec1.html) /// * [`make_vec1`](fn.make_vec1.html)
/// * [`make_vec3`](fn.make_vec3.html) /// * [`make_vec3`](fn.make_vec3.html)
/// * [`make_vec4`](fn.make_vec4.html) /// * [`make_vec4`](fn.make_vec4.html)
pub fn make_vec2<N: Scalar>(ptr: &[N]) -> TVec2<N> { pub fn make_vec2<T: Scalar>(ptr: &[T]) -> TVec2<T> {
TVec2::from_column_slice(ptr) TVec2::from_column_slice(ptr)
} }
@ -268,8 +268,8 @@ pub fn make_vec2<N: Scalar>(ptr: &[N]) -> TVec2<N> {
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html) /// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html) /// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html) /// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
pub fn vec1_to_vec3<N: Number>(v: &TVec1<N>) -> TVec3<N> { pub fn vec1_to_vec3<T: Number>(v: &TVec1<T>) -> TVec3<T> {
TVec3::new(v.x.inlined_clone(), N::zero(), N::zero()) TVec3::new(v.x.inlined_clone(), T::zero(), T::zero())
} }
/// Creates a 3D vector from another vector. /// Creates a 3D vector from another vector.
@ -284,8 +284,8 @@ pub fn vec1_to_vec3<N: Number>(v: &TVec1<N>) -> TVec3<N> {
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html) /// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html) /// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html) /// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
pub fn vec2_to_vec3<N: Number>(v: &TVec2<N>) -> TVec3<N> { pub fn vec2_to_vec3<T: Number>(v: &TVec2<T>) -> TVec3<T> {
TVec3::new(v.x.inlined_clone(), v.y.inlined_clone(), N::zero()) TVec3::new(v.x.inlined_clone(), v.y.inlined_clone(), T::zero())
} }
/// Creates a 3D vector from another vector. /// Creates a 3D vector from another vector.
@ -298,7 +298,7 @@ pub fn vec2_to_vec3<N: Number>(v: &TVec2<N>) -> TVec3<N> {
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html) /// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html) /// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html) /// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
pub fn vec3_to_vec3<N: Scalar>(v: &TVec3<N>) -> TVec3<N> { pub fn vec3_to_vec3<T: Scalar>(v: &TVec3<T>) -> TVec3<T> {
v.clone() v.clone()
} }
@ -312,7 +312,7 @@ pub fn vec3_to_vec3<N: Scalar>(v: &TVec3<N>) -> TVec3<N> {
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html) /// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html) /// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec3_to_vec4`](fn.vec3_to_vec4.html) /// * [`vec3_to_vec4`](fn.vec3_to_vec4.html)
pub fn vec4_to_vec3<N: Scalar>(v: &TVec4<N>) -> TVec3<N> { pub fn vec4_to_vec3<T: Scalar>(v: &TVec4<T>) -> TVec3<T> {
TVec3::new( TVec3::new(
v.x.inlined_clone(), v.x.inlined_clone(),
v.y.inlined_clone(), v.y.inlined_clone(),
@ -327,7 +327,7 @@ pub fn vec4_to_vec3<N: Scalar>(v: &TVec4<N>) -> TVec3<N> {
/// * [`make_vec1`](fn.make_vec1.html) /// * [`make_vec1`](fn.make_vec1.html)
/// * [`make_vec2`](fn.make_vec2.html) /// * [`make_vec2`](fn.make_vec2.html)
/// * [`make_vec4`](fn.make_vec4.html) /// * [`make_vec4`](fn.make_vec4.html)
pub fn make_vec3<N: Scalar>(ptr: &[N]) -> TVec3<N> { pub fn make_vec3<T: Scalar>(ptr: &[T]) -> TVec3<T> {
TVec3::from_column_slice(ptr) TVec3::from_column_slice(ptr)
} }
@ -343,8 +343,8 @@ pub fn make_vec3<N: Scalar>(ptr: &[N]) -> TVec3<N> {
/// * [`vec1_to_vec2`](fn.vec1_to_vec2.html) /// * [`vec1_to_vec2`](fn.vec1_to_vec2.html)
/// * [`vec1_to_vec3`](fn.vec1_to_vec3.html) /// * [`vec1_to_vec3`](fn.vec1_to_vec3.html)
/// * [`vec1_to_vec4`](fn.vec1_to_vec4.html) /// * [`vec1_to_vec4`](fn.vec1_to_vec4.html)
pub fn vec1_to_vec4<N: Number>(v: &TVec1<N>) -> TVec4<N> { pub fn vec1_to_vec4<T: Number>(v: &TVec1<T>) -> TVec4<T> {
TVec4::new(v.x, N::zero(), N::zero(), N::zero()) TVec4::new(v.x, T::zero(), T::zero(), T::zero())
} }
/// Creates a 4D vector from another vector. /// Creates a 4D vector from another vector.
@ -359,8 +359,8 @@ pub fn vec1_to_vec4<N: Number>(v: &TVec1<N>) -> TVec4<N> {
/// * [`vec2_to_vec1`](fn.vec2_to_vec1.html) /// * [`vec2_to_vec1`](fn.vec2_to_vec1.html)
/// * [`vec2_to_vec2`](fn.vec2_to_vec2.html) /// * [`vec2_to_vec2`](fn.vec2_to_vec2.html)
/// * [`vec2_to_vec3`](fn.vec2_to_vec3.html) /// * [`vec2_to_vec3`](fn.vec2_to_vec3.html)
pub fn vec2_to_vec4<N: Number>(v: &TVec2<N>) -> TVec4<N> { pub fn vec2_to_vec4<T: Number>(v: &TVec2<T>) -> TVec4<T> {
TVec4::new(v.x, v.y, N::zero(), N::zero()) TVec4::new(v.x, v.y, T::zero(), T::zero())
} }
/// Creates a 4D vector from another vector. /// Creates a 4D vector from another vector.
@ -375,8 +375,8 @@ pub fn vec2_to_vec4<N: Number>(v: &TVec2<N>) -> TVec4<N> {
/// * [`vec3_to_vec1`](fn.vec3_to_vec1.html) /// * [`vec3_to_vec1`](fn.vec3_to_vec1.html)
/// * [`vec3_to_vec2`](fn.vec3_to_vec2.html) /// * [`vec3_to_vec2`](fn.vec3_to_vec2.html)
/// * [`vec3_to_vec3`](fn.vec3_to_vec3.html) /// * [`vec3_to_vec3`](fn.vec3_to_vec3.html)
pub fn vec3_to_vec4<N: Number>(v: &TVec3<N>) -> TVec4<N> { pub fn vec3_to_vec4<T: Number>(v: &TVec3<T>) -> TVec4<T> {
TVec4::new(v.x, v.y, v.z, N::zero()) TVec4::new(v.x, v.y, v.z, T::zero())
} }
/// Creates a 4D vector from another vector. /// Creates a 4D vector from another vector.
@ -389,7 +389,7 @@ pub fn vec3_to_vec4<N: Number>(v: &TVec3<N>) -> TVec4<N> {
/// * [`vec4_to_vec1`](fn.vec4_to_vec1.html) /// * [`vec4_to_vec1`](fn.vec4_to_vec1.html)
/// * [`vec4_to_vec2`](fn.vec4_to_vec2.html) /// * [`vec4_to_vec2`](fn.vec4_to_vec2.html)
/// * [`vec4_to_vec3`](fn.vec4_to_vec3.html) /// * [`vec4_to_vec3`](fn.vec4_to_vec3.html)
pub fn vec4_to_vec4<N: Scalar>(v: &TVec4<N>) -> TVec4<N> { pub fn vec4_to_vec4<T: Scalar>(v: &TVec4<T>) -> TVec4<T> {
v.clone() v.clone()
} }
@ -400,22 +400,16 @@ pub fn vec4_to_vec4<N: Scalar>(v: &TVec4<N>) -> TVec4<N> {
/// * [`make_vec1`](fn.make_vec1.html) /// * [`make_vec1`](fn.make_vec1.html)
/// * [`make_vec2`](fn.make_vec2.html) /// * [`make_vec2`](fn.make_vec2.html)
/// * [`make_vec3`](fn.make_vec3.html) /// * [`make_vec3`](fn.make_vec3.html)
pub fn make_vec4<N: Scalar>(ptr: &[N]) -> TVec4<N> { pub fn make_vec4<T: Scalar>(ptr: &[T]) -> TVec4<T> {
TVec4::from_column_slice(ptr) TVec4::from_column_slice(ptr)
} }
/// Converts a matrix or vector to a slice arranged in column-major order. /// Converts a matrix or vector to a slice arranged in column-major order.
pub fn value_ptr<N: Scalar, R: Dimension, C: Dimension>(x: &TMat<N, R, C>) -> &[N] pub fn value_ptr<T: Scalar, const R: usize, const C: usize>(x: &TMat<T, R, C>) -> &[T] {
where
DefaultAllocator: Alloc<N, R, C>,
{
x.as_slice() x.as_slice()
} }
/// Converts a matrix or vector to a mutable slice arranged in column-major order. /// Converts a matrix or vector to a mutable slice arranged in column-major order.
pub fn value_ptr_mut<N: Scalar, R: Dimension, C: Dimension>(x: &mut TMat<N, R, C>) -> &mut [N] pub fn value_ptr_mut<T: Scalar, const R: usize, const C: usize>(x: &mut TMat<T, R, C>) -> &mut [T] {
where
DefaultAllocator: Alloc<N, R, C>,
{
x.as_mut_slice() x.as_mut_slice()
} }

View File

@ -2,12 +2,11 @@ use na::{Scalar, U2};
use crate::aliases::TVec; use crate::aliases::TVec;
pub fn float_distance<T>(x: T, y: T) -> u64 { pub fn float_distance<T>(x: T, y: T) -> u64 {
unimplemented!() unimplemented!()
} }
pub fn float_distance2<N: Scalar>(x: &TVec2<N>, y: &TVec2<N>) -> TVec<u64, U2> { pub fn float_distance2<T: Scalar>(x: &TVec2<T>, y: &TVec2<T>) -> TVec<u64, U2> {
unimplemented!() unimplemented!()
} }

View File

@ -1,7 +1,5 @@
use na::{self, DefaultAllocator};
use crate::aliases::TMat; use crate::aliases::TMat;
use crate::traits::{Alloc, Dimension, Number}; use crate::traits::Number;
/// The sum of every component of the given matrix or vector. /// The sum of every component of the given matrix or vector.
/// ///
@ -21,11 +19,8 @@ use crate::traits::{Alloc, Dimension, Number};
/// * [`comp_max`](fn.comp_max.html) /// * [`comp_max`](fn.comp_max.html)
/// * [`comp_min`](fn.comp_min.html) /// * [`comp_min`](fn.comp_min.html)
/// * [`comp_mul`](fn.comp_mul.html) /// * [`comp_mul`](fn.comp_mul.html)
pub fn comp_add<N: Number, R: Dimension, C: Dimension>(m: &TMat<N, R, C>) -> N pub fn comp_add<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
where m.iter().fold(T::zero(), |x, y| x + *y)
DefaultAllocator: Alloc<N, R, C>,
{
m.iter().fold(N::zero(), |x, y| x + *y)
} }
/// The maximum of every component of the given matrix or vector. /// The maximum of every component of the given matrix or vector.
@ -50,12 +45,9 @@ where
/// * [`max2`](fn.max2.html) /// * [`max2`](fn.max2.html)
/// * [`max3`](fn.max3.html) /// * [`max3`](fn.max3.html)
/// * [`max4`](fn.max4.html) /// * [`max4`](fn.max4.html)
pub fn comp_max<N: Number, R: Dimension, C: Dimension>(m: &TMat<N, R, C>) -> N pub fn comp_max<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
where
DefaultAllocator: Alloc<N, R, C>,
{
m.iter() m.iter()
.fold(N::min_value(), |x, y| crate::max2_scalar(x, *y)) .fold(T::min_value(), |x, y| crate::max2_scalar(x, *y))
} }
/// The minimum of every component of the given matrix or vector. /// The minimum of every component of the given matrix or vector.
@ -80,12 +72,9 @@ where
/// * [`min2`](fn.min2.html) /// * [`min2`](fn.min2.html)
/// * [`min3`](fn.min3.html) /// * [`min3`](fn.min3.html)
/// * [`min4`](fn.min4.html) /// * [`min4`](fn.min4.html)
pub fn comp_min<N: Number, R: Dimension, C: Dimension>(m: &TMat<N, R, C>) -> N pub fn comp_min<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
where
DefaultAllocator: Alloc<N, R, C>,
{
m.iter() m.iter()
.fold(N::max_value(), |x, y| crate::min2_scalar(x, *y)) .fold(T::max_value(), |x, y| crate::min2_scalar(x, *y))
} }
/// The product of every component of the given matrix or vector. /// The product of every component of the given matrix or vector.
@ -106,11 +95,8 @@ where
/// * [`comp_add`](fn.comp_add.html) /// * [`comp_add`](fn.comp_add.html)
/// * [`comp_max`](fn.comp_max.html) /// * [`comp_max`](fn.comp_max.html)
/// * [`comp_min`](fn.comp_min.html) /// * [`comp_min`](fn.comp_min.html)
pub fn comp_mul<N: Number, R: Dimension, C: Dimension>(m: &TMat<N, R, C>) -> N pub fn comp_mul<T: Number, const R: usize, const C: usize>(m: &TMat<T, R, C>) -> T {
where m.iter().fold(T::one(), |x, y| x * *y)
DefaultAllocator: Alloc<N, R, C>,
{
m.iter().fold(N::one(), |x, y| x * *y)
} }
//pub fn vec< L, floatType, Q > compNormalize (vec< L, T, Q > const &v) //pub fn vec< L, floatType, Q > compNormalize (vec< L, T, Q > const &v)

View File

@ -1,163 +1,163 @@
use na::{RealField, U3, U4}; use na::{RealField, U3, U4};
use crate::aliases::{TVec, TMat}; use crate::aliases::{TMat, TVec};
pub fn derivedEulerAngleX<N: RealField>(angleX: N, angularVelocityX: N) -> TMat4<N> { pub fn derivedEulerAngleX<T: RealField>(angleX: T, angularVelocityX: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn derivedEulerAngleY<N: RealField>(angleY: N, angularVelocityY: N) -> TMat4<N> { pub fn derivedEulerAngleY<T: RealField>(angleY: T, angularVelocityY: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn derivedEulerAngleZ<N: RealField>(angleZ: N, angularVelocityZ: N) -> TMat4<N> { pub fn derivedEulerAngleZ<T: RealField>(angleZ: T, angularVelocityZ: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn eulerAngleX<N: RealField>(angleX: N) -> TMat4<N> { pub fn eulerAngleX<T: RealField>(angleX: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn eulerAngleXY<N: RealField>(angleX: N, angleY: N) -> TMat4<N> { pub fn eulerAngleXY<T: RealField>(angleX: T, angleY: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn eulerAngleXYX<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> { pub fn eulerAngleXYX<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn eulerAngleXYZ<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> { pub fn eulerAngleXYZ<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn eulerAngleXZ<N: RealField>(angleX: N, angleZ: N) -> TMat4<N> { pub fn eulerAngleXZ<T: RealField>(angleX: T, angleZ: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn eulerAngleXZX<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> { pub fn eulerAngleXZX<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn eulerAngleXZY<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> { pub fn eulerAngleXZY<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn eulerAngleY<N: RealField>(angleY: N) -> TMat4<N> { pub fn eulerAngleY<T: RealField>(angleY: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn eulerAngleYX<N: RealField>(angleY: N, angleX: N) -> TMat4<N> { pub fn eulerAngleYX<T: RealField>(angleY: T, angleX: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn eulerAngleYXY<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> { pub fn eulerAngleYXY<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn eulerAngleYXZ<N: RealField>(yaw: N, pitch: N, roll: N) -> TMat4<N> { pub fn eulerAngleYXZ<T: RealField>(yaw: T, pitch: T, roll: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn eulerAngleYZ<N: RealField>(angleY: N, angleZ: N) -> TMat4<N> { pub fn eulerAngleYZ<T: RealField>(angleY: T, angleZ: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn eulerAngleYZX<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> { pub fn eulerAngleYZX<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn eulerAngleYZY<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> { pub fn eulerAngleYZY<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn eulerAngleZ<N: RealField>(angleZ: N) -> TMat4<N> { pub fn eulerAngleZ<T: RealField>(angleZ: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn eulerAngleZX<N: RealField>(angle: N, angleX: N) -> TMat4<N> { pub fn eulerAngleZX<T: RealField>(angle: T, angleX: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn eulerAngleZXY<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> { pub fn eulerAngleZXY<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn eulerAngleZXZ<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> { pub fn eulerAngleZXZ<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn eulerAngleZY<N: RealField>(angleZ: N, angleY: N) -> TMat4<N> { pub fn eulerAngleZY<T: RealField>(angleZ: T, angleY: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn eulerAngleZYX<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> { pub fn eulerAngleZYX<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn eulerAngleZYZ<N: RealField>(t1: N, t2: N, t3: N) -> TMat4<N> { pub fn eulerAngleZYZ<T: RealField>(t1: T, t2: T, t3: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn extractEulerAngleXYX<N: RealField>(M: &TMat4<N>) -> (N, N, N) { pub fn extractEulerAngleXYX<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
unimplemented!() unimplemented!()
} }
pub fn extractEulerAngleXYZ<N: RealField>(M: &TMat4<N>) -> (N, N, N) { pub fn extractEulerAngleXYZ<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
unimplemented!() unimplemented!()
} }
pub fn extractEulerAngleXZX<N: RealField>(M: &TMat4<N>) -> (N, N, N) { pub fn extractEulerAngleXZX<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
unimplemented!() unimplemented!()
} }
pub fn extractEulerAngleXZY<N: RealField>(M: &TMat4<N>) -> (N, N, N) { pub fn extractEulerAngleXZY<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
unimplemented!() unimplemented!()
} }
pub fn extractEulerAngleYXY<N: RealField>(M: &TMat4<N>) -> (N, N, N) { pub fn extractEulerAngleYXY<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
unimplemented!() unimplemented!()
} }
pub fn extractEulerAngleYXZ<N: RealField>(M: &TMat4<N>) -> (N, N, N) { pub fn extractEulerAngleYXZ<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
unimplemented!() unimplemented!()
} }
pub fn extractEulerAngleYZX<N: RealField>(M: &TMat4<N>) -> (N, N, N) { pub fn extractEulerAngleYZX<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
unimplemented!() unimplemented!()
} }
pub fn extractEulerAngleYZY<N: RealField>(M: &TMat4<N>) -> (N, N, N) { pub fn extractEulerAngleYZY<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
unimplemented!() unimplemented!()
} }
pub fn extractEulerAngleZXY<N: RealField>(M: &TMat4<N>) -> (N, N, N) { pub fn extractEulerAngleZXY<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
unimplemented!() unimplemented!()
} }
pub fn extractEulerAngleZXZ<N: RealField>(M: &TMat4<N>) -> (N, N, N) { pub fn extractEulerAngleZXZ<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
unimplemented!() unimplemented!()
} }
pub fn extractEulerAngleZYX<N: RealField>(M: &TMat4<N>) -> (N, N, N) { pub fn extractEulerAngleZYX<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
unimplemented!() unimplemented!()
} }
pub fn extractEulerAngleZYZ<N: RealField>(M: &TMat4<N>) -> (N, N, N) { pub fn extractEulerAngleZYZ<T: RealField>(M: &TMat4<T>) -> (T, T, T) {
unimplemented!() unimplemented!()
} }
pub fn orientate2<N: RealField>(angle: N) -> TMat3x3<N> { pub fn orientate2<T: RealField>(angle: T) -> TMat3x3<T> {
unimplemented!() unimplemented!()
} }
pub fn orientate3<N: RealField>(angles: TVec3<N>) -> TMat3x3<N> { pub fn orientate3<T: RealField>(angles: TVec3<T>) -> TMat3x3<T> {
unimplemented!() unimplemented!()
} }
pub fn orientate4<N: RealField>(angles: TVec3<N>) -> TMat4<N> { pub fn orientate4<T: RealField>(angles: TVec3<T>) -> TMat4<T> {
unimplemented!() unimplemented!()
} }
pub fn yawPitchRoll<N: RealField>(yaw: N, pitch: N, roll: N) -> TMat4<N> { pub fn yawPitchRoll<T: RealField>(yaw: T, pitch: T, roll: T) -> TMat4<T> {
unimplemented!() unimplemented!()
} }

View File

@ -2,6 +2,6 @@ use crate::aliases::TVec2;
use crate::traits::Number; use crate::traits::Number;
/// The 2D perpendicular product between two vectors. /// The 2D perpendicular product between two vectors.
pub fn cross2d<N: Number>(v: &TVec2<N>, u: &TVec2<N>) -> N { pub fn cross2d<T: Number>(v: &TVec2<T>, u: &TVec2<T>) -> T {
v.perp(u) v.perp(u)
} }

View File

@ -6,8 +6,8 @@ use crate::traits::Number;
/// # See also: /// # See also:
/// ///
/// * [`right_handed`](fn.right_handed.html) /// * [`right_handed`](fn.right_handed.html)
pub fn left_handed<N: Number>(a: &TVec3<N>, b: &TVec3<N>, c: &TVec3<N>) -> bool { pub fn left_handed<T: Number>(a: &TVec3<T>, b: &TVec3<T>, c: &TVec3<T>) -> bool {
a.cross(b).dot(c) < N::zero() a.cross(b).dot(c) < T::zero()
} }
/// Returns `true` if `{a, b, c}` forms a right-handed trihedron. /// Returns `true` if `{a, b, c}` forms a right-handed trihedron.
@ -15,6 +15,6 @@ pub fn left_handed<N: Number>(a: &TVec3<N>, b: &TVec3<N>, c: &TVec3<N>) -> bool
/// # See also: /// # See also:
/// ///
/// * [`left_handed`](fn.left_handed.html) /// * [`left_handed`](fn.left_handed.html)
pub fn right_handed<N: Number>(a: &TVec3<N>, b: &TVec3<N>, c: &TVec3<N>) -> bool { pub fn right_handed<T: Number>(a: &TVec3<T>, b: &TVec3<T>, c: &TVec3<T>) -> bool {
a.cross(b).dot(c) > N::zero() a.cross(b).dot(c) > T::zero()
} }

View File

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

View File

@ -15,7 +15,7 @@ use crate::traits::Number;
/// * [`diagonal4x2`](fn.diagonal4x2.html) /// * [`diagonal4x2`](fn.diagonal4x2.html)
/// * [`diagonal4x3`](fn.diagonal4x3.html) /// * [`diagonal4x3`](fn.diagonal4x3.html)
/// * [`diagonal4x4`](fn.diagonal4x4.html) /// * [`diagonal4x4`](fn.diagonal4x4.html)
pub fn diagonal2x2<N: Number>(v: &TVec2<N>) -> TMat2<N> { pub fn diagonal2x2<T: Number>(v: &TVec2<T>) -> TMat2<T> {
TMat2::from_diagonal(v) TMat2::from_diagonal(v)
} }
@ -31,7 +31,7 @@ pub fn diagonal2x2<N: Number>(v: &TVec2<N>) -> TMat2<N> {
/// * [`diagonal4x2`](fn.diagonal4x2.html) /// * [`diagonal4x2`](fn.diagonal4x2.html)
/// * [`diagonal4x3`](fn.diagonal4x3.html) /// * [`diagonal4x3`](fn.diagonal4x3.html)
/// * [`diagonal4x4`](fn.diagonal4x4.html) /// * [`diagonal4x4`](fn.diagonal4x4.html)
pub fn diagonal2x3<N: Number>(v: &TVec2<N>) -> TMat2x3<N> { pub fn diagonal2x3<T: Number>(v: &TVec2<T>) -> TMat2x3<T> {
TMat2x3::from_partial_diagonal(v.as_slice()) TMat2x3::from_partial_diagonal(v.as_slice())
} }
@ -47,7 +47,7 @@ pub fn diagonal2x3<N: Number>(v: &TVec2<N>) -> TMat2x3<N> {
/// * [`diagonal4x2`](fn.diagonal4x2.html) /// * [`diagonal4x2`](fn.diagonal4x2.html)
/// * [`diagonal4x3`](fn.diagonal4x3.html) /// * [`diagonal4x3`](fn.diagonal4x3.html)
/// * [`diagonal4x4`](fn.diagonal4x4.html) /// * [`diagonal4x4`](fn.diagonal4x4.html)
pub fn diagonal2x4<N: Number>(v: &TVec2<N>) -> TMat2x4<N> { pub fn diagonal2x4<T: Number>(v: &TVec2<T>) -> TMat2x4<T> {
TMat2x4::from_partial_diagonal(v.as_slice()) TMat2x4::from_partial_diagonal(v.as_slice())
} }
@ -63,7 +63,7 @@ pub fn diagonal2x4<N: Number>(v: &TVec2<N>) -> TMat2x4<N> {
/// * [`diagonal4x2`](fn.diagonal4x2.html) /// * [`diagonal4x2`](fn.diagonal4x2.html)
/// * [`diagonal4x3`](fn.diagonal4x3.html) /// * [`diagonal4x3`](fn.diagonal4x3.html)
/// * [`diagonal4x4`](fn.diagonal4x4.html) /// * [`diagonal4x4`](fn.diagonal4x4.html)
pub fn diagonal3x2<N: Number>(v: &TVec2<N>) -> TMat3x2<N> { pub fn diagonal3x2<T: Number>(v: &TVec2<T>) -> TMat3x2<T> {
TMat3x2::from_partial_diagonal(v.as_slice()) TMat3x2::from_partial_diagonal(v.as_slice())
} }
@ -79,7 +79,7 @@ pub fn diagonal3x2<N: Number>(v: &TVec2<N>) -> TMat3x2<N> {
/// * [`diagonal4x2`](fn.diagonal4x2.html) /// * [`diagonal4x2`](fn.diagonal4x2.html)
/// * [`diagonal4x3`](fn.diagonal4x3.html) /// * [`diagonal4x3`](fn.diagonal4x3.html)
/// * [`diagonal4x4`](fn.diagonal4x4.html) /// * [`diagonal4x4`](fn.diagonal4x4.html)
pub fn diagonal3x3<N: Number>(v: &TVec3<N>) -> TMat3<N> { pub fn diagonal3x3<T: Number>(v: &TVec3<T>) -> TMat3<T> {
TMat3::from_diagonal(v) TMat3::from_diagonal(v)
} }
@ -95,7 +95,7 @@ pub fn diagonal3x3<N: Number>(v: &TVec3<N>) -> TMat3<N> {
/// * [`diagonal4x2`](fn.diagonal4x2.html) /// * [`diagonal4x2`](fn.diagonal4x2.html)
/// * [`diagonal4x3`](fn.diagonal4x3.html) /// * [`diagonal4x3`](fn.diagonal4x3.html)
/// * [`diagonal4x4`](fn.diagonal4x4.html) /// * [`diagonal4x4`](fn.diagonal4x4.html)
pub fn diagonal3x4<N: Number>(v: &TVec3<N>) -> TMat3x4<N> { pub fn diagonal3x4<T: Number>(v: &TVec3<T>) -> TMat3x4<T> {
TMat3x4::from_partial_diagonal(v.as_slice()) TMat3x4::from_partial_diagonal(v.as_slice())
} }
@ -111,7 +111,7 @@ pub fn diagonal3x4<N: Number>(v: &TVec3<N>) -> TMat3x4<N> {
/// * [`diagonal3x4`](fn.diagonal3x4.html) /// * [`diagonal3x4`](fn.diagonal3x4.html)
/// * [`diagonal4x3`](fn.diagonal4x3.html) /// * [`diagonal4x3`](fn.diagonal4x3.html)
/// * [`diagonal4x4`](fn.diagonal4x4.html) /// * [`diagonal4x4`](fn.diagonal4x4.html)
pub fn diagonal4x2<N: Number>(v: &TVec2<N>) -> TMat4x2<N> { pub fn diagonal4x2<T: Number>(v: &TVec2<T>) -> TMat4x2<T> {
TMat4x2::from_partial_diagonal(v.as_slice()) TMat4x2::from_partial_diagonal(v.as_slice())
} }
@ -127,7 +127,7 @@ pub fn diagonal4x2<N: Number>(v: &TVec2<N>) -> TMat4x2<N> {
/// * [`diagonal3x4`](fn.diagonal3x4.html) /// * [`diagonal3x4`](fn.diagonal3x4.html)
/// * [`diagonal4x2`](fn.diagonal4x2.html) /// * [`diagonal4x2`](fn.diagonal4x2.html)
/// * [`diagonal4x4`](fn.diagonal4x4.html) /// * [`diagonal4x4`](fn.diagonal4x4.html)
pub fn diagonal4x3<N: Number>(v: &TVec3<N>) -> TMat4x3<N> { pub fn diagonal4x3<T: Number>(v: &TVec3<T>) -> TMat4x3<T> {
TMat4x3::from_partial_diagonal(v.as_slice()) TMat4x3::from_partial_diagonal(v.as_slice())
} }
@ -143,6 +143,6 @@ pub fn diagonal4x3<N: Number>(v: &TVec3<N>) -> TMat4x3<N> {
/// * [`diagonal3x4`](fn.diagonal3x4.html) /// * [`diagonal3x4`](fn.diagonal3x4.html)
/// * [`diagonal4x2`](fn.diagonal4x2.html) /// * [`diagonal4x2`](fn.diagonal4x2.html)
/// * [`diagonal4x3`](fn.diagonal4x3.html) /// * [`diagonal4x3`](fn.diagonal4x3.html)
pub fn diagonal4x4<N: Number>(v: &TVec4<N>) -> TMat4<N> { pub fn diagonal4x4<T: Number>(v: &TVec4<T>) -> TMat4<T> {
TMat4::from_diagonal(v) TMat4::from_diagonal(v)
} }

View File

@ -1,17 +1,13 @@
use na::{DefaultAllocator, RealField}; use na::RealField;
use crate::aliases::TVec; use crate::aliases::TVec;
use crate::traits::{Alloc, Dimension};
/// The squared distance between two points. /// The squared distance between two points.
/// ///
/// # See also: /// # See also:
/// ///
/// * [`distance`](fn.distance.html) /// * [`distance`](fn.distance.html)
pub fn distance2<N: RealField, D: Dimension>(p0: &TVec<N, D>, p1: &TVec<N, D>) -> N pub fn distance2<T: RealField, const D: usize>(p0: &TVec<T, D>, p1: &TVec<T, D>) -> T {
where
DefaultAllocator: Alloc<N, D>,
{
(p1 - p0).norm_squared() (p1 - p0).norm_squared()
} }
@ -22,10 +18,7 @@ where
/// * [`l1_norm`](fn.l1_norm.html) /// * [`l1_norm`](fn.l1_norm.html)
/// * [`l2_distance`](fn.l2_distance.html) /// * [`l2_distance`](fn.l2_distance.html)
/// * [`l2_norm`](fn.l2_norm.html) /// * [`l2_norm`](fn.l2_norm.html)
pub fn l1_distance<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N pub fn l1_distance<T: RealField, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
where
DefaultAllocator: Alloc<N, D>,
{
l1_norm(&(y - x)) l1_norm(&(y - x))
} }
@ -39,10 +32,7 @@ where
/// * [`l1_distance`](fn.l1_distance.html) /// * [`l1_distance`](fn.l1_distance.html)
/// * [`l2_distance`](fn.l2_distance.html) /// * [`l2_distance`](fn.l2_distance.html)
/// * [`l2_norm`](fn.l2_norm.html) /// * [`l2_norm`](fn.l2_norm.html)
pub fn l1_norm<N: RealField, D: Dimension>(v: &TVec<N, D>) -> N pub fn l1_norm<T: RealField, const D: usize>(v: &TVec<T, D>) -> T {
where
DefaultAllocator: Alloc<N, D>,
{
crate::comp_add(&v.abs()) crate::comp_add(&v.abs())
} }
@ -60,10 +50,7 @@ where
/// * [`length2`](fn.length2.html) /// * [`length2`](fn.length2.html)
/// * [`magnitude`](fn.magnitude.html) /// * [`magnitude`](fn.magnitude.html)
/// * [`magnitude2`](fn.magnitude2.html) /// * [`magnitude2`](fn.magnitude2.html)
pub fn l2_distance<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N pub fn l2_distance<T: RealField, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
where
DefaultAllocator: Alloc<N, D>,
{
l2_norm(&(y - x)) l2_norm(&(y - x))
} }
@ -83,10 +70,7 @@ where
/// * [`length2`](fn.length2.html) /// * [`length2`](fn.length2.html)
/// * [`magnitude`](fn.magnitude.html) /// * [`magnitude`](fn.magnitude.html)
/// * [`magnitude2`](fn.magnitude2.html) /// * [`magnitude2`](fn.magnitude2.html)
pub fn l2_norm<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N pub fn l2_norm<T: RealField, const D: usize>(x: &TVec<T, D>) -> T {
where
DefaultAllocator: Alloc<N, D>,
{
x.norm() x.norm()
} }
@ -101,10 +85,7 @@ where
/// * [`length`](fn.length.html) /// * [`length`](fn.length.html)
/// * [`magnitude`](fn.magnitude.html) /// * [`magnitude`](fn.magnitude.html)
/// * [`magnitude2`](fn.magnitude2.html) /// * [`magnitude2`](fn.magnitude2.html)
pub fn length2<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N pub fn length2<T: RealField, const D: usize>(x: &TVec<T, D>) -> T {
where
DefaultAllocator: Alloc<N, D>,
{
x.norm_squared() x.norm_squared()
} }
@ -119,19 +100,14 @@ where
/// * [`length2`](fn.length2.html) /// * [`length2`](fn.length2.html)
/// * [`magnitude`](fn.magnitude.html) /// * [`magnitude`](fn.magnitude.html)
/// * [`nalgebra::norm_squared`](../nalgebra/fn.norm_squared.html) /// * [`nalgebra::norm_squared`](../nalgebra/fn.norm_squared.html)
pub fn magnitude2<N: RealField, D: Dimension>(x: &TVec<N, D>) -> N pub fn magnitude2<T: RealField, const D: usize>(x: &TVec<T, D>) -> T {
where
DefaultAllocator: Alloc<N, D>,
{
x.norm_squared() x.norm_squared()
} }
//pub fn lxNorm<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>, unsigned int Depth) -> N //pub fn lxNorm<T: RealField, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>, unsigned int Depth) -> T {
// where DefaultAllocator: Alloc<N, D> {
// unimplemented!() // unimplemented!()
//} //}
// //
//pub fn lxNorm<N: RealField, D: Dimension>(x: &TVec<N, D>, unsigned int Depth) -> N //pub fn lxNorm<T: RealField, const D: usize>(x: &TVec<T, D>, unsigned int Depth) -> T {
// where DefaultAllocator: Alloc<N, D> {
// unimplemented!() // unimplemented!()
//} //}

View File

@ -5,6 +5,6 @@ use crate::aliases::TVec3;
/// The normal vector of the given triangle. /// The normal vector of the given triangle.
/// ///
/// The normal is computed as the normalized vector `cross(p2 - p1, p3 - p1)`. /// The normal is computed as the normalized vector `cross(p2 - p1, p3 - p1)`.
pub fn triangle_normal<N: RealField>(p1: &TVec3<N>, p2: &TVec3<N>, p3: &TVec3<N>) -> TVec3<N> { pub fn triangle_normal<T: RealField>(p1: &TVec3<T>, p2: &TVec3<T>, p3: &TVec3<T>) -> TVec3<T> {
(p2 - p1).cross(&(p3 - p1)).normalize() (p2 - p1).cross(&(p3 - p1)).normalize()
} }

View File

@ -1,7 +1,6 @@
use na::{DefaultAllocator, RealField}; use na::RealField;
use crate::aliases::TVec; use crate::aliases::TVec;
use crate::traits::{Alloc, Dimension};
/// The dot product of the normalized version of `x` and `y`. /// The dot product of the normalized version of `x` and `y`.
/// ///
@ -10,10 +9,7 @@ use crate::traits::{Alloc, Dimension};
/// # See also: /// # See also:
/// ///
/// * [`normalize_dot`](fn.normalize_dot.html`) /// * [`normalize_dot`](fn.normalize_dot.html`)
pub fn fast_normalize_dot<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N pub fn fast_normalize_dot<T: RealField, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
where
DefaultAllocator: Alloc<N, D>,
{
// XXX: improve those. // XXX: improve those.
x.normalize().dot(&y.normalize()) x.normalize().dot(&y.normalize())
} }
@ -23,10 +19,7 @@ where
/// # See also: /// # See also:
/// ///
/// * [`fast_normalize_dot`](fn.fast_normalize_dot.html`) /// * [`fast_normalize_dot`](fn.fast_normalize_dot.html`)
pub fn normalize_dot<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N pub fn normalize_dot<T: RealField, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
where
DefaultAllocator: Alloc<N, D>,
{
// XXX: improve those. // XXX: improve those.
x.normalize().dot(&y.normalize()) x.normalize().dot(&y.normalize())
} }

View File

@ -1,97 +1,97 @@
use na::{RealField, Rotation3, Unit, UnitQuaternion, U3}; use na::{RealField, Rotation3, Unit, UnitQuaternion};
use crate::aliases::{Qua, TMat3, TMat4, TVec3, TVec4}; use crate::aliases::{Qua, TMat3, TMat4, TVec3, TVec4};
/// Rotate the vector `v` by the quaternion `q` assumed to be normalized. /// Rotate the vector `v` by the quaternion `q` assumed to be normalized.
pub fn quat_cross_vec<N: RealField>(q: &Qua<N>, v: &TVec3<N>) -> TVec3<N> { pub fn quat_cross_vec<T: RealField>(q: &Qua<T>, v: &TVec3<T>) -> TVec3<T> {
UnitQuaternion::new_unchecked(*q) * v UnitQuaternion::new_unchecked(*q) * v
} }
/// Rotate the vector `v` by the inverse of the quaternion `q` assumed to be normalized. /// Rotate the vector `v` by the inverse of the quaternion `q` assumed to be normalized.
pub fn quat_inv_cross_vec<N: RealField>(v: &TVec3<N>, q: &Qua<N>) -> TVec3<N> { pub fn quat_inv_cross_vec<T: RealField>(v: &TVec3<T>, q: &Qua<T>) -> TVec3<T> {
UnitQuaternion::new_unchecked(*q).inverse() * v UnitQuaternion::new_unchecked(*q).inverse() * v
} }
/// The quaternion `w` component. /// The quaternion `w` component.
pub fn quat_extract_real_component<N: RealField>(q: &Qua<N>) -> N { pub fn quat_extract_real_component<T: RealField>(q: &Qua<T>) -> T {
q.w q.w
} }
/// Normalized linear interpolation between two quaternions. /// Normalized linear interpolation between two quaternions.
pub fn quat_fast_mix<N: RealField>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> { pub fn quat_fast_mix<T: RealField>(x: &Qua<T>, y: &Qua<T>, a: T) -> Qua<T> {
Unit::new_unchecked(*x) Unit::new_unchecked(*x)
.nlerp(&Unit::new_unchecked(*y), a) .nlerp(&Unit::new_unchecked(*y), a)
.into_inner() .into_inner()
} }
//pub fn quat_intermediate<N: RealField>(prev: &Qua<N>, curr: &Qua<N>, next: &Qua<N>) -> Qua<N> { //pub fn quat_intermediate<T: RealField>(prev: &Qua<T>, curr: &Qua<T>, next: &Qua<T>) -> Qua<T> {
// unimplemented!() // unimplemented!()
//} //}
/// The squared magnitude of a quaternion `q`. /// The squared magnitude of a quaternion `q`.
pub fn quat_length2<N: RealField>(q: &Qua<N>) -> N { pub fn quat_length2<T: RealField>(q: &Qua<T>) -> T {
q.norm_squared() q.norm_squared()
} }
/// The squared magnitude of a quaternion `q`. /// The squared magnitude of a quaternion `q`.
pub fn quat_magnitude2<N: RealField>(q: &Qua<N>) -> N { pub fn quat_magnitude2<T: RealField>(q: &Qua<T>) -> T {
q.norm_squared() q.norm_squared()
} }
/// The quaternion representing the identity rotation. /// The quaternion representing the identity rotation.
pub fn quat_identity<N: RealField>() -> Qua<N> { pub fn quat_identity<T: RealField>() -> Qua<T> {
UnitQuaternion::identity().into_inner() UnitQuaternion::identity().into_inner()
} }
/// Rotates a vector by a quaternion assumed to be normalized. /// Rotates a vector by a quaternion assumed to be normalized.
pub fn quat_rotate_vec3<N: RealField>(q: &Qua<N>, v: &TVec3<N>) -> TVec3<N> { pub fn quat_rotate_vec3<T: RealField>(q: &Qua<T>, v: &TVec3<T>) -> TVec3<T> {
UnitQuaternion::new_unchecked(*q) * v UnitQuaternion::new_unchecked(*q) * v
} }
/// Rotates a vector in homogeneous coordinates by a quaternion assumed to be normalized. /// Rotates a vector in homogeneous coordinates by a quaternion assumed to be normalized.
pub fn quat_rotate_vec<N: RealField>(q: &Qua<N>, v: &TVec4<N>) -> TVec4<N> { pub fn quat_rotate_vec<T: RealField>(q: &Qua<T>, v: &TVec4<T>) -> TVec4<T> {
let rotated = Unit::new_unchecked(*q) * v.fixed_rows::<U3>(0); let rotated = Unit::new_unchecked(*q) * v.fixed_rows::<3>(0);
TVec4::new(rotated.x, rotated.y, rotated.z, v.w) TVec4::new(rotated.x, rotated.y, rotated.z, v.w)
} }
/// The rotation required to align `orig` to `dest`. /// The rotation required to align `orig` to `dest`.
pub fn quat_rotation<N: RealField>(orig: &TVec3<N>, dest: &TVec3<N>) -> Qua<N> { pub fn quat_rotation<T: RealField>(orig: &TVec3<T>, dest: &TVec3<T>) -> Qua<T> {
UnitQuaternion::rotation_between(orig, dest) UnitQuaternion::rotation_between(orig, dest)
.unwrap_or_else(UnitQuaternion::identity) .unwrap_or_else(UnitQuaternion::identity)
.into_inner() .into_inner()
} }
/// The spherical linear interpolation between two quaternions. /// The spherical linear interpolation between two quaternions.
pub fn quat_short_mix<N: RealField>(x: &Qua<N>, y: &Qua<N>, a: N) -> Qua<N> { pub fn quat_short_mix<T: RealField>(x: &Qua<T>, y: &Qua<T>, a: T) -> Qua<T> {
Unit::new_normalize(*x) Unit::new_normalize(*x)
.slerp(&Unit::new_normalize(*y), a) .slerp(&Unit::new_normalize(*y), a)
.into_inner() .into_inner()
} }
//pub fn quat_squad<N: RealField>(q1: &Qua<N>, q2: &Qua<N>, s1: &Qua<N>, s2: &Qua<N>, h: N) -> Qua<N> { //pub fn quat_squad<T: RealField>(q1: &Qua<T>, q2: &Qua<T>, s1: &Qua<T>, s2: &Qua<T>, h: T) -> Qua<T> {
// unimplemented!() // unimplemented!()
//} //}
/// Converts a quaternion to a rotation matrix. /// Converts a quaternion to a rotation matrix.
pub fn quat_to_mat3<N: RealField>(x: &Qua<N>) -> TMat3<N> { pub fn quat_to_mat3<T: RealField>(x: &Qua<T>) -> TMat3<T> {
UnitQuaternion::new_unchecked(*x) UnitQuaternion::new_unchecked(*x)
.to_rotation_matrix() .to_rotation_matrix()
.into_inner() .into_inner()
} }
/// Converts a quaternion to a rotation matrix in homogenous coordinates. /// Converts a quaternion to a rotation matrix in homogenous coordinates.
pub fn quat_to_mat4<N: RealField>(x: &Qua<N>) -> TMat4<N> { pub fn quat_to_mat4<T: RealField>(x: &Qua<T>) -> TMat4<T> {
UnitQuaternion::new_unchecked(*x).to_homogeneous() UnitQuaternion::new_unchecked(*x).to_homogeneous()
} }
/// Converts a rotation matrix to a quaternion. /// Converts a rotation matrix to a quaternion.
pub fn mat3_to_quat<N: RealField>(x: &TMat3<N>) -> Qua<N> { pub fn mat3_to_quat<T: RealField>(x: &TMat3<T>) -> Qua<T> {
let r = Rotation3::from_matrix_unchecked(*x); let r = Rotation3::from_matrix_unchecked(*x);
UnitQuaternion::from_rotation_matrix(&r).into_inner() UnitQuaternion::from_rotation_matrix(&r).into_inner()
} }
/// Converts a rotation matrix in homogeneous coordinates to a quaternion. /// Converts a rotation matrix in homogeneous coordinates to a quaternion.
pub fn to_quat<N: RealField>(x: &TMat4<N>) -> Qua<N> { pub fn to_quat<T: RealField>(x: &TMat4<T>) -> Qua<T> {
let rot = x.fixed_slice::<U3, U3>(0, 0).into_owned(); let rot = x.fixed_slice::<3, 3>(0, 0).into_owned();
mat3_to_quat(&rot) mat3_to_quat(&rot)
} }

View File

@ -9,7 +9,7 @@ use crate::aliases::{Qua, TMat4, TVec3};
/// * `m` - Input matrix multiplied by this rotation matrix. /// * `m` - Input matrix multiplied by this rotation matrix.
/// * `angle` - Rotation angle expressed in radians. /// * `angle` - Rotation angle expressed in radians.
/// * `axis` - Rotation axis, must be normalized. /// * `axis` - Rotation axis, must be normalized.
pub fn rotate_normalized_axis<N: RealField>(m: &TMat4<N>, angle: N, axis: &TVec3<N>) -> TMat4<N> { pub fn rotate_normalized_axis<T: RealField>(m: &TMat4<T>, angle: T, axis: &TVec3<T>) -> TMat4<T> {
m * Rotation3::from_axis_angle(&Unit::new_unchecked(*axis), angle).to_homogeneous() m * Rotation3::from_axis_angle(&Unit::new_unchecked(*axis), angle).to_homogeneous()
} }
@ -20,6 +20,6 @@ pub fn rotate_normalized_axis<N: RealField>(m: &TMat4<N>, angle: N, axis: &TVec3
/// * `q` - Source orientation. /// * `q` - Source orientation.
/// * `angle` - Angle expressed in radians. /// * `angle` - Angle expressed in radians.
/// * `axis` - Normalized axis of the rotation, must be normalized. /// * `axis` - Normalized axis of the rotation, must be normalized.
pub fn quat_rotate_normalized_axis<N: RealField>(q: &Qua<N>, angle: N, axis: &TVec3<N>) -> Qua<N> { pub fn quat_rotate_normalized_axis<T: RealField>(q: &Qua<T>, angle: T, axis: &TVec3<T>) -> Qua<T> {
q * UnitQuaternion::from_axis_angle(&Unit::new_unchecked(*axis), angle).into_inner() q * UnitQuaternion::from_axis_angle(&Unit::new_unchecked(*axis), angle).into_inner()
} }

View File

@ -3,7 +3,7 @@ use na::{RealField, Rotation3, Unit, UnitComplex};
use crate::aliases::{TMat4, TVec2, TVec3, TVec4}; use crate::aliases::{TMat4, TVec2, TVec3, TVec4};
/// Build the rotation matrix needed to align `normal` and `up`. /// Build the rotation matrix needed to align `normal` and `up`.
pub fn orientation<N: RealField>(normal: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> { pub fn orientation<T: RealField>(normal: &TVec3<T>, up: &TVec3<T>) -> TMat4<T> {
if let Some(r) = Rotation3::rotation_between(normal, up) { if let Some(r) = Rotation3::rotation_between(normal, up) {
r.to_homogeneous() r.to_homogeneous()
} else { } else {
@ -12,52 +12,52 @@ pub fn orientation<N: RealField>(normal: &TVec3<N>, up: &TVec3<N>) -> TMat4<N> {
} }
/// Rotate a two dimensional vector. /// Rotate a two dimensional vector.
pub fn rotate_vec2<N: RealField>(v: &TVec2<N>, angle: N) -> TVec2<N> { pub fn rotate_vec2<T: RealField>(v: &TVec2<T>, angle: T) -> TVec2<T> {
UnitComplex::new(angle) * v UnitComplex::new(angle) * v
} }
/// Rotate a three dimensional vector around an axis. /// Rotate a three dimensional vector around an axis.
pub fn rotate_vec3<N: RealField>(v: &TVec3<N>, angle: N, normal: &TVec3<N>) -> TVec3<N> { pub fn rotate_vec3<T: RealField>(v: &TVec3<T>, angle: T, normal: &TVec3<T>) -> TVec3<T> {
Rotation3::from_axis_angle(&Unit::new_normalize(*normal), angle) * v Rotation3::from_axis_angle(&Unit::new_normalize(*normal), angle) * v
} }
/// Rotate a thee dimensional vector in homogeneous coordinates around an axis. /// Rotate a thee dimensional vector in homogeneous coordinates around an axis.
pub fn rotate_vec4<N: RealField>(v: &TVec4<N>, angle: N, normal: &TVec3<N>) -> TVec4<N> { pub fn rotate_vec4<T: RealField>(v: &TVec4<T>, angle: T, normal: &TVec3<T>) -> TVec4<T> {
Rotation3::from_axis_angle(&Unit::new_normalize(*normal), angle).to_homogeneous() * v Rotation3::from_axis_angle(&Unit::new_normalize(*normal), angle).to_homogeneous() * v
} }
/// Rotate a three dimensional vector around the `X` axis. /// Rotate a three dimensional vector around the `X` axis.
pub fn rotate_x_vec3<N: RealField>(v: &TVec3<N>, angle: N) -> TVec3<N> { pub fn rotate_x_vec3<T: RealField>(v: &TVec3<T>, angle: T) -> TVec3<T> {
Rotation3::from_axis_angle(&TVec3::x_axis(), angle) * v Rotation3::from_axis_angle(&TVec3::x_axis(), angle) * v
} }
/// Rotate a three dimensional vector in homogeneous coordinates around the `X` axis. /// Rotate a three dimensional vector in homogeneous coordinates around the `X` axis.
pub fn rotate_x_vec4<N: RealField>(v: &TVec4<N>, angle: N) -> TVec4<N> { pub fn rotate_x_vec4<T: RealField>(v: &TVec4<T>, angle: T) -> TVec4<T> {
Rotation3::from_axis_angle(&TVec3::x_axis(), angle).to_homogeneous() * v Rotation3::from_axis_angle(&TVec3::x_axis(), angle).to_homogeneous() * v
} }
/// Rotate a three dimensional vector around the `Y` axis. /// Rotate a three dimensional vector around the `Y` axis.
pub fn rotate_y_vec3<N: RealField>(v: &TVec3<N>, angle: N) -> TVec3<N> { pub fn rotate_y_vec3<T: RealField>(v: &TVec3<T>, angle: T) -> TVec3<T> {
Rotation3::from_axis_angle(&TVec3::y_axis(), angle) * v Rotation3::from_axis_angle(&TVec3::y_axis(), angle) * v
} }
/// Rotate a three dimensional vector in homogeneous coordinates around the `Y` axis. /// Rotate a three dimensional vector in homogeneous coordinates around the `Y` axis.
pub fn rotate_y_vec4<N: RealField>(v: &TVec4<N>, angle: N) -> TVec4<N> { pub fn rotate_y_vec4<T: RealField>(v: &TVec4<T>, angle: T) -> TVec4<T> {
Rotation3::from_axis_angle(&TVec3::y_axis(), angle).to_homogeneous() * v Rotation3::from_axis_angle(&TVec3::y_axis(), angle).to_homogeneous() * v
} }
/// Rotate a three dimensional vector around the `Z` axis. /// Rotate a three dimensional vector around the `Z` axis.
pub fn rotate_z_vec3<N: RealField>(v: &TVec3<N>, angle: N) -> TVec3<N> { pub fn rotate_z_vec3<T: RealField>(v: &TVec3<T>, angle: T) -> TVec3<T> {
Rotation3::from_axis_angle(&TVec3::z_axis(), angle) * v Rotation3::from_axis_angle(&TVec3::z_axis(), angle) * v
} }
/// Rotate a three dimensional vector in homogeneous coordinates around the `Z` axis. /// Rotate a three dimensional vector in homogeneous coordinates around the `Z` axis.
pub fn rotate_z_vec4<N: RealField>(v: &TVec4<N>, angle: N) -> TVec4<N> { pub fn rotate_z_vec4<T: RealField>(v: &TVec4<T>, angle: T) -> TVec4<T> {
Rotation3::from_axis_angle(&TVec3::z_axis(), angle).to_homogeneous() * v Rotation3::from_axis_angle(&TVec3::z_axis(), angle).to_homogeneous() * v
} }
/// Computes a spherical linear interpolation between the vectors `x` and `y` assumed to be normalized. /// Computes a spherical linear interpolation between the vectors `x` and `y` assumed to be normalized.
pub fn slerp<N: RealField>(x: &TVec3<N>, y: &TVec3<N>, a: N) -> TVec3<N> { pub fn slerp<T: RealField>(x: &TVec3<T>, y: &TVec3<T>, a: T) -> TVec3<T> {
Unit::new_unchecked(*x) Unit::new_unchecked(*x)
.slerp(&Unit::new_unchecked(*y), a) .slerp(&Unit::new_unchecked(*y), a)
.into_inner() .into_inner()

View File

@ -12,7 +12,7 @@ use crate::traits::Number;
/// * [`rotation2d`](fn.rotation2d.html) /// * [`rotation2d`](fn.rotation2d.html)
/// * [`scaling2d`](fn.scaling2d.html) /// * [`scaling2d`](fn.scaling2d.html)
/// * [`translation2d`](fn.translation2d.html) /// * [`translation2d`](fn.translation2d.html)
pub fn rotation<N: RealField>(angle: N, v: &TVec3<N>) -> TMat4<N> { pub fn rotation<T: RealField>(angle: T, v: &TVec3<T>) -> TMat4<T> {
Rotation3::from_axis_angle(&Unit::new_normalize(*v), angle).to_homogeneous() Rotation3::from_axis_angle(&Unit::new_normalize(*v), angle).to_homogeneous()
} }
@ -25,7 +25,7 @@ pub fn rotation<N: RealField>(angle: N, v: &TVec3<N>) -> TMat4<N> {
/// * [`rotation2d`](fn.rotation2d.html) /// * [`rotation2d`](fn.rotation2d.html)
/// * [`scaling2d`](fn.scaling2d.html) /// * [`scaling2d`](fn.scaling2d.html)
/// * [`translation2d`](fn.translation2d.html) /// * [`translation2d`](fn.translation2d.html)
pub fn scaling<N: Number>(v: &TVec3<N>) -> TMat4<N> { pub fn scaling<T: Number>(v: &TVec3<T>) -> TMat4<T> {
TMat4::new_nonuniform_scaling(v) TMat4::new_nonuniform_scaling(v)
} }
@ -38,7 +38,7 @@ pub fn scaling<N: Number>(v: &TVec3<N>) -> TMat4<N> {
/// * [`rotation2d`](fn.rotation2d.html) /// * [`rotation2d`](fn.rotation2d.html)
/// * [`scaling2d`](fn.scaling2d.html) /// * [`scaling2d`](fn.scaling2d.html)
/// * [`translation2d`](fn.translation2d.html) /// * [`translation2d`](fn.translation2d.html)
pub fn translation<N: Number>(v: &TVec3<N>) -> TMat4<N> { pub fn translation<T: Number>(v: &TVec3<T>) -> TMat4<T> {
TMat4::new_translation(v) TMat4::new_translation(v)
} }
@ -51,7 +51,7 @@ pub fn translation<N: Number>(v: &TVec3<N>) -> TMat4<N> {
/// * [`translation`](fn.translation.html) /// * [`translation`](fn.translation.html)
/// * [`scaling2d`](fn.scaling2d.html) /// * [`scaling2d`](fn.scaling2d.html)
/// * [`translation2d`](fn.translation2d.html) /// * [`translation2d`](fn.translation2d.html)
pub fn rotation2d<N: RealField>(angle: N) -> TMat3<N> { pub fn rotation2d<T: RealField>(angle: T) -> TMat3<T> {
Rotation2::new(angle).to_homogeneous() Rotation2::new(angle).to_homogeneous()
} }
@ -64,7 +64,7 @@ pub fn rotation2d<N: RealField>(angle: N) -> TMat3<N> {
/// * [`translation`](fn.translation.html) /// * [`translation`](fn.translation.html)
/// * [`rotation2d`](fn.rotation2d.html) /// * [`rotation2d`](fn.rotation2d.html)
/// * [`translation2d`](fn.translation2d.html) /// * [`translation2d`](fn.translation2d.html)
pub fn scaling2d<N: Number>(v: &TVec2<N>) -> TMat3<N> { pub fn scaling2d<T: Number>(v: &TVec2<T>) -> TMat3<T> {
TMat3::new_nonuniform_scaling(v) TMat3::new_nonuniform_scaling(v)
} }
@ -77,6 +77,6 @@ pub fn scaling2d<N: Number>(v: &TVec2<N>) -> TMat3<N> {
/// * [`translation`](fn.translation.html) /// * [`translation`](fn.translation.html)
/// * [`rotation2d`](fn.rotation2d.html) /// * [`rotation2d`](fn.rotation2d.html)
/// * [`scaling2d`](fn.scaling2d.html) /// * [`scaling2d`](fn.scaling2d.html)
pub fn translation2d<N: Number>(v: &TVec2<N>) -> TMat3<N> { pub fn translation2d<T: Number>(v: &TVec2<T>) -> TMat3<T> {
TMat3::new_translation(v) TMat3::new_translation(v)
} }

View File

@ -1,14 +1,12 @@
use na::{U2, U3};
use crate::aliases::{TMat3, TMat4, TVec2, TVec3}; use crate::aliases::{TMat3, TMat4, TVec2, TVec3};
use crate::traits::Number; use crate::traits::Number;
/// Build planar projection matrix along normal axis and right-multiply it to `m`. /// Build planar projection matrix along normal axis and right-multiply it to `m`.
pub fn proj2d<N: Number>(m: &TMat3<N>, normal: &TVec2<N>) -> TMat3<N> { pub fn proj2d<T: Number>(m: &TMat3<T>, normal: &TVec2<T>) -> TMat3<T> {
let mut res = TMat3::identity(); let mut res = TMat3::identity();
{ {
let mut part = res.fixed_slice_mut::<U2, U2>(0, 0); let mut part = res.fixed_slice_mut::<2, 2>(0, 0);
part -= normal * normal.transpose(); part -= normal * normal.transpose();
} }
@ -16,11 +14,11 @@ pub fn proj2d<N: Number>(m: &TMat3<N>, normal: &TVec2<N>) -> TMat3<N> {
} }
/// Build planar projection matrix along normal axis, and right-multiply it to `m`. /// Build planar projection matrix along normal axis, and right-multiply it to `m`.
pub fn proj<N: Number>(m: &TMat4<N>, normal: &TVec3<N>) -> TMat4<N> { pub fn proj<T: Number>(m: &TMat4<T>, normal: &TVec3<T>) -> TMat4<T> {
let mut res = TMat4::identity(); let mut res = TMat4::identity();
{ {
let mut part = res.fixed_slice_mut::<U3, U3>(0, 0); let mut part = res.fixed_slice_mut::<3, 3>(0, 0);
part -= normal * normal.transpose(); part -= normal * normal.transpose();
} }
@ -28,33 +26,33 @@ pub fn proj<N: Number>(m: &TMat4<N>, normal: &TVec3<N>) -> TMat4<N> {
} }
/// Builds a reflection matrix and right-multiply it to `m`. /// Builds a reflection matrix and right-multiply it to `m`.
pub fn reflect2d<N: Number>(m: &TMat3<N>, normal: &TVec2<N>) -> TMat3<N> { pub fn reflect2d<T: Number>(m: &TMat3<T>, normal: &TVec2<T>) -> TMat3<T> {
let mut res = TMat3::identity(); let mut res = TMat3::identity();
{ {
let mut part = res.fixed_slice_mut::<U2, U2>(0, 0); let mut part = res.fixed_slice_mut::<2, 2>(0, 0);
part -= (normal * N::from_f64(2.0).unwrap()) * normal.transpose(); part -= (normal * T::from_f64(2.0).unwrap()) * normal.transpose();
} }
m * res m * res
} }
/// Builds a reflection matrix, and right-multiply it to `m`. /// Builds a reflection matrix, and right-multiply it to `m`.
pub fn reflect<N: Number>(m: &TMat4<N>, normal: &TVec3<N>) -> TMat4<N> { pub fn reflect<T: Number>(m: &TMat4<T>, normal: &TVec3<T>) -> TMat4<T> {
let mut res = TMat4::identity(); let mut res = TMat4::identity();
{ {
let mut part = res.fixed_slice_mut::<U3, U3>(0, 0); let mut part = res.fixed_slice_mut::<3, 3>(0, 0);
part -= (normal * N::from_f64(2.0).unwrap()) * normal.transpose(); part -= (normal * T::from_f64(2.0).unwrap()) * normal.transpose();
} }
m * res m * res
} }
/// Builds a scale-bias matrix. /// Builds a scale-bias matrix.
pub fn scale_bias_matrix<N: Number>(scale: N, bias: N) -> TMat4<N> { pub fn scale_bias_matrix<T: Number>(scale: T, bias: T) -> TMat4<T> {
let _0 = N::zero(); let _0 = T::zero();
let _1 = N::one(); let _1 = T::one();
TMat4::new( TMat4::new(
scale, _0, _0, bias, _0, scale, _0, bias, _0, _0, scale, bias, _0, _0, _0, _1, scale, _0, _0, bias, _0, scale, _0, bias, _0, _0, scale, bias, _0, _0, _0, _1,
@ -62,50 +60,50 @@ pub fn scale_bias_matrix<N: Number>(scale: N, bias: N) -> TMat4<N> {
} }
/// Builds a scale-bias matrix, and right-multiply it to `m`. /// Builds a scale-bias matrix, and right-multiply it to `m`.
pub fn scale_bias<N: Number>(m: &TMat4<N>, scale: N, bias: N) -> TMat4<N> { pub fn scale_bias<T: Number>(m: &TMat4<T>, scale: T, bias: T) -> TMat4<T> {
m * scale_bias_matrix(scale, bias) m * scale_bias_matrix(scale, bias)
} }
/// Transforms a matrix with a shearing on X axis. /// Transforms a matrix with a shearing on X axis.
pub fn shear2d_x<N: Number>(m: &TMat3<N>, y: N) -> TMat3<N> { pub fn shear2d_x<T: Number>(m: &TMat3<T>, y: T) -> TMat3<T> {
let _0 = N::zero(); let _0 = T::zero();
let _1 = N::one(); let _1 = T::one();
let shear = TMat3::new(_1, y, _0, _0, _1, _0, _0, _0, _1); let shear = TMat3::new(_1, y, _0, _0, _1, _0, _0, _0, _1);
m * shear m * shear
} }
/// Transforms a matrix with a shearing on Y axis. /// Transforms a matrix with a shearing on Y axis.
pub fn shear_x<N: Number>(m: &TMat4<N>, y: N, z: N) -> TMat4<N> { pub fn shear_x<T: Number>(m: &TMat4<T>, y: T, z: T) -> TMat4<T> {
let _0 = N::zero(); let _0 = T::zero();
let _1 = N::one(); let _1 = T::one();
let shear = TMat4::new(_1, _0, _0, _0, y, _1, _0, _0, z, _0, _1, _0, _0, _0, _0, _1); let shear = TMat4::new(_1, _0, _0, _0, y, _1, _0, _0, z, _0, _1, _0, _0, _0, _0, _1);
m * shear m * shear
} }
/// Transforms a matrix with a shearing on Y axis. /// Transforms a matrix with a shearing on Y axis.
pub fn shear2d_y<N: Number>(m: &TMat3<N>, x: N) -> TMat3<N> { pub fn shear2d_y<T: Number>(m: &TMat3<T>, x: T) -> TMat3<T> {
let _0 = N::zero(); let _0 = T::zero();
let _1 = N::one(); let _1 = T::one();
let shear = TMat3::new(_1, _0, _0, x, _1, _0, _0, _0, _1); let shear = TMat3::new(_1, _0, _0, x, _1, _0, _0, _0, _1);
m * shear m * shear
} }
/// Transforms a matrix with a shearing on Y axis. /// Transforms a matrix with a shearing on Y axis.
pub fn shear_y<N: Number>(m: &TMat4<N>, x: N, z: N) -> TMat4<N> { pub fn shear_y<T: Number>(m: &TMat4<T>, x: T, z: T) -> TMat4<T> {
let _0 = N::zero(); let _0 = T::zero();
let _1 = N::one(); let _1 = T::one();
let shear = TMat4::new(_1, x, _0, _0, _0, _1, _0, _0, _0, z, _1, _0, _0, _0, _0, _1); let shear = TMat4::new(_1, x, _0, _0, _0, _1, _0, _0, _0, z, _1, _0, _0, _0, _0, _1);
m * shear m * shear
} }
/// Transforms a matrix with a shearing on Z axis. /// Transforms a matrix with a shearing on Z axis.
pub fn shear_z<N: Number>(m: &TMat4<N>, x: N, y: N) -> TMat4<N> { pub fn shear_z<T: Number>(m: &TMat4<T>, x: T, y: T) -> TMat4<T> {
let _0 = N::zero(); let _0 = T::zero();
let _1 = N::one(); let _1 = T::one();
let shear = TMat4::new(_1, _0, x, _0, _0, _1, y, _0, _0, _0, _1, _0, _0, _0, _0, _1); let shear = TMat4::new(_1, _0, x, _0, _0, _1, y, _0, _0, _0, _1, _0, _0, _0, _0, _1);
m * shear m * shear

View File

@ -12,7 +12,7 @@ use crate::traits::Number;
/// * [`scaling2d`](fn.scaling2d.html) /// * [`scaling2d`](fn.scaling2d.html)
/// * [`translate2d`](fn.translate2d.html) /// * [`translate2d`](fn.translate2d.html)
/// * [`translation2d`](fn.translation2d.html) /// * [`translation2d`](fn.translation2d.html)
pub fn rotate2d<N: RealField>(m: &TMat3<N>, angle: N) -> TMat3<N> { pub fn rotate2d<T: RealField>(m: &TMat3<T>, angle: T) -> TMat3<T> {
m * UnitComplex::new(angle).to_homogeneous() m * UnitComplex::new(angle).to_homogeneous()
} }
@ -25,7 +25,7 @@ pub fn rotate2d<N: RealField>(m: &TMat3<N>, angle: N) -> TMat3<N> {
/// * [`scaling2d`](fn.scaling2d.html) /// * [`scaling2d`](fn.scaling2d.html)
/// * [`translate2d`](fn.translate2d.html) /// * [`translate2d`](fn.translate2d.html)
/// * [`translation2d`](fn.translation2d.html) /// * [`translation2d`](fn.translation2d.html)
pub fn scale2d<N: Number>(m: &TMat3<N>, v: &TVec2<N>) -> TMat3<N> { pub fn scale2d<T: Number>(m: &TMat3<T>, v: &TVec2<T>) -> TMat3<T> {
m.prepend_nonuniform_scaling(v) m.prepend_nonuniform_scaling(v)
} }
@ -38,6 +38,6 @@ pub fn scale2d<N: Number>(m: &TMat3<N>, v: &TVec2<N>) -> TMat3<N> {
/// * [`scale2d`](fn.scale2d.html) /// * [`scale2d`](fn.scale2d.html)
/// * [`scaling2d`](fn.scaling2d.html) /// * [`scaling2d`](fn.scaling2d.html)
/// * [`translation2d`](fn.translation2d.html) /// * [`translation2d`](fn.translation2d.html)
pub fn translate2d<N: Number>(m: &TMat3<N>, v: &TVec2<N>) -> TMat3<N> { pub fn translate2d<T: Number>(m: &TMat3<T>, v: &TVec2<T>) -> TMat3<T> {
m.prepend_translation(v) m.prepend_translation(v)
} }

View File

@ -1,20 +1,16 @@
use na::{DefaultAllocator, RealField}; use na::RealField;
use crate::aliases::TVec; use crate::aliases::TVec;
use crate::traits::{Alloc, Dimension};
/// The angle between two vectors. /// The angle between two vectors.
pub fn angle<N: RealField, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> N pub fn angle<T: RealField, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> T {
where
DefaultAllocator: Alloc<N, D>,
{
x.angle(y) x.angle(y)
} }
//pub fn oriented_angle<N: RealField>(x: &TVec2<N>, y: &TVec2<N>) -> N { //pub fn oriented_angle<T: RealField>(x: &TVec2<T>, y: &TVec2<T>) -> T {
// unimplemented!() // unimplemented!()
//} //}
// //
//pub fn oriented_angle_ref<N: RealField>(x: &TVec3<N>, y: &TVec3<N>, refv: &TVec3<N>) -> N { //pub fn oriented_angle_ref<T: RealField>(x: &TVec3<T>, y: &TVec3<T>, refv: &TVec3<T>) -> T {
// unimplemented!() // unimplemented!()
//} //}

View File

@ -1,14 +1,14 @@
use na::{DefaultAllocator, RealField}; use na::RealField;
use crate::aliases::{TVec, TVec2, TVec3}; use crate::aliases::{TVec, TVec2, TVec3};
use crate::traits::{Alloc, Dimension, Number}; use crate::traits::Number;
/// Returns `true` if two vectors are collinear (up to an epsilon). /// Returns `true` if two vectors are collinear (up to an epsilon).
/// ///
/// # See also: /// # See also:
/// ///
/// * [`are_collinear2d`](fn.are_collinear2d.html) /// * [`are_collinear2d`](fn.are_collinear2d.html)
pub fn are_collinear<N: Number>(v0: &TVec3<N>, v1: &TVec3<N>, epsilon: N) -> bool { pub fn are_collinear<T: Number>(v0: &TVec3<T>, v1: &TVec3<T>, epsilon: T) -> bool {
is_null(&v0.cross(v1), epsilon) is_null(&v0.cross(v1), epsilon)
} }
@ -17,43 +17,34 @@ pub fn are_collinear<N: Number>(v0: &TVec3<N>, v1: &TVec3<N>, epsilon: N) -> boo
/// # See also: /// # See also:
/// ///
/// * [`are_collinear`](fn.are_collinear.html) /// * [`are_collinear`](fn.are_collinear.html)
pub fn are_collinear2d<N: Number>(v0: &TVec2<N>, v1: &TVec2<N>, epsilon: N) -> bool { pub fn are_collinear2d<T: Number>(v0: &TVec2<T>, v1: &TVec2<T>, epsilon: T) -> bool {
abs_diff_eq!(v0.perp(v1), N::zero(), epsilon = epsilon) abs_diff_eq!(v0.perp(v1), T::zero(), epsilon = epsilon)
} }
/// Returns `true` if two vectors are orthogonal (up to an epsilon). /// Returns `true` if two vectors are orthogonal (up to an epsilon).
pub fn are_orthogonal<N: Number, D: Dimension>(v0: &TVec<N, D>, v1: &TVec<N, D>, epsilon: N) -> bool pub fn are_orthogonal<T: Number, const D: usize>(
where v0: &TVec<T, D>,
DefaultAllocator: Alloc<N, D>, v1: &TVec<T, D>,
{ epsilon: T,
abs_diff_eq!(v0.dot(v1), N::zero(), epsilon = epsilon) ) -> bool {
abs_diff_eq!(v0.dot(v1), T::zero(), epsilon = epsilon)
} }
//pub fn are_orthonormal<N: Number, D: Dimension>(v0: &TVec<N, D>, v1: &TVec<N, D>, epsilon: N) -> bool //pub fn are_orthonormal<T: Number, const D: usize>(v0: &TVec<T, D>, v1: &TVec<T, D>, epsilon: T) -> bool {
// where DefaultAllocator: Alloc<N, D> {
// unimplemented!() // unimplemented!()
//} //}
/// Returns `true` if all the components of `v` are zero (up to an epsilon). /// Returns `true` if all the components of `v` are zero (up to an epsilon).
pub fn is_comp_null<N: Number, D: Dimension>(v: &TVec<N, D>, epsilon: N) -> TVec<bool, D> pub fn is_comp_null<T: Number, const D: usize>(v: &TVec<T, D>, epsilon: T) -> TVec<bool, D> {
where v.map(|x| abs_diff_eq!(x, T::zero(), epsilon = epsilon))
DefaultAllocator: Alloc<N, D>,
{
v.map(|x| abs_diff_eq!(x, N::zero(), epsilon = epsilon))
} }
/// Returns `true` if `v` has a magnitude of 1 (up to an epsilon). /// Returns `true` if `v` has a magnitude of 1 (up to an epsilon).
pub fn is_normalized<N: RealField, D: Dimension>(v: &TVec<N, D>, epsilon: N) -> bool pub fn is_normalized<T: RealField, const D: usize>(v: &TVec<T, D>, epsilon: T) -> bool {
where abs_diff_eq!(v.norm_squared(), T::one(), epsilon = epsilon * epsilon)
DefaultAllocator: Alloc<N, D>,
{
abs_diff_eq!(v.norm_squared(), N::one(), epsilon = epsilon * epsilon)
} }
/// Returns `true` if `v` is zero (up to an epsilon). /// Returns `true` if `v` is zero (up to an epsilon).
pub fn is_null<N: Number, D: Dimension>(v: &TVec<N, D>, epsilon: N) -> bool pub fn is_null<T: Number, const D: usize>(v: &TVec<T, D>, epsilon: T) -> bool {
where abs_diff_eq!(*v, TVec::<T, D>::zeros(), epsilon = epsilon)
DefaultAllocator: Alloc<N, D>,
{
abs_diff_eq!(*v, TVec::<N, D>::zeros(), epsilon = epsilon)
} }

View File

@ -1,29 +1,46 @@
use na::{Scalar, RealField, U3, DefaultAllocator}; use na::{DefaultAllocator, RealField, Scalar, U3};
use crate::traits::{Number, Alloc, Dimension};
use crate::aliases::TVec; use crate::aliases::TVec;
use crate::traits::{Alloc, Dimension, Number};
pub fn bitCount<T>(v: T) -> i32 { pub fn bitCount<T>(v: T) -> i32 {
unimplemented!() unimplemented!()
} }
pub fn bitCount2<N: Scalar, D: Dimension>(v: &TVec<N, D>) -> TVec<i32, D> pub fn bitCount2<T: Scalar, const D: usize>(v: &TVec<T, D>) -> TVec<i32, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<T, D>,
{
unimplemented!() unimplemented!()
} }
pub fn bitfieldExtract<N: Scalar, D: Dimension>(Value: &TVec<N, D>, Offset: i32, Bits: i32) -> TVec<N, D> pub fn bitfieldExtract<T: Scalar, const D: usize>(
where DefaultAllocator: Alloc<N, D> { Value: &TVec<T, D>,
Offset: i32,
Bits: i32,
) -> TVec<T, D>
where
DefaultAllocator: Alloc<T, D>,
{
unimplemented!() unimplemented!()
} }
pub fn bitfieldInsert<N: Scalar, D: Dimension>(Base: &TVec<N, D>, Insert: &TVec<N, D>, Offset: i32, Bits: i32) -> TVec<N, D> pub fn bitfieldInsert<T: Scalar, const D: usize>(
where DefaultAllocator: Alloc<N, D> { Base: &TVec<T, D>,
Insert: &TVec<T, D>,
Offset: i32,
Bits: i32,
) -> TVec<T, D>
where
DefaultAllocator: Alloc<T, D>,
{
unimplemented!() unimplemented!()
} }
pub fn bitfieldReverse<N: Scalar, D: Dimension>(v: &TVec<N, D>) -> TVec<N, D> pub fn bitfieldReverse<T: Scalar, const D: usize>(v: &TVec<T, D>) -> TVec<T, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<T, D>,
{
unimplemented!() unimplemented!()
} }
@ -31,8 +48,10 @@ pub fn findLSB<IU>(x: IU) -> u32 {
unimplemented!() unimplemented!()
} }
pub fn findLSB2<N: Scalar, D: Dimension>(v: &TVec<N, D>) -> TVec<i32, D> pub fn findLSB2<T: Scalar, const D: usize>(v: &TVec<T, D>) -> TVec<i32, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<T, D>,
{
unimplemented!() unimplemented!()
} }
@ -40,27 +59,53 @@ pub fn findMSB<IU>(x: IU) -> i32 {
unimplemented!() unimplemented!()
} }
pub fn findMSB2<N: Scalar, D: Dimension>(v: &TVec<N, D>) -> TVec<i32, D> pub fn findMSB2<T: Scalar, const D: usize>(v: &TVec<T, D>) -> TVec<i32, D>
where DefaultAllocator: Alloc<N, D> { where
DefaultAllocator: Alloc<T, D>,
{
unimplemented!() unimplemented!()
} }
pub fn imulExtended<N: Scalar, D: Dimension>(x: &TVec<i32, D>, y: &TVec<i32, D>, msb: &TVec<i32, D>, lsb: &TVec<i32, D>) pub fn imulExtended<T: Scalar, const D: usize>(
where DefaultAllocator: Alloc<N, D> { x: &TVec<i32, D>,
y: &TVec<i32, D>,
msb: &TVec<i32, D>,
lsb: &TVec<i32, D>,
) where
DefaultAllocator: Alloc<T, D>,
{
unimplemented!() unimplemented!()
} }
pub fn uaddCarry<N: Scalar, D: Dimension>(x: &TVec<u32, D>, y: &TVec<u32, D>, carry: &TVec<u32, D>) -> TVec<u32, D> pub fn uaddCarry<T: Scalar, const D: usize>(
where DefaultAllocator: Alloc<N, D> { x: &TVec<u32, D>,
y: &TVec<u32, D>,
carry: &TVec<u32, D>,
) -> TVec<u32, D>
where
DefaultAllocator: Alloc<T, D>,
{
unimplemented!() unimplemented!()
} }
pub fn umulExtended<N: Scalar, D: Dimension>(x: &TVec<u32, D>, y: &TVec<u32, D>, msb: &TVec<u32, D>, lsb: &TVec<u32, D>) pub fn umulExtended<T: Scalar, const D: usize>(
where DefaultAllocator: Alloc<N, D> { x: &TVec<u32, D>,
unimplemented!() y: &TVec<u32, D>,
} msb: &TVec<u32, D>,
lsb: &TVec<u32, D>,
pub fn usubBorrow<N: Scalar, D: Dimension>(x: &TVec<u32, D>, y: &TVec<u32, D>, borrow: &TVec<u32, D>) -> TVec<u32, D> ) where
where DefaultAllocator: Alloc<N, D> { DefaultAllocator: Alloc<T, D>,
{
unimplemented!()
}
pub fn usubBorrow<T: Scalar, const D: usize>(
x: &TVec<u32, D>,
y: &TVec<u32, D>,
borrow: &TVec<u32, D>,
) -> TVec<u32, D>
where
DefaultAllocator: Alloc<T, D>,
{
unimplemented!() unimplemented!()
} }

View File

@ -54,7 +54,7 @@
### Vector and matrix construction ### Vector and matrix construction
Vectors, matrices, and quaternions can be constructed using several approaches: Vectors, matrices, and quaternions can be constructed using several approaches:
* Using functions with the same name as their type in lower-case. For example [`glm::vec3(x, y, z)`](fn.vec3.html) will create a 3D vector. * Using functions with the same name as their type in lower-case. For example [`glm::vec3(x, y, z)`](fn.vec3.html) will create a 3D vector.
* Using the `::new` constructor. For example [`Vec3::new(x, y, z)`](../nalgebra/base/type.MatrixMN.html#method.new-27) will create a 3D vector. * Using the `::new` constructor. For example [`Vec3::new(x, y, z)`](../nalgebra/base/type.OMatrix.html#method.new-27) will create a 3D vector.
* Using the functions prefixed by `make_` to build a vector a matrix from a slice. For example [`glm::make_vec3(&[x, y, z])`](fn.make_vec3.html) will create a 3D vector. * Using the functions prefixed by `make_` to build a vector a matrix from a slice. For example [`glm::make_vec3(&[x, y, z])`](fn.make_vec3.html) will create a 3D vector.
Keep in mind that constructing a matrix using this type of functions require its components to be arranged in column-major order on the slice. Keep in mind that constructing a matrix using this type of functions require its components to be arranged in column-major order on the slice.
* Using a geometric construction function. For example [`glm::rotation(angle, axis)`](fn.rotation.html) will build a 4x4 homogeneous rotation matrix from an angle (in radians) and an axis. * Using a geometric construction function. For example [`glm::rotation(angle, axis)`](fn.rotation.html) will build a 4x4 homogeneous rotation matrix from an angle (in radians) and an axis.
@ -119,7 +119,7 @@ extern crate approx;
extern crate nalgebra as na; extern crate nalgebra as na;
pub use crate::aliases::*; pub use crate::aliases::*;
pub use crate::traits::{Alloc, Dimension, Number}; pub use crate::traits::Number;
pub use common::{ pub use common::{
abs, ceil, clamp, clamp_scalar, clamp_vec, float_bits_to_int, float_bits_to_int_vec, abs, ceil, clamp, clamp_scalar, clamp_vec, float_bits_to_int, float_bits_to_int_vec,
float_bits_to_uint, float_bits_to_uint_vec, floor, fract, int_bits_to_float, float_bits_to_uint, float_bits_to_uint_vec, floor, fract, int_bits_to_float,

View File

@ -1,52 +1,40 @@
use na::{DefaultAllocator, RealField, Scalar}; use na::{Const, DimMin, RealField, Scalar};
use crate::aliases::{TMat, TVec}; use crate::aliases::{TMat, TVec};
use crate::traits::{Alloc, Dimension, Number}; use crate::traits::Number;
/// The determinant of the matrix `m`. /// The determinant of the matrix `m`.
pub fn determinant<N: RealField, D: Dimension>(m: &TMat<N, D, D>) -> N pub fn determinant<T: RealField, const D: usize>(m: &TMat<T, D, D>) -> T
where where
DefaultAllocator: Alloc<N, D, D>, Const<D>: DimMin<Const<D>, Output = Const<D>>,
{ {
m.determinant() m.determinant()
} }
/// The inverse of the matrix `m`. /// The inverse of the matrix `m`.
pub fn inverse<N: RealField, D: Dimension>(m: &TMat<N, D, D>) -> TMat<N, D, D> pub fn inverse<T: RealField, const D: usize>(m: &TMat<T, D, D>) -> TMat<T, D, D> {
where
DefaultAllocator: Alloc<N, D, D>,
{
m.clone() m.clone()
.try_inverse() .try_inverse()
.unwrap_or_else(TMat::<N, D, D>::zeros) .unwrap_or_else(TMat::<T, D, D>::zeros)
} }
/// Component-wise multiplication of two matrices. /// Component-wise multiplication of two matrices.
pub fn matrix_comp_mult<N: Number, R: Dimension, C: Dimension>( pub fn matrix_comp_mult<T: Number, const R: usize, const C: usize>(
x: &TMat<N, R, C>, x: &TMat<T, R, C>,
y: &TMat<N, R, C>, y: &TMat<T, R, C>,
) -> TMat<N, R, C> ) -> TMat<T, R, C> {
where
DefaultAllocator: Alloc<N, R, C>,
{
x.component_mul(y) x.component_mul(y)
} }
/// Treats the first parameter `c` as a column vector and the second parameter `r` as a row vector and does a linear algebraic matrix multiply `c * r`. /// Treats the first parameter `c` as a column vector and the second parameter `r` as a row vector and does a linear algebraic matrix multiply `c * r`.
pub fn outer_product<N: Number, R: Dimension, C: Dimension>( pub fn outer_product<T: Number, const R: usize, const C: usize>(
c: &TVec<N, R>, c: &TVec<T, R>,
r: &TVec<N, C>, r: &TVec<T, C>,
) -> TMat<N, R, C> ) -> TMat<T, R, C> {
where
DefaultAllocator: Alloc<N, R, C>,
{
c * r.transpose() c * r.transpose()
} }
/// The transpose of the matrix `m`. /// The transpose of the matrix `m`.
pub fn transpose<N: Scalar, R: Dimension, C: Dimension>(x: &TMat<N, R, C>) -> TMat<N, C, R> pub fn transpose<T: Scalar, const R: usize, const C: usize>(x: &TMat<T, R, C>) -> TMat<T, C, R> {
where
DefaultAllocator: Alloc<N, R, C>,
{
x.transpose() x.transpose()
} }

View File

@ -1,52 +1,51 @@
use na::Scalar; use na::Scalar;
use crate::aliases::{Vec2, Vec4, UVec2}; use crate::aliases::{UVec2, Vec2, Vec4};
pub fn packDouble2x32<T: Scalar>(v: &UVec2) -> f64 {
pub fn packDouble2x32<N: Scalar>(v: &UVec2) -> f64 {
unimplemented!() unimplemented!()
} }
pub fn packHalf2x16<N: Scalar>(v: &Vec2) -> u32 { pub fn packHalf2x16<T: Scalar>(v: &Vec2) -> u32 {
unimplemented!() unimplemented!()
} }
pub fn packSnorm2x16<N: Scalar>(v: &Vec2) -> u32 { pub fn packSnorm2x16<T: Scalar>(v: &Vec2) -> u32 {
unimplemented!() unimplemented!()
} }
pub fn packSnorm4x8<N: Scalar>(v: &Vec4) -> u32 { pub fn packSnorm4x8<T: Scalar>(v: &Vec4) -> u32 {
unimplemented!() unimplemented!()
} }
pub fn packUnorm2x16<N: Scalar>(v: &Vec2) -> u32 { pub fn packUnorm2x16<T: Scalar>(v: &Vec2) -> u32 {
unimplemented!() unimplemented!()
} }
pub fn packUnorm4x8<N: Scalar>(v: &Vec4) -> u32 { pub fn packUnorm4x8<T: Scalar>(v: &Vec4) -> u32 {
unimplemented!() unimplemented!()
} }
pub fn unpackDouble2x32<N: Scalar>(v: f64) -> UVec2 { pub fn unpackDouble2x32<T: Scalar>(v: f64) -> UVec2 {
unimplemented!() unimplemented!()
} }
pub fn unpackHalf2x16<N: Scalar>(v: u32) -> Vec2 { pub fn unpackHalf2x16<T: Scalar>(v: u32) -> Vec2 {
unimplemented!() unimplemented!()
} }
pub fn unpackSnorm2x16<N: Scalar>(p: u32) -> Vec2 { pub fn unpackSnorm2x16<T: Scalar>(p: u32) -> Vec2 {
unimplemented!() unimplemented!()
} }
pub fn unpackSnorm4x8<N: Scalar>(p: u32) -> Vec4 { pub fn unpackSnorm4x8<T: Scalar>(p: u32) -> Vec4 {
unimplemented!() unimplemented!()
} }
pub fn unpackUnorm2x16<N: Scalar>(p: u32) -> Vec2 { pub fn unpackUnorm2x16<T: Scalar>(p: u32) -> Vec2 {
unimplemented!() unimplemented!()
} }
pub fn unpackUnorm4x8<N: Scalar>(p: u32) -> Vec4 { pub fn unpackUnorm4x8<T: Scalar>(p: u32) -> Vec4 {
unimplemented!() unimplemented!()
} }

View File

@ -1,15 +1,10 @@
use approx::AbsDiffEq; use approx::AbsDiffEq;
use num::{Bounded, FromPrimitive, Signed}; use num::{Bounded, FromPrimitive, Signed};
use na::allocator::Allocator; use na::Scalar;
use na::{DimMin, DimName, Scalar, U1};
use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub}; use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub};
use std::cmp::PartialOrd; use std::cmp::PartialOrd;
/// A type-level number representing a vector, matrix row, or matrix column, dimension.
pub trait Dimension: DimName + DimMin<Self, Output = Self> {}
impl<D: DimName + DimMin<D, Output = Self>> Dimension for D {}
/// A number that can either be an integer or a float. /// A number that can either be an integer or a float.
pub trait Number: pub trait Number:
Scalar Scalar
@ -39,64 +34,3 @@ impl<
> Number for T > Number for T
{ {
} }
#[doc(hidden)]
pub trait Alloc<N: Scalar, R: Dimension, C: Dimension = U1>:
Allocator<N, R>
+ Allocator<N, C>
+ Allocator<N, U1, R>
+ Allocator<N, U1, C>
+ Allocator<N, R, C>
+ Allocator<N, C, R>
+ Allocator<N, R, R>
+ Allocator<N, C, C>
+ Allocator<bool, R>
+ Allocator<bool, C>
+ Allocator<f32, R>
+ Allocator<f32, C>
+ Allocator<u32, R>
+ Allocator<u32, C>
+ Allocator<i32, R>
+ Allocator<i32, C>
+ Allocator<f64, R>
+ Allocator<f64, C>
+ Allocator<u64, R>
+ Allocator<u64, C>
+ Allocator<i64, R>
+ Allocator<i64, C>
+ Allocator<i16, R>
+ Allocator<i16, C>
+ Allocator<(usize, usize), R>
+ Allocator<(usize, usize), C>
{
}
impl<N: Scalar, R: Dimension, C: Dimension, T> Alloc<N, R, C> for T where
T: Allocator<N, R>
+ Allocator<N, C>
+ Allocator<N, U1, R>
+ Allocator<N, U1, C>
+ Allocator<N, R, C>
+ Allocator<N, C, R>
+ Allocator<N, R, R>
+ Allocator<N, C, C>
+ Allocator<bool, R>
+ Allocator<bool, C>
+ Allocator<f32, R>
+ Allocator<f32, C>
+ Allocator<u32, R>
+ Allocator<u32, C>
+ Allocator<i32, R>
+ Allocator<i32, C>
+ Allocator<f64, R>
+ Allocator<f64, C>
+ Allocator<u64, R>
+ Allocator<u64, C>
+ Allocator<i64, R>
+ Allocator<i64, C>
+ Allocator<i16, R>
+ Allocator<i16, C>
+ Allocator<(usize, usize), R>
+ Allocator<(usize, usize), C>
{
}

View File

@ -1,124 +1,78 @@
use na::{self, DefaultAllocator, RealField}; use na::{self, RealField};
use crate::aliases::TVec; use crate::aliases::TVec;
use crate::traits::{Alloc, Dimension};
/// Component-wise arc-cosinus. /// Component-wise arc-cosinus.
pub fn acos<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn acos<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.map(|e| e.acos()) x.map(|e| e.acos())
} }
/// Component-wise hyperbolic arc-cosinus. /// Component-wise hyperbolic arc-cosinus.
pub fn acosh<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn acosh<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.map(|e| e.acosh()) x.map(|e| e.acosh())
} }
/// Component-wise arc-sinus. /// Component-wise arc-sinus.
pub fn asin<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn asin<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.map(|e| e.asin()) x.map(|e| e.asin())
} }
/// Component-wise hyperbolic arc-sinus. /// Component-wise hyperbolic arc-sinus.
pub fn asinh<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn asinh<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.map(|e| e.asinh()) x.map(|e| e.asinh())
} }
/// Component-wise arc-tangent of `y / x`. /// Component-wise arc-tangent of `y / x`.
pub fn atan2<N: RealField, D: Dimension>(y: &TVec<N, D>, x: &TVec<N, D>) -> TVec<N, D> pub fn atan2<T: RealField, const D: usize>(y: &TVec<T, D>, x: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
y.zip_map(x, |y, x| y.atan2(x)) y.zip_map(x, |y, x| y.atan2(x))
} }
/// Component-wise arc-tangent. /// Component-wise arc-tangent.
pub fn atan<N: RealField, D: Dimension>(y_over_x: &TVec<N, D>) -> TVec<N, D> pub fn atan<T: RealField, const D: usize>(y_over_x: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
y_over_x.map(|e| e.atan()) y_over_x.map(|e| e.atan())
} }
/// Component-wise hyperbolic arc-tangent. /// Component-wise hyperbolic arc-tangent.
pub fn atanh<N: RealField, D: Dimension>(x: &TVec<N, D>) -> TVec<N, D> pub fn atanh<T: RealField, const D: usize>(x: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.map(|e| e.atanh()) x.map(|e| e.atanh())
} }
/// Component-wise cosinus. /// Component-wise cosinus.
pub fn cos<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D> pub fn cos<T: RealField, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
angle.map(|e| e.cos()) angle.map(|e| e.cos())
} }
/// Component-wise hyperbolic cosinus. /// Component-wise hyperbolic cosinus.
pub fn cosh<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D> pub fn cosh<T: RealField, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
angle.map(|e| e.cosh()) angle.map(|e| e.cosh())
} }
/// Component-wise conversion from radians to degrees. /// Component-wise conversion from radians to degrees.
pub fn degrees<N: RealField, D: Dimension>(radians: &TVec<N, D>) -> TVec<N, D> pub fn degrees<T: RealField, const D: usize>(radians: &TVec<T, D>) -> TVec<T, D> {
where radians.map(|e| e * na::convert(180.0) / T::pi())
DefaultAllocator: Alloc<N, D>,
{
radians.map(|e| e * na::convert(180.0) / N::pi())
} }
/// Component-wise conversion fro degrees to radians. /// Component-wise conversion fro degrees to radians.
pub fn radians<N: RealField, D: Dimension>(degrees: &TVec<N, D>) -> TVec<N, D> pub fn radians<T: RealField, const D: usize>(degrees: &TVec<T, D>) -> TVec<T, D> {
where degrees.map(|e| e * T::pi() / na::convert(180.0))
DefaultAllocator: Alloc<N, D>,
{
degrees.map(|e| e * N::pi() / na::convert(180.0))
} }
/// Component-wise sinus. /// Component-wise sinus.
pub fn sin<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D> pub fn sin<T: RealField, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
angle.map(|e| e.sin()) angle.map(|e| e.sin())
} }
/// Component-wise hyperbolic sinus. /// Component-wise hyperbolic sinus.
pub fn sinh<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D> pub fn sinh<T: RealField, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
angle.map(|e| e.sinh()) angle.map(|e| e.sinh())
} }
/// Component-wise tangent. /// Component-wise tangent.
pub fn tan<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D> pub fn tan<T: RealField, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
angle.map(|e| e.tan()) angle.map(|e| e.tan())
} }
/// Component-wise hyperbolic tangent. /// Component-wise hyperbolic tangent.
pub fn tanh<N: RealField, D: Dimension>(angle: &TVec<N, D>) -> TVec<N, D> pub fn tanh<T: RealField, const D: usize>(angle: &TVec<T, D>) -> TVec<T, D> {
where
DefaultAllocator: Alloc<N, D>,
{
angle.map(|e| e.tanh()) angle.map(|e| e.tanh())
} }

View File

@ -1,7 +1,5 @@
use na::DefaultAllocator;
use crate::aliases::TVec; use crate::aliases::TVec;
use crate::traits::{Alloc, Dimension, Number}; use crate::traits::Number;
/// Checks that all the vector components are `true`. /// Checks that all the vector components are `true`.
/// ///
@ -20,10 +18,7 @@ use crate::traits::{Alloc, Dimension, Number};
/// ///
/// * [`any`](fn.any.html) /// * [`any`](fn.any.html)
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
pub fn all<D: Dimension>(v: &TVec<bool, D>) -> bool pub fn all<const D: usize>(v: &TVec<bool, D>) -> bool {
where
DefaultAllocator: Alloc<bool, D>,
{
v.iter().all(|x| *x) v.iter().all(|x| *x)
} }
@ -47,10 +42,7 @@ where
/// ///
/// * [`all`](fn.all.html) /// * [`all`](fn.all.html)
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
pub fn any<D: Dimension>(v: &TVec<bool, D>) -> bool pub fn any<const D: usize>(v: &TVec<bool, D>) -> bool {
where
DefaultAllocator: Alloc<bool, D>,
{
v.iter().any(|x| *x) v.iter().any(|x| *x)
} }
@ -73,10 +65,7 @@ where
/// * [`less_than_equal`](fn.less_than_equal.html) /// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal`](fn.not_equal.html)
pub fn equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D> pub fn equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| x == y) x.zip_map(y, |x, y| x == y)
} }
@ -99,10 +88,7 @@ where
/// * [`less_than_equal`](fn.less_than_equal.html) /// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal`](fn.not_equal.html)
pub fn greater_than<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D> pub fn greater_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| x > y) x.zip_map(y, |x, y| x > y)
} }
@ -125,10 +111,10 @@ where
/// * [`less_than_equal`](fn.less_than_equal.html) /// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal`](fn.not_equal.html)
pub fn greater_than_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D> pub fn greater_than_equal<T: Number, const D: usize>(
where x: &TVec<T, D>,
DefaultAllocator: Alloc<N, D>, y: &TVec<T, D>,
{ ) -> TVec<bool, D> {
x.zip_map(y, |x, y| x >= y) x.zip_map(y, |x, y| x >= y)
} }
@ -151,10 +137,7 @@ where
/// * [`less_than_equal`](fn.less_than_equal.html) /// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal`](fn.not_equal.html)
pub fn less_than<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D> pub fn less_than<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| x < y) x.zip_map(y, |x, y| x < y)
} }
@ -177,10 +160,7 @@ where
/// * [`less_than`](fn.less_than.html) /// * [`less_than`](fn.less_than.html)
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal`](fn.not_equal.html)
pub fn less_than_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D> pub fn less_than_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| x <= y) x.zip_map(y, |x, y| x <= y)
} }
@ -204,10 +184,7 @@ where
/// * [`less_than`](fn.less_than.html) /// * [`less_than`](fn.less_than.html)
/// * [`less_than_equal`](fn.less_than_equal.html) /// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not_equal`](fn.not_equal.html) /// * [`not_equal`](fn.not_equal.html)
pub fn not<D: Dimension>(v: &TVec<bool, D>) -> TVec<bool, D> pub fn not<const D: usize>(v: &TVec<bool, D>) -> TVec<bool, D> {
where
DefaultAllocator: Alloc<bool, D>,
{
v.map(|x| !x) v.map(|x| !x)
} }
@ -230,9 +207,6 @@ where
/// * [`less_than`](fn.less_than.html) /// * [`less_than`](fn.less_than.html)
/// * [`less_than_equal`](fn.less_than_equal.html) /// * [`less_than_equal`](fn.less_than_equal.html)
/// * [`not`](fn.not.html) /// * [`not`](fn.not.html)
pub fn not_equal<N: Number, D: Dimension>(x: &TVec<N, D>, y: &TVec<N, D>) -> TVec<bool, D> pub fn not_equal<T: Number, const D: usize>(x: &TVec<T, D>, y: &TVec<T, D>) -> TVec<bool, D> {
where
DefaultAllocator: Alloc<N, D>,
{
x.zip_map(y, |x, y| x != y) x.zip_map(y, |x, y| x != y)
} }

View File

@ -7,7 +7,7 @@ use num_complex::Complex;
use na::allocator::Allocator; use na::allocator::Allocator;
use na::dimension::Dim; use na::dimension::Dim;
use na::storage::Storage; use na::storage::Storage;
use na::{DefaultAllocator, Matrix, MatrixMN, MatrixN, Scalar}; use na::{DefaultAllocator, Matrix, OMatrix, Scalar};
use lapack; use lapack;
@ -15,39 +15,39 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(serialize = "DefaultAllocator: Allocator<N, D>, serde(bound(serialize = "DefaultAllocator: Allocator<T, D>,
MatrixN<N, D>: Serialize")) OMatrix<T, D, D>: Serialize"))
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(deserialize = "DefaultAllocator: Allocator<N, D>, serde(bound(deserialize = "DefaultAllocator: Allocator<T, D>,
MatrixN<N, D>: Deserialize<'de>")) OMatrix<T, D, D>: Deserialize<'de>"))
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Cholesky<N: Scalar, D: Dim> pub struct Cholesky<T: Scalar, D: Dim>
where where
DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
l: MatrixN<N, D>, l: OMatrix<T, D, D>,
} }
impl<N: Scalar + Copy, D: Dim> Copy for Cholesky<N, D> impl<T: Scalar + Copy, D: Dim> Copy for Cholesky<T, D>
where where
DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<T, D, D>,
MatrixN<N, D>: Copy, OMatrix<T, D, D>: Copy,
{ {
} }
impl<N: CholeskyScalar + Zero, D: Dim> Cholesky<N, D> impl<T: CholeskyScalar + Zero, D: Dim> Cholesky<T, D>
where where
DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
/// Computes the cholesky decomposition of the given symmetric-definite-positive square /// Computes the cholesky decomposition of the given symmetric-definite-positive square
/// matrix. /// matrix.
/// ///
/// Only the lower-triangular part of the input matrix is considered. /// Only the lower-triangular part of the input matrix is considered.
#[inline] #[inline]
pub fn new(mut m: MatrixN<N, D>) -> Option<Self> { pub fn new(mut m: OMatrix<T, D, D>) -> Option<Self> {
// TODO: check symmetry as well? // TODO: check symmetry as well?
assert!( assert!(
m.is_square(), m.is_square(),
@ -58,14 +58,14 @@ where
let dim = m.nrows() as i32; let dim = m.nrows() as i32;
let mut info = 0; let mut info = 0;
N::xpotrf(uplo, dim, m.as_mut_slice(), dim, &mut info); T::xpotrf(uplo, dim, m.as_mut_slice(), dim, &mut info);
lapack_check!(info); lapack_check!(info);
Some(Self { l: m }) Some(Self { l: m })
} }
/// Retrieves the lower-triangular factor of the cholesky decomposition. /// Retrieves the lower-triangular factor of the cholesky decomposition.
pub fn unpack(mut self) -> MatrixN<N, D> { pub fn unpack(mut self) -> OMatrix<T, D, D> {
self.l.fill_upper_triangle(Zero::zero(), 1); self.l.fill_upper_triangle(Zero::zero(), 1);
self.l self.l
} }
@ -75,12 +75,12 @@ where
/// ///
/// This is an allocation-less version of `self.l()`. The values of the strict upper-triangular /// This is an allocation-less version of `self.l()`. The values of the strict upper-triangular
/// part are garbage and should be ignored by further computations. /// part are garbage and should be ignored by further computations.
pub fn unpack_dirty(self) -> MatrixN<N, D> { pub fn unpack_dirty(self) -> OMatrix<T, D, D> {
self.l self.l
} }
/// Retrieves the lower-triangular factor of the cholesky decomposition. /// Retrieves the lower-triangular factor of the cholesky decomposition.
pub fn l(&self) -> MatrixN<N, D> { pub fn l(&self) -> OMatrix<T, D, D> {
let mut res = self.l.clone(); let mut res = self.l.clone();
res.fill_upper_triangle(Zero::zero(), 1); res.fill_upper_triangle(Zero::zero(), 1);
res res
@ -91,7 +91,7 @@ where
/// ///
/// This is an allocation-less version of `self.l()`. The values of the strict upper-triangular /// This is an allocation-less version of `self.l()`. The values of the strict upper-triangular
/// part are garbage and should be ignored by further computations. /// part are garbage and should be ignored by further computations.
pub fn l_dirty(&self) -> &MatrixN<N, D> { pub fn l_dirty(&self) -> &OMatrix<T, D, D> {
&self.l &self.l
} }
@ -99,11 +99,11 @@ where
/// unknown to be determined. /// unknown to be determined.
pub fn solve<R2: Dim, C2: Dim, S2>( pub fn solve<R2: Dim, C2: Dim, S2>(
&self, &self,
b: &Matrix<N, R2, C2, S2>, b: &Matrix<T, R2, C2, S2>,
) -> Option<MatrixMN<N, R2, C2>> ) -> Option<OMatrix<T, R2, C2>>
where where
S2: Storage<N, R2, C2>, S2: Storage<T, R2, C2>,
DefaultAllocator: Allocator<N, R2, C2>, DefaultAllocator: Allocator<T, R2, C2>,
{ {
let mut res = b.clone_owned(); let mut res = b.clone_owned();
if self.solve_mut(&mut res) { if self.solve_mut(&mut res) {
@ -115,9 +115,9 @@ where
/// Solves in-place the symmetric-definite-positive linear system `self * x = b`, where `x` is /// Solves in-place the symmetric-definite-positive linear system `self * x = b`, where `x` is
/// the unknown to be determined. /// the unknown to be determined.
pub fn solve_mut<R2: Dim, C2: Dim>(&self, b: &mut MatrixMN<N, R2, C2>) -> bool pub fn solve_mut<R2: Dim, C2: Dim>(&self, b: &mut OMatrix<T, R2, C2>) -> bool
where where
DefaultAllocator: Allocator<N, R2, C2>, DefaultAllocator: Allocator<T, R2, C2>,
{ {
let dim = self.l.nrows(); let dim = self.l.nrows();
@ -131,7 +131,7 @@ where
let ldb = dim as i32; let ldb = dim as i32;
let mut info = 0; let mut info = 0;
N::xpotrs( T::xpotrs(
b'L', b'L',
dim as i32, dim as i32,
nrhs, nrhs,
@ -145,11 +145,11 @@ where
} }
/// Computes the inverse of the decomposed matrix. /// Computes the inverse of the decomposed matrix.
pub fn inverse(mut self) -> Option<MatrixN<N, D>> { pub fn inverse(mut self) -> Option<OMatrix<T, D, D>> {
let dim = self.l.nrows(); let dim = self.l.nrows();
let mut info = 0; let mut info = 0;
N::xpotri( T::xpotri(
b'L', b'L',
dim as i32, dim as i32,
self.l.as_mut_slice(), self.l.as_mut_slice(),

View File

@ -10,7 +10,7 @@ use crate::ComplexHelper;
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, OMatrix, OVector, Scalar};
use lapack; use lapack;
@ -19,59 +19,59 @@ use lapack;
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde( serde(
bound(serialize = "DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>, bound(serialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
VectorN<N, D>: Serialize, OVector<T, D>: Serialize,
MatrixN<N, D>: Serialize") OMatrix<T, D, D>: Serialize")
) )
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde( serde(
bound(deserialize = "DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>, bound(deserialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
VectorN<N, D>: Serialize, OVector<T, D>: Serialize,
MatrixN<N, D>: Deserialize<'de>") OMatrix<T, D, D>: Deserialize<'de>")
) )
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Eigen<N: Scalar, D: Dim> pub struct Eigen<T: Scalar, D: Dim>
where where
DefaultAllocator: Allocator<N, D> + Allocator<N, D, D>, DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
{ {
/// The eigenvalues of the decomposed matrix. /// The eigenvalues of the decomposed matrix.
pub eigenvalues: VectorN<N, D>, pub eigenvalues: OVector<T, D>,
/// The (right) eigenvectors of the decomposed matrix. /// The (right) eigenvectors of the decomposed matrix.
pub eigenvectors: Option<MatrixN<N, D>>, pub eigenvectors: Option<OMatrix<T, D, D>>,
/// The left eigenvectors of the decomposed matrix. /// The left eigenvectors of the decomposed matrix.
pub left_eigenvectors: Option<MatrixN<N, D>>, pub left_eigenvectors: Option<OMatrix<T, D, D>>,
} }
impl<N: Scalar + Copy, D: Dim> Copy for Eigen<N, D> impl<T: Scalar + Copy, D: Dim> Copy for Eigen<T, D>
where where
DefaultAllocator: Allocator<N, D> + Allocator<N, D, D>, DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
VectorN<N, D>: Copy, OVector<T, D>: Copy,
MatrixN<N, D>: Copy, OMatrix<T, D, D>: Copy,
{ {
} }
impl<N: EigenScalar + RealField, D: Dim> Eigen<N, D> impl<T: EigenScalar + RealField, D: Dim> Eigen<T, D>
where where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
{ {
/// Computes the eigenvalues and eigenvectors of the square matrix `m`. /// Computes the eigenvalues and eigenvectors of the square matrix `m`.
/// ///
/// If `eigenvectors` is `false` then, the eigenvectors are not computed explicitly. /// If `eigenvectors` is `false` then, the eigenvectors are not computed explicitly.
pub fn new( pub fn new(
mut m: MatrixN<N, D>, mut m: OMatrix<T, D, D>,
left_eigenvectors: bool, left_eigenvectors: bool,
eigenvectors: bool, eigenvectors: bool,
) -> Option<Eigen<N, D>> { ) -> Option<Eigen<T, D>> {
assert!( assert!(
m.is_square(), m.is_square(),
"Unable to compute the eigenvalue decomposition of a non-square matrix." "Unable to compute the eigenvalue decomposition of a non-square matrix."
); );
let ljob = if left_eigenvectors { b'V' } else { b'N' }; let ljob = if left_eigenvectors { b'V' } else { b'T' };
let rjob = if eigenvectors { b'V' } else { b'N' }; let rjob = if eigenvectors { b'V' } else { b'T' };
let (nrows, ncols) = m.data.shape(); let (nrows, ncols) = m.data.shape();
let n = nrows.value(); let n = nrows.value();
@ -83,10 +83,10 @@ where
let mut wi = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() }; let mut wi = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() };
let mut info = 0; let mut info = 0;
let mut placeholder1 = [N::zero()]; let mut placeholder1 = [T::zero()];
let mut placeholder2 = [N::zero()]; let mut placeholder2 = [T::zero()];
let lwork = N::xgeev_work_size( let lwork = T::xgeev_work_size(
ljob, ljob,
rjob, rjob,
n as i32, n as i32,
@ -112,7 +112,7 @@ where
let mut vr = let mut vr =
unsafe { Matrix::new_uninitialized_generic(nrows, ncols).assume_init() }; unsafe { Matrix::new_uninitialized_generic(nrows, ncols).assume_init() };
N::xgeev( T::xgeev(
ljob, ljob,
rjob, rjob,
n as i32, n as i32,
@ -142,7 +142,7 @@ where
let mut vl = let mut vl =
unsafe { Matrix::new_uninitialized_generic(nrows, ncols).assume_init() }; unsafe { Matrix::new_uninitialized_generic(nrows, ncols).assume_init() };
N::xgeev( T::xgeev(
ljob, ljob,
rjob, rjob,
n as i32, n as i32,
@ -172,7 +172,7 @@ where
let mut vr = let mut vr =
unsafe { Matrix::new_uninitialized_generic(nrows, ncols).assume_init() }; unsafe { Matrix::new_uninitialized_generic(nrows, ncols).assume_init() };
N::xgeev( T::xgeev(
ljob, ljob,
rjob, rjob,
n as i32, n as i32,
@ -199,7 +199,7 @@ where
} }
} }
(false, false) => { (false, false) => {
N::xgeev( T::xgeev(
ljob, ljob,
rjob, rjob,
n as i32, n as i32,
@ -233,9 +233,9 @@ where
/// The complex eigenvalues of the given matrix. /// The complex eigenvalues of the given matrix.
/// ///
/// Panics if the eigenvalue computation does not converge. /// Panics if the eigenvalue computation does not converge.
pub fn complex_eigenvalues(mut m: MatrixN<N, D>) -> VectorN<Complex<N>, D> pub fn complex_eigenvalues(mut m: OMatrix<T, D, D>) -> OVector<Complex<T>, D>
where where
DefaultAllocator: Allocator<Complex<N>, D>, DefaultAllocator: Allocator<Complex<T>, D>,
{ {
assert!( assert!(
m.is_square(), m.is_square(),
@ -251,12 +251,12 @@ where
let mut wi = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() }; let mut wi = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() };
let mut info = 0; let mut info = 0;
let mut placeholder1 = [N::zero()]; let mut placeholder1 = [T::zero()];
let mut placeholder2 = [N::zero()]; let mut placeholder2 = [T::zero()];
let lwork = N::xgeev_work_size( let lwork = T::xgeev_work_size(
b'N', b'T',
b'N', b'T',
n as i32, n as i32,
m.as_mut_slice(), m.as_mut_slice(),
lda, lda,
@ -273,9 +273,9 @@ where
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) }; let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
N::xgeev( T::xgeev(
b'N', b'T',
b'N', b'T',
n as i32, n as i32,
m.as_mut_slice(), m.as_mut_slice(),
lda, lda,
@ -302,8 +302,8 @@ where
/// The determinant of the decomposed matrix. /// The determinant of the decomposed matrix.
#[inline] #[inline]
pub fn determinant(&self) -> N { pub fn determinant(&self) -> T {
let mut det = N::one(); let mut det = T::one();
for e in self.eigenvalues.iter() { for e in self.eigenvalues.iter() {
det *= *e; det *= *e;
} }

View File

@ -5,7 +5,7 @@ use crate::ComplexHelper;
use na::allocator::Allocator; 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, OMatrix, OVector, Scalar};
use lapack; use lapack;
@ -13,41 +13,41 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(serialize = "DefaultAllocator: Allocator<N, D, D> + serde(bound(serialize = "DefaultAllocator: Allocator<T, D, D> +
Allocator<N, DimDiff<D, U1>>, Allocator<T, DimDiff<D, U1>>,
MatrixN<N, D>: Serialize, OMatrix<T, D, D>: Serialize,
VectorN<N, DimDiff<D, U1>>: Serialize")) OVector<T, DimDiff<D, U1>>: Serialize"))
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(deserialize = "DefaultAllocator: Allocator<N, D, D> + serde(bound(deserialize = "DefaultAllocator: Allocator<T, D, D> +
Allocator<N, DimDiff<D, U1>>, Allocator<T, DimDiff<D, U1>>,
MatrixN<N, D>: Deserialize<'de>, OMatrix<T, D, D>: Deserialize<'de>,
VectorN<N, DimDiff<D, U1>>: Deserialize<'de>")) OVector<T, DimDiff<D, U1>>: Deserialize<'de>"))
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Hessenberg<N: Scalar, D: DimSub<U1>> pub struct Hessenberg<T: Scalar, D: DimSub<U1>>
where where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimDiff<D, U1>>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, DimDiff<D, U1>>,
{ {
h: MatrixN<N, D>, h: OMatrix<T, D, D>,
tau: VectorN<N, DimDiff<D, U1>>, tau: OVector<T, DimDiff<D, U1>>,
} }
impl<N: Scalar + Copy, D: DimSub<U1>> Copy for Hessenberg<N, D> impl<T: Scalar + Copy, D: DimSub<U1>> Copy for Hessenberg<T, D>
where where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimDiff<D, U1>>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, DimDiff<D, U1>>,
MatrixN<N, D>: Copy, OMatrix<T, D, D>: Copy,
VectorN<N, DimDiff<D, U1>>: Copy, OVector<T, DimDiff<D, U1>>: Copy,
{ {
} }
impl<N: HessenbergScalar + Zero, D: DimSub<U1>> Hessenberg<N, D> impl<T: HessenbergScalar + Zero, D: DimSub<U1>> Hessenberg<T, D>
where where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimDiff<D, U1>>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, DimDiff<D, U1>>,
{ {
/// Computes the hessenberg decomposition of the matrix `m`. /// Computes the hessenberg decomposition of the matrix `m`.
pub fn new(mut m: MatrixN<N, D>) -> Self { pub fn new(mut m: OMatrix<T, D, D>) -> Self {
let nrows = m.data.shape().0; let nrows = m.data.shape().0;
let n = nrows.value() as i32; let n = nrows.value() as i32;
@ -64,12 +64,12 @@ where
let mut info = 0; let mut info = 0;
let lwork = let lwork =
N::xgehrd_work_size(n, 1, n, m.as_mut_slice(), n, tau.as_mut_slice(), &mut info); T::xgehrd_work_size(n, 1, n, m.as_mut_slice(), n, tau.as_mut_slice(), &mut info);
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) }; let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
lapack_panic!(info); lapack_panic!(info);
N::xgehrd( T::xgehrd(
n, n,
1, 1,
n, n,
@ -87,36 +87,36 @@ where
/// Computes the hessenberg matrix of this decomposition. /// Computes the hessenberg matrix of this decomposition.
#[inline] #[inline]
pub fn h(&self) -> MatrixN<N, D> { pub fn h(&self) -> OMatrix<T, D, D> {
let mut h = self.h.clone_owned(); let mut h = self.h.clone_owned();
h.fill_lower_triangle(N::zero(), 2); h.fill_lower_triangle(T::zero(), 2);
h h
} }
} }
impl<N: HessenbergReal + Zero, D: DimSub<U1>> Hessenberg<N, D> impl<T: HessenbergReal + Zero, D: DimSub<U1>> Hessenberg<T, D>
where where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimDiff<D, U1>>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, DimDiff<D, U1>>,
{ {
/// Computes the matrices `(Q, H)` of this decomposition. /// Computes the matrices `(Q, H)` of this decomposition.
#[inline] #[inline]
pub fn unpack(self) -> (MatrixN<N, D>, MatrixN<N, D>) { pub fn unpack(self) -> (OMatrix<T, D, D>, OMatrix<T, D, D>) {
(self.q(), self.h()) (self.q(), self.h())
} }
/// Computes the unitary matrix `Q` of this decomposition. /// Computes the unitary matrix `Q` of this decomposition.
#[inline] #[inline]
pub fn q(&self) -> MatrixN<N, D> { pub fn q(&self) -> OMatrix<T, D, D> {
let n = self.h.nrows() as i32; let n = self.h.nrows() as i32;
let mut q = self.h.clone_owned(); let mut q = self.h.clone_owned();
let mut info = 0; let mut info = 0;
let lwork = let lwork =
N::xorghr_work_size(n, 1, n, q.as_mut_slice(), n, self.tau.as_slice(), &mut info); T::xorghr_work_size(n, 1, n, q.as_mut_slice(), n, self.tau.as_slice(), &mut info);
let mut work = vec![N::zero(); lwork as usize]; let mut work = vec![T::zero(); lwork as usize];
N::xorghr( T::xorghr(
n, n,
1, 1,
n, n,

View File

@ -5,7 +5,7 @@ use crate::ComplexHelper;
use na::allocator::Allocator; 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, OMatrix, OVector, Scalar};
use lapack; use lapack;
@ -20,57 +20,57 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(serialize = "DefaultAllocator: Allocator<N, R, C> + serde(bound(serialize = "DefaultAllocator: Allocator<T, R, C> +
Allocator<i32, DimMinimum<R, C>>, Allocator<i32, DimMinimum<R, C>>,
MatrixMN<N, R, C>: Serialize, OMatrix<T, R, C>: Serialize,
PermutationSequence<DimMinimum<R, C>>: Serialize")) PermutationSequence<DimMinimum<R, C>>: Serialize"))
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(deserialize = "DefaultAllocator: Allocator<N, R, C> + serde(bound(deserialize = "DefaultAllocator: Allocator<T, R, C> +
Allocator<i32, DimMinimum<R, C>>, Allocator<i32, DimMinimum<R, C>>,
MatrixMN<N, R, C>: Deserialize<'de>, OMatrix<T, R, C>: Deserialize<'de>,
PermutationSequence<DimMinimum<R, C>>: Deserialize<'de>")) PermutationSequence<DimMinimum<R, C>>: Deserialize<'de>"))
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct LU<N: Scalar, R: DimMin<C>, C: Dim> pub struct LU<T: Scalar, R: DimMin<C>, C: Dim>
where where
DefaultAllocator: Allocator<i32, DimMinimum<R, C>> + Allocator<N, R, C>, DefaultAllocator: Allocator<i32, DimMinimum<R, C>> + Allocator<T, R, C>,
{ {
lu: MatrixMN<N, R, C>, lu: OMatrix<T, R, C>,
p: VectorN<i32, DimMinimum<R, C>>, p: OVector<i32, DimMinimum<R, C>>,
} }
impl<N: Scalar + Copy, R: DimMin<C>, C: Dim> Copy for LU<N, R, C> impl<T: Scalar + Copy, R: DimMin<C>, C: Dim> Copy for LU<T, R, C>
where where
DefaultAllocator: Allocator<N, R, C> + Allocator<i32, DimMinimum<R, C>>, DefaultAllocator: Allocator<T, R, C> + Allocator<i32, DimMinimum<R, C>>,
MatrixMN<N, R, C>: Copy, OMatrix<T, R, C>: Copy,
VectorN<i32, DimMinimum<R, C>>: Copy, OVector<i32, DimMinimum<R, C>>: Copy,
{ {
} }
impl<N: LUScalar, R: Dim, C: Dim> LU<N, R, C> impl<T: LUScalar, R: Dim, C: Dim> LU<T, R, C>
where where
N: Zero + One, T: Zero + One,
R: DimMin<C>, R: DimMin<C>,
DefaultAllocator: Allocator<N, R, C> DefaultAllocator: Allocator<T, R, C>
+ Allocator<N, R, R> + Allocator<T, R, R>
+ Allocator<N, R, DimMinimum<R, C>> + Allocator<T, R, DimMinimum<R, C>>
+ Allocator<N, DimMinimum<R, C>, C> + Allocator<T, DimMinimum<R, C>, C>
+ Allocator<i32, DimMinimum<R, C>>, + Allocator<i32, DimMinimum<R, C>>,
{ {
/// Computes the LU decomposition with partial (row) pivoting of `matrix`. /// Computes the LU decomposition with partial (row) pivoting of `matrix`.
pub fn new(mut m: MatrixMN<N, R, C>) -> Self { pub fn new(mut m: OMatrix<T, R, C>) -> Self {
let (nrows, ncols) = m.data.shape(); let (nrows, ncols) = m.data.shape();
let min_nrows_ncols = nrows.min(ncols); let min_nrows_ncols = nrows.min(ncols);
let nrows = nrows.value() as i32; let nrows = nrows.value() as i32;
let ncols = ncols.value() as i32; let ncols = ncols.value() as i32;
let mut ipiv: VectorN<i32, _> = Matrix::zeros_generic(min_nrows_ncols, U1); let mut ipiv: OVector<i32, _> = Matrix::zeros_generic(min_nrows_ncols, U1);
let mut info = 0; let mut info = 0;
N::xgetrf( T::xgetrf(
nrows, nrows,
ncols, ncols,
m.as_mut_slice(), m.as_mut_slice(),
@ -85,7 +85,7 @@ where
/// Gets the lower-triangular matrix part of the decomposition. /// Gets the lower-triangular matrix part of the decomposition.
#[inline] #[inline]
pub fn l(&self) -> MatrixMN<N, R, DimMinimum<R, C>> { pub fn l(&self) -> OMatrix<T, R, DimMinimum<R, C>> {
let (nrows, ncols) = self.lu.data.shape(); let (nrows, ncols) = self.lu.data.shape();
let mut res = self.lu.columns_generic(0, nrows.min(ncols)).into_owned(); let mut res = self.lu.columns_generic(0, nrows.min(ncols)).into_owned();
@ -97,7 +97,7 @@ where
/// Gets the upper-triangular matrix part of the decomposition. /// Gets the upper-triangular matrix part of the decomposition.
#[inline] #[inline]
pub fn u(&self) -> MatrixMN<N, DimMinimum<R, C>, C> { pub fn u(&self) -> OMatrix<T, DimMinimum<R, C>, C> {
let (nrows, ncols) = self.lu.data.shape(); let (nrows, ncols) = self.lu.data.shape();
let mut res = self.lu.rows_generic(0, nrows.min(ncols)).into_owned(); let mut res = self.lu.rows_generic(0, nrows.min(ncols)).into_owned();
@ -111,7 +111,7 @@ where
/// Computing the permutation matrix explicitly is costly and usually not necessary. /// Computing the permutation matrix explicitly is costly and usually not necessary.
/// To permute rows of a matrix or vector, use the method `self.permute(...)` instead. /// To permute rows of a matrix or vector, use the method `self.permute(...)` instead.
#[inline] #[inline]
pub fn p(&self) -> MatrixN<N, R> { pub fn p(&self) -> OMatrix<T, R> {
let (dim, _) = self.lu.data.shape(); let (dim, _) = self.lu.data.shape();
let mut id = Matrix::identity_generic(dim, dim); let mut id = Matrix::identity_generic(dim, dim);
self.permute(&mut id); self.permute(&mut id);
@ -124,19 +124,19 @@ where
/// Gets the LAPACK permutation indices. /// Gets the LAPACK permutation indices.
#[inline] #[inline]
pub fn permutation_indices(&self) -> &VectorN<i32, DimMinimum<R, C>> { pub fn permutation_indices(&self) -> &OVector<i32, DimMinimum<R, C>> {
&self.p &self.p
} }
/// Applies the permutation matrix to a given matrix or vector in-place. /// Applies the permutation matrix to a given matrix or vector in-place.
#[inline] #[inline]
pub fn permute<C2: Dim>(&self, rhs: &mut MatrixMN<N, R, C2>) pub fn permute<C2: Dim>(&self, rhs: &mut OMatrix<T, R, C2>)
where where
DefaultAllocator: Allocator<N, R, C2>, DefaultAllocator: Allocator<T, R, C2>,
{ {
let (nrows, ncols) = rhs.shape(); let (nrows, ncols) = rhs.shape();
N::xlaswp( T::xlaswp(
ncols as i32, ncols as i32,
rhs.as_mut_slice(), rhs.as_mut_slice(),
nrows as i32, nrows as i32,
@ -147,9 +147,9 @@ where
); );
} }
fn generic_solve_mut<R2: Dim, C2: Dim>(&self, trans: u8, b: &mut MatrixMN<N, R2, C2>) -> bool fn generic_solve_mut<R2: Dim, C2: Dim>(&self, trans: u8, b: &mut OMatrix<T, R2, C2>) -> bool
where where
DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2>, DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
{ {
let dim = self.lu.nrows(); let dim = self.lu.nrows();
@ -167,7 +167,7 @@ where
let ldb = dim as i32; let ldb = dim as i32;
let mut info = 0; let mut info = 0;
N::xgetrs( T::xgetrs(
trans, trans,
dim as i32, dim as i32,
nrhs, nrhs,
@ -184,14 +184,14 @@ where
/// Solves the linear system `self * x = b`, where `x` is the unknown to be determined. /// Solves the linear system `self * x = b`, where `x` is the unknown to be determined.
pub fn solve<R2: Dim, C2: Dim, S2>( pub fn solve<R2: Dim, C2: Dim, S2>(
&self, &self,
b: &Matrix<N, R2, C2, S2>, b: &Matrix<T, R2, C2, S2>,
) -> Option<MatrixMN<N, R2, C2>> ) -> Option<OMatrix<T, R2, C2>>
where where
S2: Storage<N, R2, C2>, S2: Storage<T, R2, C2>,
DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2>, DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
{ {
let mut res = b.clone_owned(); let mut res = b.clone_owned();
if self.generic_solve_mut(b'N', &mut res) { if self.generic_solve_mut(b'T', &mut res) {
Some(res) Some(res)
} else { } else {
None None
@ -202,11 +202,11 @@ where
/// determined. /// determined.
pub fn solve_transpose<R2: Dim, C2: Dim, S2>( pub fn solve_transpose<R2: Dim, C2: Dim, S2>(
&self, &self,
b: &Matrix<N, R2, C2, S2>, b: &Matrix<T, R2, C2, S2>,
) -> Option<MatrixMN<N, R2, C2>> ) -> Option<OMatrix<T, R2, C2>>
where where
S2: Storage<N, R2, C2>, S2: Storage<T, R2, C2>,
DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2>, DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
{ {
let mut res = b.clone_owned(); let mut res = b.clone_owned();
if self.generic_solve_mut(b'T', &mut res) { if self.generic_solve_mut(b'T', &mut res) {
@ -220,11 +220,11 @@ where
/// be determined. /// be determined.
pub fn solve_conjugate_transpose<R2: Dim, C2: Dim, S2>( pub fn solve_conjugate_transpose<R2: Dim, C2: Dim, S2>(
&self, &self,
b: &Matrix<N, R2, C2, S2>, b: &Matrix<T, R2, C2, S2>,
) -> Option<MatrixMN<N, R2, C2>> ) -> Option<OMatrix<T, R2, C2>>
where where
S2: Storage<N, R2, C2>, S2: Storage<T, R2, C2>,
DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2>, DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
{ {
let mut res = b.clone_owned(); let mut res = b.clone_owned();
if self.generic_solve_mut(b'T', &mut res) { if self.generic_solve_mut(b'T', &mut res) {
@ -237,20 +237,20 @@ where
/// Solves in-place the linear system `self * x = b`, where `x` is the unknown to be determined. /// Solves in-place the linear system `self * x = b`, where `x` is the unknown to be determined.
/// ///
/// Returns `false` if no solution was found (the decomposed matrix is singular). /// Returns `false` if no solution was found (the decomposed matrix is singular).
pub fn solve_mut<R2: Dim, C2: Dim>(&self, b: &mut MatrixMN<N, R2, C2>) -> bool pub fn solve_mut<R2: Dim, C2: Dim>(&self, b: &mut OMatrix<T, R2, C2>) -> bool
where where
DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2>, DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
{ {
self.generic_solve_mut(b'N', b) self.generic_solve_mut(b'T', b)
} }
/// Solves in-place the linear system `self.transpose() * x = b`, where `x` is the unknown to be /// Solves in-place the linear system `self.transpose() * x = b`, where `x` is the unknown to be
/// determined. /// determined.
/// ///
/// Returns `false` if no solution was found (the decomposed matrix is singular). /// Returns `false` if no solution was found (the decomposed matrix is singular).
pub fn solve_transpose_mut<R2: Dim, C2: Dim>(&self, b: &mut MatrixMN<N, R2, C2>) -> bool pub fn solve_transpose_mut<R2: Dim, C2: Dim>(&self, b: &mut OMatrix<T, R2, C2>) -> bool
where where
DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2>, DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
{ {
self.generic_solve_mut(b'T', b) self.generic_solve_mut(b'T', b)
} }
@ -259,25 +259,25 @@ where
/// be determined. /// be determined.
/// ///
/// Returns `false` if no solution was found (the decomposed matrix is singular). /// Returns `false` if no solution was found (the decomposed matrix is singular).
pub fn solve_adjoint_mut<R2: Dim, C2: Dim>(&self, b: &mut MatrixMN<N, R2, C2>) -> bool pub fn solve_adjoint_mut<R2: Dim, C2: Dim>(&self, b: &mut OMatrix<T, R2, C2>) -> bool
where where
DefaultAllocator: Allocator<N, R2, C2> + Allocator<i32, R2>, DefaultAllocator: Allocator<T, R2, C2> + Allocator<i32, R2>,
{ {
self.generic_solve_mut(b'T', b) self.generic_solve_mut(b'T', b)
} }
} }
impl<N: LUScalar, D: Dim> LU<N, D, D> impl<T: LUScalar, D: Dim> LU<T, D, D>
where where
N: Zero + One, T: Zero + One,
D: DimMin<D, Output = D>, D: DimMin<D, Output = D>,
DefaultAllocator: Allocator<N, D, D> + Allocator<i32, D>, DefaultAllocator: Allocator<T, D, D> + Allocator<i32, D>,
{ {
/// Computes the inverse of the decomposed matrix. /// Computes the inverse of the decomposed matrix.
pub fn inverse(mut self) -> Option<MatrixN<N, D>> { pub fn inverse(mut self) -> Option<OMatrix<T, D, D>> {
let dim = self.lu.nrows() as i32; let dim = self.lu.nrows() as i32;
let mut info = 0; let mut info = 0;
let lwork = N::xgetri_work_size( let lwork = T::xgetri_work_size(
dim, dim,
self.lu.as_mut_slice(), self.lu.as_mut_slice(),
dim, dim,
@ -288,7 +288,7 @@ where
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) }; let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
N::xgetri( T::xgetri(
dim, dim,
self.lu.as_mut_slice(), self.lu.as_mut_slice(),
dim, dim,

View File

@ -8,7 +8,7 @@ use crate::ComplexHelper;
use na::allocator::Allocator; 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, OMatrix, OVector, Scalar};
use lapack; use lapack;
@ -16,44 +16,44 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(serialize = "DefaultAllocator: Allocator<N, R, C> + serde(bound(serialize = "DefaultAllocator: Allocator<T, R, C> +
Allocator<N, DimMinimum<R, C>>, Allocator<T, DimMinimum<R, C>>,
MatrixMN<N, R, C>: Serialize, OMatrix<T, R, C>: Serialize,
VectorN<N, DimMinimum<R, C>>: Serialize")) OVector<T, DimMinimum<R, C>>: Serialize"))
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(deserialize = "DefaultAllocator: Allocator<N, R, C> + serde(bound(deserialize = "DefaultAllocator: Allocator<T, R, C> +
Allocator<N, DimMinimum<R, C>>, Allocator<T, DimMinimum<R, C>>,
MatrixMN<N, R, C>: Deserialize<'de>, OMatrix<T, R, C>: Deserialize<'de>,
VectorN<N, DimMinimum<R, C>>: Deserialize<'de>")) OVector<T, DimMinimum<R, C>>: Deserialize<'de>"))
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct QR<N: Scalar, R: DimMin<C>, C: Dim> pub struct QR<T: Scalar, R: DimMin<C>, C: Dim>
where where
DefaultAllocator: Allocator<N, R, C> + Allocator<N, DimMinimum<R, C>>, DefaultAllocator: Allocator<T, R, C> + Allocator<T, DimMinimum<R, C>>,
{ {
qr: MatrixMN<N, R, C>, qr: OMatrix<T, R, C>,
tau: VectorN<N, DimMinimum<R, C>>, tau: OVector<T, DimMinimum<R, C>>,
} }
impl<N: Scalar + Copy, R: DimMin<C>, C: Dim> Copy for QR<N, R, C> impl<T: Scalar + Copy, R: DimMin<C>, C: Dim> Copy for QR<T, R, C>
where where
DefaultAllocator: Allocator<N, R, C> + Allocator<N, DimMinimum<R, C>>, DefaultAllocator: Allocator<T, R, C> + Allocator<T, DimMinimum<R, C>>,
MatrixMN<N, R, C>: Copy, OMatrix<T, R, C>: Copy,
VectorN<N, DimMinimum<R, C>>: Copy, OVector<T, DimMinimum<R, C>>: Copy,
{ {
} }
impl<N: QRScalar + Zero, R: DimMin<C>, C: Dim> QR<N, R, C> impl<T: QRScalar + Zero, R: DimMin<C>, C: Dim> QR<T, R, C>
where where
DefaultAllocator: Allocator<N, R, C> DefaultAllocator: Allocator<T, R, C>
+ Allocator<N, R, DimMinimum<R, C>> + Allocator<T, R, DimMinimum<R, C>>
+ Allocator<N, DimMinimum<R, C>, C> + Allocator<T, DimMinimum<R, C>, C>
+ Allocator<N, DimMinimum<R, C>>, + Allocator<T, DimMinimum<R, C>>,
{ {
/// Computes the QR decomposition of the matrix `m`. /// Computes the QR decomposition of the matrix `m`.
pub fn new(mut m: MatrixMN<N, R, C>) -> Self { pub fn new(mut m: OMatrix<T, R, C>) -> Self {
let (nrows, ncols) = m.data.shape(); let (nrows, ncols) = m.data.shape();
let mut info = 0; let mut info = 0;
@ -64,7 +64,7 @@ where
return Self { qr: m, tau: tau }; return Self { qr: m, tau: tau };
} }
let lwork = N::xgeqrf_work_size( let lwork = T::xgeqrf_work_size(
nrows.value() as i32, nrows.value() as i32,
ncols.value() as i32, ncols.value() as i32,
m.as_mut_slice(), m.as_mut_slice(),
@ -75,7 +75,7 @@ where
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) }; let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
N::xgeqrf( T::xgeqrf(
nrows.value() as i32, nrows.value() as i32,
ncols.value() as i32, ncols.value() as i32,
m.as_mut_slice(), m.as_mut_slice(),
@ -91,37 +91,37 @@ where
/// Retrieves the upper trapezoidal submatrix `R` of this decomposition. /// Retrieves the upper trapezoidal submatrix `R` of this decomposition.
#[inline] #[inline]
pub fn r(&self) -> MatrixMN<N, DimMinimum<R, C>, C> { pub fn r(&self) -> OMatrix<T, DimMinimum<R, C>, C> {
let (nrows, ncols) = self.qr.data.shape(); let (nrows, ncols) = self.qr.data.shape();
self.qr.rows_generic(0, nrows.min(ncols)).upper_triangle() self.qr.rows_generic(0, nrows.min(ncols)).upper_triangle()
} }
} }
impl<N: QRReal + Zero, R: DimMin<C>, C: Dim> QR<N, R, C> impl<T: QRReal + Zero, R: DimMin<C>, C: Dim> QR<T, R, C>
where where
DefaultAllocator: Allocator<N, R, C> DefaultAllocator: Allocator<T, R, C>
+ Allocator<N, R, DimMinimum<R, C>> + Allocator<T, R, DimMinimum<R, C>>
+ Allocator<N, DimMinimum<R, C>, C> + Allocator<T, DimMinimum<R, C>, C>
+ Allocator<N, DimMinimum<R, C>>, + Allocator<T, DimMinimum<R, C>>,
{ {
/// Retrieves the matrices `(Q, R)` of this decompositions. /// Retrieves the matrices `(Q, R)` of this decompositions.
pub fn unpack( pub fn unpack(
self, self,
) -> ( ) -> (
MatrixMN<N, R, DimMinimum<R, C>>, OMatrix<T, R, DimMinimum<R, C>>,
MatrixMN<N, DimMinimum<R, C>, C>, OMatrix<T, DimMinimum<R, C>, C>,
) { ) {
(self.q(), self.r()) (self.q(), self.r())
} }
/// Computes the orthogonal matrix `Q` of this decomposition. /// Computes the orthogonal matrix `Q` of this decomposition.
#[inline] #[inline]
pub fn q(&self) -> MatrixMN<N, R, DimMinimum<R, C>> { pub fn q(&self) -> OMatrix<T, R, DimMinimum<R, C>> {
let (nrows, ncols) = self.qr.data.shape(); let (nrows, ncols) = self.qr.data.shape();
let min_nrows_ncols = nrows.min(ncols); let min_nrows_ncols = nrows.min(ncols);
if min_nrows_ncols.value() == 0 { if min_nrows_ncols.value() == 0 {
return MatrixMN::from_element_generic(nrows, min_nrows_ncols, N::zero()); return OMatrix::from_element_generic(nrows, min_nrows_ncols, T::zero());
} }
let mut q = self let mut q = self
@ -132,7 +132,7 @@ where
let mut info = 0; let mut info = 0;
let nrows = nrows.value() as i32; let nrows = nrows.value() as i32;
let lwork = N::xorgqr_work_size( let lwork = T::xorgqr_work_size(
nrows, nrows,
min_nrows_ncols.value() as i32, min_nrows_ncols.value() as i32,
self.tau.len() as i32, self.tau.len() as i32,
@ -142,9 +142,9 @@ where
&mut info, &mut info,
); );
let mut work = vec![N::zero(); lwork as usize]; let mut work = vec![T::zero(); lwork as usize];
N::xorgqr( T::xorgqr(
nrows, nrows,
min_nrows_ncols.value() as i32, min_nrows_ncols.value() as i32,
self.tau.len() as i32, self.tau.len() as i32,

View File

@ -10,7 +10,7 @@ use crate::ComplexHelper;
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, OMatrix, OVector, Scalar};
use lapack; use lapack;
@ -19,53 +19,53 @@ use lapack;
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde( serde(
bound(serialize = "DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>, bound(serialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
VectorN<N, D>: Serialize, OVector<T, D>: Serialize,
MatrixN<N, D>: Serialize") OMatrix<T, D, D>: Serialize")
) )
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde( serde(
bound(deserialize = "DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>, bound(deserialize = "DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
VectorN<N, D>: Serialize, OVector<T, D>: Serialize,
MatrixN<N, D>: Deserialize<'de>") OMatrix<T, D, D>: Deserialize<'de>")
) )
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Schur<N: Scalar, D: Dim> pub struct Schur<T: Scalar, D: Dim>
where where
DefaultAllocator: Allocator<N, D> + Allocator<N, D, D>, DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
{ {
re: VectorN<N, D>, re: OVector<T, D>,
im: VectorN<N, D>, im: OVector<T, D>,
t: MatrixN<N, D>, t: OMatrix<T, D, D>,
q: MatrixN<N, D>, q: OMatrix<T, D, D>,
} }
impl<N: Scalar + Copy, D: Dim> Copy for Schur<N, D> impl<T: Scalar + Copy, D: Dim> Copy for Schur<T, D>
where where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
MatrixN<N, D>: Copy, OMatrix<T, D, D>: Copy,
VectorN<N, D>: Copy, OVector<T, D>: Copy,
{ {
} }
impl<N: SchurScalar + RealField, D: Dim> Schur<N, D> impl<T: SchurScalar + RealField, D: Dim> Schur<T, D>
where where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
{ {
/// Computes the eigenvalues and real Schur form of the matrix `m`. /// Computes the eigenvalues and real Schur form of the matrix `m`.
/// ///
/// Panics if the method did not converge. /// Panics if the method did not converge.
pub fn new(m: MatrixN<N, D>) -> Self { pub fn new(m: OMatrix<T, D, D>) -> Self {
Self::try_new(m).expect("Schur decomposition: convergence failed.") Self::try_new(m).expect("Schur decomposition: convergence failed.")
} }
/// Computes the eigenvalues and real Schur form of the matrix `m`. /// Computes the eigenvalues and real Schur form of the matrix `m`.
/// ///
/// Returns `None` if the method did not converge. /// Returns `None` if the method did not converge.
pub fn try_new(mut m: MatrixN<N, D>) -> Option<Self> { pub fn try_new(mut m: OMatrix<T, D, D>) -> Option<Self> {
assert!( assert!(
m.is_square(), m.is_square(),
"Unable to compute the eigenvalue decomposition of a non-square matrix." "Unable to compute the eigenvalue decomposition of a non-square matrix."
@ -85,9 +85,9 @@ where
let mut bwork = [0i32]; let mut bwork = [0i32];
let mut unused = 0; let mut unused = 0;
let lwork = N::xgees_work_size( let lwork = T::xgees_work_size(
b'V', b'V',
b'N', b'T',
n as i32, n as i32,
m.as_mut_slice(), m.as_mut_slice(),
lda, lda,
@ -103,9 +103,9 @@ where
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) }; let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
N::xgees( T::xgees(
b'V', b'V',
b'N', b'T',
n as i32, n as i32,
m.as_mut_slice(), m.as_mut_slice(),
lda, lda,
@ -131,14 +131,14 @@ where
/// Retrieves the unitary matrix `Q` and the upper-quasitriangular matrix `T` such that the /// Retrieves the unitary matrix `Q` and the upper-quasitriangular matrix `T` such that the
/// decomposed matrix equals `Q * T * Q.transpose()`. /// decomposed matrix equals `Q * T * Q.transpose()`.
pub fn unpack(self) -> (MatrixN<N, D>, MatrixN<N, D>) { pub fn unpack(self) -> (OMatrix<T, D, D>, OMatrix<T, D, D>) {
(self.q, self.t) (self.q, self.t)
} }
/// Computes the real eigenvalues of the decomposed matrix. /// Computes the real eigenvalues of the decomposed matrix.
/// ///
/// Return `None` if some eigenvalues are complex. /// Return `None` if some eigenvalues are complex.
pub fn eigenvalues(&self) -> Option<VectorN<N, D>> { pub fn eigenvalues(&self) -> Option<OVector<T, D>> {
if self.im.iter().all(|e| e.is_zero()) { if self.im.iter().all(|e| e.is_zero()) {
Some(self.re.clone()) Some(self.re.clone())
} else { } else {
@ -147,12 +147,12 @@ where
} }
/// Computes the complex eigenvalues of the decomposed matrix. /// Computes the complex eigenvalues of the decomposed matrix.
pub fn complex_eigenvalues(&self) -> VectorN<Complex<N>, D> pub fn complex_eigenvalues(&self) -> OVector<Complex<T>, D>
where where
DefaultAllocator: Allocator<Complex<N>, D>, DefaultAllocator: Allocator<Complex<T>, D>,
{ {
let mut out = let mut out =
unsafe { VectorN::new_uninitialized_generic(self.t.data.shape().0, U1).assume_init() }; unsafe { OVector::new_uninitialized_generic(self.t.data.shape().0, U1).assume_init() };
for i in 0..out.len() { for i in 0..out.len() {
out[i] = Complex::new(self.re[i], self.im[i]) out[i] = Complex::new(self.re[i], self.im[i])

View File

@ -7,7 +7,7 @@ use std::cmp;
use na::allocator::Allocator; 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, OMatrix, OVector, Scalar};
use lapack; use lapack;
@ -15,41 +15,41 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(serialize = "DefaultAllocator: Allocator<N, DimMinimum<R, C>> + serde(bound(serialize = "DefaultAllocator: Allocator<T, DimMinimum<R, C>> +
Allocator<N, R, R> + Allocator<T, R, R> +
Allocator<N, C, C>, Allocator<T, C, C>,
MatrixN<N, R>: Serialize, OMatrix<T, R>: Serialize,
MatrixN<N, C>: Serialize, OMatrix<T, C>: Serialize,
VectorN<N, DimMinimum<R, C>>: Serialize")) OVector<T, DimMinimum<R, C>>: Serialize"))
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(serialize = "DefaultAllocator: Allocator<N, DimMinimum<R, C>> + serde(bound(serialize = "DefaultAllocator: Allocator<T, DimMinimum<R, C>> +
Allocator<N, R, R> + Allocator<T, R, R> +
Allocator<N, C, C>, Allocator<T, C, C>,
MatrixN<N, R>: Deserialize<'de>, OMatrix<T, R>: Deserialize<'de>,
MatrixN<N, C>: Deserialize<'de>, OMatrix<T, C>: Deserialize<'de>,
VectorN<N, DimMinimum<R, C>>: Deserialize<'de>")) OVector<T, DimMinimum<R, C>>: Deserialize<'de>"))
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct SVD<N: Scalar, R: DimMin<C>, C: Dim> pub struct SVD<T: Scalar, R: DimMin<C>, C: Dim>
where where
DefaultAllocator: Allocator<N, R, R> + Allocator<N, DimMinimum<R, C>> + Allocator<N, C, C>, DefaultAllocator: Allocator<T, R, R> + Allocator<T, DimMinimum<R, C>> + Allocator<T, C, C>,
{ {
/// The left-singular vectors `U` of this SVD. /// The left-singular vectors `U` of this SVD.
pub u: MatrixN<N, R>, // TODO: should be MatrixMN<N, R, DimMinimum<R, C>> pub u: OMatrix<T, R>, // TODO: should be OMatrix<T, R, DimMinimum<R, C>>
/// The right-singular vectors `V^t` of this SVD. /// The right-singular vectors `V^t` of this SVD.
pub vt: MatrixN<N, C>, // TODO: should be MatrixMN<N, DimMinimum<R, C>, C> pub vt: OMatrix<T, C>, // TODO: should be OMatrix<T, DimMinimum<R, C>, C>
/// The singular values of this SVD. /// The singular values of this SVD.
pub singular_values: VectorN<N, DimMinimum<R, C>>, pub singular_values: OVector<T, DimMinimum<R, C>>,
} }
impl<N: Scalar + Copy, R: DimMin<C>, C: Dim> Copy for SVD<N, R, C> impl<T: Scalar + Copy, R: DimMin<C>, C: Dim> Copy for SVD<T, R, C>
where where
DefaultAllocator: Allocator<N, C, C> + Allocator<N, R, R> + Allocator<N, DimMinimum<R, C>>, DefaultAllocator: Allocator<T, C, C> + Allocator<T, R, R> + Allocator<T, DimMinimum<R, C>>,
MatrixMN<N, R, R>: Copy, OMatrix<T, R, R>: Copy,
MatrixMN<N, C, C>: Copy, OMatrix<T, C, C>: Copy,
VectorN<N, DimMinimum<R, C>>: Copy, OVector<T, DimMinimum<R, C>>: Copy,
{ {
} }
@ -63,19 +63,19 @@ where
+ Allocator<Self, C, C>, + Allocator<Self, C, C>,
{ {
/// Computes the SVD decomposition of `m`. /// Computes the SVD decomposition of `m`.
fn compute(m: MatrixMN<Self, R, C>) -> Option<SVD<Self, R, C>>; fn compute(m: OMatrix<Self, R, C>) -> Option<SVD<Self, R, C>>;
} }
impl<N: SVDScalar<R, C>, R: DimMin<C>, C: Dim> SVD<N, R, C> impl<T: SVDScalar<R, C>, R: DimMin<C>, C: Dim> SVD<T, R, C>
where where
DefaultAllocator: Allocator<N, R, R> DefaultAllocator: Allocator<T, R, R>
+ Allocator<N, R, C> + Allocator<T, R, C>
+ Allocator<N, DimMinimum<R, C>> + Allocator<T, DimMinimum<R, C>>
+ Allocator<N, C, C>, + Allocator<T, C, C>,
{ {
/// Computes the Singular Value Decomposition of `matrix`. /// Computes the Singular Value Decomposition of `matrix`.
pub fn new(m: MatrixMN<N, R, C>) -> Option<Self> { pub fn new(m: OMatrix<T, R, C>) -> Option<Self> {
N::compute(m) T::compute(m)
} }
} }
@ -88,7 +88,7 @@ macro_rules! svd_impl(
Allocator<$t, C, C> + Allocator<$t, C, C> +
Allocator<$t, DimMinimum<R, C>> { Allocator<$t, DimMinimum<R, C>> {
fn compute(mut m: MatrixMN<$t, R, C>) -> Option<SVD<$t, R, C>> { fn compute(mut m: OMatrix<$t, R, C>) -> Option<SVD<$t, R, C>> {
let (nrows, ncols) = m.data.shape(); let (nrows, ncols) = m.data.shape();
if nrows.value() == 0 || ncols.value() == 0 { if nrows.value() == 0 || ncols.value() == 0 {
@ -150,12 +150,12 @@ macro_rules! svd_impl(
/// Useful if some components (e.g. some singular values) of this decomposition have /// Useful if some components (e.g. some singular values) of this decomposition have
/// been manually changed by the user. /// been manually changed by the user.
#[inline] #[inline]
pub fn recompose(self) -> MatrixMN<$t, R, C> { pub fn recompose(self) -> OMatrix<$t, R, C> {
let nrows = self.u.data.shape().0; let nrows = self.u.data.shape().0;
let ncols = self.vt.data.shape().1; let ncols = self.vt.data.shape().1;
let min_nrows_ncols = nrows.min(ncols); let min_nrows_ncols = nrows.min(ncols);
let mut res: MatrixMN<_, R, C> = Matrix::zeros_generic(nrows, ncols); let mut res: OMatrix<_, R, C> = Matrix::zeros_generic(nrows, ncols);
{ {
let mut sres = res.generic_slice_mut((0, 0), (min_nrows_ncols, ncols)); let mut sres = res.generic_slice_mut((0, 0), (min_nrows_ncols, ncols));
@ -175,12 +175,12 @@ macro_rules! svd_impl(
/// ///
/// All singular value below epsilon will be set to zero instead of being inverted. /// All singular value below epsilon will be set to zero instead of being inverted.
#[inline] #[inline]
pub fn pseudo_inverse(&self, epsilon: $t) -> MatrixMN<$t, C, R> { pub fn pseudo_inverse(&self, epsilon: $t) -> OMatrix<$t, C, R> {
let nrows = self.u.data.shape().0; let nrows = self.u.data.shape().0;
let ncols = self.vt.data.shape().1; let ncols = self.vt.data.shape().1;
let min_nrows_ncols = nrows.min(ncols); let min_nrows_ncols = nrows.min(ncols);
let mut res: MatrixMN<_, C, R> = Matrix::zeros_generic(ncols, nrows); let mut res: OMatrix<_, C, R> = Matrix::zeros_generic(ncols, nrows);
{ {
let mut sres = res.generic_slice_mut((0, 0), (min_nrows_ncols, nrows)); let mut sres = res.generic_slice_mut((0, 0), (min_nrows_ncols, nrows));
@ -230,9 +230,9 @@ macro_rules! svd_complex_impl(
($name: ident, $t: ty, $lapack_func: path) => ( ($name: ident, $t: ty, $lapack_func: path) => (
impl SVDScalar for Complex<$t> { impl SVDScalar for Complex<$t> {
fn compute<R: Dim, C: Dim, S>(mut m: Matrix<$t, R, C, S>) -> Option<SVD<$t, R, C, S::Alloc>> fn compute<R: Dim, C: Dim, S>(mut m: Matrix<$t, R, C, S>) -> Option<SVD<$t, R, C, S::Alloc>>
Option<(MatrixN<Complex<$t>, R, S::Alloc>, Option<(OMatrix<Complex<$t>, R, S::Alloc>,
VectorN<$t, DimMinimum<R, C>, S::Alloc>, OVector<$t, DimMinimum<R, C>, S::Alloc>,
MatrixN<Complex<$t>, C, S::Alloc>)> OMatrix<Complex<$t>, C, S::Alloc>)>
where R: DimMin<C>, where R: DimMin<C>,
S: ContiguousStorage<Complex<$t>, R, C>, S: ContiguousStorage<Complex<$t>, R, C>,
S::Alloc: OwnedAllocator<Complex<$t>, R, C, S> + S::Alloc: OwnedAllocator<Complex<$t>, R, C, S> +

View File

@ -10,7 +10,7 @@ use crate::ComplexHelper;
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, OMatrix, OVector, Scalar};
use lapack; use lapack;
@ -18,47 +18,47 @@ use lapack;
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(serialize = "DefaultAllocator: Allocator<N, D, D> + serde(bound(serialize = "DefaultAllocator: Allocator<T, D, D> +
Allocator<N, D>, Allocator<T, D>,
VectorN<N, D>: Serialize, OVector<T, D>: Serialize,
MatrixN<N, D>: Serialize")) OMatrix<T, D, D>: Serialize"))
)] )]
#[cfg_attr( #[cfg_attr(
feature = "serde-serialize", feature = "serde-serialize",
serde(bound(deserialize = "DefaultAllocator: Allocator<N, D, D> + serde(bound(deserialize = "DefaultAllocator: Allocator<T, D, D> +
Allocator<N, D>, Allocator<T, D>,
VectorN<N, D>: Deserialize<'de>, OVector<T, D>: Deserialize<'de>,
MatrixN<N, D>: Deserialize<'de>")) OMatrix<T, D, D>: Deserialize<'de>"))
)] )]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct SymmetricEigen<N: Scalar, D: Dim> pub struct SymmetricEigen<T: Scalar, D: Dim>
where where
DefaultAllocator: Allocator<N, D> + Allocator<N, D, D>, DefaultAllocator: Allocator<T, D> + Allocator<T, D, D>,
{ {
/// The eigenvectors of the decomposed matrix. /// The eigenvectors of the decomposed matrix.
pub eigenvectors: MatrixN<N, D>, pub eigenvectors: OMatrix<T, D, D>,
/// The unsorted eigenvalues of the decomposed matrix. /// The unsorted eigenvalues of the decomposed matrix.
pub eigenvalues: VectorN<N, D>, pub eigenvalues: OVector<T, D>,
} }
impl<N: Scalar + Copy, D: Dim> Copy for SymmetricEigen<N, D> impl<T: Scalar + Copy, D: Dim> Copy for SymmetricEigen<T, D>
where where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
MatrixN<N, D>: Copy, OMatrix<T, D, D>: Copy,
VectorN<N, D>: Copy, OVector<T, D>: Copy,
{ {
} }
impl<N: SymmetricEigenScalar + RealField, D: Dim> SymmetricEigen<N, D> impl<T: SymmetricEigenScalar + RealField, D: Dim> SymmetricEigen<T, D>
where where
DefaultAllocator: Allocator<N, D, D> + Allocator<N, D>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, D>,
{ {
/// Computes the eigenvalues and eigenvectors of the symmetric matrix `m`. /// Computes the eigenvalues and eigenvectors of the symmetric matrix `m`.
/// ///
/// Only the lower-triangular part of `m` is read. If `eigenvectors` is `false` then, the /// Only the lower-triangular part of `m` is read. If `eigenvectors` is `false` then, the
/// eigenvectors are not computed explicitly. Panics if the method did not converge. /// eigenvectors are not computed explicitly. Panics if the method did not converge.
pub fn new(m: MatrixN<N, D>) -> Self { pub fn new(m: OMatrix<T, D, D>) -> Self {
let (vals, vecs) = let (vals, vecs) =
Self::do_decompose(m, true).expect("SymmetricEigen: convergence failure."); Self::do_decompose(m, true).expect("SymmetricEigen: convergence failure.");
Self { Self {
@ -71,7 +71,7 @@ where
/// ///
/// Only the lower-triangular part of `m` is read. If `eigenvectors` is `false` then, the /// Only the lower-triangular part of `m` is read. If `eigenvectors` is `false` then, the
/// eigenvectors are not computed explicitly. Returns `None` if the method did not converge. /// eigenvectors are not computed explicitly. Returns `None` if the method did not converge.
pub fn try_new(m: MatrixN<N, D>) -> Option<Self> { pub fn try_new(m: OMatrix<T, D, D>) -> Option<Self> {
Self::do_decompose(m, true).map(|(vals, vecs)| SymmetricEigen { Self::do_decompose(m, true).map(|(vals, vecs)| SymmetricEigen {
eigenvalues: vals, eigenvalues: vals,
eigenvectors: vecs.unwrap(), eigenvectors: vecs.unwrap(),
@ -79,15 +79,15 @@ where
} }
fn do_decompose( fn do_decompose(
mut m: MatrixN<N, D>, mut m: OMatrix<T, D, D>,
eigenvectors: bool, eigenvectors: bool,
) -> Option<(VectorN<N, D>, Option<MatrixN<N, D>>)> { ) -> Option<(OVector<T, D>, Option<OMatrix<T, D, D>>)> {
assert!( assert!(
m.is_square(), m.is_square(),
"Unable to compute the eigenvalue decomposition of a non-square matrix." "Unable to compute the eigenvalue decomposition of a non-square matrix."
); );
let jobz = if eigenvectors { b'V' } else { b'N' }; let jobz = if eigenvectors { b'V' } else { b'T' };
let nrows = m.data.shape().0; let nrows = m.data.shape().0;
let n = nrows.value(); let n = nrows.value();
@ -97,12 +97,12 @@ where
let mut values = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() }; let mut values = unsafe { Matrix::new_uninitialized_generic(nrows, U1).assume_init() };
let mut info = 0; let mut info = 0;
let lwork = N::xsyev_work_size(jobz, b'L', n as i32, m.as_mut_slice(), lda, &mut info); let lwork = T::xsyev_work_size(jobz, b'L', n as i32, m.as_mut_slice(), lda, &mut info);
lapack_check!(info); lapack_check!(info);
let mut work = unsafe { crate::uninitialized_vec(lwork as usize) }; let mut work = unsafe { crate::uninitialized_vec(lwork as usize) };
N::xsyev( T::xsyev(
jobz, jobz,
b'L', b'L',
n as i32, n as i32,
@ -122,7 +122,7 @@ where
/// Computes only the eigenvalues of the input matrix. /// Computes only the eigenvalues of the input matrix.
/// ///
/// Panics if the method does not converge. /// Panics if the method does not converge.
pub fn eigenvalues(m: MatrixN<N, D>) -> VectorN<N, D> { pub fn eigenvalues(m: OMatrix<T, D, D>) -> OVector<T, D> {
Self::do_decompose(m, false) Self::do_decompose(m, false)
.expect("SymmetricEigen eigenvalues: convergence failure.") .expect("SymmetricEigen eigenvalues: convergence failure.")
.0 .0
@ -131,14 +131,14 @@ where
/// Computes only the eigenvalues of the input matrix. /// Computes only the eigenvalues of the input matrix.
/// ///
/// Returns `None` if the method does not converge. /// Returns `None` if the method does not converge.
pub fn try_eigenvalues(m: MatrixN<N, D>) -> Option<VectorN<N, D>> { pub fn try_eigenvalues(m: OMatrix<T, D, D>) -> Option<OVector<T, D>> {
Self::do_decompose(m, false).map(|res| res.0) Self::do_decompose(m, false).map(|res| res.0)
} }
/// The determinant of the decomposed matrix. /// The determinant of the decomposed matrix.
#[inline] #[inline]
pub fn determinant(&self) -> N { pub fn determinant(&self) -> T {
let mut det = N::one(); let mut det = T::one();
for e in self.eigenvalues.iter() { for e in self.eigenvalues.iter() {
det *= *e; det *= *e;
} }
@ -149,7 +149,7 @@ where
/// Rebuild the original matrix. /// Rebuild the original matrix.
/// ///
/// This is useful if some of the eigenvalues have been manually modified. /// This is useful if some of the eigenvalues have been manually modified.
pub fn recompose(&self) -> MatrixN<N, D> { pub fn recompose(&self) -> OMatrix<T, D, D> {
let mut u_t = self.eigenvectors.clone(); let mut u_t = self.eigenvectors.clone();
for i in 0..self.eigenvalues.len() { for i in 0..self.eigenvalues.len() {
let val = self.eigenvalues[i]; let val = self.eigenvalues[i];

View File

@ -10,7 +10,7 @@ use nalgebra::allocator::Allocator;
use nalgebra::base::storage::Storage; use nalgebra::base::storage::Storage;
use nalgebra::constraint::{DimEq, ShapeConstraint}; use nalgebra::constraint::{DimEq, ShapeConstraint};
use nalgebra::{ use nalgebra::{
ClosedAdd, ClosedDiv, ClosedMul, ClosedSub, DefaultAllocator, Dim, Dynamic, Matrix, MatrixMN, ClosedAdd, ClosedDiv, ClosedMul, ClosedSub, DefaultAllocator, Dim, Dynamic, Matrix, OMatrix,
Scalar, U1, Scalar, U1,
}; };
use num_traits::{One, Zero}; use num_traits::{One, Zero};
@ -274,7 +274,7 @@ macro_rules! impl_spmm_cs_dense {
impl_spmm_cs_dense!(&'a $matrix_type_name<T>, &'a Matrix<T, R, C, S>, $spmm_fn, |lhs, rhs| { impl_spmm_cs_dense!(&'a $matrix_type_name<T>, &'a Matrix<T, R, C, S>, $spmm_fn, |lhs, rhs| {
let (_, ncols) = rhs.data.shape(); let (_, ncols) = rhs.data.shape();
let nrows = Dynamic::new(lhs.nrows()); let nrows = Dynamic::new(lhs.nrows());
let mut result = MatrixMN::<T, Dynamic, C>::zeros_generic(nrows, ncols); let mut result = OMatrix::<T, Dynamic, C>::zeros_generic(nrows, ncols);
$spmm_fn(T::zero(), &mut result, T::one(), Op::NoOp(lhs), Op::NoOp(rhs)); $spmm_fn(T::zero(), &mut result, T::one(), Op::NoOp(lhs), Op::NoOp(rhs));
result result
}); });
@ -305,7 +305,7 @@ macro_rules! impl_spmm_cs_dense {
DefaultAllocator: Allocator<T, Dynamic, C>, DefaultAllocator: Allocator<T, Dynamic, C>,
// TODO: Is it possible to simplify these bounds? // TODO: Is it possible to simplify these bounds?
ShapeConstraint: ShapeConstraint:
// Bounds so that we can turn MatrixMN<T, Dynamic, C> into a DMatrixSliceMut // Bounds so that we can turn OMatrix<T, Dynamic, C> into a DMatrixSliceMut
DimEq<U1, <<DefaultAllocator as Allocator<T, Dynamic, C>>::Buffer as Storage<T, Dynamic, C>>::RStride> DimEq<U1, <<DefaultAllocator as Allocator<T, Dynamic, C>>::Buffer as Storage<T, Dynamic, C>>::RStride>
+ DimEq<C, Dynamic> + DimEq<C, Dynamic>
+ DimEq<Dynamic, <<DefaultAllocator as Allocator<T, Dynamic, C>>::Buffer as Storage<T, Dynamic, C>>::CStride> + DimEq<Dynamic, <<DefaultAllocator as Allocator<T, Dynamic, C>>::Buffer as Storage<T, Dynamic, C>>::CStride>
@ -316,7 +316,7 @@ macro_rules! impl_spmm_cs_dense {
{ {
// We need the column dimension to be generic, so that if RHS is a vector, then // We need the column dimension to be generic, so that if RHS is a vector, then
// we also get a vector (and not a matrix) // we also get a vector (and not a matrix)
type Output = MatrixMN<T, Dynamic, C>; type Output = OMatrix<T, Dynamic, C>;
fn mul(self, rhs: $dense_matrix_type) -> Self::Output { fn mul(self, rhs: $dense_matrix_type) -> Self::Output {
let $lhs = self; let $lhs = self;

View File

@ -13,247 +13,248 @@ use crate::base::{Const, Matrix, Unit};
* *
* *
*/ */
/// A statically sized column-major matrix with `R` rows and `C` columns.
/// An owned matrix column-major matrix with `R` rows and `C` columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated(note = "This matrix name contains a typo. Use MatrixMN instead.")] pub type OMatrix<T, R, C> = Matrix<T, R, C, Owned<T, R, C>>;
pub type MatrixNM<N, R, C> = Matrix<N, R, C, Owned<N, R, C>>;
/// An owned matrix column-major matrix with `R` rows and `C` columns.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated(
note = "use SMatrix for a statically-sized matrix using integer dimensions, or OMatrix for an owned matrix using types as dimensions."
)]
pub type MatrixMN<T, R, C> = Matrix<T, R, C, Owned<T, R, C>>;
/// A statically sized column-major matrix with `R` rows and `C` columns. /// A statically sized column-major matrix with `R` rows and `C` columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixMN<N, R, C> = Matrix<N, R, C, Owned<N, R, C>>; pub type SMatrix<T, const R: usize, const C: usize> =
pub type CMatrixMN<N, const R: usize, const C: usize> = Matrix<T, Const<R>, Const<C>, Owned<T, Const<R>, Const<C>>>;
Matrix<N, Const<R>, Const<C>, Owned<N, Const<R>, Const<C>>>;
/// A statically sized column-major square matrix with `D` rows and columns.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixN<N, D> = Matrix<N, D, D, Owned<N, D, D>>;
pub type CMatrixN<N, const D: usize> = Matrix<N, Const<D>, Const<D>, Owned<N, Const<D>, Const<D>>>;
/// A dynamically sized column-major matrix. /// A dynamically sized column-major matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type DMatrix<N> = Matrix<N, Dynamic, Dynamic, Owned<N, Dynamic, Dynamic>>; pub type DMatrix<T> = Matrix<T, Dynamic, Dynamic, Owned<T, Dynamic, Dynamic>>;
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 1 columns. /// A heap-allocated, column-major, matrix with a dynamic number of rows and 1 columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type MatrixXx1<N> = Matrix<N, Dynamic, U1, Owned<N, Dynamic, U1>>; pub type MatrixXx1<T> = Matrix<T, Dynamic, U1, Owned<T, Dynamic, U1>>;
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 2 columns. /// A heap-allocated, column-major, matrix with a dynamic number of rows and 2 columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type MatrixXx2<N> = Matrix<N, Dynamic, U2, Owned<N, Dynamic, U2>>; pub type MatrixXx2<T> = Matrix<T, Dynamic, U2, Owned<T, Dynamic, U2>>;
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 3 columns. /// A heap-allocated, column-major, matrix with a dynamic number of rows and 3 columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type MatrixXx3<N> = Matrix<N, Dynamic, U3, Owned<N, Dynamic, U3>>; pub type MatrixXx3<T> = Matrix<T, Dynamic, U3, Owned<T, Dynamic, U3>>;
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 4 columns. /// A heap-allocated, column-major, matrix with a dynamic number of rows and 4 columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type MatrixXx4<N> = Matrix<N, Dynamic, U4, Owned<N, Dynamic, U4>>; pub type MatrixXx4<T> = Matrix<T, Dynamic, U4, Owned<T, Dynamic, U4>>;
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 5 columns. /// A heap-allocated, column-major, matrix with a dynamic number of rows and 5 columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type MatrixXx5<N> = Matrix<N, Dynamic, U5, Owned<N, Dynamic, U5>>; pub type MatrixXx5<T> = Matrix<T, Dynamic, U5, Owned<T, Dynamic, U5>>;
/// A heap-allocated, column-major, matrix with a dynamic number of rows and 6 columns. /// A heap-allocated, column-major, matrix with a dynamic number of rows and 6 columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type MatrixXx6<N> = Matrix<N, Dynamic, U6, Owned<N, Dynamic, U6>>; pub type MatrixXx6<T> = Matrix<T, Dynamic, U6, Owned<T, Dynamic, U6>>;
/// A heap-allocated, row-major, matrix with 1 rows and a dynamic number of columns. /// A heap-allocated, row-major, matrix with 1 rows and a dynamic number of columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix1xX<N> = Matrix<N, U1, Dynamic, Owned<N, U1, Dynamic>>; pub type Matrix1xX<T> = Matrix<T, U1, Dynamic, Owned<T, U1, Dynamic>>;
/// A heap-allocated, row-major, matrix with 2 rows and a dynamic number of columns. /// A heap-allocated, row-major, matrix with 2 rows and a dynamic number of columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix2xX<N> = Matrix<N, U2, Dynamic, Owned<N, U2, Dynamic>>; pub type Matrix2xX<T> = Matrix<T, U2, Dynamic, Owned<T, U2, Dynamic>>;
/// A heap-allocated, row-major, matrix with 3 rows and a dynamic number of columns. /// A heap-allocated, row-major, matrix with 3 rows and a dynamic number of columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix3xX<N> = Matrix<N, U3, Dynamic, Owned<N, U3, Dynamic>>; pub type Matrix3xX<T> = Matrix<T, U3, Dynamic, Owned<T, U3, Dynamic>>;
/// A heap-allocated, row-major, matrix with 4 rows and a dynamic number of columns. /// A heap-allocated, row-major, matrix with 4 rows and a dynamic number of columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix4xX<N> = Matrix<N, U4, Dynamic, Owned<N, U4, Dynamic>>; pub type Matrix4xX<T> = Matrix<T, U4, Dynamic, Owned<T, U4, Dynamic>>;
/// A heap-allocated, row-major, matrix with 5 rows and a dynamic number of columns. /// A heap-allocated, row-major, matrix with 5 rows and a dynamic number of columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix5xX<N> = Matrix<N, U5, Dynamic, Owned<N, U5, Dynamic>>; pub type Matrix5xX<T> = Matrix<T, U5, Dynamic, Owned<T, U5, Dynamic>>;
/// A heap-allocated, row-major, matrix with 6 rows and a dynamic number of columns. /// A heap-allocated, row-major, matrix with 6 rows and a dynamic number of columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type Matrix6xX<N> = Matrix<N, U6, Dynamic, Owned<N, U6, Dynamic>>; pub type Matrix6xX<T> = Matrix<T, U6, Dynamic, Owned<T, U6, Dynamic>>;
/// A stack-allocated, column-major, 1x1 square matrix. /// A stack-allocated, column-major, 1x1 square matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix1<N> = Matrix<N, U1, U1, Owned<N, U1, U1>>; pub type Matrix1<T> = Matrix<T, U1, U1, Owned<T, U1, U1>>;
/// A stack-allocated, column-major, 2x2 square matrix. /// A stack-allocated, column-major, 2x2 square matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix2<N> = Matrix<N, U2, U2, Owned<N, U2, U2>>; pub type Matrix2<T> = Matrix<T, U2, U2, Owned<T, U2, U2>>;
/// A stack-allocated, column-major, 3x3 square matrix. /// A stack-allocated, column-major, 3x3 square matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix3<N> = Matrix<N, U3, U3, Owned<N, U3, U3>>; pub type Matrix3<T> = Matrix<T, U3, U3, Owned<T, U3, U3>>;
/// A stack-allocated, column-major, 4x4 square matrix. /// A stack-allocated, column-major, 4x4 square matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix4<N> = Matrix<N, U4, U4, Owned<N, U4, U4>>; pub type Matrix4<T> = Matrix<T, U4, U4, Owned<T, U4, U4>>;
/// A stack-allocated, column-major, 5x5 square matrix. /// A stack-allocated, column-major, 5x5 square matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix5<N> = Matrix<N, U5, U5, Owned<N, U5, U5>>; pub type Matrix5<T> = Matrix<T, U5, U5, Owned<T, U5, U5>>;
/// A stack-allocated, column-major, 6x6 square matrix. /// A stack-allocated, column-major, 6x6 square matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix6<N> = Matrix<N, U6, U6, Owned<N, U6, U6>>; pub type Matrix6<T> = Matrix<T, U6, U6, Owned<T, U6, U6>>;
/// A stack-allocated, column-major, 1x2 matrix. /// A stack-allocated, column-major, 1x2 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix1x2<N> = Matrix<N, U1, U2, Owned<N, U1, U2>>; pub type Matrix1x2<T> = Matrix<T, U1, U2, Owned<T, U1, U2>>;
/// A stack-allocated, column-major, 1x3 matrix. /// A stack-allocated, column-major, 1x3 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix1x3<N> = Matrix<N, U1, U3, Owned<N, U1, U3>>; pub type Matrix1x3<T> = Matrix<T, U1, U3, Owned<T, U1, U3>>;
/// A stack-allocated, column-major, 1x4 matrix. /// A stack-allocated, column-major, 1x4 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix1x4<N> = Matrix<N, U1, U4, Owned<N, U1, U4>>; pub type Matrix1x4<T> = Matrix<T, U1, U4, Owned<T, U1, U4>>;
/// A stack-allocated, column-major, 1x5 matrix. /// A stack-allocated, column-major, 1x5 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix1x5<N> = Matrix<N, U1, U5, Owned<N, U1, U5>>; pub type Matrix1x5<T> = Matrix<T, U1, U5, Owned<T, U1, U5>>;
/// A stack-allocated, column-major, 1x6 matrix. /// A stack-allocated, column-major, 1x6 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix1x6<N> = Matrix<N, U1, U6, Owned<N, U1, U6>>; pub type Matrix1x6<T> = Matrix<T, U1, U6, Owned<T, U1, U6>>;
/// A stack-allocated, column-major, 2x3 matrix. /// A stack-allocated, column-major, 2x3 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix2x3<N> = Matrix<N, U2, U3, Owned<N, U2, U3>>; pub type Matrix2x3<T> = Matrix<T, U2, U3, Owned<T, U2, U3>>;
/// A stack-allocated, column-major, 2x4 matrix. /// A stack-allocated, column-major, 2x4 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix2x4<N> = Matrix<N, U2, U4, Owned<N, U2, U4>>; pub type Matrix2x4<T> = Matrix<T, U2, U4, Owned<T, U2, U4>>;
/// A stack-allocated, column-major, 2x5 matrix. /// A stack-allocated, column-major, 2x5 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix2x5<N> = Matrix<N, U2, U5, Owned<N, U2, U5>>; pub type Matrix2x5<T> = Matrix<T, U2, U5, Owned<T, U2, U5>>;
/// A stack-allocated, column-major, 2x6 matrix. /// A stack-allocated, column-major, 2x6 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix2x6<N> = Matrix<N, U2, U6, Owned<N, U2, U6>>; pub type Matrix2x6<T> = Matrix<T, U2, U6, Owned<T, U2, U6>>;
/// A stack-allocated, column-major, 3x4 matrix. /// A stack-allocated, column-major, 3x4 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix3x4<N> = Matrix<N, U3, U4, Owned<N, U3, U4>>; pub type Matrix3x4<T> = Matrix<T, U3, U4, Owned<T, U3, U4>>;
/// A stack-allocated, column-major, 3x5 matrix. /// A stack-allocated, column-major, 3x5 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix3x5<N> = Matrix<N, U3, U5, Owned<N, U3, U5>>; pub type Matrix3x5<T> = Matrix<T, U3, U5, Owned<T, U3, U5>>;
/// A stack-allocated, column-major, 3x6 matrix. /// A stack-allocated, column-major, 3x6 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix3x6<N> = Matrix<N, U3, U6, Owned<N, U3, U6>>; pub type Matrix3x6<T> = Matrix<T, U3, U6, Owned<T, U3, U6>>;
/// A stack-allocated, column-major, 4x5 matrix. /// A stack-allocated, column-major, 4x5 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix4x5<N> = Matrix<N, U4, U5, Owned<N, U4, U5>>; pub type Matrix4x5<T> = Matrix<T, U4, U5, Owned<T, U4, U5>>;
/// A stack-allocated, column-major, 4x6 matrix. /// A stack-allocated, column-major, 4x6 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix4x6<N> = Matrix<N, U4, U6, Owned<N, U4, U6>>; pub type Matrix4x6<T> = Matrix<T, U4, U6, Owned<T, U4, U6>>;
/// A stack-allocated, column-major, 5x6 matrix. /// A stack-allocated, column-major, 5x6 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix5x6<N> = Matrix<N, U5, U6, Owned<N, U5, U6>>; pub type Matrix5x6<T> = Matrix<T, U5, U6, Owned<T, U5, U6>>;
/// A stack-allocated, column-major, 2x1 matrix. /// A stack-allocated, column-major, 2x1 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix2x1<N> = Matrix<N, U2, U1, Owned<N, U2, U1>>; pub type Matrix2x1<T> = Matrix<T, U2, U1, Owned<T, U2, U1>>;
/// A stack-allocated, column-major, 3x1 matrix. /// A stack-allocated, column-major, 3x1 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix3x1<N> = Matrix<N, U3, U1, Owned<N, U3, U1>>; pub type Matrix3x1<T> = Matrix<T, U3, U1, Owned<T, U3, U1>>;
/// A stack-allocated, column-major, 4x1 matrix. /// A stack-allocated, column-major, 4x1 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix4x1<N> = Matrix<N, U4, U1, Owned<N, U4, U1>>; pub type Matrix4x1<T> = Matrix<T, U4, U1, Owned<T, U4, U1>>;
/// A stack-allocated, column-major, 5x1 matrix. /// A stack-allocated, column-major, 5x1 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix5x1<N> = Matrix<N, U5, U1, Owned<N, U5, U1>>; pub type Matrix5x1<T> = Matrix<T, U5, U1, Owned<T, U5, U1>>;
/// A stack-allocated, column-major, 6x1 matrix. /// A stack-allocated, column-major, 6x1 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix6x1<N> = Matrix<N, U6, U1, Owned<N, U6, U1>>; pub type Matrix6x1<T> = Matrix<T, U6, U1, Owned<T, U6, U1>>;
/// A stack-allocated, column-major, 3x2 matrix. /// A stack-allocated, column-major, 3x2 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix3x2<N> = Matrix<N, U3, U2, Owned<N, U3, U2>>; pub type Matrix3x2<T> = Matrix<T, U3, U2, Owned<T, U3, U2>>;
/// A stack-allocated, column-major, 4x2 matrix. /// A stack-allocated, column-major, 4x2 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix4x2<N> = Matrix<N, U4, U2, Owned<N, U4, U2>>; pub type Matrix4x2<T> = Matrix<T, U4, U2, Owned<T, U4, U2>>;
/// A stack-allocated, column-major, 5x2 matrix. /// A stack-allocated, column-major, 5x2 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix5x2<N> = Matrix<N, U5, U2, Owned<N, U5, U2>>; pub type Matrix5x2<T> = Matrix<T, U5, U2, Owned<T, U5, U2>>;
/// A stack-allocated, column-major, 6x2 matrix. /// A stack-allocated, column-major, 6x2 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix6x2<N> = Matrix<N, U6, U2, Owned<N, U6, U2>>; pub type Matrix6x2<T> = Matrix<T, U6, U2, Owned<T, U6, U2>>;
/// A stack-allocated, column-major, 4x3 matrix. /// A stack-allocated, column-major, 4x3 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix4x3<N> = Matrix<N, U4, U3, Owned<N, U4, U3>>; pub type Matrix4x3<T> = Matrix<T, U4, U3, Owned<T, U4, U3>>;
/// A stack-allocated, column-major, 5x3 matrix. /// A stack-allocated, column-major, 5x3 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix5x3<N> = Matrix<N, U5, U3, Owned<N, U5, U3>>; pub type Matrix5x3<T> = Matrix<T, U5, U3, Owned<T, U5, U3>>;
/// A stack-allocated, column-major, 6x3 matrix. /// A stack-allocated, column-major, 6x3 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix6x3<N> = Matrix<N, U6, U3, Owned<N, U6, U3>>; pub type Matrix6x3<T> = Matrix<T, U6, U3, Owned<T, U6, U3>>;
/// A stack-allocated, column-major, 5x4 matrix. /// A stack-allocated, column-major, 5x4 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix5x4<N> = Matrix<N, U5, U4, Owned<N, U5, U4>>; pub type Matrix5x4<T> = Matrix<T, U5, U4, Owned<T, U5, U4>>;
/// A stack-allocated, column-major, 6x4 matrix. /// A stack-allocated, column-major, 6x4 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix6x4<N> = Matrix<N, U6, U4, Owned<N, U6, U4>>; pub type Matrix6x4<T> = Matrix<T, U6, U4, Owned<T, U6, U4>>;
/// A stack-allocated, column-major, 6x5 matrix. /// A stack-allocated, column-major, 6x5 matrix.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type Matrix6x5<N> = Matrix<N, U6, U5, Owned<N, U6, U5>>; pub type Matrix6x5<T> = Matrix<T, U6, U5, Owned<T, U6, U5>>;
/* /*
* *
@ -264,24 +265,33 @@ pub type Matrix6x5<N> = Matrix<N, U6, U5, Owned<N, U6, U5>>;
*/ */
/// A dynamically sized column vector. /// A dynamically sized column vector.
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type DVector<N> = Matrix<N, Dynamic, U1, VecStorage<N, Dynamic, U1>>; pub type DVector<T> = Matrix<T, Dynamic, U1, VecStorage<T, Dynamic, U1>>;
/// An owned D-dimensional column vector.
pub type OVector<T, D> = Matrix<T, D, U1, Owned<T, D, U1>>;
/// A statically sized D-dimensional column vector. /// A statically sized D-dimensional column vector.
pub type VectorN<N, D> = Matrix<N, D, U1, Owned<N, D, U1>>; pub type SVector<T, const D: usize> = Matrix<T, Const<D>, U1, Owned<T, Const<D>, U1>>;
pub type CVectorN<N, const D: usize> = Matrix<N, Const<D>, U1, Owned<N, Const<D>, U1>>;
/// An owned matrix column-major matrix with `R` rows and `C` columns.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
#[deprecated(
note = "use SVector for a statically-sized matrix using integer dimensions, or OVector for an owned matrix using types as dimensions."
)]
pub type VectorN<T, D> = Matrix<T, D, U1, Owned<T, D, U1>>;
/// A stack-allocated, 1-dimensional column vector. /// A stack-allocated, 1-dimensional column vector.
pub type Vector1<N> = Matrix<N, U1, U1, Owned<N, U1, U1>>; pub type Vector1<T> = Matrix<T, U1, U1, Owned<T, U1, U1>>;
/// A stack-allocated, 2-dimensional column vector. /// A stack-allocated, 2-dimensional column vector.
pub type Vector2<N> = Matrix<N, U2, U1, Owned<N, U2, U1>>; pub type Vector2<T> = Matrix<T, U2, U1, Owned<T, U2, U1>>;
/// A stack-allocated, 3-dimensional column vector. /// A stack-allocated, 3-dimensional column vector.
pub type Vector3<N> = Matrix<N, U3, U1, Owned<N, U3, U1>>; pub type Vector3<T> = Matrix<T, U3, U1, Owned<T, U3, U1>>;
/// A stack-allocated, 4-dimensional column vector. /// A stack-allocated, 4-dimensional column vector.
pub type Vector4<N> = Matrix<N, U4, U1, Owned<N, U4, U1>>; pub type Vector4<T> = Matrix<T, U4, U1, Owned<T, U4, U1>>;
/// A stack-allocated, 5-dimensional column vector. /// A stack-allocated, 5-dimensional column vector.
pub type Vector5<N> = Matrix<N, U5, U1, Owned<N, U5, U1>>; pub type Vector5<T> = Matrix<T, U5, U1, Owned<T, U5, U1>>;
/// A stack-allocated, 6-dimensional column vector. /// A stack-allocated, 6-dimensional column vector.
pub type Vector6<N> = Matrix<N, U6, U1, Owned<N, U6, U1>>; pub type Vector6<T> = Matrix<T, U6, U1, Owned<T, U6, U1>>;
/* /*
* *
@ -292,23 +302,26 @@ pub type Vector6<N> = Matrix<N, U6, U1, Owned<N, U6, U1>>;
*/ */
/// A dynamically sized row vector. /// A dynamically sized row vector.
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub type RowDVector<N> = Matrix<N, U1, Dynamic, VecStorage<N, U1, Dynamic>>; pub type RowDVector<T> = Matrix<T, U1, Dynamic, VecStorage<T, U1, Dynamic>>;
/// An owned D-dimensional row vector.
pub type RowOVector<T, D> = Matrix<T, U1, D, Owned<T, U1, D>>;
/// A statically sized D-dimensional row vector. /// A statically sized D-dimensional row vector.
pub type RowVectorN<N, D> = Matrix<N, U1, D, Owned<N, U1, D>>; pub type RowSVector<T, const D: usize> = Matrix<T, U1, Const<D>, Owned<T, U1, Const<D>>>;
/// A stack-allocated, 1-dimensional row vector. /// A stack-allocated, 1-dimensional row vector.
pub type RowVector1<N> = Matrix<N, U1, U1, Owned<N, U1, U1>>; pub type RowVector1<T> = Matrix<T, U1, U1, Owned<T, U1, U1>>;
/// A stack-allocated, 2-dimensional row vector. /// A stack-allocated, 2-dimensional row vector.
pub type RowVector2<N> = Matrix<N, U1, U2, Owned<N, U1, U2>>; pub type RowVector2<T> = Matrix<T, U1, U2, Owned<T, U1, U2>>;
/// A stack-allocated, 3-dimensional row vector. /// A stack-allocated, 3-dimensional row vector.
pub type RowVector3<N> = Matrix<N, U1, U3, Owned<N, U1, U3>>; pub type RowVector3<T> = Matrix<T, U1, U3, Owned<T, U1, U3>>;
/// A stack-allocated, 4-dimensional row vector. /// A stack-allocated, 4-dimensional row vector.
pub type RowVector4<N> = Matrix<N, U1, U4, Owned<N, U1, U4>>; pub type RowVector4<T> = Matrix<T, U1, U4, Owned<T, U1, U4>>;
/// A stack-allocated, 5-dimensional row vector. /// A stack-allocated, 5-dimensional row vector.
pub type RowVector5<N> = Matrix<N, U1, U5, Owned<N, U1, U5>>; pub type RowVector5<T> = Matrix<T, U1, U5, Owned<T, U1, U5>>;
/// A stack-allocated, 6-dimensional row vector. /// A stack-allocated, 6-dimensional row vector.
pub type RowVector6<N> = Matrix<N, U1, U6, Owned<N, U1, U6>>; pub type RowVector6<T> = Matrix<T, U1, U6, Owned<T, U1, U6>>;
/* /*
* *
@ -318,14 +331,14 @@ pub type RowVector6<N> = Matrix<N, U1, U6, Owned<N, U1, U6>>;
* *
*/ */
/// A stack-allocated, 1-dimensional unit vector. /// A stack-allocated, 1-dimensional unit vector.
pub type UnitVector1<N> = Unit<Matrix<N, U1, U1, Owned<N, U1, U1>>>; pub type UnitVector1<T> = Unit<Matrix<T, U1, U1, Owned<T, U1, U1>>>;
/// A stack-allocated, 2-dimensional unit vector. /// A stack-allocated, 2-dimensional unit vector.
pub type UnitVector2<N> = Unit<Matrix<N, U2, U1, Owned<N, U2, U1>>>; pub type UnitVector2<T> = Unit<Matrix<T, U2, U1, Owned<T, U2, U1>>>;
/// A stack-allocated, 3-dimensional unit vector. /// A stack-allocated, 3-dimensional unit vector.
pub type UnitVector3<N> = Unit<Matrix<N, U3, U1, Owned<N, U3, U1>>>; pub type UnitVector3<T> = Unit<Matrix<T, U3, U1, Owned<T, U3, U1>>>;
/// A stack-allocated, 4-dimensional unit vector. /// A stack-allocated, 4-dimensional unit vector.
pub type UnitVector4<N> = Unit<Matrix<N, U4, U1, Owned<N, U4, U1>>>; pub type UnitVector4<T> = Unit<Matrix<T, U4, U1, Owned<T, U4, U1>>>;
/// A stack-allocated, 5-dimensional unit vector. /// A stack-allocated, 5-dimensional unit vector.
pub type UnitVector5<N> = Unit<Matrix<N, U5, U1, Owned<N, U5, U1>>>; pub type UnitVector5<T> = Unit<Matrix<T, U5, U1, Owned<T, U5, U1>>>;
/// A stack-allocated, 6-dimensional unit vector. /// A stack-allocated, 6-dimensional unit vector.
pub type UnitVector6<N> = Unit<Matrix<N, U6, U1, Owned<N, U6, U1>>>; pub type UnitVector6<T> = Unit<Matrix<T, U6, U1, Owned<T, U6, U1>>>;

View File

@ -1,6 +1,6 @@
use crate::base::dimension::{Dynamic, U1, U2, U3, U4, U5, U6}; use crate::base::dimension::{Dynamic, U1, U2, U3, U4, U5, U6};
use crate::base::matrix_slice::{SliceStorage, SliceStorageMut}; use crate::base::matrix_slice::{SliceStorage, SliceStorageMut};
use crate::base::Matrix; use crate::base::{Const, Matrix};
/* /*
* *
@ -9,287 +9,290 @@ use crate::base::Matrix;
* *
* *
*/ */
/// A column-major matrix slice with `R` rows and `C` columns. // NOTE: we can't provide defaults for the strides because it's not supported yet by min_const_generics.
/// A column-major matrix slice with dimensions known at compile-time.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMN<'a, N, R, C, RStride = U1, CStride = R> = pub type SMatrixSlice<'a, T, const R: usize, const C: usize> =
Matrix<N, R, C, SliceStorage<'a, N, R, C, RStride, CStride>>; Matrix<T, Const<R>, Const<C>, SliceStorage<'a, T, Const<R>, Const<C>, Const<1>, Const<R>>>;
/// A column-major matrix slice with `D` rows and columns.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceN<'a, N, D, RStride = U1, CStride = D> =
Matrix<N, D, D, SliceStorage<'a, N, D, D, RStride, CStride>>;
/// A column-major matrix slice dynamic numbers of rows and columns. /// A column-major matrix slice dynamic numbers of rows and columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type DMatrixSlice<'a, N, RStride = U1, CStride = Dynamic> = pub type DMatrixSlice<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<N, Dynamic, Dynamic, SliceStorage<'a, N, Dynamic, Dynamic, RStride, CStride>>; Matrix<T, Dynamic, Dynamic, SliceStorage<'a, T, Dynamic, Dynamic, RStride, CStride>>;
/// A column-major 1x1 matrix slice. /// A column-major 1x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice1<'a, N, RStride = U1, CStride = U1> = pub type MatrixSlice1<'a, T, RStride = U1, CStride = U1> =
Matrix<N, U1, U1, SliceStorage<'a, N, U1, U1, RStride, CStride>>; Matrix<T, U1, U1, SliceStorage<'a, T, U1, U1, RStride, CStride>>;
/// A column-major 2x2 matrix slice. /// A column-major 2x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice2<'a, N, RStride = U1, CStride = U2> = pub type MatrixSlice2<'a, T, RStride = U1, CStride = U2> =
Matrix<N, U2, U2, SliceStorage<'a, N, U2, U2, RStride, CStride>>; Matrix<T, U2, U2, SliceStorage<'a, T, U2, U2, RStride, CStride>>;
/// A column-major 3x3 matrix slice. /// A column-major 3x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice3<'a, N, RStride = U1, CStride = U3> = pub type MatrixSlice3<'a, T, RStride = U1, CStride = U3> =
Matrix<N, U3, U3, SliceStorage<'a, N, U3, U3, RStride, CStride>>; Matrix<T, U3, U3, SliceStorage<'a, T, U3, U3, RStride, CStride>>;
/// A column-major 4x4 matrix slice. /// A column-major 4x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice4<'a, N, RStride = U1, CStride = U4> = pub type MatrixSlice4<'a, T, RStride = U1, CStride = U4> =
Matrix<N, U4, U4, SliceStorage<'a, N, U4, U4, RStride, CStride>>; Matrix<T, U4, U4, SliceStorage<'a, T, U4, U4, RStride, CStride>>;
/// A column-major 5x5 matrix slice. /// A column-major 5x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice5<'a, N, RStride = U1, CStride = U5> = pub type MatrixSlice5<'a, T, RStride = U1, CStride = U5> =
Matrix<N, U5, U5, SliceStorage<'a, N, U5, U5, RStride, CStride>>; Matrix<T, U5, U5, SliceStorage<'a, T, U5, U5, RStride, CStride>>;
/// A column-major 6x6 matrix slice. /// A column-major 6x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice6<'a, N, RStride = U1, CStride = U6> = pub type MatrixSlice6<'a, T, RStride = U1, CStride = U6> =
Matrix<N, U6, U6, SliceStorage<'a, N, U6, U6, RStride, CStride>>; Matrix<T, U6, U6, SliceStorage<'a, T, U6, U6, RStride, CStride>>;
/// A column-major 1x2 matrix slice. /// A column-major 1x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice1x2<'a, N, RStride = U1, CStride = U1> = pub type MatrixSlice1x2<'a, T, RStride = U1, CStride = U1> =
Matrix<N, U1, U2, SliceStorage<'a, N, U1, U2, RStride, CStride>>; Matrix<T, U1, U2, SliceStorage<'a, T, U1, U2, RStride, CStride>>;
/// A column-major 1x3 matrix slice. /// A column-major 1x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice1x3<'a, N, RStride = U1, CStride = U1> = pub type MatrixSlice1x3<'a, T, RStride = U1, CStride = U1> =
Matrix<N, U1, U3, SliceStorage<'a, N, U1, U3, RStride, CStride>>; Matrix<T, U1, U3, SliceStorage<'a, T, U1, U3, RStride, CStride>>;
/// A column-major 1x4 matrix slice. /// A column-major 1x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice1x4<'a, N, RStride = U1, CStride = U1> = pub type MatrixSlice1x4<'a, T, RStride = U1, CStride = U1> =
Matrix<N, U1, U4, SliceStorage<'a, N, U1, U4, RStride, CStride>>; Matrix<T, U1, U4, SliceStorage<'a, T, U1, U4, RStride, CStride>>;
/// A column-major 1x5 matrix slice. /// A column-major 1x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice1x5<'a, N, RStride = U1, CStride = U1> = pub type MatrixSlice1x5<'a, T, RStride = U1, CStride = U1> =
Matrix<N, U1, U5, SliceStorage<'a, N, U1, U5, RStride, CStride>>; Matrix<T, U1, U5, SliceStorage<'a, T, U1, U5, RStride, CStride>>;
/// A column-major 1x6 matrix slice. /// A column-major 1x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice1x6<'a, N, RStride = U1, CStride = U1> = pub type MatrixSlice1x6<'a, T, RStride = U1, CStride = U1> =
Matrix<N, U1, U6, SliceStorage<'a, N, U1, U6, RStride, CStride>>; Matrix<T, U1, U6, SliceStorage<'a, T, U1, U6, RStride, CStride>>;
/// A column-major 2x1 matrix slice. /// A column-major 2x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice2x1<'a, N, RStride = U1, CStride = U2> = pub type MatrixSlice2x1<'a, T, RStride = U1, CStride = U2> =
Matrix<N, U2, U1, SliceStorage<'a, N, U2, U1, RStride, CStride>>; Matrix<T, U2, U1, SliceStorage<'a, T, U2, U1, RStride, CStride>>;
/// A column-major 2x3 matrix slice. /// A column-major 2x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice2x3<'a, N, RStride = U1, CStride = U2> = pub type MatrixSlice2x3<'a, T, RStride = U1, CStride = U2> =
Matrix<N, U2, U3, SliceStorage<'a, N, U2, U3, RStride, CStride>>; Matrix<T, U2, U3, SliceStorage<'a, T, U2, U3, RStride, CStride>>;
/// A column-major 2x4 matrix slice. /// A column-major 2x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice2x4<'a, N, RStride = U1, CStride = U2> = pub type MatrixSlice2x4<'a, T, RStride = U1, CStride = U2> =
Matrix<N, U2, U4, SliceStorage<'a, N, U2, U4, RStride, CStride>>; Matrix<T, U2, U4, SliceStorage<'a, T, U2, U4, RStride, CStride>>;
/// A column-major 2x5 matrix slice. /// A column-major 2x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice2x5<'a, N, RStride = U1, CStride = U2> = pub type MatrixSlice2x5<'a, T, RStride = U1, CStride = U2> =
Matrix<N, U2, U5, SliceStorage<'a, N, U2, U5, RStride, CStride>>; Matrix<T, U2, U5, SliceStorage<'a, T, U2, U5, RStride, CStride>>;
/// A column-major 2x6 matrix slice. /// A column-major 2x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice2x6<'a, N, RStride = U1, CStride = U2> = pub type MatrixSlice2x6<'a, T, RStride = U1, CStride = U2> =
Matrix<N, U2, U6, SliceStorage<'a, N, U2, U6, RStride, CStride>>; Matrix<T, U2, U6, SliceStorage<'a, T, U2, U6, RStride, CStride>>;
/// A column-major 3x1 matrix slice. /// A column-major 3x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice3x1<'a, N, RStride = U1, CStride = U3> = pub type MatrixSlice3x1<'a, T, RStride = U1, CStride = U3> =
Matrix<N, U3, U1, SliceStorage<'a, N, U3, U1, RStride, CStride>>; Matrix<T, U3, U1, SliceStorage<'a, T, U3, U1, RStride, CStride>>;
/// A column-major 3x2 matrix slice. /// A column-major 3x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice3x2<'a, N, RStride = U1, CStride = U3> = pub type MatrixSlice3x2<'a, T, RStride = U1, CStride = U3> =
Matrix<N, U3, U2, SliceStorage<'a, N, U3, U2, RStride, CStride>>; Matrix<T, U3, U2, SliceStorage<'a, T, U3, U2, RStride, CStride>>;
/// A column-major 3x4 matrix slice. /// A column-major 3x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice3x4<'a, N, RStride = U1, CStride = U3> = pub type MatrixSlice3x4<'a, T, RStride = U1, CStride = U3> =
Matrix<N, U3, U4, SliceStorage<'a, N, U3, U4, RStride, CStride>>; Matrix<T, U3, U4, SliceStorage<'a, T, U3, U4, RStride, CStride>>;
/// A column-major 3x5 matrix slice. /// A column-major 3x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice3x5<'a, N, RStride = U1, CStride = U3> = pub type MatrixSlice3x5<'a, T, RStride = U1, CStride = U3> =
Matrix<N, U3, U5, SliceStorage<'a, N, U3, U5, RStride, CStride>>; Matrix<T, U3, U5, SliceStorage<'a, T, U3, U5, RStride, CStride>>;
/// A column-major 3x6 matrix slice. /// A column-major 3x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice3x6<'a, N, RStride = U1, CStride = U3> = pub type MatrixSlice3x6<'a, T, RStride = U1, CStride = U3> =
Matrix<N, U3, U6, SliceStorage<'a, N, U3, U6, RStride, CStride>>; Matrix<T, U3, U6, SliceStorage<'a, T, U3, U6, RStride, CStride>>;
/// A column-major 4x1 matrix slice. /// A column-major 4x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice4x1<'a, N, RStride = U1, CStride = U4> = pub type MatrixSlice4x1<'a, T, RStride = U1, CStride = U4> =
Matrix<N, U4, U1, SliceStorage<'a, N, U4, U1, RStride, CStride>>; Matrix<T, U4, U1, SliceStorage<'a, T, U4, U1, RStride, CStride>>;
/// A column-major 4x2 matrix slice. /// A column-major 4x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice4x2<'a, N, RStride = U1, CStride = U4> = pub type MatrixSlice4x2<'a, T, RStride = U1, CStride = U4> =
Matrix<N, U4, U2, SliceStorage<'a, N, U4, U2, RStride, CStride>>; Matrix<T, U4, U2, SliceStorage<'a, T, U4, U2, RStride, CStride>>;
/// A column-major 4x3 matrix slice. /// A column-major 4x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice4x3<'a, N, RStride = U1, CStride = U4> = pub type MatrixSlice4x3<'a, T, RStride = U1, CStride = U4> =
Matrix<N, U4, U3, SliceStorage<'a, N, U4, U3, RStride, CStride>>; Matrix<T, U4, U3, SliceStorage<'a, T, U4, U3, RStride, CStride>>;
/// A column-major 4x5 matrix slice. /// A column-major 4x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice4x5<'a, N, RStride = U1, CStride = U4> = pub type MatrixSlice4x5<'a, T, RStride = U1, CStride = U4> =
Matrix<N, U4, U5, SliceStorage<'a, N, U4, U5, RStride, CStride>>; Matrix<T, U4, U5, SliceStorage<'a, T, U4, U5, RStride, CStride>>;
/// A column-major 4x6 matrix slice. /// A column-major 4x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice4x6<'a, N, RStride = U1, CStride = U4> = pub type MatrixSlice4x6<'a, T, RStride = U1, CStride = U4> =
Matrix<N, U4, U6, SliceStorage<'a, N, U4, U6, RStride, CStride>>; Matrix<T, U4, U6, SliceStorage<'a, T, U4, U6, RStride, CStride>>;
/// A column-major 5x1 matrix slice. /// A column-major 5x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice5x1<'a, N, RStride = U1, CStride = U5> = pub type MatrixSlice5x1<'a, T, RStride = U1, CStride = U5> =
Matrix<N, U5, U1, SliceStorage<'a, N, U5, U1, RStride, CStride>>; Matrix<T, U5, U1, SliceStorage<'a, T, U5, U1, RStride, CStride>>;
/// A column-major 5x2 matrix slice. /// A column-major 5x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice5x2<'a, N, RStride = U1, CStride = U5> = pub type MatrixSlice5x2<'a, T, RStride = U1, CStride = U5> =
Matrix<N, U5, U2, SliceStorage<'a, N, U5, U2, RStride, CStride>>; Matrix<T, U5, U2, SliceStorage<'a, T, U5, U2, RStride, CStride>>;
/// A column-major 5x3 matrix slice. /// A column-major 5x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice5x3<'a, N, RStride = U1, CStride = U5> = pub type MatrixSlice5x3<'a, T, RStride = U1, CStride = U5> =
Matrix<N, U5, U3, SliceStorage<'a, N, U5, U3, RStride, CStride>>; Matrix<T, U5, U3, SliceStorage<'a, T, U5, U3, RStride, CStride>>;
/// A column-major 5x4 matrix slice. /// A column-major 5x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice5x4<'a, N, RStride = U1, CStride = U5> = pub type MatrixSlice5x4<'a, T, RStride = U1, CStride = U5> =
Matrix<N, U5, U4, SliceStorage<'a, N, U5, U4, RStride, CStride>>; Matrix<T, U5, U4, SliceStorage<'a, T, U5, U4, RStride, CStride>>;
/// A column-major 5x6 matrix slice. /// A column-major 5x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice5x6<'a, N, RStride = U1, CStride = U5> = pub type MatrixSlice5x6<'a, T, RStride = U1, CStride = U5> =
Matrix<N, U5, U6, SliceStorage<'a, N, U5, U6, RStride, CStride>>; Matrix<T, U5, U6, SliceStorage<'a, T, U5, U6, RStride, CStride>>;
/// A column-major 6x1 matrix slice. /// A column-major 6x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice6x1<'a, N, RStride = U1, CStride = U6> = pub type MatrixSlice6x1<'a, T, RStride = U1, CStride = U6> =
Matrix<N, U6, U1, SliceStorage<'a, N, U6, U1, RStride, CStride>>; Matrix<T, U6, U1, SliceStorage<'a, T, U6, U1, RStride, CStride>>;
/// A column-major 6x2 matrix slice. /// A column-major 6x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice6x2<'a, N, RStride = U1, CStride = U6> = pub type MatrixSlice6x2<'a, T, RStride = U1, CStride = U6> =
Matrix<N, U6, U2, SliceStorage<'a, N, U6, U2, RStride, CStride>>; Matrix<T, U6, U2, SliceStorage<'a, T, U6, U2, RStride, CStride>>;
/// A column-major 6x3 matrix slice. /// A column-major 6x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice6x3<'a, N, RStride = U1, CStride = U6> = pub type MatrixSlice6x3<'a, T, RStride = U1, CStride = U6> =
Matrix<N, U6, U3, SliceStorage<'a, N, U6, U3, RStride, CStride>>; Matrix<T, U6, U3, SliceStorage<'a, T, U6, U3, RStride, CStride>>;
/// A column-major 6x4 matrix slice. /// A column-major 6x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice6x4<'a, N, RStride = U1, CStride = U6> = pub type MatrixSlice6x4<'a, T, RStride = U1, CStride = U6> =
Matrix<N, U6, U4, SliceStorage<'a, N, U6, U4, RStride, CStride>>; Matrix<T, U6, U4, SliceStorage<'a, T, U6, U4, RStride, CStride>>;
/// A column-major 6x5 matrix slice. /// A column-major 6x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSlice6x5<'a, N, RStride = U1, CStride = U6> = pub type MatrixSlice6x5<'a, T, RStride = U1, CStride = U6> =
Matrix<N, U6, U5, SliceStorage<'a, N, U6, U5, RStride, CStride>>; Matrix<T, U6, U5, SliceStorage<'a, T, U6, U5, RStride, CStride>>;
/// A column-major matrix slice with 1 row and a number of columns chosen at runtime. /// A column-major matrix slice with 1 row and a number of columns chosen at runtime.
pub type MatrixSlice1xX<'a, N, RStride = U1, CStride = U1> = pub type MatrixSlice1xX<'a, T, RStride = U1, CStride = U1> =
Matrix<N, U1, Dynamic, SliceStorage<'a, N, U1, Dynamic, RStride, CStride>>; Matrix<T, U1, Dynamic, SliceStorage<'a, T, U1, Dynamic, RStride, CStride>>;
/// A column-major matrix slice with 2 rows and a number of columns chosen at runtime. /// A column-major matrix slice with 2 rows and a number of columns chosen at runtime.
pub type MatrixSlice2xX<'a, N, RStride = U1, CStride = U2> = pub type MatrixSlice2xX<'a, T, RStride = U1, CStride = U2> =
Matrix<N, U2, Dynamic, SliceStorage<'a, N, U2, Dynamic, RStride, CStride>>; Matrix<T, U2, Dynamic, SliceStorage<'a, T, U2, Dynamic, RStride, CStride>>;
/// A column-major matrix slice with 3 rows and a number of columns chosen at runtime. /// A column-major matrix slice with 3 rows and a number of columns chosen at runtime.
pub type MatrixSlice3xX<'a, N, RStride = U1, CStride = U3> = pub type MatrixSlice3xX<'a, T, RStride = U1, CStride = U3> =
Matrix<N, U3, Dynamic, SliceStorage<'a, N, U3, Dynamic, RStride, CStride>>; Matrix<T, U3, Dynamic, SliceStorage<'a, T, U3, Dynamic, RStride, CStride>>;
/// A column-major matrix slice with 4 rows and a number of columns chosen at runtime. /// A column-major matrix slice with 4 rows and a number of columns chosen at runtime.
pub type MatrixSlice4xX<'a, N, RStride = U1, CStride = U4> = pub type MatrixSlice4xX<'a, T, RStride = U1, CStride = U4> =
Matrix<N, U4, Dynamic, SliceStorage<'a, N, U4, Dynamic, RStride, CStride>>; Matrix<T, U4, Dynamic, SliceStorage<'a, T, U4, Dynamic, RStride, CStride>>;
/// A column-major matrix slice with 5 rows and a number of columns chosen at runtime. /// A column-major matrix slice with 5 rows and a number of columns chosen at runtime.
pub type MatrixSlice5xX<'a, N, RStride = U1, CStride = U5> = pub type MatrixSlice5xX<'a, T, RStride = U1, CStride = U5> =
Matrix<N, U5, Dynamic, SliceStorage<'a, N, U5, Dynamic, RStride, CStride>>; Matrix<T, U5, Dynamic, SliceStorage<'a, T, U5, Dynamic, RStride, CStride>>;
/// A column-major matrix slice with 6 rows and a number of columns chosen at runtime. /// A column-major matrix slice with 6 rows and a number of columns chosen at runtime.
pub type MatrixSlice6xX<'a, N, RStride = U1, CStride = U6> = pub type MatrixSlice6xX<'a, T, RStride = U1, CStride = U6> =
Matrix<N, U6, Dynamic, SliceStorage<'a, N, U6, Dynamic, RStride, CStride>>; Matrix<T, U6, Dynamic, SliceStorage<'a, T, U6, Dynamic, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 1 column. /// A column-major matrix slice with a number of rows chosen at runtime and 1 column.
pub type MatrixSliceXx1<'a, N, RStride = U1, CStride = Dynamic> = pub type MatrixSliceXx1<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<N, Dynamic, U1, SliceStorage<'a, N, Dynamic, U1, RStride, CStride>>; Matrix<T, Dynamic, U1, SliceStorage<'a, T, Dynamic, U1, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 2 columns. /// A column-major matrix slice with a number of rows chosen at runtime and 2 columns.
pub type MatrixSliceXx2<'a, N, RStride = U1, CStride = Dynamic> = pub type MatrixSliceXx2<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<N, Dynamic, U2, SliceStorage<'a, N, Dynamic, U2, RStride, CStride>>; Matrix<T, Dynamic, U2, SliceStorage<'a, T, Dynamic, U2, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 3 columns. /// A column-major matrix slice with a number of rows chosen at runtime and 3 columns.
pub type MatrixSliceXx3<'a, N, RStride = U1, CStride = Dynamic> = pub type MatrixSliceXx3<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<N, Dynamic, U3, SliceStorage<'a, N, Dynamic, U3, RStride, CStride>>; Matrix<T, Dynamic, U3, SliceStorage<'a, T, Dynamic, U3, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 4 columns. /// A column-major matrix slice with a number of rows chosen at runtime and 4 columns.
pub type MatrixSliceXx4<'a, N, RStride = U1, CStride = Dynamic> = pub type MatrixSliceXx4<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<N, Dynamic, U4, SliceStorage<'a, N, Dynamic, U4, RStride, CStride>>; Matrix<T, Dynamic, U4, SliceStorage<'a, T, Dynamic, U4, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 5 columns. /// A column-major matrix slice with a number of rows chosen at runtime and 5 columns.
pub type MatrixSliceXx5<'a, N, RStride = U1, CStride = Dynamic> = pub type MatrixSliceXx5<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<N, Dynamic, U5, SliceStorage<'a, N, Dynamic, U5, RStride, CStride>>; Matrix<T, Dynamic, U5, SliceStorage<'a, T, Dynamic, U5, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 6 columns. /// A column-major matrix slice with a number of rows chosen at runtime and 6 columns.
pub type MatrixSliceXx6<'a, N, RStride = U1, CStride = Dynamic> = pub type MatrixSliceXx6<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<N, Dynamic, U6, SliceStorage<'a, N, Dynamic, U6, RStride, CStride>>; Matrix<T, Dynamic, U6, SliceStorage<'a, T, Dynamic, U6, RStride, CStride>>;
/// A column vector slice with `D` rows. /// A column vector slice with dimensions known at compile-time.
pub type VectorSliceN<'a, N, D, RStride = U1, CStride = D> = ///
Matrix<N, D, U1, SliceStorage<'a, N, D, U1, RStride, CStride>>; /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorSlice<'a, T, D, RStride = U1, CStride = D> =
Matrix<T, D, U1, SliceStorage<'a, T, D, U1, RStride, CStride>>;
/// A column vector slice with dimensions known at compile-time.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type SVectorSlice<'a, T, const D: usize> =
Matrix<T, Const<D>, Const<1>, SliceStorage<'a, T, Const<D>, Const<1>, Const<1>, Const<D>>>;
/// A column vector slice dynamic numbers of rows and columns. /// A column vector slice dynamic numbers of rows and columns.
pub type DVectorSlice<'a, N, RStride = U1, CStride = Dynamic> = pub type DVectorSlice<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<N, Dynamic, U1, SliceStorage<'a, N, Dynamic, U1, RStride, CStride>>; Matrix<T, Dynamic, U1, SliceStorage<'a, T, Dynamic, U1, RStride, CStride>>;
/// A 1D column vector slice. /// A 1D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorSlice1<'a, N, RStride = U1, CStride = U1> = pub type VectorSlice1<'a, T, RStride = U1, CStride = U1> =
Matrix<N, U1, U1, SliceStorage<'a, N, U1, U1, RStride, CStride>>; Matrix<T, U1, U1, SliceStorage<'a, T, U1, U1, RStride, CStride>>;
/// A 2D column vector slice. /// A 2D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorSlice2<'a, N, RStride = U1, CStride = U2> = pub type VectorSlice2<'a, T, RStride = U1, CStride = U2> =
Matrix<N, U2, U1, SliceStorage<'a, N, U2, U1, RStride, CStride>>; Matrix<T, U2, U1, SliceStorage<'a, T, U2, U1, RStride, CStride>>;
/// A 3D column vector slice. /// A 3D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorSlice3<'a, N, RStride = U1, CStride = U3> = pub type VectorSlice3<'a, T, RStride = U1, CStride = U3> =
Matrix<N, U3, U1, SliceStorage<'a, N, U3, U1, RStride, CStride>>; Matrix<T, U3, U1, SliceStorage<'a, T, U3, U1, RStride, CStride>>;
/// A 4D column vector slice. /// A 4D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorSlice4<'a, N, RStride = U1, CStride = U4> = pub type VectorSlice4<'a, T, RStride = U1, CStride = U4> =
Matrix<N, U4, U1, SliceStorage<'a, N, U4, U1, RStride, CStride>>; Matrix<T, U4, U1, SliceStorage<'a, T, U4, U1, RStride, CStride>>;
/// A 5D column vector slice. /// A 5D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorSlice5<'a, N, RStride = U1, CStride = U5> = pub type VectorSlice5<'a, T, RStride = U1, CStride = U5> =
Matrix<N, U5, U1, SliceStorage<'a, N, U5, U1, RStride, CStride>>; Matrix<T, U5, U1, SliceStorage<'a, T, U5, U1, RStride, CStride>>;
/// A 6D column vector slice. /// A 6D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorSlice6<'a, N, RStride = U1, CStride = U6> = pub type VectorSlice6<'a, T, RStride = U1, CStride = U6> =
Matrix<N, U6, U1, SliceStorage<'a, N, U6, U1, RStride, CStride>>; Matrix<T, U6, U1, SliceStorage<'a, T, U6, U1, RStride, CStride>>;
/* /*
* *
@ -301,281 +304,297 @@ pub type VectorSlice6<'a, N, RStride = U1, CStride = U6> =
/// A column-major matrix slice with `R` rows and `C` columns. /// A column-major matrix slice with `R` rows and `C` columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMutMN<'a, N, R, C, RStride = U1, CStride = R> = pub type MatrixSliceMutMN<'a, T, R, C, RStride = U1, CStride = R> =
Matrix<N, R, C, SliceStorageMut<'a, N, R, C, RStride, CStride>>; Matrix<T, R, C, SliceStorageMut<'a, T, R, C, RStride, CStride>>;
/// A column-major matrix slice with `D` rows and columns. /// A column-major matrix slice with `D` rows and columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMutN<'a, N, D, RStride = U1, CStride = D> = pub type MatrixSliceMutN<'a, T, D, RStride = U1, CStride = D> =
Matrix<N, D, D, SliceStorageMut<'a, N, D, D, RStride, CStride>>; Matrix<T, D, D, SliceStorageMut<'a, T, D, D, RStride, CStride>>;
/// A column-major matrix slice with dimensions known at compile-time.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type SMatrixSliceMut<'a, T, const R: usize, const C: usize> =
Matrix<T, Const<R>, Const<C>, SliceStorageMut<'a, T, Const<R>, Const<C>, Const<1>, Const<R>>>;
/// A column-major matrix slice dynamic numbers of rows and columns. /// A column-major matrix slice dynamic numbers of rows and columns.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type DMatrixSliceMut<'a, N, RStride = U1, CStride = Dynamic> = pub type DMatrixSliceMut<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<N, Dynamic, Dynamic, SliceStorageMut<'a, N, Dynamic, Dynamic, RStride, CStride>>; Matrix<T, Dynamic, Dynamic, SliceStorageMut<'a, T, Dynamic, Dynamic, RStride, CStride>>;
/// A column-major 1x1 matrix slice. /// A column-major 1x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut1<'a, N, RStride = U1, CStride = U1> = pub type MatrixSliceMut1<'a, T, RStride = U1, CStride = U1> =
Matrix<N, U1, U1, SliceStorageMut<'a, N, U1, U1, RStride, CStride>>; Matrix<T, U1, U1, SliceStorageMut<'a, T, U1, U1, RStride, CStride>>;
/// A column-major 2x2 matrix slice. /// A column-major 2x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut2<'a, N, RStride = U1, CStride = U2> = pub type MatrixSliceMut2<'a, T, RStride = U1, CStride = U2> =
Matrix<N, U2, U2, SliceStorageMut<'a, N, U2, U2, RStride, CStride>>; Matrix<T, U2, U2, SliceStorageMut<'a, T, U2, U2, RStride, CStride>>;
/// A column-major 3x3 matrix slice. /// A column-major 3x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut3<'a, N, RStride = U1, CStride = U3> = pub type MatrixSliceMut3<'a, T, RStride = U1, CStride = U3> =
Matrix<N, U3, U3, SliceStorageMut<'a, N, U3, U3, RStride, CStride>>; Matrix<T, U3, U3, SliceStorageMut<'a, T, U3, U3, RStride, CStride>>;
/// A column-major 4x4 matrix slice. /// A column-major 4x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut4<'a, N, RStride = U1, CStride = U4> = pub type MatrixSliceMut4<'a, T, RStride = U1, CStride = U4> =
Matrix<N, U4, U4, SliceStorageMut<'a, N, U4, U4, RStride, CStride>>; Matrix<T, U4, U4, SliceStorageMut<'a, T, U4, U4, RStride, CStride>>;
/// A column-major 5x5 matrix slice. /// A column-major 5x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut5<'a, N, RStride = U1, CStride = U5> = pub type MatrixSliceMut5<'a, T, RStride = U1, CStride = U5> =
Matrix<N, U5, U5, SliceStorageMut<'a, N, U5, U5, RStride, CStride>>; Matrix<T, U5, U5, SliceStorageMut<'a, T, U5, U5, RStride, CStride>>;
/// A column-major 6x6 matrix slice. /// A column-major 6x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut6<'a, N, RStride = U1, CStride = U6> = pub type MatrixSliceMut6<'a, T, RStride = U1, CStride = U6> =
Matrix<N, U6, U6, SliceStorageMut<'a, N, U6, U6, RStride, CStride>>; Matrix<T, U6, U6, SliceStorageMut<'a, T, U6, U6, RStride, CStride>>;
/// A column-major 1x2 matrix slice. /// A column-major 1x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut1x2<'a, N, RStride = U1, CStride = U1> = pub type MatrixSliceMut1x2<'a, T, RStride = U1, CStride = U1> =
Matrix<N, U1, U2, SliceStorageMut<'a, N, U1, U2, RStride, CStride>>; Matrix<T, U1, U2, SliceStorageMut<'a, T, U1, U2, RStride, CStride>>;
/// A column-major 1x3 matrix slice. /// A column-major 1x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut1x3<'a, N, RStride = U1, CStride = U1> = pub type MatrixSliceMut1x3<'a, T, RStride = U1, CStride = U1> =
Matrix<N, U1, U3, SliceStorageMut<'a, N, U1, U3, RStride, CStride>>; Matrix<T, U1, U3, SliceStorageMut<'a, T, U1, U3, RStride, CStride>>;
/// A column-major 1x4 matrix slice. /// A column-major 1x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut1x4<'a, N, RStride = U1, CStride = U1> = pub type MatrixSliceMut1x4<'a, T, RStride = U1, CStride = U1> =
Matrix<N, U1, U4, SliceStorageMut<'a, N, U1, U4, RStride, CStride>>; Matrix<T, U1, U4, SliceStorageMut<'a, T, U1, U4, RStride, CStride>>;
/// A column-major 1x5 matrix slice. /// A column-major 1x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut1x5<'a, N, RStride = U1, CStride = U1> = pub type MatrixSliceMut1x5<'a, T, RStride = U1, CStride = U1> =
Matrix<N, U1, U5, SliceStorageMut<'a, N, U1, U5, RStride, CStride>>; Matrix<T, U1, U5, SliceStorageMut<'a, T, U1, U5, RStride, CStride>>;
/// A column-major 1x6 matrix slice. /// A column-major 1x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut1x6<'a, N, RStride = U1, CStride = U1> = pub type MatrixSliceMut1x6<'a, T, RStride = U1, CStride = U1> =
Matrix<N, U1, U6, SliceStorageMut<'a, N, U1, U6, RStride, CStride>>; Matrix<T, U1, U6, SliceStorageMut<'a, T, U1, U6, RStride, CStride>>;
/// A column-major 2x1 matrix slice. /// A column-major 2x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut2x1<'a, N, RStride = U1, CStride = U2> = pub type MatrixSliceMut2x1<'a, T, RStride = U1, CStride = U2> =
Matrix<N, U2, U1, SliceStorageMut<'a, N, U2, U1, RStride, CStride>>; Matrix<T, U2, U1, SliceStorageMut<'a, T, U2, U1, RStride, CStride>>;
/// A column-major 2x3 matrix slice. /// A column-major 2x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut2x3<'a, N, RStride = U1, CStride = U2> = pub type MatrixSliceMut2x3<'a, T, RStride = U1, CStride = U2> =
Matrix<N, U2, U3, SliceStorageMut<'a, N, U2, U3, RStride, CStride>>; Matrix<T, U2, U3, SliceStorageMut<'a, T, U2, U3, RStride, CStride>>;
/// A column-major 2x4 matrix slice. /// A column-major 2x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut2x4<'a, N, RStride = U1, CStride = U2> = pub type MatrixSliceMut2x4<'a, T, RStride = U1, CStride = U2> =
Matrix<N, U2, U4, SliceStorageMut<'a, N, U2, U4, RStride, CStride>>; Matrix<T, U2, U4, SliceStorageMut<'a, T, U2, U4, RStride, CStride>>;
/// A column-major 2x5 matrix slice. /// A column-major 2x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut2x5<'a, N, RStride = U1, CStride = U2> = pub type MatrixSliceMut2x5<'a, T, RStride = U1, CStride = U2> =
Matrix<N, U2, U5, SliceStorageMut<'a, N, U2, U5, RStride, CStride>>; Matrix<T, U2, U5, SliceStorageMut<'a, T, U2, U5, RStride, CStride>>;
/// A column-major 2x6 matrix slice. /// A column-major 2x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut2x6<'a, N, RStride = U1, CStride = U2> = pub type MatrixSliceMut2x6<'a, T, RStride = U1, CStride = U2> =
Matrix<N, U2, U6, SliceStorageMut<'a, N, U2, U6, RStride, CStride>>; Matrix<T, U2, U6, SliceStorageMut<'a, T, U2, U6, RStride, CStride>>;
/// A column-major 3x1 matrix slice. /// A column-major 3x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut3x1<'a, N, RStride = U1, CStride = U3> = pub type MatrixSliceMut3x1<'a, T, RStride = U1, CStride = U3> =
Matrix<N, U3, U1, SliceStorageMut<'a, N, U3, U1, RStride, CStride>>; Matrix<T, U3, U1, SliceStorageMut<'a, T, U3, U1, RStride, CStride>>;
/// A column-major 3x2 matrix slice. /// A column-major 3x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut3x2<'a, N, RStride = U1, CStride = U3> = pub type MatrixSliceMut3x2<'a, T, RStride = U1, CStride = U3> =
Matrix<N, U3, U2, SliceStorageMut<'a, N, U3, U2, RStride, CStride>>; Matrix<T, U3, U2, SliceStorageMut<'a, T, U3, U2, RStride, CStride>>;
/// A column-major 3x4 matrix slice. /// A column-major 3x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut3x4<'a, N, RStride = U1, CStride = U3> = pub type MatrixSliceMut3x4<'a, T, RStride = U1, CStride = U3> =
Matrix<N, U3, U4, SliceStorageMut<'a, N, U3, U4, RStride, CStride>>; Matrix<T, U3, U4, SliceStorageMut<'a, T, U3, U4, RStride, CStride>>;
/// A column-major 3x5 matrix slice. /// A column-major 3x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut3x5<'a, N, RStride = U1, CStride = U3> = pub type MatrixSliceMut3x5<'a, T, RStride = U1, CStride = U3> =
Matrix<N, U3, U5, SliceStorageMut<'a, N, U3, U5, RStride, CStride>>; Matrix<T, U3, U5, SliceStorageMut<'a, T, U3, U5, RStride, CStride>>;
/// A column-major 3x6 matrix slice. /// A column-major 3x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut3x6<'a, N, RStride = U1, CStride = U3> = pub type MatrixSliceMut3x6<'a, T, RStride = U1, CStride = U3> =
Matrix<N, U3, U6, SliceStorageMut<'a, N, U3, U6, RStride, CStride>>; Matrix<T, U3, U6, SliceStorageMut<'a, T, U3, U6, RStride, CStride>>;
/// A column-major 4x1 matrix slice. /// A column-major 4x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut4x1<'a, N, RStride = U1, CStride = U4> = pub type MatrixSliceMut4x1<'a, T, RStride = U1, CStride = U4> =
Matrix<N, U4, U1, SliceStorageMut<'a, N, U4, U1, RStride, CStride>>; Matrix<T, U4, U1, SliceStorageMut<'a, T, U4, U1, RStride, CStride>>;
/// A column-major 4x2 matrix slice. /// A column-major 4x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut4x2<'a, N, RStride = U1, CStride = U4> = pub type MatrixSliceMut4x2<'a, T, RStride = U1, CStride = U4> =
Matrix<N, U4, U2, SliceStorageMut<'a, N, U4, U2, RStride, CStride>>; Matrix<T, U4, U2, SliceStorageMut<'a, T, U4, U2, RStride, CStride>>;
/// A column-major 4x3 matrix slice. /// A column-major 4x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut4x3<'a, N, RStride = U1, CStride = U4> = pub type MatrixSliceMut4x3<'a, T, RStride = U1, CStride = U4> =
Matrix<N, U4, U3, SliceStorageMut<'a, N, U4, U3, RStride, CStride>>; Matrix<T, U4, U3, SliceStorageMut<'a, T, U4, U3, RStride, CStride>>;
/// A column-major 4x5 matrix slice. /// A column-major 4x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut4x5<'a, N, RStride = U1, CStride = U4> = pub type MatrixSliceMut4x5<'a, T, RStride = U1, CStride = U4> =
Matrix<N, U4, U5, SliceStorageMut<'a, N, U4, U5, RStride, CStride>>; Matrix<T, U4, U5, SliceStorageMut<'a, T, U4, U5, RStride, CStride>>;
/// A column-major 4x6 matrix slice. /// A column-major 4x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut4x6<'a, N, RStride = U1, CStride = U4> = pub type MatrixSliceMut4x6<'a, T, RStride = U1, CStride = U4> =
Matrix<N, U4, U6, SliceStorageMut<'a, N, U4, U6, RStride, CStride>>; Matrix<T, U4, U6, SliceStorageMut<'a, T, U4, U6, RStride, CStride>>;
/// A column-major 5x1 matrix slice. /// A column-major 5x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut5x1<'a, N, RStride = U1, CStride = U5> = pub type MatrixSliceMut5x1<'a, T, RStride = U1, CStride = U5> =
Matrix<N, U5, U1, SliceStorageMut<'a, N, U5, U1, RStride, CStride>>; Matrix<T, U5, U1, SliceStorageMut<'a, T, U5, U1, RStride, CStride>>;
/// A column-major 5x2 matrix slice. /// A column-major 5x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut5x2<'a, N, RStride = U1, CStride = U5> = pub type MatrixSliceMut5x2<'a, T, RStride = U1, CStride = U5> =
Matrix<N, U5, U2, SliceStorageMut<'a, N, U5, U2, RStride, CStride>>; Matrix<T, U5, U2, SliceStorageMut<'a, T, U5, U2, RStride, CStride>>;
/// A column-major 5x3 matrix slice. /// A column-major 5x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut5x3<'a, N, RStride = U1, CStride = U5> = pub type MatrixSliceMut5x3<'a, T, RStride = U1, CStride = U5> =
Matrix<N, U5, U3, SliceStorageMut<'a, N, U5, U3, RStride, CStride>>; Matrix<T, U5, U3, SliceStorageMut<'a, T, U5, U3, RStride, CStride>>;
/// A column-major 5x4 matrix slice. /// A column-major 5x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut5x4<'a, N, RStride = U1, CStride = U5> = pub type MatrixSliceMut5x4<'a, T, RStride = U1, CStride = U5> =
Matrix<N, U5, U4, SliceStorageMut<'a, N, U5, U4, RStride, CStride>>; Matrix<T, U5, U4, SliceStorageMut<'a, T, U5, U4, RStride, CStride>>;
/// A column-major 5x6 matrix slice. /// A column-major 5x6 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut5x6<'a, N, RStride = U1, CStride = U5> = pub type MatrixSliceMut5x6<'a, T, RStride = U1, CStride = U5> =
Matrix<N, U5, U6, SliceStorageMut<'a, N, U5, U6, RStride, CStride>>; Matrix<T, U5, U6, SliceStorageMut<'a, T, U5, U6, RStride, CStride>>;
/// A column-major 6x1 matrix slice. /// A column-major 6x1 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut6x1<'a, N, RStride = U1, CStride = U6> = pub type MatrixSliceMut6x1<'a, T, RStride = U1, CStride = U6> =
Matrix<N, U6, U1, SliceStorageMut<'a, N, U6, U1, RStride, CStride>>; Matrix<T, U6, U1, SliceStorageMut<'a, T, U6, U1, RStride, CStride>>;
/// A column-major 6x2 matrix slice. /// A column-major 6x2 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut6x2<'a, N, RStride = U1, CStride = U6> = pub type MatrixSliceMut6x2<'a, T, RStride = U1, CStride = U6> =
Matrix<N, U6, U2, SliceStorageMut<'a, N, U6, U2, RStride, CStride>>; Matrix<T, U6, U2, SliceStorageMut<'a, T, U6, U2, RStride, CStride>>;
/// A column-major 6x3 matrix slice. /// A column-major 6x3 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut6x3<'a, N, RStride = U1, CStride = U6> = pub type MatrixSliceMut6x3<'a, T, RStride = U1, CStride = U6> =
Matrix<N, U6, U3, SliceStorageMut<'a, N, U6, U3, RStride, CStride>>; Matrix<T, U6, U3, SliceStorageMut<'a, T, U6, U3, RStride, CStride>>;
/// A column-major 6x4 matrix slice. /// A column-major 6x4 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut6x4<'a, N, RStride = U1, CStride = U6> = pub type MatrixSliceMut6x4<'a, T, RStride = U1, CStride = U6> =
Matrix<N, U6, U4, SliceStorageMut<'a, N, U6, U4, RStride, CStride>>; Matrix<T, U6, U4, SliceStorageMut<'a, T, U6, U4, RStride, CStride>>;
/// A column-major 6x5 matrix slice. /// A column-major 6x5 matrix slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type MatrixSliceMut6x5<'a, N, RStride = U1, CStride = U6> = pub type MatrixSliceMut6x5<'a, T, RStride = U1, CStride = U6> =
Matrix<N, U6, U5, SliceStorageMut<'a, N, U6, U5, RStride, CStride>>; Matrix<T, U6, U5, SliceStorageMut<'a, T, U6, U5, RStride, CStride>>;
/// A column-major matrix slice with 1 row and a number of columns chosen at runtime. /// A column-major matrix slice with 1 row and a number of columns chosen at runtime.
pub type MatrixSliceMut1xX<'a, N, RStride = U1, CStride = U1> = pub type MatrixSliceMut1xX<'a, T, RStride = U1, CStride = U1> =
Matrix<N, U1, Dynamic, SliceStorageMut<'a, N, U1, Dynamic, RStride, CStride>>; Matrix<T, U1, Dynamic, SliceStorageMut<'a, T, U1, Dynamic, RStride, CStride>>;
/// A column-major matrix slice with 2 rows and a number of columns chosen at runtime. /// A column-major matrix slice with 2 rows and a number of columns chosen at runtime.
pub type MatrixSliceMut2xX<'a, N, RStride = U1, CStride = U2> = pub type MatrixSliceMut2xX<'a, T, RStride = U1, CStride = U2> =
Matrix<N, U2, Dynamic, SliceStorageMut<'a, N, U2, Dynamic, RStride, CStride>>; Matrix<T, U2, Dynamic, SliceStorageMut<'a, T, U2, Dynamic, RStride, CStride>>;
/// A column-major matrix slice with 3 rows and a number of columns chosen at runtime. /// A column-major matrix slice with 3 rows and a number of columns chosen at runtime.
pub type MatrixSliceMut3xX<'a, N, RStride = U1, CStride = U3> = pub type MatrixSliceMut3xX<'a, T, RStride = U1, CStride = U3> =
Matrix<N, U3, Dynamic, SliceStorageMut<'a, N, U3, Dynamic, RStride, CStride>>; Matrix<T, U3, Dynamic, SliceStorageMut<'a, T, U3, Dynamic, RStride, CStride>>;
/// A column-major matrix slice with 4 rows and a number of columns chosen at runtime. /// A column-major matrix slice with 4 rows and a number of columns chosen at runtime.
pub type MatrixSliceMut4xX<'a, N, RStride = U1, CStride = U4> = pub type MatrixSliceMut4xX<'a, T, RStride = U1, CStride = U4> =
Matrix<N, U4, Dynamic, SliceStorageMut<'a, N, U4, Dynamic, RStride, CStride>>; Matrix<T, U4, Dynamic, SliceStorageMut<'a, T, U4, Dynamic, RStride, CStride>>;
/// A column-major matrix slice with 5 rows and a number of columns chosen at runtime. /// A column-major matrix slice with 5 rows and a number of columns chosen at runtime.
pub type MatrixSliceMut5xX<'a, N, RStride = U1, CStride = U5> = pub type MatrixSliceMut5xX<'a, T, RStride = U1, CStride = U5> =
Matrix<N, U5, Dynamic, SliceStorageMut<'a, N, U5, Dynamic, RStride, CStride>>; Matrix<T, U5, Dynamic, SliceStorageMut<'a, T, U5, Dynamic, RStride, CStride>>;
/// A column-major matrix slice with 6 rows and a number of columns chosen at runtime. /// A column-major matrix slice with 6 rows and a number of columns chosen at runtime.
pub type MatrixSliceMut6xX<'a, N, RStride = U1, CStride = U6> = pub type MatrixSliceMut6xX<'a, T, RStride = U1, CStride = U6> =
Matrix<N, U6, Dynamic, SliceStorageMut<'a, N, U6, Dynamic, RStride, CStride>>; Matrix<T, U6, Dynamic, SliceStorageMut<'a, T, U6, Dynamic, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 1 column. /// A column-major matrix slice with a number of rows chosen at runtime and 1 column.
pub type MatrixSliceMutXx1<'a, N, RStride = U1, CStride = Dynamic> = pub type MatrixSliceMutXx1<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<N, Dynamic, U1, SliceStorageMut<'a, N, Dynamic, U1, RStride, CStride>>; Matrix<T, Dynamic, U1, SliceStorageMut<'a, T, Dynamic, U1, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 2 columns. /// A column-major matrix slice with a number of rows chosen at runtime and 2 columns.
pub type MatrixSliceMutXx2<'a, N, RStride = U1, CStride = Dynamic> = pub type MatrixSliceMutXx2<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<N, Dynamic, U2, SliceStorageMut<'a, N, Dynamic, U2, RStride, CStride>>; Matrix<T, Dynamic, U2, SliceStorageMut<'a, T, Dynamic, U2, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 3 columns. /// A column-major matrix slice with a number of rows chosen at runtime and 3 columns.
pub type MatrixSliceMutXx3<'a, N, RStride = U1, CStride = Dynamic> = pub type MatrixSliceMutXx3<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<N, Dynamic, U3, SliceStorageMut<'a, N, Dynamic, U3, RStride, CStride>>; Matrix<T, Dynamic, U3, SliceStorageMut<'a, T, Dynamic, U3, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 4 columns. /// A column-major matrix slice with a number of rows chosen at runtime and 4 columns.
pub type MatrixSliceMutXx4<'a, N, RStride = U1, CStride = Dynamic> = pub type MatrixSliceMutXx4<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<N, Dynamic, U4, SliceStorageMut<'a, N, Dynamic, U4, RStride, CStride>>; Matrix<T, Dynamic, U4, SliceStorageMut<'a, T, Dynamic, U4, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 5 columns. /// A column-major matrix slice with a number of rows chosen at runtime and 5 columns.
pub type MatrixSliceMutXx5<'a, N, RStride = U1, CStride = Dynamic> = pub type MatrixSliceMutXx5<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<N, Dynamic, U5, SliceStorageMut<'a, N, Dynamic, U5, RStride, CStride>>; Matrix<T, Dynamic, U5, SliceStorageMut<'a, T, Dynamic, U5, RStride, CStride>>;
/// A column-major matrix slice with a number of rows chosen at runtime and 6 columns. /// A column-major matrix slice with a number of rows chosen at runtime and 6 columns.
pub type MatrixSliceMutXx6<'a, N, RStride = U1, CStride = Dynamic> = pub type MatrixSliceMutXx6<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<N, Dynamic, U6, SliceStorageMut<'a, N, Dynamic, U6, RStride, CStride>>; Matrix<T, Dynamic, U6, SliceStorageMut<'a, T, Dynamic, U6, RStride, CStride>>;
/// A column vector slice with `D` rows. /// A column vector slice with dimensions known at compile-time.
pub type VectorSliceMutN<'a, N, D, RStride = U1, CStride = D> = ///
Matrix<N, D, U1, SliceStorageMut<'a, N, D, U1, RStride, CStride>>; /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorSliceMut<'a, T, D, RStride = U1, CStride = D> =
Matrix<T, D, U1, SliceStorageMut<'a, T, D, U1, RStride, CStride>>;
/// A column vector slice with dimensions known at compile-time.
///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type SVectorSliceMut<'a, T, const D: usize> =
Matrix<T, Const<D>, Const<1>, SliceStorageMut<'a, T, Const<D>, Const<1>, Const<1>, Const<D>>>;
/// A column vector slice dynamic numbers of rows and columns. /// A column vector slice dynamic numbers of rows and columns.
pub type DVectorSliceMut<'a, N, RStride = U1, CStride = Dynamic> = ///
Matrix<N, Dynamic, U1, SliceStorageMut<'a, N, Dynamic, U1, RStride, CStride>>; /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type DVectorSliceMut<'a, T, RStride = U1, CStride = Dynamic> =
Matrix<T, Dynamic, U1, SliceStorageMut<'a, T, Dynamic, U1, RStride, CStride>>;
/// A 1D column vector slice. /// A 1D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorSliceMut1<'a, N, RStride = U1, CStride = U1> = pub type VectorSliceMut1<'a, T, RStride = U1, CStride = U1> =
Matrix<N, U1, U1, SliceStorageMut<'a, N, U1, U1, RStride, CStride>>; Matrix<T, U1, U1, SliceStorageMut<'a, T, U1, U1, RStride, CStride>>;
/// A 2D column vector slice. /// A 2D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorSliceMut2<'a, N, RStride = U1, CStride = U2> = pub type VectorSliceMut2<'a, T, RStride = U1, CStride = U2> =
Matrix<N, U2, U1, SliceStorageMut<'a, N, U2, U1, RStride, CStride>>; Matrix<T, U2, U1, SliceStorageMut<'a, T, U2, U1, RStride, CStride>>;
/// A 3D column vector slice. /// A 3D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorSliceMut3<'a, N, RStride = U1, CStride = U3> = pub type VectorSliceMut3<'a, T, RStride = U1, CStride = U3> =
Matrix<N, U3, U1, SliceStorageMut<'a, N, U3, U1, RStride, CStride>>; Matrix<T, U3, U1, SliceStorageMut<'a, T, U3, U1, RStride, CStride>>;
/// A 4D column vector slice. /// A 4D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorSliceMut4<'a, N, RStride = U1, CStride = U4> = pub type VectorSliceMut4<'a, T, RStride = U1, CStride = U4> =
Matrix<N, U4, U1, SliceStorageMut<'a, N, U4, U1, RStride, CStride>>; Matrix<T, U4, U1, SliceStorageMut<'a, T, U4, U1, RStride, CStride>>;
/// A 5D column vector slice. /// A 5D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorSliceMut5<'a, N, RStride = U1, CStride = U5> = pub type VectorSliceMut5<'a, T, RStride = U1, CStride = U5> =
Matrix<N, U5, U1, SliceStorageMut<'a, N, U5, U1, RStride, CStride>>; Matrix<T, U5, U1, SliceStorageMut<'a, T, U5, U1, RStride, CStride>>;
/// A 6D column vector slice. /// A 6D column vector slice.
/// ///
/// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.** /// **Because this is an alias, not all its methods are listed here. See the [`Matrix`](crate::base::Matrix) type too.**
pub type VectorSliceMut6<'a, N, RStride = U1, CStride = U6> = pub type VectorSliceMut6<'a, T, RStride = U1, CStride = U6> =
Matrix<N, U6, U1, SliceStorageMut<'a, N, U6, U1, RStride, CStride>>; Matrix<T, U6, U1, SliceStorageMut<'a, T, U6, U1, RStride, CStride>>;

View File

@ -9,7 +9,7 @@ use crate::base::storage::ContiguousStorageMut;
use crate::base::{DefaultAllocator, Scalar}; use crate::base::{DefaultAllocator, Scalar};
/// A matrix allocator of a memory buffer that may contain `R::to_usize() * C::to_usize()` /// A matrix allocator of a memory buffer that may contain `R::to_usize() * C::to_usize()`
/// elements of type `N`. /// elements of type `T`.
/// ///
/// An allocator is said to be: /// An allocator is said to be:
/// static: if `R` and `C` both implement `DimName`. /// static: if `R` and `C` both implement `DimName`.
@ -17,25 +17,35 @@ use crate::base::{DefaultAllocator, Scalar};
/// ///
/// Every allocator must be both static and dynamic. Though not all implementations may share the /// Every allocator must be both static and dynamic. Though not all implementations may share the
/// same `Buffer` type. /// same `Buffer` type.
pub trait Allocator<N: Scalar, R: Dim, C: Dim = U1>: Any + Sized { pub trait Allocator<T: Scalar, R: Dim, C: Dim = U1>: Any + Sized {
/// The type of buffer this allocator can instanciate. /// The type of buffer this allocator can instanciate.
type Buffer: ContiguousStorageMut<N, R, C> + Clone; type Buffer: ContiguousStorageMut<T, R, C> + Clone;
/// Allocates a buffer with the given number of rows and columns without initializing its content. /// Allocates a buffer with the given number of rows and columns without initializing its content.
unsafe fn allocate_uninitialized(nrows: R, ncols: C) -> mem::MaybeUninit<Self::Buffer>; unsafe fn allocate_uninitialized(nrows: R, ncols: C) -> mem::MaybeUninit<Self::Buffer>;
/// Allocates a buffer initialized with the content of the given iterator. /// Allocates a buffer initialized with the content of the given iterator.
fn allocate_from_iterator<I: IntoIterator<Item = N>>( fn allocate_from_iterator<I: IntoIterator<Item = T>>(
nrows: R, nrows: R,
ncols: C, ncols: C,
iter: I, iter: I,
) -> Self::Buffer; ) -> Self::Buffer;
unsafe fn allocate_more<R2: Dim, C2: Dim>(
nrows: R2,
ncols: C2,
) -> mem::MaybeUninit<<Self as Allocator<T, R2, C2>>::Buffer>
where
Self: Allocator<T, R2, C2>,
{
<Self as Allocator<T, R2, C2>>::allocate_uninitialized(nrows, ncols)
}
} }
/// A matrix reallocator. Changes the size of the memory buffer that initially contains (RFrom × /// A matrix reallocator. Changes the size of the memory buffer that initially contains (RFrom ×
/// CFrom) elements to a smaller or larger size (RTo, CTo). /// CFrom) elements to a smaller or larger size (RTo, CTo).
pub trait Reallocator<N: Scalar, RFrom: Dim, CFrom: Dim, RTo: Dim, CTo: Dim>: pub trait Reallocator<T: Scalar, RFrom: Dim, CFrom: Dim, RTo: Dim, CTo: Dim>:
Allocator<N, RFrom, CFrom> + Allocator<N, RTo, CTo> Allocator<T, RFrom, CFrom> + Allocator<T, RTo, CTo>
{ {
/// Reallocates a buffer of shape `(RTo, CTo)`, possibly reusing a previously allocated buffer /// Reallocates a buffer of shape `(RTo, CTo)`, possibly reusing a previously allocated buffer
/// `buf`. Data stored by `buf` are linearly copied to the output: /// `buf`. Data stored by `buf` are linearly copied to the output:
@ -47,8 +57,8 @@ pub trait Reallocator<N: Scalar, RFrom: Dim, CFrom: Dim, RTo: Dim, CTo: Dim>:
unsafe fn reallocate_copy( unsafe fn reallocate_copy(
nrows: RTo, nrows: RTo,
ncols: CTo, ncols: CTo,
buf: <Self as Allocator<N, RFrom, CFrom>>::Buffer, buf: <Self as Allocator<T, RFrom, CFrom>>::Buffer,
) -> <Self as Allocator<N, RTo, CTo>>::Buffer; ) -> <Self as Allocator<T, RTo, CTo>>::Buffer;
} }
/// The number of rows of the result of a componentwise operation on two matrices. /// The number of rows of the result of a componentwise operation on two matrices.
@ -59,48 +69,48 @@ pub type SameShapeC<C1, C2> = <ShapeConstraint as SameNumberOfColumns<C1, C2>>::
// TODO: Bad name. // TODO: Bad name.
/// Restricts the given number of rows and columns to be respectively the same. /// Restricts the given number of rows and columns to be respectively the same.
pub trait SameShapeAllocator<N, R1, C1, R2, C2>: pub trait SameShapeAllocator<T, R1, C1, R2, C2>:
Allocator<N, R1, C1> + Allocator<N, SameShapeR<R1, R2>, SameShapeC<C1, C2>> Allocator<T, R1, C1> + Allocator<T, SameShapeR<R1, R2>, SameShapeC<C1, C2>>
where where
R1: Dim, R1: Dim,
R2: Dim, R2: Dim,
C1: Dim, C1: Dim,
C2: Dim, C2: Dim,
N: Scalar, T: Scalar,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>, ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>,
{ {
} }
impl<N, R1, R2, C1, C2> SameShapeAllocator<N, R1, C1, R2, C2> for DefaultAllocator impl<T, R1, R2, C1, C2> SameShapeAllocator<T, R1, C1, R2, C2> for DefaultAllocator
where where
R1: Dim, R1: Dim,
R2: Dim, R2: Dim,
C1: Dim, C1: Dim,
C2: Dim, C2: Dim,
N: Scalar, T: Scalar,
DefaultAllocator: Allocator<N, R1, C1> + Allocator<N, SameShapeR<R1, R2>, SameShapeC<C1, C2>>, DefaultAllocator: Allocator<T, R1, C1> + Allocator<T, SameShapeR<R1, R2>, SameShapeC<C1, C2>>,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>, ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>,
{ {
} }
// XXX: Bad name. // XXX: Bad name.
/// Restricts the given number of rows to be equal. /// Restricts the given number of rows to be equal.
pub trait SameShapeVectorAllocator<N, R1, R2>: pub trait SameShapeVectorAllocator<T, R1, R2>:
Allocator<N, R1> + Allocator<N, SameShapeR<R1, R2>> + SameShapeAllocator<N, R1, U1, R2, U1> Allocator<T, R1> + Allocator<T, SameShapeR<R1, R2>> + SameShapeAllocator<T, R1, U1, R2, U1>
where where
R1: Dim, R1: Dim,
R2: Dim, R2: Dim,
N: Scalar, T: Scalar,
ShapeConstraint: SameNumberOfRows<R1, R2>, ShapeConstraint: SameNumberOfRows<R1, R2>,
{ {
} }
impl<N, R1, R2> SameShapeVectorAllocator<N, R1, R2> for DefaultAllocator impl<T, R1, R2> SameShapeVectorAllocator<T, R1, R2> for DefaultAllocator
where where
R1: Dim, R1: Dim,
R2: Dim, R2: Dim,
N: Scalar, T: Scalar,
DefaultAllocator: Allocator<N, R1, U1> + Allocator<N, SameShapeR<R1, R2>>, DefaultAllocator: Allocator<T, R1, U1> + Allocator<T, SameShapeR<R1, R2>>,
ShapeConstraint: SameNumberOfRows<R1, R2>, ShapeConstraint: SameNumberOfRows<R1, R2>,
{ {
} }

View File

@ -34,42 +34,38 @@ use crate::base::Scalar;
/// A array-based statically sized matrix data storage. /// A array-based statically sized matrix data storage.
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, PartialEq, Eq, Hash)] #[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct ArrayStorage<N, const R: usize, const C: usize> { pub struct ArrayStorage<T, const R: usize, const C: usize>(pub [[T; R]; C]);
data: [[N; R]; C],
}
// TODO: remove this once the stdlib implements Default for arrays. // TODO: remove this once the stdlib implements Default for arrays.
impl<N: Default, const R: usize, const C: usize> Default for ArrayStorage<N, R, C> impl<T: Default, const R: usize, const C: usize> Default for ArrayStorage<T, R, C>
where where
[[N; R]; C]: Default, [[T; R]; C]: Default,
{ {
#[inline] #[inline]
fn default() -> Self { fn default() -> Self {
Self { Self(Default::default())
data: Default::default(),
}
} }
} }
impl<N: Debug, const R: usize, const C: usize> Debug for ArrayStorage<N, R, C> { impl<T: Debug, const R: usize, const C: usize> Debug for ArrayStorage<T, R, C> {
#[inline] #[inline]
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
self.data.fmt(fmt) self.0.fmt(fmt)
} }
} }
unsafe impl<N, const R: usize, const C: usize> Storage<N, Const<R>, Const<C>> unsafe impl<T, const R: usize, const C: usize> Storage<T, Const<R>, Const<C>>
for ArrayStorage<N, R, C> for ArrayStorage<T, R, C>
where where
N: Scalar, T: Scalar,
DefaultAllocator: Allocator<N, Const<R>, Const<C>, Buffer = Self>, DefaultAllocator: Allocator<T, Const<R>, Const<C>, Buffer = Self>,
{ {
type RStride = Const<1>; type RStride = Const<1>;
type CStride = Const<R>; type CStride = Const<R>;
#[inline] #[inline]
fn ptr(&self) -> *const N { fn ptr(&self) -> *const T {
self.data.as_ptr() as *const N self.0.as_ptr() as *const T
} }
#[inline] #[inline]
@ -88,65 +84,65 @@ where
} }
#[inline] #[inline]
fn into_owned(self) -> Owned<N, Const<R>, Const<C>> fn into_owned(self) -> Owned<T, Const<R>, Const<C>>
where where
DefaultAllocator: Allocator<N, Const<R>, Const<C>>, DefaultAllocator: Allocator<T, Const<R>, Const<C>>,
{ {
self self
} }
#[inline] #[inline]
fn clone_owned(&self) -> Owned<N, Const<R>, Const<C>> fn clone_owned(&self) -> Owned<T, Const<R>, Const<C>>
where where
DefaultAllocator: Allocator<N, Const<R>, Const<C>>, DefaultAllocator: Allocator<T, Const<R>, Const<C>>,
{ {
let it = self.as_slice().iter().cloned(); let it = self.as_slice().iter().cloned();
DefaultAllocator::allocate_from_iterator(self.shape().0, self.shape().1, it) DefaultAllocator::allocate_from_iterator(self.shape().0, self.shape().1, it)
} }
#[inline] #[inline]
fn as_slice(&self) -> &[N] { fn as_slice(&self) -> &[T] {
unsafe { std::slice::from_raw_parts(self.ptr(), R * C) } unsafe { std::slice::from_raw_parts(self.ptr(), R * C) }
} }
} }
unsafe impl<N, const R: usize, const C: usize> StorageMut<N, Const<R>, Const<C>> unsafe impl<T, const R: usize, const C: usize> StorageMut<T, Const<R>, Const<C>>
for ArrayStorage<N, R, C> for ArrayStorage<T, R, C>
where where
N: Scalar, T: Scalar,
DefaultAllocator: Allocator<N, Const<R>, Const<C>, Buffer = Self>, DefaultAllocator: Allocator<T, Const<R>, Const<C>, Buffer = Self>,
{ {
#[inline] #[inline]
fn ptr_mut(&mut self) -> *mut N { fn ptr_mut(&mut self) -> *mut T {
self.data.as_mut_ptr() as *mut N self.0.as_mut_ptr() as *mut T
} }
#[inline] #[inline]
fn as_mut_slice(&mut self) -> &mut [N] { fn as_mut_slice(&mut self) -> &mut [T] {
unsafe { std::slice::from_raw_parts_mut(self.ptr_mut(), R * C) } unsafe { std::slice::from_raw_parts_mut(self.ptr_mut(), R * C) }
} }
} }
unsafe impl<N, const R: usize, const C: usize> ContiguousStorage<N, Const<R>, Const<C>> unsafe impl<T, const R: usize, const C: usize> ContiguousStorage<T, Const<R>, Const<C>>
for ArrayStorage<N, R, C> for ArrayStorage<T, R, C>
where where
N: Scalar, T: Scalar,
DefaultAllocator: Allocator<N, Const<R>, Const<C>, Buffer = Self>, DefaultAllocator: Allocator<T, Const<R>, Const<C>, Buffer = Self>,
{ {
} }
unsafe impl<N, const R: usize, const C: usize> ContiguousStorageMut<N, Const<R>, Const<C>> unsafe impl<T, const R: usize, const C: usize> ContiguousStorageMut<T, Const<R>, Const<C>>
for ArrayStorage<N, R, C> for ArrayStorage<T, R, C>
where where
N: Scalar, T: Scalar,
DefaultAllocator: Allocator<N, Const<R>, Const<C>, Buffer = Self>, DefaultAllocator: Allocator<T, Const<R>, Const<C>, Buffer = Self>,
{ {
} }
impl<N, const R1: usize, const C1: usize, const R2: usize, const C2: usize> impl<T, const R1: usize, const C1: usize, const R2: usize, const C2: usize>
ReshapableStorage<N, Const<R1>, Const<C1>, Const<R2>, Const<C2>> for ArrayStorage<N, R1, C1> ReshapableStorage<T, Const<R1>, Const<C1>, Const<R2>, Const<C2>> for ArrayStorage<T, R1, C1>
where where
N: Scalar, T: Scalar,
Const<R1>: ToTypenum, Const<R1>: ToTypenum,
Const<C1>: ToTypenum, Const<C1>: ToTypenum,
Const<R2>: ToTypenum, Const<R2>: ToTypenum,
@ -160,13 +156,13 @@ where
>, >,
>, >,
{ {
type Output = ArrayStorage<N, R2, C2>; type Output = ArrayStorage<T, R2, C2>;
fn reshape_generic(self, _: Const<R2>, _: Const<C2>) -> Self::Output { fn reshape_generic(self, _: Const<R2>, _: Const<C2>) -> Self::Output {
unsafe { unsafe {
let data: [[N; R2]; C2] = std::mem::transmute_copy(&self.data); let data: [[T; R2]; C2] = std::mem::transmute_copy(&self.0);
std::mem::forget(self.data); std::mem::forget(self.0);
ArrayStorage { data } ArrayStorage(data)
} }
} }
} }
@ -178,9 +174,9 @@ where
*/ */
// XXX: open an issue for serde so that it allows the serialization/deserialization of all arrays? // XXX: open an issue for serde so that it allows the serialization/deserialization of all arrays?
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<N, const R: usize, const C: usize> Serialize for ArrayStorage<N, R, C> impl<T, const R: usize, const C: usize> Serialize for ArrayStorage<T, R, C>
where where
N: Scalar + Serialize, T: Scalar + Serialize,
{ {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@ -197,9 +193,9 @@ where
} }
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<'a, N, const R: usize, const C: usize> Deserialize<'a> for ArrayStorage<N, R, C> impl<'a, T, const R: usize, const C: usize> Deserialize<'a> for ArrayStorage<T, R, C>
where where
N: Scalar + Deserialize<'a>, T: Scalar + Deserialize<'a>,
{ {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where
@ -211,14 +207,14 @@ where
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
/// A visitor that produces a matrix array. /// A visitor that produces a matrix array.
struct ArrayStorageVisitor<N, const R: usize, const C: usize> { struct ArrayStorageVisitor<T, const R: usize, const C: usize> {
marker: PhantomData<N>, marker: PhantomData<T>,
} }
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<N, const R: usize, const C: usize> ArrayStorageVisitor<N, R, C> impl<T, const R: usize, const C: usize> ArrayStorageVisitor<T, R, C>
where where
N: Scalar, T: Scalar,
{ {
/// Construct a new sequence visitor. /// Construct a new sequence visitor.
pub fn new() -> Self { pub fn new() -> Self {
@ -229,18 +225,18 @@ where
} }
#[cfg(feature = "serde-serialize")] #[cfg(feature = "serde-serialize")]
impl<'a, N, const R: usize, const C: usize> Visitor<'a> for ArrayStorageVisitor<N, R, C> impl<'a, T, const R: usize, const C: usize> Visitor<'a> for ArrayStorageVisitor<T, R, C>
where where
N: Scalar + Deserialize<'a>, T: Scalar + Deserialize<'a>,
{ {
type Value = ArrayStorage<N, R, C>; type Value = ArrayStorage<T, R, C>;
fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
formatter.write_str("a matrix array") formatter.write_str("a matrix array")
} }
#[inline] #[inline]
fn visit_seq<V>(self, mut visitor: V) -> Result<ArrayStorage<N, R, C>, V::Error> fn visit_seq<V>(self, mut visitor: V) -> Result<ArrayStorage<T, R, C>, V::Error>
where where
V: SeqAccess<'a>, V: SeqAccess<'a>,
{ {
@ -263,29 +259,21 @@ where
} }
#[cfg(feature = "bytemuck")] #[cfg(feature = "bytemuck")]
unsafe impl<N: Scalar + bytemuck::Zeroable, R: DimName, C: DimName> bytemuck::Zeroable unsafe impl<T: Scalar + Copy + bytemuck::Zeroable, const R: usize, const C: usize>
for ArrayStorage<N, R, C> bytemuck::Zeroable for ArrayStorage<T, R, C>
where
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
Self: Copy,
{ {
} }
#[cfg(feature = "bytemuck")] #[cfg(feature = "bytemuck")]
unsafe impl<N: Scalar + bytemuck::Pod, R: DimName, C: DimName> bytemuck::Pod unsafe impl<T: Scalar + Copy + bytemuck::Pod, const R: usize, const C: usize> bytemuck::Pod
for ArrayStorage<N, R, C> for ArrayStorage<T, R, C>
where
R::Value: Mul<C::Value>,
Prod<R::Value, C::Value>: ArrayLength<N>,
Self: Copy,
{ {
} }
#[cfg(feature = "abomonation-serialize")] #[cfg(feature = "abomonation-serialize")]
impl<N, const R: usize, const C: usize> Abomonation for ArrayStorage<N, R, C> impl<T, const R: usize, const C: usize> Abomonation for ArrayStorage<T, R, C>
where where
N: Scalar + Abomonation, T: Scalar + Abomonation,
{ {
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> { unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
for element in self.as_slice() { for element in self.as_slice() {

View File

@ -13,22 +13,22 @@ use crate::base::constraint::{
use crate::base::dimension::{Const, Dim, Dynamic, U1, U2, U3, U4}; use crate::base::dimension::{Const, Dim, Dynamic, U1, U2, U3, U4};
use crate::base::storage::{Storage, StorageMut}; use crate::base::storage::{Storage, StorageMut};
use crate::base::{ use crate::base::{
DVectorSlice, DefaultAllocator, Matrix, Scalar, SquareMatrix, Vector, VectorSliceN, DVectorSlice, DefaultAllocator, Matrix, Scalar, SquareMatrix, Vector, VectorSlice,
}; };
/// # Dot/scalar product /// # Dot/scalar product
impl<N, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> impl<T, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S>
where where
N: Scalar + Zero + ClosedAdd + ClosedMul, T: Scalar + Zero + ClosedAdd + ClosedMul,
{ {
#[inline(always)] #[inline(always)]
fn dotx<R2: Dim, C2: Dim, SB>( fn dotx<R2: Dim, C2: Dim, SB>(
&self, &self,
rhs: &Matrix<N, R2, C2, SB>, rhs: &Matrix<T, R2, C2, SB>,
conjugate: impl Fn(N) -> N, conjugate: impl Fn(T) -> T,
) -> N ) -> T
where where
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
ShapeConstraint: DimEq<R, R2> + DimEq<C, C2>, ShapeConstraint: DimEq<R, R2> + DimEq<C, C2>,
{ {
assert!( assert!(
@ -92,7 +92,7 @@ where
// //
// And this comment from bluss: // And this comment from bluss:
// https://users.rust-lang.org/t/how-to-zip-two-slices-efficiently/2048/12 // https://users.rust-lang.org/t/how-to-zip-two-slices-efficiently/2048/12
let mut res = N::zero(); let mut res = T::zero();
// We have to define them outside of the loop (and not inside at first assignment) // We have to define them outside of the loop (and not inside at first assignment)
// otherwise vectorization won't kick in for some reason. // otherwise vectorization won't kick in for some reason.
@ -108,14 +108,14 @@ where
for j in 0..self.ncols() { for j in 0..self.ncols() {
let mut i = 0; let mut i = 0;
acc0 = N::zero(); acc0 = T::zero();
acc1 = N::zero(); acc1 = T::zero();
acc2 = N::zero(); acc2 = T::zero();
acc3 = N::zero(); acc3 = T::zero();
acc4 = N::zero(); acc4 = T::zero();
acc5 = N::zero(); acc5 = T::zero();
acc6 = N::zero(); acc6 = T::zero();
acc7 = N::zero(); acc7 = T::zero();
while self.nrows() - i >= 8 { while self.nrows() - i >= 8 {
acc0 += unsafe { acc0 += unsafe {
@ -193,9 +193,9 @@ where
/// ``` /// ```
/// ///
#[inline] #[inline]
pub fn dot<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> N pub fn dot<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> T
where where
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
ShapeConstraint: DimEq<R, R2> + DimEq<C, C2>, ShapeConstraint: DimEq<R, R2> + DimEq<C, C2>,
{ {
self.dotx(rhs, |e| e) self.dotx(rhs, |e| e)
@ -221,13 +221,13 @@ where
/// assert_ne!(vec1.dotc(&vec2), vec1.dot(&vec2)); /// assert_ne!(vec1.dotc(&vec2), vec1.dot(&vec2));
/// ``` /// ```
#[inline] #[inline]
pub fn dotc<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> N pub fn dotc<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> T
where where
N: SimdComplexField, T: SimdComplexField,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
ShapeConstraint: DimEq<R, R2> + DimEq<C, C2>, ShapeConstraint: DimEq<R, R2> + DimEq<C, C2>,
{ {
self.dotx(rhs, N::simd_conjugate) self.dotx(rhs, T::simd_conjugate)
} }
/// The dot product between the transpose of `self` and `rhs`. /// The dot product between the transpose of `self` and `rhs`.
@ -248,9 +248,9 @@ where
/// assert_eq!(mat1.tr_dot(&mat2), 9.1); /// assert_eq!(mat1.tr_dot(&mat2), 9.1);
/// ``` /// ```
#[inline] #[inline]
pub fn tr_dot<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> N pub fn tr_dot<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> T
where where
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
ShapeConstraint: DimEq<C, R2> + DimEq<R, C2>, ShapeConstraint: DimEq<C, R2> + DimEq<R, C2>,
{ {
let (nrows, ncols) = self.shape(); let (nrows, ncols) = self.shape();
@ -260,7 +260,7 @@ where
"Transposed dot product dimension mismatch." "Transposed dot product dimension mismatch."
); );
let mut res = N::zero(); let mut res = T::zero();
for j in 0..self.nrows() { for j in 0..self.nrows() {
for i in 0..self.ncols() { for i in 0..self.ncols() {
@ -275,17 +275,17 @@ where
} }
} }
fn array_axcpy<N>( fn array_axcpy<T>(
y: &mut [N], y: &mut [T],
a: N, a: T,
x: &[N], x: &[T],
c: N, c: T,
beta: N, beta: T,
stride1: usize, stride1: usize,
stride2: usize, stride2: usize,
len: usize, len: usize,
) where ) where
N: Scalar + Zero + ClosedAdd + ClosedMul, T: Scalar + Zero + ClosedAdd + ClosedMul,
{ {
for i in 0..len { for i in 0..len {
unsafe { unsafe {
@ -298,9 +298,9 @@ fn array_axcpy<N>(
} }
} }
fn array_axc<N>(y: &mut [N], a: N, x: &[N], c: N, stride1: usize, stride2: usize, len: usize) fn array_axc<T>(y: &mut [T], a: T, x: &[T], c: T, stride1: usize, stride2: usize, len: usize)
where where
N: Scalar + Zero + ClosedAdd + ClosedMul, T: Scalar + Zero + ClosedAdd + ClosedMul,
{ {
for i in 0..len { for i in 0..len {
unsafe { unsafe {
@ -312,10 +312,10 @@ where
} }
/// # BLAS functions /// # BLAS functions
impl<N, D: Dim, S> Vector<N, D, S> impl<T, D: Dim, S> Vector<T, D, S>
where where
N: Scalar + Zero + ClosedAdd + ClosedMul, T: Scalar + Zero + ClosedAdd + ClosedMul,
S: StorageMut<N, D>, S: StorageMut<T, D>,
{ {
/// Computes `self = a * x * c + b * self`. /// Computes `self = a * x * c + b * self`.
/// ///
@ -331,9 +331,9 @@ where
/// assert_eq!(vec1, Vector3::new(6.0, 12.0, 18.0)); /// assert_eq!(vec1, Vector3::new(6.0, 12.0, 18.0));
/// ``` /// ```
#[inline] #[inline]
pub fn axcpy<D2: Dim, SB>(&mut self, a: N, x: &Vector<N, D2, SB>, c: N, b: N) pub fn axcpy<D2: Dim, SB>(&mut self, a: T, x: &Vector<T, D2, SB>, c: T, b: T)
where where
SB: Storage<N, D2>, SB: Storage<T, D2>,
ShapeConstraint: DimEq<D, D2>, ShapeConstraint: DimEq<D, D2>,
{ {
assert_eq!(self.nrows(), x.nrows(), "Axcpy: mismatched vector shapes."); assert_eq!(self.nrows(), x.nrows(), "Axcpy: mismatched vector shapes.");
@ -365,14 +365,14 @@ where
/// assert_eq!(vec1, Vector3::new(6.0, 12.0, 18.0)); /// assert_eq!(vec1, Vector3::new(6.0, 12.0, 18.0));
/// ``` /// ```
#[inline] #[inline]
pub fn axpy<D2: Dim, SB>(&mut self, a: N, x: &Vector<N, D2, SB>, b: N) pub fn axpy<D2: Dim, SB>(&mut self, a: T, x: &Vector<T, D2, SB>, b: T)
where where
N: One, T: One,
SB: Storage<N, D2>, SB: Storage<T, D2>,
ShapeConstraint: DimEq<D, D2>, ShapeConstraint: DimEq<D, D2>,
{ {
assert_eq!(self.nrows(), x.nrows(), "Axpy: mismatched vector shapes."); assert_eq!(self.nrows(), x.nrows(), "Axpy: mismatched vector shapes.");
self.axcpy(a, x, N::one(), b) self.axcpy(a, x, T::one(), b)
} }
/// Computes `self = alpha * a * x + beta * self`, where `a` is a matrix, `x` a vector, and /// Computes `self = alpha * a * x + beta * self`, where `a` is a matrix, `x` a vector, and
@ -394,14 +394,14 @@ where
#[inline] #[inline]
pub fn gemv<R2: Dim, C2: Dim, D3: Dim, SB, SC>( pub fn gemv<R2: Dim, C2: Dim, D3: Dim, SB, SC>(
&mut self, &mut self,
alpha: N, alpha: T,
a: &Matrix<N, R2, C2, SB>, a: &Matrix<T, R2, C2, SB>,
x: &Vector<N, D3, SC>, x: &Vector<T, D3, SC>,
beta: N, beta: T,
) where ) where
N: One, T: One,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
SC: Storage<N, D3>, SC: Storage<T, D3>,
ShapeConstraint: DimEq<D, R2> + AreMultipliable<R2, C2, D3, U1>, ShapeConstraint: DimEq<D, R2> + AreMultipliable<R2, C2, D3, U1>,
{ {
let dim1 = self.nrows(); let dim1 = self.nrows();
@ -418,7 +418,7 @@ where
// because we documented the guaranty that `self` is // because we documented the guaranty that `self` is
// never read if `beta` is zero. // never read if `beta` is zero.
if beta.is_zero() { if beta.is_zero() {
self.fill(N::zero()); self.fill(T::zero());
} else { } else {
*self *= beta; *self *= beta;
} }
@ -434,25 +434,25 @@ where
let col2 = a.column(j); let col2 = a.column(j);
let val = unsafe { x.vget_unchecked(j).inlined_clone() }; let val = unsafe { x.vget_unchecked(j).inlined_clone() };
self.axcpy(alpha.inlined_clone(), &col2, val, N::one()); self.axcpy(alpha.inlined_clone(), &col2, val, T::one());
} }
} }
#[inline(always)] #[inline(always)]
fn xxgemv<D2: Dim, D3: Dim, SB, SC>( fn xxgemv<D2: Dim, D3: Dim, SB, SC>(
&mut self, &mut self,
alpha: N, alpha: T,
a: &SquareMatrix<N, D2, SB>, a: &SquareMatrix<T, D2, SB>,
x: &Vector<N, D3, SC>, x: &Vector<T, D3, SC>,
beta: N, beta: T,
dot: impl Fn( dot: impl Fn(
&DVectorSlice<N, SB::RStride, SB::CStride>, &DVectorSlice<T, SB::RStride, SB::CStride>,
&DVectorSlice<N, SC::RStride, SC::CStride>, &DVectorSlice<T, SC::RStride, SC::CStride>,
) -> N, ) -> T,
) where ) where
N: One, T: One,
SB: Storage<N, D2, D2>, SB: Storage<T, D2, D2>,
SC: Storage<N, D3>, SC: Storage<T, D3>,
ShapeConstraint: DimEq<D, D2> + AreMultipliable<D2, D2, D3, U1>, ShapeConstraint: DimEq<D, D2> + AreMultipliable<D2, D2, D3, U1>,
{ {
let dim1 = self.nrows(); let dim1 = self.nrows();
@ -490,7 +490,7 @@ where
self.rows_range_mut(j + 1..).axpy( self.rows_range_mut(j + 1..).axpy(
alpha.inlined_clone() * val, alpha.inlined_clone() * val,
&col2.rows_range(j + 1..), &col2.rows_range(j + 1..),
N::one(), T::one(),
); );
} }
} }
@ -501,14 +501,14 @@ where
#[deprecated(note = "This is renamed `sygemv` to match the original BLAS terminology.")] #[deprecated(note = "This is renamed `sygemv` to match the original BLAS terminology.")]
pub fn gemv_symm<D2: Dim, D3: Dim, SB, SC>( pub fn gemv_symm<D2: Dim, D3: Dim, SB, SC>(
&mut self, &mut self,
alpha: N, alpha: T,
a: &SquareMatrix<N, D2, SB>, a: &SquareMatrix<T, D2, SB>,
x: &Vector<N, D3, SC>, x: &Vector<T, D3, SC>,
beta: N, beta: T,
) where ) where
N: One, T: One,
SB: Storage<N, D2, D2>, SB: Storage<T, D2, D2>,
SC: Storage<N, D3>, SC: Storage<T, D3>,
ShapeConstraint: DimEq<D, D2> + AreMultipliable<D2, D2, D3, U1>, ShapeConstraint: DimEq<D, D2> + AreMultipliable<D2, D2, D3, U1>,
{ {
self.sygemv(alpha, a, x, beta) self.sygemv(alpha, a, x, beta)
@ -545,14 +545,14 @@ where
#[inline] #[inline]
pub fn sygemv<D2: Dim, D3: Dim, SB, SC>( pub fn sygemv<D2: Dim, D3: Dim, SB, SC>(
&mut self, &mut self,
alpha: N, alpha: T,
a: &SquareMatrix<N, D2, SB>, a: &SquareMatrix<T, D2, SB>,
x: &Vector<N, D3, SC>, x: &Vector<T, D3, SC>,
beta: N, beta: T,
) where ) where
N: One, T: One,
SB: Storage<N, D2, D2>, SB: Storage<T, D2, D2>,
SC: Storage<N, D3>, SC: Storage<T, D3>,
ShapeConstraint: DimEq<D, D2> + AreMultipliable<D2, D2, D3, U1>, ShapeConstraint: DimEq<D, D2> + AreMultipliable<D2, D2, D3, U1>,
{ {
self.xxgemv(alpha, a, x, beta, |a, b| a.dot(b)) self.xxgemv(alpha, a, x, beta, |a, b| a.dot(b))
@ -590,14 +590,14 @@ where
#[inline] #[inline]
pub fn hegemv<D2: Dim, D3: Dim, SB, SC>( pub fn hegemv<D2: Dim, D3: Dim, SB, SC>(
&mut self, &mut self,
alpha: N, alpha: T,
a: &SquareMatrix<N, D2, SB>, a: &SquareMatrix<T, D2, SB>,
x: &Vector<N, D3, SC>, x: &Vector<T, D3, SC>,
beta: N, beta: T,
) where ) where
N: SimdComplexField, T: SimdComplexField,
SB: Storage<N, D2, D2>, SB: Storage<T, D2, D2>,
SC: Storage<N, D3>, SC: Storage<T, D3>,
ShapeConstraint: DimEq<D, D2> + AreMultipliable<D2, D2, D3, U1>, ShapeConstraint: DimEq<D, D2> + AreMultipliable<D2, D2, D3, U1>,
{ {
self.xxgemv(alpha, a, x, beta, |a, b| a.dotc(b)) self.xxgemv(alpha, a, x, beta, |a, b| a.dotc(b))
@ -606,15 +606,15 @@ where
#[inline(always)] #[inline(always)]
fn gemv_xx<R2: Dim, C2: Dim, D3: Dim, SB, SC>( fn gemv_xx<R2: Dim, C2: Dim, D3: Dim, SB, SC>(
&mut self, &mut self,
alpha: N, alpha: T,
a: &Matrix<N, R2, C2, SB>, a: &Matrix<T, R2, C2, SB>,
x: &Vector<N, D3, SC>, x: &Vector<T, D3, SC>,
beta: N, beta: T,
dot: impl Fn(&VectorSliceN<N, R2, SB::RStride, SB::CStride>, &Vector<N, D3, SC>) -> N, dot: impl Fn(&VectorSlice<T, R2, SB::RStride, SB::CStride>, &Vector<T, D3, SC>) -> T,
) where ) where
N: One, T: One,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
SC: Storage<N, D3>, SC: Storage<T, D3>,
ShapeConstraint: DimEq<D, C2> + AreMultipliable<C2, R2, D3, U1>, ShapeConstraint: DimEq<D, C2> + AreMultipliable<C2, R2, D3, U1>,
{ {
let dim1 = self.nrows(); let dim1 = self.nrows();
@ -665,14 +665,14 @@ where
#[inline] #[inline]
pub fn gemv_tr<R2: Dim, C2: Dim, D3: Dim, SB, SC>( pub fn gemv_tr<R2: Dim, C2: Dim, D3: Dim, SB, SC>(
&mut self, &mut self,
alpha: N, alpha: T,
a: &Matrix<N, R2, C2, SB>, a: &Matrix<T, R2, C2, SB>,
x: &Vector<N, D3, SC>, x: &Vector<T, D3, SC>,
beta: N, beta: T,
) where ) where
N: One, T: One,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
SC: Storage<N, D3>, SC: Storage<T, D3>,
ShapeConstraint: DimEq<D, C2> + AreMultipliable<C2, R2, D3, U1>, ShapeConstraint: DimEq<D, C2> + AreMultipliable<C2, R2, D3, U1>,
{ {
self.gemv_xx(alpha, a, x, beta, |a, b| a.dot(b)) self.gemv_xx(alpha, a, x, beta, |a, b| a.dot(b))
@ -700,36 +700,36 @@ where
#[inline] #[inline]
pub fn gemv_ad<R2: Dim, C2: Dim, D3: Dim, SB, SC>( pub fn gemv_ad<R2: Dim, C2: Dim, D3: Dim, SB, SC>(
&mut self, &mut self,
alpha: N, alpha: T,
a: &Matrix<N, R2, C2, SB>, a: &Matrix<T, R2, C2, SB>,
x: &Vector<N, D3, SC>, x: &Vector<T, D3, SC>,
beta: N, beta: T,
) where ) where
N: SimdComplexField, T: SimdComplexField,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
SC: Storage<N, D3>, SC: Storage<T, D3>,
ShapeConstraint: DimEq<D, C2> + AreMultipliable<C2, R2, D3, U1>, ShapeConstraint: DimEq<D, C2> + AreMultipliable<C2, R2, D3, U1>,
{ {
self.gemv_xx(alpha, a, x, beta, |a, b| a.dotc(b)) self.gemv_xx(alpha, a, x, beta, |a, b| a.dotc(b))
} }
} }
impl<N, R1: Dim, C1: Dim, S: StorageMut<N, R1, C1>> Matrix<N, R1, C1, S> impl<T, R1: Dim, C1: Dim, S: StorageMut<T, R1, C1>> Matrix<T, R1, C1, S>
where where
N: Scalar + Zero + ClosedAdd + ClosedMul, T: Scalar + Zero + ClosedAdd + ClosedMul,
{ {
#[inline(always)] #[inline(always)]
fn gerx<D2: Dim, D3: Dim, SB, SC>( fn gerx<D2: Dim, D3: Dim, SB, SC>(
&mut self, &mut self,
alpha: N, alpha: T,
x: &Vector<N, D2, SB>, x: &Vector<T, D2, SB>,
y: &Vector<N, D3, SC>, y: &Vector<T, D3, SC>,
beta: N, beta: T,
conjugate: impl Fn(N) -> N, conjugate: impl Fn(T) -> T,
) where ) where
N: One, T: One,
SB: Storage<N, D2>, SB: Storage<T, D2>,
SC: Storage<N, D3>, SC: Storage<T, D3>,
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>, ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
{ {
let (nrows1, ncols1) = self.shape(); let (nrows1, ncols1) = self.shape();
@ -768,14 +768,14 @@ where
#[inline] #[inline]
pub fn ger<D2: Dim, D3: Dim, SB, SC>( pub fn ger<D2: Dim, D3: Dim, SB, SC>(
&mut self, &mut self,
alpha: N, alpha: T,
x: &Vector<N, D2, SB>, x: &Vector<T, D2, SB>,
y: &Vector<N, D3, SC>, y: &Vector<T, D3, SC>,
beta: N, beta: T,
) where ) where
N: One, T: One,
SB: Storage<N, D2>, SB: Storage<T, D2>,
SC: Storage<N, D3>, SC: Storage<T, D3>,
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>, ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
{ {
self.gerx(alpha, x, y, beta, |e| e) self.gerx(alpha, x, y, beta, |e| e)
@ -801,14 +801,14 @@ where
#[inline] #[inline]
pub fn gerc<D2: Dim, D3: Dim, SB, SC>( pub fn gerc<D2: Dim, D3: Dim, SB, SC>(
&mut self, &mut self,
alpha: N, alpha: T,
x: &Vector<N, D2, SB>, x: &Vector<T, D2, SB>,
y: &Vector<N, D3, SC>, y: &Vector<T, D3, SC>,
beta: N, beta: T,
) where ) where
N: SimdComplexField, T: SimdComplexField,
SB: Storage<N, D2>, SB: Storage<T, D2>,
SC: Storage<N, D3>, SC: Storage<T, D3>,
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>, ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
{ {
self.gerx(alpha, x, y, beta, SimdComplexField::simd_conjugate) self.gerx(alpha, x, y, beta, SimdComplexField::simd_conjugate)
@ -838,14 +838,14 @@ where
#[inline] #[inline]
pub fn gemm<R2: Dim, C2: Dim, R3: Dim, C3: Dim, SB, SC>( pub fn gemm<R2: Dim, C2: Dim, R3: Dim, C3: Dim, SB, SC>(
&mut self, &mut self,
alpha: N, alpha: T,
a: &Matrix<N, R2, C2, SB>, a: &Matrix<T, R2, C2, SB>,
b: &Matrix<N, R3, C3, SC>, b: &Matrix<T, R3, C3, SC>,
beta: N, beta: T,
) where ) where
N: One, T: One,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
SC: Storage<N, R3, C3>, SC: Storage<T, R3, C3>,
ShapeConstraint: SameNumberOfRows<R1, R2> ShapeConstraint: SameNumberOfRows<R1, R2>
+ SameNumberOfColumns<C1, C3> + SameNumberOfColumns<C1, C3>
+ AreMultipliable<R2, C2, R3, C3>, + AreMultipliable<R2, C2, R3, C3>,
@ -897,14 +897,14 @@ where
// because we documented the guaranty that `self` is // because we documented the guaranty that `self` is
// never read if `beta` is zero. // never read if `beta` is zero.
if beta.is_zero() { if beta.is_zero() {
self.fill(N::zero()); self.fill(T::zero());
} else { } else {
*self *= beta; *self *= beta;
} }
return; return;
} }
if N::is::<f32>() { if T::is::<f32>() {
let (rsa, csa) = a.strides(); let (rsa, csa) = a.strides();
let (rsb, csb) = b.strides(); let (rsb, csb) = b.strides();
let (rsc, csc) = self.strides(); let (rsc, csc) = self.strides();
@ -928,7 +928,7 @@ where
); );
} }
return; return;
} else if N::is::<f64>() { } else if T::is::<f64>() {
let (rsa, csa) = a.strides(); let (rsa, csa) = a.strides();
let (rsb, csb) = b.strides(); let (rsb, csb) = b.strides();
let (rsc, csc) = self.strides(); let (rsc, csc) = self.strides();
@ -993,14 +993,14 @@ where
#[inline] #[inline]
pub fn gemm_tr<R2: Dim, C2: Dim, R3: Dim, C3: Dim, SB, SC>( pub fn gemm_tr<R2: Dim, C2: Dim, R3: Dim, C3: Dim, SB, SC>(
&mut self, &mut self,
alpha: N, alpha: T,
a: &Matrix<N, R2, C2, SB>, a: &Matrix<T, R2, C2, SB>,
b: &Matrix<N, R3, C3, SC>, b: &Matrix<T, R3, C3, SC>,
beta: N, beta: T,
) where ) where
N: One, T: One,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
SC: Storage<N, R3, C3>, SC: Storage<T, R3, C3>,
ShapeConstraint: SameNumberOfRows<R1, C2> ShapeConstraint: SameNumberOfRows<R1, C2>
+ SameNumberOfColumns<C1, C3> + SameNumberOfColumns<C1, C3>
+ AreMultipliable<C2, R2, R3, C3>, + AreMultipliable<C2, R2, R3, C3>,
@ -1055,14 +1055,14 @@ where
#[inline] #[inline]
pub fn gemm_ad<R2: Dim, C2: Dim, R3: Dim, C3: Dim, SB, SC>( pub fn gemm_ad<R2: Dim, C2: Dim, R3: Dim, C3: Dim, SB, SC>(
&mut self, &mut self,
alpha: N, alpha: T,
a: &Matrix<N, R2, C2, SB>, a: &Matrix<T, R2, C2, SB>,
b: &Matrix<N, R3, C3, SC>, b: &Matrix<T, R3, C3, SC>,
beta: N, beta: T,
) where ) where
N: SimdComplexField, T: SimdComplexField,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
SC: Storage<N, R3, C3>, SC: Storage<T, R3, C3>,
ShapeConstraint: SameNumberOfRows<R1, C2> ShapeConstraint: SameNumberOfRows<R1, C2>
+ SameNumberOfColumns<C1, C3> + SameNumberOfColumns<C1, C3>
+ AreMultipliable<C2, R2, R3, C3>, + AreMultipliable<C2, R2, R3, C3>,
@ -1088,22 +1088,22 @@ where
} }
} }
impl<N, R1: Dim, C1: Dim, S: StorageMut<N, R1, C1>> Matrix<N, R1, C1, S> impl<T, R1: Dim, C1: Dim, S: StorageMut<T, R1, C1>> Matrix<T, R1, C1, S>
where where
N: Scalar + Zero + ClosedAdd + ClosedMul, T: Scalar + Zero + ClosedAdd + ClosedMul,
{ {
#[inline(always)] #[inline(always)]
fn xxgerx<D2: Dim, D3: Dim, SB, SC>( fn xxgerx<D2: Dim, D3: Dim, SB, SC>(
&mut self, &mut self,
alpha: N, alpha: T,
x: &Vector<N, D2, SB>, x: &Vector<T, D2, SB>,
y: &Vector<N, D3, SC>, y: &Vector<T, D3, SC>,
beta: N, beta: T,
conjugate: impl Fn(N) -> N, conjugate: impl Fn(T) -> T,
) where ) where
N: One, T: One,
SB: Storage<N, D2>, SB: Storage<T, D2>,
SC: Storage<N, D3>, SC: Storage<T, D3>,
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>, ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
{ {
let dim1 = self.nrows(); let dim1 = self.nrows();
@ -1151,14 +1151,14 @@ where
#[deprecated(note = "This is renamed `syger` to match the original BLAS terminology.")] #[deprecated(note = "This is renamed `syger` to match the original BLAS terminology.")]
pub fn ger_symm<D2: Dim, D3: Dim, SB, SC>( pub fn ger_symm<D2: Dim, D3: Dim, SB, SC>(
&mut self, &mut self,
alpha: N, alpha: T,
x: &Vector<N, D2, SB>, x: &Vector<T, D2, SB>,
y: &Vector<N, D3, SC>, y: &Vector<T, D3, SC>,
beta: N, beta: T,
) where ) where
N: One, T: One,
SB: Storage<N, D2>, SB: Storage<T, D2>,
SC: Storage<N, D3>, SC: Storage<T, D3>,
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>, ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
{ {
self.syger(alpha, x, y, beta) self.syger(alpha, x, y, beta)
@ -1187,14 +1187,14 @@ where
#[inline] #[inline]
pub fn syger<D2: Dim, D3: Dim, SB, SC>( pub fn syger<D2: Dim, D3: Dim, SB, SC>(
&mut self, &mut self,
alpha: N, alpha: T,
x: &Vector<N, D2, SB>, x: &Vector<T, D2, SB>,
y: &Vector<N, D3, SC>, y: &Vector<T, D3, SC>,
beta: N, beta: T,
) where ) where
N: One, T: One,
SB: Storage<N, D2>, SB: Storage<T, D2>,
SC: Storage<N, D3>, SC: Storage<T, D3>,
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>, ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
{ {
self.xxgerx(alpha, x, y, beta, |e| e) self.xxgerx(alpha, x, y, beta, |e| e)
@ -1222,23 +1222,23 @@ where
#[inline] #[inline]
pub fn hegerc<D2: Dim, D3: Dim, SB, SC>( pub fn hegerc<D2: Dim, D3: Dim, SB, SC>(
&mut self, &mut self,
alpha: N, alpha: T,
x: &Vector<N, D2, SB>, x: &Vector<T, D2, SB>,
y: &Vector<N, D3, SC>, y: &Vector<T, D3, SC>,
beta: N, beta: T,
) where ) where
N: SimdComplexField, T: SimdComplexField,
SB: Storage<N, D2>, SB: Storage<T, D2>,
SC: Storage<N, D3>, SC: Storage<T, D3>,
ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>, ShapeConstraint: DimEq<R1, D2> + DimEq<C1, D3>,
{ {
self.xxgerx(alpha, x, y, beta, SimdComplexField::simd_conjugate) self.xxgerx(alpha, x, y, beta, SimdComplexField::simd_conjugate)
} }
} }
impl<N, D1: Dim, S: StorageMut<N, D1, D1>> SquareMatrix<N, D1, S> impl<T, D1: Dim, S: StorageMut<T, D1, D1>> SquareMatrix<T, D1, S>
where where
N: Scalar + Zero + One + ClosedAdd + ClosedMul, T: Scalar + Zero + One + ClosedAdd + ClosedMul,
{ {
/// Computes the quadratic form `self = alpha * lhs * mid * lhs.transpose() + beta * self`. /// Computes the quadratic form `self = alpha * lhs * mid * lhs.transpose() + beta * self`.
/// ///
@ -1268,27 +1268,27 @@ where
/// assert_relative_eq!(mat, expected); /// assert_relative_eq!(mat, expected);
pub fn quadform_tr_with_workspace<D2, S2, R3, C3, S3, D4, S4>( pub fn quadform_tr_with_workspace<D2, S2, R3, C3, S3, D4, S4>(
&mut self, &mut self,
work: &mut Vector<N, D2, S2>, work: &mut Vector<T, D2, S2>,
alpha: N, alpha: T,
lhs: &Matrix<N, R3, C3, S3>, lhs: &Matrix<T, R3, C3, S3>,
mid: &SquareMatrix<N, D4, S4>, mid: &SquareMatrix<T, D4, S4>,
beta: N, beta: T,
) where ) where
D2: Dim, D2: Dim,
R3: Dim, R3: Dim,
C3: Dim, C3: Dim,
D4: Dim, D4: Dim,
S2: StorageMut<N, D2>, S2: StorageMut<T, D2>,
S3: Storage<N, R3, C3>, S3: Storage<T, R3, C3>,
S4: Storage<N, D4, D4>, S4: Storage<T, D4, D4>,
ShapeConstraint: DimEq<D1, D2> + DimEq<D1, R3> + DimEq<D2, R3> + DimEq<C3, D4>, ShapeConstraint: DimEq<D1, D2> + DimEq<D1, R3> + DimEq<D2, R3> + DimEq<C3, D4>,
{ {
work.gemv(N::one(), lhs, &mid.column(0), N::zero()); work.gemv(T::one(), lhs, &mid.column(0), T::zero());
self.ger(alpha.inlined_clone(), work, &lhs.column(0), beta); self.ger(alpha.inlined_clone(), work, &lhs.column(0), beta);
for j in 1..mid.ncols() { for j in 1..mid.ncols() {
work.gemv(N::one(), lhs, &mid.column(j), N::zero()); work.gemv(T::one(), lhs, &mid.column(j), T::zero());
self.ger(alpha.inlined_clone(), work, &lhs.column(j), N::one()); self.ger(alpha.inlined_clone(), work, &lhs.column(j), T::one());
} }
} }
@ -1315,21 +1315,22 @@ where
/// assert_relative_eq!(mat, expected); /// assert_relative_eq!(mat, expected);
pub fn quadform_tr<R3, C3, S3, D4, S4>( pub fn quadform_tr<R3, C3, S3, D4, S4>(
&mut self, &mut self,
alpha: N, alpha: T,
lhs: &Matrix<N, R3, C3, S3>, lhs: &Matrix<T, R3, C3, S3>,
mid: &SquareMatrix<N, D4, S4>, mid: &SquareMatrix<T, D4, S4>,
beta: N, beta: T,
) where ) where
R3: Dim, R3: Dim,
C3: Dim, C3: Dim,
D4: Dim, D4: Dim,
S3: Storage<N, R3, C3>, S3: Storage<T, R3, C3>,
S4: Storage<N, D4, D4>, S4: Storage<T, D4, D4>,
ShapeConstraint: DimEq<D1, D1> + DimEq<D1, R3> + DimEq<C3, D4>, ShapeConstraint: DimEq<D1, D1> + DimEq<D1, R3> + DimEq<C3, D4>,
DefaultAllocator: Allocator<N, D1>, DefaultAllocator: Allocator<T, D1>,
{ {
let mut work = let mut work = unsafe {
unsafe { crate::unimplemented_or_uninitialized_generic!(self.data.shape().0, Const::<1>) }; crate::unimplemented_or_uninitialized_generic!(self.data.shape().0, Const::<1>)
};
self.quadform_tr_with_workspace(&mut work, alpha, lhs, mid, beta) self.quadform_tr_with_workspace(&mut work, alpha, lhs, mid, beta)
} }
@ -1360,28 +1361,28 @@ where
/// assert_relative_eq!(mat, expected); /// assert_relative_eq!(mat, expected);
pub fn quadform_with_workspace<D2, S2, D3, S3, R4, C4, S4>( pub fn quadform_with_workspace<D2, S2, D3, S3, R4, C4, S4>(
&mut self, &mut self,
work: &mut Vector<N, D2, S2>, work: &mut Vector<T, D2, S2>,
alpha: N, alpha: T,
mid: &SquareMatrix<N, D3, S3>, mid: &SquareMatrix<T, D3, S3>,
rhs: &Matrix<N, R4, C4, S4>, rhs: &Matrix<T, R4, C4, S4>,
beta: N, beta: T,
) where ) where
D2: Dim, D2: Dim,
D3: Dim, D3: Dim,
R4: Dim, R4: Dim,
C4: Dim, C4: Dim,
S2: StorageMut<N, D2>, S2: StorageMut<T, D2>,
S3: Storage<N, D3, D3>, S3: Storage<T, D3, D3>,
S4: Storage<N, R4, C4>, S4: Storage<T, R4, C4>,
ShapeConstraint: ShapeConstraint:
DimEq<D3, R4> + DimEq<D1, C4> + DimEq<D2, D3> + AreMultipliable<C4, R4, D2, U1>, DimEq<D3, R4> + DimEq<D1, C4> + DimEq<D2, D3> + AreMultipliable<C4, R4, D2, U1>,
{ {
work.gemv(N::one(), mid, &rhs.column(0), N::zero()); work.gemv(T::one(), mid, &rhs.column(0), T::zero());
self.column_mut(0) self.column_mut(0)
.gemv_tr(alpha.inlined_clone(), &rhs, work, beta.inlined_clone()); .gemv_tr(alpha.inlined_clone(), &rhs, work, beta.inlined_clone());
for j in 1..rhs.ncols() { for j in 1..rhs.ncols() {
work.gemv(N::one(), mid, &rhs.column(j), N::zero()); work.gemv(T::one(), mid, &rhs.column(j), T::zero());
self.column_mut(j) self.column_mut(j)
.gemv_tr(alpha.inlined_clone(), &rhs, work, beta.inlined_clone()); .gemv_tr(alpha.inlined_clone(), &rhs, work, beta.inlined_clone());
} }
@ -1409,21 +1410,22 @@ where
/// assert_relative_eq!(mat, expected); /// assert_relative_eq!(mat, expected);
pub fn quadform<D2, S2, R3, C3, S3>( pub fn quadform<D2, S2, R3, C3, S3>(
&mut self, &mut self,
alpha: N, alpha: T,
mid: &SquareMatrix<N, D2, S2>, mid: &SquareMatrix<T, D2, S2>,
rhs: &Matrix<N, R3, C3, S3>, rhs: &Matrix<T, R3, C3, S3>,
beta: N, beta: T,
) where ) where
D2: Dim, D2: Dim,
R3: Dim, R3: Dim,
C3: Dim, C3: Dim,
S2: Storage<N, D2, D2>, S2: Storage<T, D2, D2>,
S3: Storage<N, R3, C3>, S3: Storage<T, R3, C3>,
ShapeConstraint: DimEq<D2, R3> + DimEq<D1, C3> + AreMultipliable<C3, R3, D2, U1>, ShapeConstraint: DimEq<D2, R3> + DimEq<D1, C3> + AreMultipliable<C3, R3, D2, U1>,
DefaultAllocator: Allocator<N, D2>, DefaultAllocator: Allocator<T, D2>,
{ {
let mut work = let mut work = unsafe {
unsafe { crate::unimplemented_or_uninitialized_generic!(mid.data.shape().0, Const::<1>) }; crate::unimplemented_or_uninitialized_generic!(mid.data.shape().0, Const::<1>)
};
self.quadform_with_workspace(&mut work, alpha, mid, rhs, beta) self.quadform_with_workspace(&mut work, alpha, mid, rhs, beta)
} }
} }

View File

@ -11,8 +11,8 @@ use crate::base::allocator::Allocator;
use crate::base::dimension::{DimName, DimNameDiff, DimNameSub, U1}; use crate::base::dimension::{DimName, DimNameDiff, DimNameSub, U1};
use crate::base::storage::{Storage, StorageMut}; use crate::base::storage::{Storage, StorageMut};
use crate::base::{ use crate::base::{
Const, DefaultAllocator, Matrix3, Matrix4, MatrixN, Scalar, SquareMatrix, Unit, Vector, Const, DefaultAllocator, Matrix3, Matrix4, OMatrix, OVector, Scalar, SquareMatrix, Unit,
Vector2, Vector3, VectorN, Vector, Vector2, Vector3,
}; };
use crate::geometry::{ use crate::geometry::{
Isometry, IsometryMatrix3, Orthographic3, Perspective3, Point, Point2, Point3, Rotation2, Isometry, IsometryMatrix3, Orthographic3, Perspective3, Point, Point2, Point3, Rotation2,
@ -22,26 +22,26 @@ use crate::geometry::{
use simba::scalar::{ClosedAdd, ClosedMul, RealField}; use simba::scalar::{ClosedAdd, ClosedMul, RealField};
/// # Translation and scaling in any dimension /// # Translation and scaling in any dimension
impl<N, D: DimName> MatrixN<N, D> impl<T, D: DimName> OMatrix<T, D, D>
where where
N: Scalar + Zero + One, T: Scalar + Zero + One,
DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
/// Creates a new homogeneous matrix that applies the same scaling factor on each dimension. /// Creates a new homogeneous matrix that applies the same scaling factor on each dimension.
#[inline] #[inline]
pub fn new_scaling(scaling: N) -> Self { pub fn new_scaling(scaling: T) -> Self {
let mut res = Self::from_diagonal_element(scaling); let mut res = Self::from_diagonal_element(scaling);
res[(D::dim() - 1, D::dim() - 1)] = N::one(); res[(D::dim() - 1, D::dim() - 1)] = T::one();
res res
} }
/// Creates a new homogeneous matrix that applies a distinct scaling factor for each dimension. /// Creates a new homogeneous matrix that applies a distinct scaling factor for each dimension.
#[inline] #[inline]
pub fn new_nonuniform_scaling<SB>(scaling: &Vector<N, DimNameDiff<D, U1>, SB>) -> Self pub fn new_nonuniform_scaling<SB>(scaling: &Vector<T, DimNameDiff<D, U1>, SB>) -> Self
where where
D: DimNameSub<U1>, D: DimNameSub<U1>,
SB: Storage<N, DimNameDiff<D, U1>>, SB: Storage<T, DimNameDiff<D, U1>>,
{ {
let mut res = Self::identity(); let mut res = Self::identity();
for i in 0..scaling.len() { for i in 0..scaling.len() {
@ -53,13 +53,16 @@ where
/// Creates a new homogeneous matrix that applies a pure translation. /// Creates a new homogeneous matrix that applies a pure translation.
#[inline] #[inline]
pub fn new_translation<SB>(translation: &Vector<N, DimNameDiff<D, U1>, SB>) -> Self pub fn new_translation<SB>(translation: &Vector<T, DimNameDiff<D, U1>, SB>) -> Self
where where
D: DimNameSub<U1>, D: DimNameSub<U1>,
SB: Storage<N, DimNameDiff<D, U1>>, SB: Storage<T, DimNameDiff<D, U1>>,
{ {
let mut res = Self::identity(); let mut res = Self::identity();
res.fixed_slice_mut::<DimNameDiff<D, U1>, U1>(0, D::dim() - 1) res.generic_slice_mut(
(0, D::dim() - 1),
(DimNameDiff::<D, U1>::name(), Const::<1>),
)
.copy_from(translation); .copy_from(translation);
res res
@ -67,10 +70,10 @@ where
} }
/// # 2D transformations as a Matrix3 /// # 2D transformations as a Matrix3
impl<N: RealField> Matrix3<N> { impl<T: RealField> Matrix3<T> {
/// Builds a 2 dimensional homogeneous rotation matrix from an angle in radian. /// Builds a 2 dimensional homogeneous rotation matrix from an angle in radian.
#[inline] #[inline]
pub fn new_rotation(angle: N) -> Self { pub fn new_rotation(angle: T) -> Self {
Rotation2::new(angle).to_homogeneous() Rotation2::new(angle).to_homogeneous()
} }
@ -78,9 +81,9 @@ impl<N: RealField> Matrix3<N> {
/// ///
/// Can be used to implement "zoom_to" functionality. /// Can be used to implement "zoom_to" functionality.
#[inline] #[inline]
pub fn new_nonuniform_scaling_wrt_point(scaling: &Vector2<N>, pt: &Point2<N>) -> Self { pub fn new_nonuniform_scaling_wrt_point(scaling: &Vector2<T>, pt: &Point2<T>) -> Self {
let zero = N::zero(); let zero = T::zero();
let one = N::one(); let one = T::one();
Matrix3::new( Matrix3::new(
scaling.x, scaling.x,
zero, zero,
@ -96,12 +99,12 @@ impl<N: RealField> Matrix3<N> {
} }
/// # 3D transformations as a Matrix4 /// # 3D transformations as a Matrix4
impl<N: RealField> Matrix4<N> { impl<T: RealField> Matrix4<T> {
/// Builds a 3D homogeneous rotation matrix from an axis and an angle (multiplied together). /// Builds a 3D homogeneous rotation matrix from an axis and an angle (multiplied together).
/// ///
/// Returns the identity matrix if the given argument is zero. /// Returns the identity matrix if the given argument is zero.
#[inline] #[inline]
pub fn new_rotation(axisangle: Vector3<N>) -> Self { pub fn new_rotation(axisangle: Vector3<T>) -> Self {
Rotation3::new(axisangle).to_homogeneous() Rotation3::new(axisangle).to_homogeneous()
} }
@ -109,7 +112,7 @@ impl<N: RealField> Matrix4<N> {
/// ///
/// Returns the identity matrix if the given argument is zero. /// Returns the identity matrix if the given argument is zero.
#[inline] #[inline]
pub fn new_rotation_wrt_point(axisangle: Vector3<N>, pt: Point3<N>) -> Self { pub fn new_rotation_wrt_point(axisangle: Vector3<T>, pt: Point3<T>) -> Self {
let rot = Rotation3::from_scaled_axis(axisangle); let rot = Rotation3::from_scaled_axis(axisangle);
Isometry::rotation_wrt_point(rot, pt).to_homogeneous() Isometry::rotation_wrt_point(rot, pt).to_homogeneous()
} }
@ -118,9 +121,9 @@ impl<N: RealField> Matrix4<N> {
/// ///
/// Can be used to implement "zoom_to" functionality. /// Can be used to implement "zoom_to" functionality.
#[inline] #[inline]
pub fn new_nonuniform_scaling_wrt_point(scaling: &Vector3<N>, pt: &Point3<N>) -> Self { pub fn new_nonuniform_scaling_wrt_point(scaling: &Vector3<T>, pt: &Point3<T>) -> Self {
let zero = N::zero(); let zero = T::zero();
let one = N::one(); let one = T::one();
Matrix4::new( Matrix4::new(
scaling.x, scaling.x,
zero, zero,
@ -146,31 +149,31 @@ impl<N: RealField> Matrix4<N> {
/// Returns the identity matrix if the given argument is zero. /// Returns the identity matrix if the given argument is zero.
/// This is identical to `Self::new_rotation`. /// This is identical to `Self::new_rotation`.
#[inline] #[inline]
pub fn from_scaled_axis(axisangle: Vector3<N>) -> Self { pub fn from_scaled_axis(axisangle: Vector3<T>) -> Self {
Rotation3::from_scaled_axis(axisangle).to_homogeneous() Rotation3::from_scaled_axis(axisangle).to_homogeneous()
} }
/// Creates a new rotation from Euler angles. /// Creates a new rotation from Euler angles.
/// ///
/// The primitive rotations are applied in order: 1 roll 2 pitch 3 yaw. /// The primitive rotations are applied in order: 1 roll 2 pitch 3 yaw.
pub fn from_euler_angles(roll: N, pitch: N, yaw: N) -> Self { pub fn from_euler_angles(roll: T, pitch: T, yaw: T) -> Self {
Rotation3::from_euler_angles(roll, pitch, yaw).to_homogeneous() Rotation3::from_euler_angles(roll, pitch, yaw).to_homogeneous()
} }
/// Builds a 3D homogeneous rotation matrix from an axis and a rotation angle. /// Builds a 3D homogeneous rotation matrix from an axis and a rotation angle.
pub fn from_axis_angle(axis: &Unit<Vector3<N>>, angle: N) -> Self { pub fn from_axis_angle(axis: &Unit<Vector3<T>>, angle: T) -> Self {
Rotation3::from_axis_angle(axis, angle).to_homogeneous() Rotation3::from_axis_angle(axis, angle).to_homogeneous()
} }
/// Creates a new homogeneous matrix for an orthographic projection. /// Creates a new homogeneous matrix for an orthographic projection.
#[inline] #[inline]
pub fn new_orthographic(left: N, right: N, bottom: N, top: N, znear: N, zfar: N) -> Self { pub fn new_orthographic(left: T, right: T, bottom: T, top: T, znear: T, zfar: T) -> Self {
Orthographic3::new(left, right, bottom, top, znear, zfar).into_inner() Orthographic3::new(left, right, bottom, top, znear, zfar).into_inner()
} }
/// Creates a new homogeneous matrix for a perspective projection. /// Creates a new homogeneous matrix for a perspective projection.
#[inline] #[inline]
pub fn new_perspective(aspect: N, fovy: N, znear: N, zfar: N) -> Self { pub fn new_perspective(aspect: T, fovy: T, znear: T, zfar: T) -> Self {
Perspective3::new(aspect, fovy, znear, zfar).into_inner() Perspective3::new(aspect, fovy, znear, zfar).into_inner()
} }
@ -180,40 +183,40 @@ impl<N: RealField> Matrix4<N> {
/// It maps the view direction `target - eye` to the positive `z` axis and the origin to the /// It maps the view direction `target - eye` to the positive `z` axis and the origin to the
/// `eye`. /// `eye`.
#[inline] #[inline]
pub fn face_towards(eye: &Point3<N>, target: &Point3<N>, up: &Vector3<N>) -> Self { pub fn face_towards(eye: &Point3<T>, target: &Point3<T>, up: &Vector3<T>) -> Self {
IsometryMatrix3::face_towards(eye, target, up).to_homogeneous() IsometryMatrix3::face_towards(eye, target, up).to_homogeneous()
} }
/// Deprecated: Use [Matrix4::face_towards] instead. /// Deprecated: Use [Matrix4::face_towards] instead.
#[deprecated(note = "renamed to `face_towards`")] #[deprecated(note = "renamed to `face_towards`")]
pub fn new_observer_frame(eye: &Point3<N>, target: &Point3<N>, up: &Vector3<N>) -> Self { pub fn new_observer_frame(eye: &Point3<T>, target: &Point3<T>, up: &Vector3<T>) -> Self {
Matrix4::face_towards(eye, target, up) Matrix4::face_towards(eye, target, up)
} }
/// Builds a right-handed look-at view matrix. /// Builds a right-handed look-at view matrix.
#[inline] #[inline]
pub fn look_at_rh(eye: &Point3<N>, target: &Point3<N>, up: &Vector3<N>) -> Self { pub fn look_at_rh(eye: &Point3<T>, target: &Point3<T>, up: &Vector3<T>) -> Self {
IsometryMatrix3::look_at_rh(eye, target, up).to_homogeneous() IsometryMatrix3::look_at_rh(eye, target, up).to_homogeneous()
} }
/// Builds a left-handed look-at view matrix. /// Builds a left-handed look-at view matrix.
#[inline] #[inline]
pub fn look_at_lh(eye: &Point3<N>, target: &Point3<N>, up: &Vector3<N>) -> Self { pub fn look_at_lh(eye: &Point3<T>, target: &Point3<T>, up: &Vector3<T>) -> Self {
IsometryMatrix3::look_at_lh(eye, target, up).to_homogeneous() IsometryMatrix3::look_at_lh(eye, target, up).to_homogeneous()
} }
} }
/// # Append/prepend translation and scaling /// # Append/prepend translation and scaling
impl<N: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<N, D, D>> impl<T: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<T, D, D>>
SquareMatrix<N, D, S> SquareMatrix<T, D, S>
{ {
/// Computes the transformation equal to `self` followed by an uniform scaling factor. /// Computes the transformation equal to `self` followed by an uniform scaling factor.
#[inline] #[inline]
#[must_use = "Did you mean to use append_scaling_mut()?"] #[must_use = "Did you mean to use append_scaling_mut()?"]
pub fn append_scaling(&self, scaling: N) -> MatrixN<N, D> pub fn append_scaling(&self, scaling: T) -> OMatrix<T, D, D>
where where
D: DimNameSub<U1>, D: DimNameSub<U1>,
DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.append_scaling_mut(scaling); res.append_scaling_mut(scaling);
@ -223,10 +226,10 @@ impl<N: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<N, D
/// Computes the transformation equal to an uniform scaling factor followed by `self`. /// Computes the transformation equal to an uniform scaling factor followed by `self`.
#[inline] #[inline]
#[must_use = "Did you mean to use prepend_scaling_mut()?"] #[must_use = "Did you mean to use prepend_scaling_mut()?"]
pub fn prepend_scaling(&self, scaling: N) -> MatrixN<N, D> pub fn prepend_scaling(&self, scaling: T) -> OMatrix<T, D, D>
where where
D: DimNameSub<U1>, D: DimNameSub<U1>,
DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.prepend_scaling_mut(scaling); res.prepend_scaling_mut(scaling);
@ -238,12 +241,12 @@ impl<N: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<N, D
#[must_use = "Did you mean to use append_nonuniform_scaling_mut()?"] #[must_use = "Did you mean to use append_nonuniform_scaling_mut()?"]
pub fn append_nonuniform_scaling<SB>( pub fn append_nonuniform_scaling<SB>(
&self, &self,
scaling: &Vector<N, DimNameDiff<D, U1>, SB>, scaling: &Vector<T, DimNameDiff<D, U1>, SB>,
) -> MatrixN<N, D> ) -> OMatrix<T, D, D>
where where
D: DimNameSub<U1>, D: DimNameSub<U1>,
SB: Storage<N, DimNameDiff<D, U1>>, SB: Storage<T, DimNameDiff<D, U1>>,
DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.append_nonuniform_scaling_mut(scaling); res.append_nonuniform_scaling_mut(scaling);
@ -255,12 +258,12 @@ impl<N: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<N, D
#[must_use = "Did you mean to use prepend_nonuniform_scaling_mut()?"] #[must_use = "Did you mean to use prepend_nonuniform_scaling_mut()?"]
pub fn prepend_nonuniform_scaling<SB>( pub fn prepend_nonuniform_scaling<SB>(
&self, &self,
scaling: &Vector<N, DimNameDiff<D, U1>, SB>, scaling: &Vector<T, DimNameDiff<D, U1>, SB>,
) -> MatrixN<N, D> ) -> OMatrix<T, D, D>
where where
D: DimNameSub<U1>, D: DimNameSub<U1>,
SB: Storage<N, DimNameDiff<D, U1>>, SB: Storage<T, DimNameDiff<D, U1>>,
DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.prepend_nonuniform_scaling_mut(scaling); res.prepend_nonuniform_scaling_mut(scaling);
@ -270,11 +273,14 @@ impl<N: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<N, D
/// Computes the transformation equal to `self` followed by a translation. /// Computes the transformation equal to `self` followed by a translation.
#[inline] #[inline]
#[must_use = "Did you mean to use append_translation_mut()?"] #[must_use = "Did you mean to use append_translation_mut()?"]
pub fn append_translation<SB>(&self, shift: &Vector<N, DimNameDiff<D, U1>, SB>) -> MatrixN<N, D> pub fn append_translation<SB>(
&self,
shift: &Vector<T, DimNameDiff<D, U1>, SB>,
) -> OMatrix<T, D, D>
where where
D: DimNameSub<U1>, D: DimNameSub<U1>,
SB: Storage<N, DimNameDiff<D, U1>>, SB: Storage<T, DimNameDiff<D, U1>>,
DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.append_translation_mut(shift); res.append_translation_mut(shift);
@ -286,12 +292,12 @@ impl<N: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<N, D
#[must_use = "Did you mean to use prepend_translation_mut()?"] #[must_use = "Did you mean to use prepend_translation_mut()?"]
pub fn prepend_translation<SB>( pub fn prepend_translation<SB>(
&self, &self,
shift: &Vector<N, DimNameDiff<D, U1>, SB>, shift: &Vector<T, DimNameDiff<D, U1>, SB>,
) -> MatrixN<N, D> ) -> OMatrix<T, D, D>
where where
D: DimNameSub<U1>, D: DimNameSub<U1>,
SB: Storage<N, DimNameDiff<D, U1>>, SB: Storage<T, DimNameDiff<D, U1>>,
DefaultAllocator: Allocator<N, D, D> + Allocator<N, DimNameDiff<D, U1>>, DefaultAllocator: Allocator<T, D, D> + Allocator<T, DimNameDiff<D, U1>>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.prepend_translation_mut(shift); res.prepend_translation_mut(shift);
@ -300,36 +306,36 @@ impl<N: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<N, D
/// Computes in-place the transformation equal to `self` followed by an uniform scaling factor. /// Computes in-place the transformation equal to `self` followed by an uniform scaling factor.
#[inline] #[inline]
pub fn append_scaling_mut(&mut self, scaling: N) pub fn append_scaling_mut(&mut self, scaling: T)
where where
S: StorageMut<N, D, D>, S: StorageMut<T, D, D>,
D: DimNameSub<U1>, D: DimNameSub<U1>,
{ {
let mut to_scale = self.fixed_rows_mut::<DimNameDiff<D, U1>>(0); let mut to_scale = self.rows_generic_mut(0, DimNameDiff::<D, U1>::name());
to_scale *= scaling; to_scale *= scaling;
} }
/// Computes in-place the transformation equal to an uniform scaling factor followed by `self`. /// Computes in-place the transformation equal to an uniform scaling factor followed by `self`.
#[inline] #[inline]
pub fn prepend_scaling_mut(&mut self, scaling: N) pub fn prepend_scaling_mut(&mut self, scaling: T)
where where
S: StorageMut<N, D, D>, S: StorageMut<T, D, D>,
D: DimNameSub<U1>, D: DimNameSub<U1>,
{ {
let mut to_scale = self.fixed_columns_mut::<DimNameDiff<D, U1>>(0); let mut to_scale = self.columns_generic_mut(0, DimNameDiff::<D, U1>::name());
to_scale *= scaling; to_scale *= scaling;
} }
/// Computes in-place the transformation equal to `self` followed by a non-uniform scaling factor. /// Computes in-place the transformation equal to `self` followed by a non-uniform scaling factor.
#[inline] #[inline]
pub fn append_nonuniform_scaling_mut<SB>(&mut self, scaling: &Vector<N, DimNameDiff<D, U1>, SB>) pub fn append_nonuniform_scaling_mut<SB>(&mut self, scaling: &Vector<T, DimNameDiff<D, U1>, SB>)
where where
S: StorageMut<N, D, D>, S: StorageMut<T, D, D>,
D: DimNameSub<U1>, D: DimNameSub<U1>,
SB: Storage<N, DimNameDiff<D, U1>>, SB: Storage<T, DimNameDiff<D, U1>>,
{ {
for i in 0..scaling.len() { for i in 0..scaling.len() {
let mut to_scale = self.fixed_rows_mut::<U1>(i); let mut to_scale = self.fixed_rows_mut::<1>(i);
to_scale *= scaling[i].inlined_clone(); to_scale *= scaling[i].inlined_clone();
} }
} }
@ -338,25 +344,25 @@ impl<N: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<N, D
#[inline] #[inline]
pub fn prepend_nonuniform_scaling_mut<SB>( pub fn prepend_nonuniform_scaling_mut<SB>(
&mut self, &mut self,
scaling: &Vector<N, DimNameDiff<D, U1>, SB>, scaling: &Vector<T, DimNameDiff<D, U1>, SB>,
) where ) where
S: StorageMut<N, D, D>, S: StorageMut<T, D, D>,
D: DimNameSub<U1>, D: DimNameSub<U1>,
SB: Storage<N, DimNameDiff<D, U1>>, SB: Storage<T, DimNameDiff<D, U1>>,
{ {
for i in 0..scaling.len() { for i in 0..scaling.len() {
let mut to_scale = self.fixed_columns_mut::<U1>(i); let mut to_scale = self.fixed_columns_mut::<1>(i);
to_scale *= scaling[i].inlined_clone(); to_scale *= scaling[i].inlined_clone();
} }
} }
/// Computes the transformation equal to `self` followed by a translation. /// Computes the transformation equal to `self` followed by a translation.
#[inline] #[inline]
pub fn append_translation_mut<SB>(&mut self, shift: &Vector<N, DimNameDiff<D, U1>, SB>) pub fn append_translation_mut<SB>(&mut self, shift: &Vector<T, DimNameDiff<D, U1>, SB>)
where where
S: StorageMut<N, D, D>, S: StorageMut<T, D, D>,
D: DimNameSub<U1>, D: DimNameSub<U1>,
SB: Storage<N, DimNameDiff<D, U1>>, SB: Storage<T, DimNameDiff<D, U1>>,
{ {
for i in 0..D::dim() { for i in 0..D::dim() {
for j in 0..D::dim() - 1 { for j in 0..D::dim() - 1 {
@ -368,41 +374,55 @@ impl<N: Scalar + Zero + One + ClosedMul + ClosedAdd, D: DimName, S: Storage<N, D
/// Computes the transformation equal to a translation followed by `self`. /// Computes the transformation equal to a translation followed by `self`.
#[inline] #[inline]
pub fn prepend_translation_mut<SB>(&mut self, shift: &Vector<N, DimNameDiff<D, U1>, SB>) pub fn prepend_translation_mut<SB>(&mut self, shift: &Vector<T, DimNameDiff<D, U1>, SB>)
where where
D: DimNameSub<U1>, D: DimNameSub<U1>,
S: StorageMut<N, D, D>, S: StorageMut<T, D, D>,
SB: Storage<N, DimNameDiff<D, U1>>, SB: Storage<T, DimNameDiff<D, U1>>,
DefaultAllocator: Allocator<N, DimNameDiff<D, U1>>, DefaultAllocator: Allocator<T, DimNameDiff<D, U1>>,
{ {
let scale = self let scale = self
.fixed_slice::<U1, DimNameDiff<D, U1>>(D::dim() - 1, 0) .generic_slice(
(D::dim() - 1, 0),
(Const::<1>, DimNameDiff::<D, U1>::name()),
)
.tr_dot(&shift); .tr_dot(&shift);
let post_translation = let post_translation = self.generic_slice(
self.fixed_slice::<DimNameDiff<D, U1>, DimNameDiff<D, U1>>(0, 0) * shift; (0, 0),
(DimNameDiff::<D, U1>::name(), DimNameDiff::<D, U1>::name()),
) * shift;
self[(D::dim() - 1, D::dim() - 1)] += scale; self[(D::dim() - 1, D::dim() - 1)] += scale;
let mut translation = self.fixed_slice_mut::<DimNameDiff<D, U1>, U1>(0, D::dim() - 1); let mut translation = self.generic_slice_mut(
(0, D::dim() - 1),
(DimNameDiff::<D, U1>::name(), Const::<1>),
);
translation += post_translation; translation += post_translation;
} }
} }
/// # Transformation of vectors and points /// # Transformation of vectors and points
impl<N: RealField, D: DimNameSub<U1>, S: Storage<N, D, D>> SquareMatrix<N, D, S> impl<T: RealField, D: DimNameSub<U1>, S: Storage<T, D, D>> SquareMatrix<T, D, S>
where where
DefaultAllocator: Allocator<N, D, D> DefaultAllocator: Allocator<T, D, D>
+ Allocator<N, DimNameDiff<D, U1>> + Allocator<T, DimNameDiff<D, U1>>
+ Allocator<N, DimNameDiff<D, U1>, DimNameDiff<D, U1>>, + Allocator<T, DimNameDiff<D, U1>, DimNameDiff<D, U1>>,
{ {
/// Transforms the given vector, assuming the matrix `self` uses homogeneous coordinates. /// Transforms the given vector, assuming the matrix `self` uses homogeneous coordinates.
#[inline] #[inline]
pub fn transform_vector( pub fn transform_vector(
&self, &self,
v: &VectorN<N, DimNameDiff<D, U1>>, v: &OVector<T, DimNameDiff<D, U1>>,
) -> VectorN<N, DimNameDiff<D, U1>> { ) -> OVector<T, DimNameDiff<D, U1>> {
let transform = self.fixed_slice::<DimNameDiff<D, U1>, DimNameDiff<D, U1>>(0, 0); let transform = self.generic_slice(
let normalizer = self.fixed_slice::<U1, DimNameDiff<D, U1>>(D::dim() - 1, 0); (0, 0),
(DimNameDiff::<D, U1>::name(), DimNameDiff::<D, U1>::name()),
);
let normalizer = self.generic_slice(
(D::dim() - 1, 0),
(Const::<1>, DimNameDiff::<D, U1>::name()),
);
let n = normalizer.tr_dot(&v); let n = normalizer.tr_dot(&v);
if !n.is_zero() { if !n.is_zero() {
@ -413,13 +433,13 @@ where
} }
} }
impl<N: RealField, S: Storage<N, Const<3>, Const<3>>> SquareMatrix<N, Const<3>, S> { impl<T: RealField, S: Storage<T, Const<3>, Const<3>>> SquareMatrix<T, Const<3>, S> {
/// Transforms the given point, assuming the matrix `self` uses homogeneous coordinates. /// Transforms the given point, assuming the matrix `self` uses homogeneous coordinates.
#[inline] #[inline]
pub fn transform_point(&self, pt: &Point<N, 2>) -> Point<N, 2> { pub fn transform_point(&self, pt: &Point<T, 2>) -> Point<T, 2> {
let transform = self.fixed_slice::<Const<2>, Const<2>>(0, 0); let transform = self.fixed_slice::<2, 2>(0, 0);
let translation = self.fixed_slice::<Const<2>, U1>(0, 2); let translation = self.fixed_slice::<2, 1>(0, 2);
let normalizer = self.fixed_slice::<U1, Const<2>>(2, 0); let normalizer = self.fixed_slice::<1, 2>(2, 0);
let n = normalizer.tr_dot(&pt.coords) + unsafe { *self.get_unchecked((2, 2)) }; let n = normalizer.tr_dot(&pt.coords) + unsafe { *self.get_unchecked((2, 2)) };
if !n.is_zero() { if !n.is_zero() {
@ -430,13 +450,13 @@ impl<N: RealField, S: Storage<N, Const<3>, Const<3>>> SquareMatrix<N, Const<3>,
} }
} }
impl<N: RealField, S: Storage<N, Const<4>, Const<4>>> SquareMatrix<N, Const<4>, S> { impl<T: RealField, S: Storage<T, Const<4>, Const<4>>> SquareMatrix<T, Const<4>, S> {
/// Transforms the given point, assuming the matrix `self` uses homogeneous coordinates. /// Transforms the given point, assuming the matrix `self` uses homogeneous coordinates.
#[inline] #[inline]
pub fn transform_point(&self, pt: &Point<N, 3>) -> Point<N, 3> { pub fn transform_point(&self, pt: &Point<T, 3>) -> Point<T, 3> {
let transform = self.fixed_slice::<Const<3>, Const<3>>(0, 0); let transform = self.fixed_slice::<3, 3>(0, 0);
let translation = self.fixed_slice::<Const<3>, U1>(0, 3); let translation = self.fixed_slice::<3, 1>(0, 3);
let normalizer = self.fixed_slice::<U1, Const<3>>(3, 0); let normalizer = self.fixed_slice::<1, 3>(3, 0);
let n = normalizer.tr_dot(&pt.coords) + unsafe { *self.get_unchecked((3, 3)) }; let n = normalizer.tr_dot(&pt.coords) + unsafe { *self.get_unchecked((3, 3)) };
if !n.is_zero() { if !n.is_zero() {

View File

@ -10,13 +10,13 @@ use crate::base::allocator::{Allocator, SameShapeAllocator};
use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
use crate::base::dimension::Dim; use crate::base::dimension::Dim;
use crate::base::storage::{Storage, StorageMut}; use crate::base::storage::{Storage, StorageMut};
use crate::base::{DefaultAllocator, Matrix, MatrixMN, MatrixSum, Scalar}; use crate::base::{DefaultAllocator, Matrix, MatrixSum, OMatrix, Scalar};
use crate::ClosedAdd; use crate::ClosedAdd;
/// The type of the result of a matrix component-wise operation. /// The type of the result of a matrix component-wise operation.
pub type MatrixComponentOp<N, R1, C1, R2, C2> = MatrixSum<N, R1, C1, R2, C2>; pub type MatrixComponentOp<T, R1, C1, R2, C2> = MatrixSum<T, R1, C1, R2, C2>;
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> { impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
/// Computes the component-wise absolute value. /// Computes the component-wise absolute value.
/// ///
/// # Example /// # Example
@ -28,10 +28,10 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// assert_eq!(a.abs(), Matrix2::new(0.0, 1.0, 2.0, 3.0)) /// assert_eq!(a.abs(), Matrix2::new(0.0, 1.0, 2.0, 3.0))
/// ``` /// ```
#[inline] #[inline]
pub fn abs(&self) -> MatrixMN<N, R, C> pub fn abs(&self) -> OMatrix<T, R, C>
where where
N: Signed, T: Signed,
DefaultAllocator: Allocator<N, R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
@ -49,11 +49,11 @@ macro_rules! component_binop_impl(
($($binop: ident, $binop_mut: ident, $binop_assign: ident, $cmpy: ident, $Trait: ident . $op: ident . $op_assign: ident, $desc:expr, $desc_cmpy:expr, $desc_mut:expr);* $(;)*) => {$( ($($binop: ident, $binop_mut: ident, $binop_assign: ident, $cmpy: ident, $Trait: ident . $op: ident . $op_assign: ident, $desc:expr, $desc_cmpy:expr, $desc_mut:expr);* $(;)*) => {$(
#[doc = $desc] #[doc = $desc]
#[inline] #[inline]
pub fn $binop<R2, C2, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> MatrixComponentOp<N, R1, C1, R2, C2> pub fn $binop<R2, C2, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> MatrixComponentOp<T, R1, C1, R2, C2>
where N: $Trait, where T: $Trait,
R2: Dim, C2: Dim, R2: Dim, C2: Dim,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
DefaultAllocator: SameShapeAllocator<N, R1, C1, R2, C2>, DefaultAllocator: SameShapeAllocator<T, R1, C1, R2, C2>,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> { ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> {
assert_eq!(self.shape(), rhs.shape(), "Componentwise mul/div: mismatched matrix dimensions."); assert_eq!(self.shape(), rhs.shape(), "Componentwise mul/div: mismatched matrix dimensions.");
@ -73,13 +73,13 @@ macro_rules! component_binop_impl(
// componentwise binop plus Y. // componentwise binop plus Y.
#[doc = $desc_cmpy] #[doc = $desc_cmpy]
#[inline] #[inline]
pub fn $cmpy<R2, C2, SB, R3, C3, SC>(&mut self, alpha: N, a: &Matrix<N, R2, C2, SB>, b: &Matrix<N, R3, C3, SC>, beta: N) pub fn $cmpy<R2, C2, SB, R3, C3, SC>(&mut self, alpha: T, a: &Matrix<T, R2, C2, SB>, b: &Matrix<T, R3, C3, SC>, beta: T)
where N: $Trait + Zero + Mul<N, Output = N> + Add<N, Output = N>, where T: $Trait + Zero + Mul<T, Output = T> + Add<T, Output = T>,
R2: Dim, C2: Dim, R2: Dim, C2: Dim,
R3: Dim, C3: Dim, R3: Dim, C3: Dim,
SA: StorageMut<N, R1, C1>, SA: StorageMut<T, R1, C1>,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
SC: Storage<N, R3, C3>, SC: Storage<T, R3, C3>,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> + ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> +
SameNumberOfRows<R1, R3> + SameNumberOfColumns<C1, C3> { SameNumberOfRows<R1, R3> + SameNumberOfColumns<C1, C3> {
assert_eq!(self.shape(), a.shape(), "Componentwise mul/div: mismatched matrix dimensions."); assert_eq!(self.shape(), a.shape(), "Componentwise mul/div: mismatched matrix dimensions.");
@ -109,12 +109,12 @@ macro_rules! component_binop_impl(
#[doc = $desc_mut] #[doc = $desc_mut]
#[inline] #[inline]
pub fn $binop_assign<R2, C2, SB>(&mut self, rhs: &Matrix<N, R2, C2, SB>) pub fn $binop_assign<R2, C2, SB>(&mut self, rhs: &Matrix<T, R2, C2, SB>)
where N: $Trait, where T: $Trait,
R2: Dim, R2: Dim,
C2: Dim, C2: Dim,
SA: StorageMut<N, R1, C1>, SA: StorageMut<T, R1, C1>,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> { ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> {
assert_eq!(self.shape(), rhs.shape(), "Componentwise mul/div: mismatched matrix dimensions."); assert_eq!(self.shape(), rhs.shape(), "Componentwise mul/div: mismatched matrix dimensions.");
@ -131,12 +131,12 @@ macro_rules! component_binop_impl(
#[doc = $desc_mut] #[doc = $desc_mut]
#[inline] #[inline]
#[deprecated(note = "This is renamed using the `_assign` suffix instead of the `_mut` suffix.")] #[deprecated(note = "This is renamed using the `_assign` suffix instead of the `_mut` suffix.")]
pub fn $binop_mut<R2, C2, SB>(&mut self, rhs: &Matrix<N, R2, C2, SB>) pub fn $binop_mut<R2, C2, SB>(&mut self, rhs: &Matrix<T, R2, C2, SB>)
where N: $Trait, where T: $Trait,
R2: Dim, R2: Dim,
C2: Dim, C2: Dim,
SA: StorageMut<N, R1, C1>, SA: StorageMut<T, R1, C1>,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> { ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> {
self.$binop_assign(rhs) self.$binop_assign(rhs)
} }
@ -144,7 +144,7 @@ macro_rules! component_binop_impl(
); );
/// # Componentwise operations /// # Componentwise operations
impl<N: Scalar, R1: Dim, C1: Dim, SA: Storage<N, R1, C1>> Matrix<N, R1, C1, SA> { impl<T: Scalar, R1: Dim, C1: Dim, SA: Storage<T, R1, C1>> Matrix<T, R1, C1, SA> {
component_binop_impl!( component_binop_impl!(
component_mul, component_mul_mut, component_mul_assign, cmpy, ClosedMul.mul.mul_assign, component_mul, component_mul_mut, component_mul_assign, cmpy, ClosedMul.mul.mul_assign,
r" r"
@ -241,30 +241,30 @@ impl<N: Scalar, R1: Dim, C1: Dim, SA: Storage<N, R1, C1>> Matrix<N, R1, C1, SA>
/// Computes the infimum (aka. componentwise min) of two matrices/vectors. /// Computes the infimum (aka. componentwise min) of two matrices/vectors.
#[inline] #[inline]
pub fn inf(&self, other: &Self) -> MatrixMN<N, R1, C1> pub fn inf(&self, other: &Self) -> OMatrix<T, R1, C1>
where where
N: SimdPartialOrd, T: SimdPartialOrd,
DefaultAllocator: Allocator<N, R1, C1>, DefaultAllocator: Allocator<T, R1, C1>,
{ {
self.zip_map(other, |a, b| a.simd_min(b)) self.zip_map(other, |a, b| a.simd_min(b))
} }
/// Computes the supremum (aka. componentwise max) of two matrices/vectors. /// Computes the supremum (aka. componentwise max) of two matrices/vectors.
#[inline] #[inline]
pub fn sup(&self, other: &Self) -> MatrixMN<N, R1, C1> pub fn sup(&self, other: &Self) -> OMatrix<T, R1, C1>
where where
N: SimdPartialOrd, T: SimdPartialOrd,
DefaultAllocator: Allocator<N, R1, C1>, DefaultAllocator: Allocator<T, R1, C1>,
{ {
self.zip_map(other, |a, b| a.simd_max(b)) self.zip_map(other, |a, b| a.simd_max(b))
} }
/// Computes the (infimum, supremum) of two matrices/vectors. /// Computes the (infimum, supremum) of two matrices/vectors.
#[inline] #[inline]
pub fn inf_sup(&self, other: &Self) -> (MatrixMN<N, R1, C1>, MatrixMN<N, R1, C1>) pub fn inf_sup(&self, other: &Self) -> (OMatrix<T, R1, C1>, OMatrix<T, R1, C1>)
where where
N: SimdPartialOrd, T: SimdPartialOrd,
DefaultAllocator: Allocator<N, R1, C1>, DefaultAllocator: Allocator<T, R1, C1>,
{ {
// TODO: can this be optimized? // TODO: can this be optimized?
(self.inf(other), self.sup(other)) (self.inf(other), self.sup(other))
@ -273,10 +273,10 @@ impl<N: Scalar, R1: Dim, C1: Dim, SA: Storage<N, R1, C1>> Matrix<N, R1, C1, SA>
/// Adds a scalar to `self`. /// Adds a scalar to `self`.
#[inline] #[inline]
#[must_use = "Did you mean to use add_scalar_mut()?"] #[must_use = "Did you mean to use add_scalar_mut()?"]
pub fn add_scalar(&self, rhs: N) -> MatrixMN<N, R1, C1> pub fn add_scalar(&self, rhs: T) -> OMatrix<T, R1, C1>
where where
N: ClosedAdd, T: ClosedAdd,
DefaultAllocator: Allocator<N, R1, C1>, DefaultAllocator: Allocator<T, R1, C1>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.add_scalar_mut(rhs); res.add_scalar_mut(rhs);
@ -285,10 +285,10 @@ impl<N: Scalar, R1: Dim, C1: Dim, SA: Storage<N, R1, C1>> Matrix<N, R1, C1, SA>
/// Adds a scalar to `self` in-place. /// Adds a scalar to `self` in-place.
#[inline] #[inline]
pub fn add_scalar_mut(&mut self, rhs: N) pub fn add_scalar_mut(&mut self, rhs: T)
where where
N: ClosedAdd, T: ClosedAdd,
SA: StorageMut<N, R1, C1>, SA: StorageMut<T, R1, C1>,
{ {
for e in self.iter_mut() { for e in self.iter_mut() {
*e += rhs.inlined_clone() *e += rhs.inlined_clone()

View File

@ -22,9 +22,7 @@ use simba::scalar::{ClosedAdd, ClosedMul};
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{Dim, DimName, Dynamic, ToTypenum}; use crate::base::dimension::{Dim, DimName, Dynamic, ToTypenum};
use crate::base::storage::Storage; use crate::base::storage::Storage;
use crate::base::{ use crate::base::{Const, DefaultAllocator, Matrix, OMatrix, OVector, Scalar, Unit, Vector};
Const, DefaultAllocator, Matrix, MatrixMN, MatrixN, Scalar, Unit, Vector, VectorN,
};
/// When "no_unsound_assume_init" is enabled, expands to `unimplemented!()` instead of `new_uninitialized_generic().assume_init()`. /// When "no_unsound_assume_init" is enabled, expands to `unimplemented!()` instead of `new_uninitialized_generic().assume_init()`.
/// Intended as a placeholder, each callsite should be refactored to use uninitialized memory soundly /// Intended as a placeholder, each callsite should be refactored to use uninitialized memory soundly
@ -33,7 +31,7 @@ macro_rules! unimplemented_or_uninitialized_generic {
($nrows:expr, $ncols:expr) => {{ ($nrows:expr, $ncols:expr) => {{
#[cfg(feature="no_unsound_assume_init")] { #[cfg(feature="no_unsound_assume_init")] {
// Some of the call sites need the number of rows and columns from this to infer a type, so // Some of the call sites need the number of rows and columns from this to infer a type, so
// uninitialized memory is used to infer the type, as `N: Zero` isn't available at all callsites. // uninitialized memory is used to infer the type, as `T: Zero` isn't available at all callsites.
// This may technically still be UB even though the assume_init is dead code, but all callsites should be fixed before #556 is closed. // This may technically still be UB even though the assume_init is dead code, but all callsites should be fixed before #556 is closed.
let typeinference_helper = crate::base::Matrix::new_uninitialized_generic($nrows, $ncols); let typeinference_helper = crate::base::Matrix::new_uninitialized_generic($nrows, $ncols);
unimplemented!(); unimplemented!();
@ -49,9 +47,9 @@ macro_rules! unimplemented_or_uninitialized_generic {
/// the dimension as inputs. /// the dimension as inputs.
/// ///
/// These functions should only be used when working on dimension-generic code. /// These functions should only be used when working on dimension-generic code.
impl<N: Scalar, R: Dim, C: Dim> MatrixMN<N, R, C> impl<T: Scalar, R: Dim, C: Dim> OMatrix<T, R, C>
where where
DefaultAllocator: Allocator<N, R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
/// Creates a new uninitialized matrix. If the matrix has a compile-time dimension, this panics /// Creates a new uninitialized matrix. If the matrix has a compile-time dimension, this panics
/// if `nrows != R::to_usize()` or `ncols != C::to_usize()`. /// if `nrows != R::to_usize()` or `ncols != C::to_usize()`.
@ -62,7 +60,7 @@ where
/// Creates a matrix with all its elements set to `elem`. /// Creates a matrix with all its elements set to `elem`.
#[inline] #[inline]
pub fn from_element_generic(nrows: R, ncols: C, elem: N) -> Self { pub fn from_element_generic(nrows: R, ncols: C, elem: T) -> Self {
let len = nrows.value() * ncols.value(); let len = nrows.value() * ncols.value();
Self::from_iterator_generic(nrows, ncols, iter::repeat(elem).take(len)) Self::from_iterator_generic(nrows, ncols, iter::repeat(elem).take(len))
} }
@ -71,7 +69,7 @@ where
/// ///
/// Same as `from_element_generic`. /// Same as `from_element_generic`.
#[inline] #[inline]
pub fn repeat_generic(nrows: R, ncols: C, elem: N) -> Self { pub fn repeat_generic(nrows: R, ncols: C, elem: T) -> Self {
let len = nrows.value() * ncols.value(); let len = nrows.value() * ncols.value();
Self::from_iterator_generic(nrows, ncols, iter::repeat(elem).take(len)) Self::from_iterator_generic(nrows, ncols, iter::repeat(elem).take(len))
} }
@ -80,16 +78,16 @@ where
#[inline] #[inline]
pub fn zeros_generic(nrows: R, ncols: C) -> Self pub fn zeros_generic(nrows: R, ncols: C) -> Self
where where
N: Zero, T: Zero,
{ {
Self::from_element_generic(nrows, ncols, N::zero()) Self::from_element_generic(nrows, ncols, T::zero())
} }
/// Creates a matrix with all its elements filled by an iterator. /// Creates a matrix with all its elements filled by an iterator.
#[inline] #[inline]
pub fn from_iterator_generic<I>(nrows: R, ncols: C, iter: I) -> Self pub fn from_iterator_generic<I>(nrows: R, ncols: C, iter: I) -> Self
where where
I: IntoIterator<Item = N>, I: IntoIterator<Item = T>,
{ {
Self::from_data(DefaultAllocator::allocate_from_iterator(nrows, ncols, iter)) Self::from_data(DefaultAllocator::allocate_from_iterator(nrows, ncols, iter))
} }
@ -100,7 +98,7 @@ where
/// The order of elements in the slice must follow the usual mathematic writing, i.e., /// The order of elements in the slice must follow the usual mathematic writing, i.e.,
/// row-by-row. /// row-by-row.
#[inline] #[inline]
pub fn from_row_slice_generic(nrows: R, ncols: C, slice: &[N]) -> Self { pub fn from_row_slice_generic(nrows: R, ncols: C, slice: &[T]) -> Self {
assert!( assert!(
slice.len() == nrows.value() * ncols.value(), slice.len() == nrows.value() * ncols.value(),
"Matrix init. error: the slice did not contain the right number of elements." "Matrix init. error: the slice did not contain the right number of elements."
@ -121,7 +119,7 @@ where
/// Creates a matrix with its elements filled with the components provided by a slice. The /// Creates a matrix with its elements filled with the components provided by a slice. The
/// components must have the same layout as the matrix data storage (i.e. column-major). /// components must have the same layout as the matrix data storage (i.e. column-major).
#[inline] #[inline]
pub fn from_column_slice_generic(nrows: R, ncols: C, slice: &[N]) -> Self { pub fn from_column_slice_generic(nrows: R, ncols: C, slice: &[T]) -> Self {
Self::from_iterator_generic(nrows, ncols, slice.iter().cloned()) Self::from_iterator_generic(nrows, ncols, slice.iter().cloned())
} }
@ -130,7 +128,7 @@ where
#[inline] #[inline]
pub fn from_fn_generic<F>(nrows: R, ncols: C, mut f: F) -> Self pub fn from_fn_generic<F>(nrows: R, ncols: C, mut f: F) -> Self
where where
F: FnMut(usize, usize) -> N, F: FnMut(usize, usize) -> T,
{ {
let mut res: Self = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, ncols) }; let mut res: Self = unsafe { crate::unimplemented_or_uninitialized_generic!(nrows, ncols) };
@ -150,9 +148,9 @@ where
#[inline] #[inline]
pub fn identity_generic(nrows: R, ncols: C) -> Self pub fn identity_generic(nrows: R, ncols: C) -> Self
where where
N: Zero + One, T: Zero + One,
{ {
Self::from_diagonal_element_generic(nrows, ncols, N::one()) Self::from_diagonal_element_generic(nrows, ncols, T::one())
} }
/// Creates a new matrix with its diagonal filled with copies of `elt`. /// Creates a new matrix with its diagonal filled with copies of `elt`.
@ -160,9 +158,9 @@ where
/// If the matrix is not square, the largest square submatrix starting at index `(0, 0)` is set /// If the matrix is not square, the largest square submatrix starting at index `(0, 0)` is set
/// to the identity matrix. All other entries are set to zero. /// to the identity matrix. All other entries are set to zero.
#[inline] #[inline]
pub fn from_diagonal_element_generic(nrows: R, ncols: C, elt: N) -> Self pub fn from_diagonal_element_generic(nrows: R, ncols: C, elt: T) -> Self
where where
N: Zero + One, T: Zero + One,
{ {
let mut res = Self::zeros_generic(nrows, ncols); let mut res = Self::zeros_generic(nrows, ncols);
@ -178,9 +176,9 @@ where
/// ///
/// Panics if `elts.len()` is larger than the minimum among `nrows` and `ncols`. /// Panics if `elts.len()` is larger than the minimum among `nrows` and `ncols`.
#[inline] #[inline]
pub fn from_partial_diagonal_generic(nrows: R, ncols: C, elts: &[N]) -> Self pub fn from_partial_diagonal_generic(nrows: R, ncols: C, elts: &[T]) -> Self
where where
N: Zero, T: Zero,
{ {
let mut res = Self::zeros_generic(nrows, ncols); let mut res = Self::zeros_generic(nrows, ncols);
assert!( assert!(
@ -212,9 +210,9 @@ where
/// m.m31 == 7.0 && m.m32 == 8.0 && m.m33 == 9.0); /// m.m31 == 7.0 && m.m32 == 8.0 && m.m33 == 9.0);
/// ``` /// ```
#[inline] #[inline]
pub fn from_rows<SB>(rows: &[Matrix<N, Const<1>, C, SB>]) -> Self pub fn from_rows<SB>(rows: &[Matrix<T, Const<1>, C, SB>]) -> Self
where where
SB: Storage<N, Const<1>, C>, SB: Storage<T, Const<1>, C>,
{ {
assert!(!rows.is_empty(), "At least one row must be given."); assert!(!rows.is_empty(), "At least one row must be given.");
let nrows = R::try_to_usize().unwrap_or_else(|| rows.len()); let nrows = R::try_to_usize().unwrap_or_else(|| rows.len());
@ -254,9 +252,9 @@ where
/// m.m31 == 3.0 && m.m32 == 6.0 && m.m33 == 9.0); /// m.m31 == 3.0 && m.m32 == 6.0 && m.m33 == 9.0);
/// ``` /// ```
#[inline] #[inline]
pub fn from_columns<SB>(columns: &[Vector<N, R, SB>]) -> Self pub fn from_columns<SB>(columns: &[Vector<T, R, SB>]) -> Self
where where
SB: Storage<N, R>, SB: Storage<T, R>,
{ {
assert!(!columns.is_empty(), "At least one column must be given."); assert!(!columns.is_empty(), "At least one column must be given.");
let ncols = C::try_to_usize().unwrap_or_else(|| columns.len()); let ncols = C::try_to_usize().unwrap_or_else(|| columns.len());
@ -284,7 +282,7 @@ where
#[cfg(feature = "rand")] #[cfg(feature = "rand")]
pub fn new_random_generic(nrows: R, ncols: C) -> Self pub fn new_random_generic(nrows: R, ncols: C) -> Self
where where
Standard: Distribution<N>, Standard: Distribution<T>,
{ {
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
Self::from_fn_generic(nrows, ncols, |_, _| rng.gen()) Self::from_fn_generic(nrows, ncols, |_, _| rng.gen())
@ -293,7 +291,7 @@ where
/// Creates a matrix filled with random values from the given distribution. /// Creates a matrix filled with random values from the given distribution.
#[inline] #[inline]
#[cfg(feature = "rand-no-std")] #[cfg(feature = "rand-no-std")]
pub fn from_distribution_generic<Distr: Distribution<N> + ?Sized, G: Rng + ?Sized>( pub fn from_distribution_generic<Distr: Distribution<T> + ?Sized, G: Rng + ?Sized>(
nrows: R, nrows: R,
ncols: C, ncols: C,
distribution: &Distr, distribution: &Distr,
@ -321,15 +319,15 @@ where
/// ``` /// ```
#[inline] #[inline]
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn from_vec_generic(nrows: R, ncols: C, data: Vec<N>) -> Self { pub fn from_vec_generic(nrows: R, ncols: C, data: Vec<T>) -> Self {
Self::from_iterator_generic(nrows, ncols, data) Self::from_iterator_generic(nrows, ncols, data)
} }
} }
impl<N, D: Dim> MatrixN<N, D> impl<T, D: Dim> OMatrix<T, D, D>
where where
N: Scalar, T: Scalar,
DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
/// Creates a square matrix with its diagonal set to `diag` and all other entries set to 0. /// Creates a square matrix with its diagonal set to `diag` and all other entries set to 0.
/// ///
@ -350,9 +348,9 @@ where
/// dm[(2, 0)] == 0.0 && dm[(2, 1)] == 0.0 && dm[(2, 2)] == 3.0); /// dm[(2, 0)] == 0.0 && dm[(2, 1)] == 0.0 && dm[(2, 2)] == 3.0);
/// ``` /// ```
#[inline] #[inline]
pub fn from_diagonal<SB: Storage<N, D>>(diag: &Vector<N, D, SB>) -> Self pub fn from_diagonal<SB: Storage<T, D>>(diag: &Vector<T, D, SB>) -> Self
where where
N: Zero, T: Zero,
{ {
let (dim, _) = diag.data.shape(); let (dim, _) = diag.data.shape();
let mut res = Self::zeros_generic(dim, dim); let mut res = Self::zeros_generic(dim, dim);
@ -401,7 +399,7 @@ macro_rules! impl_constructors(
/// dm[(1, 0)] == 2.0 && dm[(1, 1)] == 2.0 && dm[(1, 2)] == 2.0); /// dm[(1, 0)] == 2.0 && dm[(1, 1)] == 2.0 && dm[(1, 2)] == 2.0);
/// ``` /// ```
#[inline] #[inline]
pub fn from_element($($args: usize,)* elem: N) -> Self { pub fn from_element($($args: usize,)* elem: T) -> Self {
Self::from_element_generic($($gargs, )* elem) Self::from_element_generic($($gargs, )* elem)
} }
@ -428,7 +426,7 @@ macro_rules! impl_constructors(
/// dm[(1, 0)] == 2.0 && dm[(1, 1)] == 2.0 && dm[(1, 2)] == 2.0); /// dm[(1, 0)] == 2.0 && dm[(1, 1)] == 2.0 && dm[(1, 2)] == 2.0);
/// ``` /// ```
#[inline] #[inline]
pub fn repeat($($args: usize,)* elem: N) -> Self { pub fn repeat($($args: usize,)* elem: T) -> Self {
Self::repeat_generic($($gargs, )* elem) Self::repeat_generic($($gargs, )* elem)
} }
@ -454,7 +452,7 @@ macro_rules! impl_constructors(
/// ``` /// ```
#[inline] #[inline]
pub fn zeros($($args: usize),*) -> Self pub fn zeros($($args: usize),*) -> Self
where N: Zero { where T: Zero {
Self::zeros_generic($($gargs),*) Self::zeros_generic($($gargs),*)
} }
@ -483,7 +481,7 @@ macro_rules! impl_constructors(
/// ``` /// ```
#[inline] #[inline]
pub fn from_iterator<I>($($args: usize,)* iter: I) -> Self pub fn from_iterator<I>($($args: usize,)* iter: I) -> Self
where I: IntoIterator<Item = N> { where I: IntoIterator<Item = T> {
Self::from_iterator_generic($($gargs, )* iter) Self::from_iterator_generic($($gargs, )* iter)
} }
@ -511,7 +509,7 @@ macro_rules! impl_constructors(
/// ``` /// ```
#[inline] #[inline]
pub fn from_fn<F>($($args: usize,)* f: F) -> Self pub fn from_fn<F>($($args: usize,)* f: F) -> Self
where F: FnMut(usize, usize) -> N { where F: FnMut(usize, usize) -> T {
Self::from_fn_generic($($gargs, )* f) Self::from_fn_generic($($gargs, )* f)
} }
@ -535,7 +533,7 @@ macro_rules! impl_constructors(
/// ``` /// ```
#[inline] #[inline]
pub fn identity($($args: usize,)*) -> Self pub fn identity($($args: usize,)*) -> Self
where N: Zero + One { where T: Zero + One {
Self::identity_generic($($gargs),* ) Self::identity_generic($($gargs),* )
} }
@ -557,8 +555,8 @@ macro_rules! impl_constructors(
/// dm[(1, 0)] == 0.0 && dm[(1, 1)] == 5.0 && dm[(1, 2)] == 0.0); /// dm[(1, 0)] == 0.0 && dm[(1, 1)] == 5.0 && dm[(1, 2)] == 0.0);
/// ``` /// ```
#[inline] #[inline]
pub fn from_diagonal_element($($args: usize,)* elt: N) -> Self pub fn from_diagonal_element($($args: usize,)* elt: T) -> Self
where N: Zero + One { where T: Zero + One {
Self::from_diagonal_element_generic($($gargs, )* elt) Self::from_diagonal_element_generic($($gargs, )* elt)
} }
@ -584,15 +582,15 @@ macro_rules! impl_constructors(
/// dm[(2, 0)] == 0.0 && dm[(2, 1)] == 0.0 && dm[(2, 2)] == 0.0); /// dm[(2, 0)] == 0.0 && dm[(2, 1)] == 0.0 && dm[(2, 2)] == 0.0);
/// ``` /// ```
#[inline] #[inline]
pub fn from_partial_diagonal($($args: usize,)* elts: &[N]) -> Self pub fn from_partial_diagonal($($args: usize,)* elts: &[T]) -> Self
where N: Zero { where T: Zero {
Self::from_partial_diagonal_generic($($gargs, )* elts) Self::from_partial_diagonal_generic($($gargs, )* elts)
} }
/// Creates a matrix or vector filled with random values from the given distribution. /// Creates a matrix or vector filled with random values from the given distribution.
#[inline] #[inline]
#[cfg(feature = "rand-no-std")] #[cfg(feature = "rand-no-std")]
pub fn from_distribution<Distr: Distribution<N> + ?Sized, G: Rng + ?Sized>( pub fn from_distribution<Distr: Distribution<T> + ?Sized, G: Rng + ?Sized>(
$($args: usize,)* $($args: usize,)*
distribution: &Distr, distribution: &Distr,
rng: &mut G, rng: &mut G,
@ -604,28 +602,28 @@ macro_rules! impl_constructors(
#[inline] #[inline]
#[cfg(feature = "rand")] #[cfg(feature = "rand")]
pub fn new_random($($args: usize),*) -> Self pub fn new_random($($args: usize),*) -> Self
where Standard: Distribution<N> { where Standard: Distribution<T> {
Self::new_random_generic($($gargs),*) Self::new_random_generic($($gargs),*)
} }
} }
); );
/// # Constructors of statically-sized vectors or statically-sized matrices /// # Constructors of statically-sized vectors or statically-sized matrices
impl<N: Scalar, R: DimName, C: DimName> MatrixMN<N, R, C> impl<T: Scalar, R: DimName, C: DimName> OMatrix<T, R, C>
where where
DefaultAllocator: Allocator<N, R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
// TODO: this is not very pretty. We could find a better call syntax. // TODO: this is not very pretty. We could find a better call syntax.
impl_constructors!(R, C; // Arguments for Matrix<N, ..., S> impl_constructors!(R, C; // Arguments for Matrix<T, ..., S>
=> R: DimName, => C: DimName; // Type parameters for impl<N, ..., S> => R: DimName, => C: DimName; // Type parameters for impl<T, ..., S>
R::name(), C::name(); // Arguments for `_generic` constructors. R::name(), C::name(); // Arguments for `_generic` constructors.
); // Arguments for non-generic constructors. ); // Arguments for non-generic constructors.
} }
/// # Constructors of matrices with a dynamic number of columns /// # Constructors of matrices with a dynamic number of columns
impl<N: Scalar, R: DimName> MatrixMN<N, R, Dynamic> impl<T: Scalar, R: DimName> OMatrix<T, R, Dynamic>
where where
DefaultAllocator: Allocator<N, R, Dynamic>, DefaultAllocator: Allocator<T, R, Dynamic>,
{ {
impl_constructors!(R, Dynamic; impl_constructors!(R, Dynamic;
=> R: DimName; => R: DimName;
@ -634,9 +632,9 @@ where
} }
/// # Constructors of dynamic vectors and matrices with a dynamic number of rows /// # Constructors of dynamic vectors and matrices with a dynamic number of rows
impl<N: Scalar, C: DimName> MatrixMN<N, Dynamic, C> impl<T: Scalar, C: DimName> OMatrix<T, Dynamic, C>
where where
DefaultAllocator: Allocator<N, Dynamic, C>, DefaultAllocator: Allocator<T, Dynamic, C>,
{ {
impl_constructors!(Dynamic, C; impl_constructors!(Dynamic, C;
=> C: DimName; => C: DimName;
@ -645,9 +643,9 @@ where
} }
/// # Constructors of fully dynamic matrices /// # Constructors of fully dynamic matrices
impl<N: Scalar> MatrixMN<N, Dynamic, Dynamic> impl<T: Scalar> OMatrix<T, Dynamic, Dynamic>
where where
DefaultAllocator: Allocator<N, Dynamic, Dynamic>, DefaultAllocator: Allocator<T, Dynamic, Dynamic>,
{ {
impl_constructors!(Dynamic, Dynamic; impl_constructors!(Dynamic, Dynamic;
; ;
@ -663,8 +661,8 @@ where
*/ */
macro_rules! impl_constructors_from_data( macro_rules! impl_constructors_from_data(
($data: ident; $($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => { ($data: ident; $($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
impl<N: Scalar, $($DimIdent: $DimBound, )*> MatrixMN<N $(, $Dims)*> impl<T: Scalar, $($DimIdent: $DimBound, )*> OMatrix<T $(, $Dims)*>
where DefaultAllocator: Allocator<N $(, $Dims)*> { where DefaultAllocator: Allocator<T $(, $Dims)*> {
/// Creates a matrix with its elements filled with the components provided by a slice /// Creates a matrix with its elements filled with the components provided by a slice
/// in row-major order. /// in row-major order.
/// ///
@ -691,7 +689,7 @@ macro_rules! impl_constructors_from_data(
/// dm[(1, 0)] == 3 && dm[(1, 1)] == 4 && dm[(1, 2)] == 5); /// dm[(1, 0)] == 3 && dm[(1, 1)] == 4 && dm[(1, 2)] == 5);
/// ``` /// ```
#[inline] #[inline]
pub fn from_row_slice($($args: usize,)* $data: &[N]) -> Self { pub fn from_row_slice($($args: usize,)* $data: &[T]) -> Self {
Self::from_row_slice_generic($($gargs, )* $data) Self::from_row_slice_generic($($gargs, )* $data)
} }
@ -718,7 +716,7 @@ macro_rules! impl_constructors_from_data(
/// dm[(1, 0)] == 1 && dm[(1, 1)] == 3 && dm[(1, 2)] == 5); /// dm[(1, 0)] == 1 && dm[(1, 1)] == 3 && dm[(1, 2)] == 5);
/// ``` /// ```
#[inline] #[inline]
pub fn from_column_slice($($args: usize,)* $data: &[N]) -> Self { pub fn from_column_slice($($args: usize,)* $data: &[T]) -> Self {
Self::from_column_slice_generic($($gargs, )* $data) Self::from_column_slice_generic($($gargs, )* $data)
} }
@ -744,7 +742,7 @@ macro_rules! impl_constructors_from_data(
/// ``` /// ```
#[inline] #[inline]
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn from_vec($($args: usize,)* $data: Vec<N>) -> Self { pub fn from_vec($($args: usize,)* $data: Vec<T>) -> Self {
Self::from_vec_generic($($gargs, )* $data) Self::from_vec_generic($($gargs, )* $data)
} }
} }
@ -752,8 +750,8 @@ macro_rules! impl_constructors_from_data(
); );
// TODO: this is not very pretty. We could find a better call syntax. // TODO: this is not very pretty. We could find a better call syntax.
impl_constructors_from_data!(data; R, C; // Arguments for Matrix<N, ..., S> impl_constructors_from_data!(data; R, C; // Arguments for Matrix<T, ..., S>
=> R: DimName, => C: DimName; // Type parameters for impl<N, ..., S> => R: DimName, => C: DimName; // Type parameters for impl<T, ..., S>
R::name(), C::name(); // Arguments for `_generic` constructors. R::name(), C::name(); // Arguments for `_generic` constructors.
); // Arguments for non-generic constructors. ); // Arguments for non-generic constructors.
@ -777,14 +775,14 @@ impl_constructors_from_data!(data; Dynamic, Dynamic;
* Zero, One, Rand traits. * Zero, One, Rand traits.
* *
*/ */
impl<N, R: DimName, C: DimName> Zero for MatrixMN<N, R, C> impl<T, R: DimName, C: DimName> Zero for OMatrix<T, R, C>
where where
N: Scalar + Zero + ClosedAdd, T: Scalar + Zero + ClosedAdd,
DefaultAllocator: Allocator<N, R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
#[inline] #[inline]
fn zero() -> Self { fn zero() -> Self {
Self::from_element(N::zero()) Self::from_element(T::zero())
} }
#[inline] #[inline]
@ -793,10 +791,10 @@ where
} }
} }
impl<N, D: DimName> One for MatrixN<N, D> impl<T, D: DimName> One for OMatrix<T, D, D>
where where
N: Scalar + Zero + One + ClosedMul + ClosedAdd, T: Scalar + Zero + One + ClosedMul + ClosedAdd,
DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
#[inline] #[inline]
fn one() -> Self { fn one() -> Self {
@ -804,45 +802,45 @@ where
} }
} }
impl<N, R: DimName, C: DimName> Bounded for MatrixMN<N, R, C> impl<T, R: DimName, C: DimName> Bounded for OMatrix<T, R, C>
where where
N: Scalar + Bounded, T: Scalar + Bounded,
DefaultAllocator: Allocator<N, R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
#[inline] #[inline]
fn max_value() -> Self { fn max_value() -> Self {
Self::from_element(N::max_value()) Self::from_element(T::max_value())
} }
#[inline] #[inline]
fn min_value() -> Self { fn min_value() -> Self {
Self::from_element(N::min_value()) Self::from_element(T::min_value())
} }
} }
#[cfg(feature = "rand-no-std")] #[cfg(feature = "rand-no-std")]
impl<N: Scalar, R: Dim, C: Dim> Distribution<MatrixMN<N, R, C>> for Standard impl<T: Scalar, R: Dim, C: Dim> Distribution<OMatrix<T, R, C>> for Standard
where where
DefaultAllocator: Allocator<N, R, C>, DefaultAllocator: Allocator<T, R, C>,
Standard: Distribution<N>, Standard: Distribution<T>,
{ {
#[inline] #[inline]
fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> MatrixMN<N, R, C> { fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> OMatrix<T, R, C> {
let nrows = R::try_to_usize().unwrap_or_else(|| rng.gen_range(0..10)); let nrows = R::try_to_usize().unwrap_or_else(|| rng.gen_range(0..10));
let ncols = C::try_to_usize().unwrap_or_else(|| rng.gen_range(0..10)); let ncols = C::try_to_usize().unwrap_or_else(|| rng.gen_range(0..10));
MatrixMN::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |_, _| rng.gen()) OMatrix::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |_, _| rng.gen())
} }
} }
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
impl<N, R, C> Arbitrary for MatrixMN<N, R, C> impl<T, R, C> Arbitrary for OMatrix<T, R, C>
where where
R: Dim, R: Dim,
C: Dim, C: Dim,
N: Scalar + Arbitrary + Send, T: Scalar + Arbitrary + Send,
DefaultAllocator: Allocator<N, R, C>, DefaultAllocator: Allocator<T, R, C>,
Owned<N, R, C>: Clone + Send, Owned<T, R, C>: Clone + Send,
{ {
#[inline] #[inline]
fn arbitrary(g: &mut Gen) -> Self { fn arbitrary(g: &mut Gen) -> Self {
@ -850,22 +848,22 @@ where
let ncols = C::try_to_usize().unwrap_or(usize::arbitrary(g) % 10); let ncols = C::try_to_usize().unwrap_or(usize::arbitrary(g) % 10);
Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |_, _| { Self::from_fn_generic(R::from_usize(nrows), C::from_usize(ncols), |_, _| {
N::arbitrary(g) T::arbitrary(g)
}) })
} }
} }
// TODO(specialization): faster impls possible for D≤4 (see rand_distr::{UnitCircle, UnitSphere}) // TODO(specialization): faster impls possible for D≤4 (see rand_distr::{UnitCircle, UnitSphere})
#[cfg(feature = "rand")] #[cfg(feature = "rand")]
impl<N: crate::RealField, D: DimName> Distribution<Unit<VectorN<N, D>>> for Standard impl<T: crate::RealField, D: DimName> Distribution<Unit<OVector<T, D>>> for Standard
where where
DefaultAllocator: Allocator<N, D>, DefaultAllocator: Allocator<T, D>,
rand_distr::StandardNormal: Distribution<N>, rand_distr::StandardNormal: Distribution<T>,
{ {
/// Generate a uniformly distributed random unit vector. /// Generate a uniformly distributed random unit vector.
#[inline] #[inline]
fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Unit<VectorN<N, D>> { fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Unit<OVector<T, D>> {
Unit::new_normalize(VectorN::from_distribution_generic( Unit::new_normalize(OVector::from_distribution_generic(
D::name(), D::name(),
Const::<1>, Const::<1>,
&rand_distr::StandardNormal, &rand_distr::StandardNormal,
@ -881,12 +879,12 @@ where
*/ */
macro_rules! componentwise_constructors_impl( macro_rules! componentwise_constructors_impl(
($($R: expr, $C: expr, $($args: ident:($irow: expr,$icol: expr)),*);* $(;)*) => {$( ($($R: expr, $C: expr, $($args: ident:($irow: expr,$icol: expr)),*);* $(;)*) => {$(
impl<N> MatrixMN<N, Const<$R>, Const<$C>> impl<T> OMatrix<T, Const<$R>, Const<$C>>
where N: Scalar, where T: Scalar,
DefaultAllocator: Allocator<N, Const<$R>, Const<$C>> { DefaultAllocator: Allocator<T, Const<$R>, Const<$C>> {
/// Initializes this matrix from its components. /// Initializes this matrix from its components.
#[inline] #[inline]
pub fn new($($args: N),*) -> Self { pub fn new($($args: T),*) -> Self {
unsafe { unsafe {
#[cfg(feature="no_unsound_assume_init")] #[cfg(feature="no_unsound_assume_init")]
let mut res: Self = unimplemented!(); let mut res: Self = unimplemented!();
@ -1051,24 +1049,24 @@ componentwise_constructors_impl!(
* Axis constructors. * Axis constructors.
* *
*/ */
impl<N, R: DimName> VectorN<N, R> impl<T, R: DimName> OVector<T, R>
where where
R: ToTypenum, R: ToTypenum,
N: Scalar + Zero + One, T: Scalar + Zero + One,
DefaultAllocator: Allocator<N, R>, DefaultAllocator: Allocator<T, R>,
{ {
/// The column vector with `val` as its i-th component. /// The column vector with `val` as its i-th component.
#[inline] #[inline]
pub fn ith(i: usize, val: N) -> Self { pub fn ith(i: usize, val: T) -> Self {
let mut res = Self::zeros(); let mut res = Self::zeros();
res[i] = val; res[i] = val;
res res
} }
/// The column unit vector with `N::one()` as its i-th component. /// The column unit vector with `T::one()` as its i-th component.
#[inline] #[inline]
pub fn ith_axis(i: usize) -> Unit<Self> { pub fn ith_axis(i: usize) -> Unit<Self> {
Unit::new_unchecked(Self::ith(i, N::one())) Unit::new_unchecked(Self::ith(i, T::one()))
} }
/// The column vector with a 1 as its first component, and zero elsewhere. /// The column vector with a 1 as its first component, and zero elsewhere.
@ -1079,7 +1077,7 @@ where
{ {
let mut res = Self::zeros(); let mut res = Self::zeros();
unsafe { unsafe {
*res.vget_unchecked_mut(0) = N::one(); *res.vget_unchecked_mut(0) = T::one();
} }
res res
@ -1093,7 +1091,7 @@ where
{ {
let mut res = Self::zeros(); let mut res = Self::zeros();
unsafe { unsafe {
*res.vget_unchecked_mut(1) = N::one(); *res.vget_unchecked_mut(1) = T::one();
} }
res res
@ -1107,7 +1105,7 @@ where
{ {
let mut res = Self::zeros(); let mut res = Self::zeros();
unsafe { unsafe {
*res.vget_unchecked_mut(2) = N::one(); *res.vget_unchecked_mut(2) = T::one();
} }
res res
@ -1121,7 +1119,7 @@ where
{ {
let mut res = Self::zeros(); let mut res = Self::zeros();
unsafe { unsafe {
*res.vget_unchecked_mut(3) = N::one(); *res.vget_unchecked_mut(3) = T::one();
} }
res res
@ -1135,7 +1133,7 @@ where
{ {
let mut res = Self::zeros(); let mut res = Self::zeros();
unsafe { unsafe {
*res.vget_unchecked_mut(4) = N::one(); *res.vget_unchecked_mut(4) = T::one();
} }
res res
@ -1149,7 +1147,7 @@ where
{ {
let mut res = Self::zeros(); let mut res = Self::zeros();
unsafe { unsafe {
*res.vget_unchecked_mut(5) = N::one(); *res.vget_unchecked_mut(5) = T::one();
} }
res res

View File

@ -1,12 +1,12 @@
use crate::base::dimension::{Const, Dim, DimName, Dynamic}; use crate::base::dimension::{Const, Dim, DimName, Dynamic};
use crate::base::matrix_slice::{SliceStorage, SliceStorageMut}; use crate::base::matrix_slice::{SliceStorage, SliceStorageMut};
use crate::base::{MatrixSliceMN, MatrixSliceMutMN, Scalar}; use crate::base::{MatrixSlice, MatrixSliceMutMN, Scalar};
use num_rational::Ratio; use num_rational::Ratio;
/// # Creating matrix slices from `&[T]` /// # Creating matrix slices from `&[T]`
impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
MatrixSliceMN<'a, N, R, C, RStride, CStride> MatrixSlice<'a, T, R, C, RStride, CStride>
{ {
/// Creates, without bound-checking, a matrix slice from an array and with dimensions and strides specified by generic types instances. /// Creates, without bound-checking, a matrix slice from an array and with dimensions and strides specified by generic types instances.
/// ///
@ -14,7 +14,7 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
/// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`. /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`.
#[inline] #[inline]
pub unsafe fn from_slice_with_strides_generic_unchecked( pub unsafe fn from_slice_with_strides_generic_unchecked(
data: &'a [N], data: &'a [T],
start: usize, start: usize,
nrows: R, nrows: R,
ncols: C, ncols: C,
@ -35,7 +35,7 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
/// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`. /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`.
#[inline] #[inline]
pub fn from_slice_with_strides_generic( pub fn from_slice_with_strides_generic(
data: &'a [N], data: &'a [T],
nrows: R, nrows: R,
ncols: C, ncols: C,
rstride: RStride, rstride: RStride,
@ -56,14 +56,14 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim> MatrixSliceMN<'a, N, R, C> { impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSlice<'a, T, R, C> {
/// Creates, without bound-checking, a matrix slice from an array and with dimensions specified by generic types instances. /// Creates, without bound-checking, a matrix slice from an array and with dimensions specified by generic types instances.
/// ///
/// This method is unsafe because the input data array is not checked to contain enough elements. /// This method is unsafe because the input data array is not checked to contain enough elements.
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`. /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
#[inline] #[inline]
pub unsafe fn from_slice_generic_unchecked( pub unsafe fn from_slice_generic_unchecked(
data: &'a [N], data: &'a [T],
start: usize, start: usize,
nrows: R, nrows: R,
ncols: C, ncols: C,
@ -78,41 +78,41 @@ impl<'a, N: Scalar, R: Dim, C: Dim> MatrixSliceMN<'a, N, R, C> {
/// Panics if the input data array dose not contain enough elements. /// Panics if the input data array dose not contain enough elements.
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`. /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
#[inline] #[inline]
pub fn from_slice_generic(data: &'a [N], nrows: R, ncols: C) -> Self { pub fn from_slice_generic(data: &'a [T], nrows: R, ncols: C) -> Self {
Self::from_slice_with_strides_generic(data, nrows, ncols, Const::<1>, nrows) Self::from_slice_with_strides_generic(data, nrows, ncols, Const::<1>, nrows)
} }
} }
macro_rules! impl_constructors( macro_rules! impl_constructors(
($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => { ($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
impl<'a, N: Scalar, $($DimIdent: $DimBound),*> MatrixSliceMN<'a, N, $($Dims),*> { impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixSlice<'a, T, $($Dims),*> {
/// Creates a new matrix slice from the given data array. /// Creates a new matrix slice from the given data array.
/// ///
/// Panics if `data` does not contain enough elements. /// Panics if `data` does not contain enough elements.
#[inline] #[inline]
pub fn from_slice(data: &'a [N], $($args: usize),*) -> Self { pub fn from_slice(data: &'a [T], $($args: usize),*) -> Self {
Self::from_slice_generic(data, $($gargs),*) Self::from_slice_generic(data, $($gargs),*)
} }
/// Creates, without bound checking, a new matrix slice from the given data array. /// Creates, without bound checking, a new matrix slice from the given data array.
#[inline] #[inline]
pub unsafe fn from_slice_unchecked(data: &'a [N], start: usize, $($args: usize),*) -> Self { pub unsafe fn from_slice_unchecked(data: &'a [T], start: usize, $($args: usize),*) -> Self {
Self::from_slice_generic_unchecked(data, start, $($gargs),*) Self::from_slice_generic_unchecked(data, start, $($gargs),*)
} }
} }
impl<'a, N: Scalar, $($DimIdent: $DimBound, )*> MatrixSliceMN<'a, N, $($Dims,)* Dynamic, Dynamic> { impl<'a, T: Scalar, $($DimIdent: $DimBound, )*> MatrixSlice<'a, T, $($Dims,)* Dynamic, Dynamic> {
/// Creates a new matrix slice with the specified strides from the given data array. /// Creates a new matrix slice with the specified strides from the given data array.
/// ///
/// Panics if `data` does not contain enough elements. /// Panics if `data` does not contain enough elements.
#[inline] #[inline]
pub fn from_slice_with_strides(data: &'a [N], $($args: usize,)* rstride: usize, cstride: usize) -> Self { pub fn from_slice_with_strides(data: &'a [T], $($args: usize,)* rstride: usize, cstride: usize) -> Self {
Self::from_slice_with_strides_generic(data, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride)) Self::from_slice_with_strides_generic(data, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
} }
/// Creates, without bound checking, a new matrix slice with the specified strides from the given data array. /// Creates, without bound checking, a new matrix slice with the specified strides from the given data array.
#[inline] #[inline]
pub unsafe fn from_slice_with_strides_unchecked(data: &'a [N], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self { pub unsafe fn from_slice_with_strides_unchecked(data: &'a [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
Self::from_slice_with_strides_generic_unchecked(data, start, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride)) Self::from_slice_with_strides_generic_unchecked(data, start, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
} }
} }
@ -120,8 +120,8 @@ macro_rules! impl_constructors(
); );
// TODO: this is not very pretty. We could find a better call syntax. // TODO: this is not very pretty. We could find a better call syntax.
impl_constructors!(R, C; // Arguments for Matrix<N, ..., S> impl_constructors!(R, C; // Arguments for Matrix<T, ..., S>
=> R: DimName, => C: DimName; // Type parameters for impl<N, ..., S> => R: DimName, => C: DimName; // Type parameters for impl<T, ..., S>
R::name(), C::name(); // Arguments for `_generic` constructors. R::name(), C::name(); // Arguments for `_generic` constructors.
); // Arguments for non-generic constructors. ); // Arguments for non-generic constructors.
@ -141,8 +141,8 @@ impl_constructors!(Dynamic, Dynamic;
nrows, ncols); nrows, ncols);
/// # Creating mutable matrix slices from `&mut [T]` /// # Creating mutable matrix slices from `&mut [T]`
impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
MatrixSliceMutMN<'a, N, R, C, RStride, CStride> MatrixSliceMutMN<'a, T, R, C, RStride, CStride>
{ {
/// Creates, without bound-checking, a mutable matrix slice from an array and with dimensions and strides specified by generic types instances. /// Creates, without bound-checking, a mutable matrix slice from an array and with dimensions and strides specified by generic types instances.
/// ///
@ -150,7 +150,7 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
/// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`. /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`.
#[inline] #[inline]
pub unsafe fn from_slice_with_strides_generic_unchecked( pub unsafe fn from_slice_with_strides_generic_unchecked(
data: &'a mut [N], data: &'a mut [T],
start: usize, start: usize,
nrows: R, nrows: R,
ncols: C, ncols: C,
@ -171,7 +171,7 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
/// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`. /// The generic types `R`, `C`, `RStride`, `CStride` can either be type-level integers or integers wrapped with `Dynamic::new()`.
#[inline] #[inline]
pub fn from_slice_with_strides_generic( pub fn from_slice_with_strides_generic(
data: &'a mut [N], data: &'a mut [T],
nrows: R, nrows: R,
ncols: C, ncols: C,
rstride: RStride, rstride: RStride,
@ -214,14 +214,14 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim> MatrixSliceMutMN<'a, N, R, C> { impl<'a, T: Scalar, R: Dim, C: Dim> MatrixSliceMutMN<'a, T, R, C> {
/// Creates, without bound-checking, a mutable matrix slice from an array and with dimensions specified by generic types instances. /// Creates, without bound-checking, a mutable matrix slice from an array and with dimensions specified by generic types instances.
/// ///
/// This method is unsafe because the input data array is not checked to contain enough elements. /// This method is unsafe because the input data array is not checked to contain enough elements.
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`. /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
#[inline] #[inline]
pub unsafe fn from_slice_generic_unchecked( pub unsafe fn from_slice_generic_unchecked(
data: &'a mut [N], data: &'a mut [T],
start: usize, start: usize,
nrows: R, nrows: R,
ncols: C, ncols: C,
@ -236,42 +236,42 @@ impl<'a, N: Scalar, R: Dim, C: Dim> MatrixSliceMutMN<'a, N, R, C> {
/// Panics if the input data array dose not contain enough elements. /// Panics if the input data array dose not contain enough elements.
/// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`. /// The generic types `R` and `C` can either be type-level integers or integers wrapped with `Dynamic::new()`.
#[inline] #[inline]
pub fn from_slice_generic(data: &'a mut [N], nrows: R, ncols: C) -> Self { pub fn from_slice_generic(data: &'a mut [T], nrows: R, ncols: C) -> Self {
Self::from_slice_with_strides_generic(data, nrows, ncols, Const::<1>, nrows) Self::from_slice_with_strides_generic(data, nrows, ncols, Const::<1>, nrows)
} }
} }
macro_rules! impl_constructors_mut( macro_rules! impl_constructors_mut(
($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => { ($($Dims: ty),*; $(=> $DimIdent: ident: $DimBound: ident),*; $($gargs: expr),*; $($args: ident),*) => {
impl<'a, N: Scalar, $($DimIdent: $DimBound),*> MatrixSliceMutMN<'a, N, $($Dims),*> { impl<'a, T: Scalar, $($DimIdent: $DimBound),*> MatrixSliceMutMN<'a, T, $($Dims),*> {
/// Creates a new mutable matrix slice from the given data array. /// Creates a new mutable matrix slice from the given data array.
/// ///
/// Panics if `data` does not contain enough elements. /// Panics if `data` does not contain enough elements.
#[inline] #[inline]
pub fn from_slice(data: &'a mut [N], $($args: usize),*) -> Self { pub fn from_slice(data: &'a mut [T], $($args: usize),*) -> Self {
Self::from_slice_generic(data, $($gargs),*) Self::from_slice_generic(data, $($gargs),*)
} }
/// Creates, without bound checking, a new mutable matrix slice from the given data array. /// Creates, without bound checking, a new mutable matrix slice from the given data array.
#[inline] #[inline]
pub unsafe fn from_slice_unchecked(data: &'a mut [N], start: usize, $($args: usize),*) -> Self { pub unsafe fn from_slice_unchecked(data: &'a mut [T], start: usize, $($args: usize),*) -> Self {
Self::from_slice_generic_unchecked(data, start, $($gargs),*) Self::from_slice_generic_unchecked(data, start, $($gargs),*)
} }
} }
impl<'a, N: Scalar, $($DimIdent: $DimBound, )*> MatrixSliceMutMN<'a, N, $($Dims,)* Dynamic, Dynamic> { impl<'a, T: Scalar, $($DimIdent: $DimBound, )*> MatrixSliceMutMN<'a, T, $($Dims,)* Dynamic, Dynamic> {
/// Creates a new mutable matrix slice with the specified strides from the given data array. /// Creates a new mutable matrix slice with the specified strides from the given data array.
/// ///
/// Panics if `data` does not contain enough elements. /// Panics if `data` does not contain enough elements.
#[inline] #[inline]
pub fn from_slice_with_strides_mut(data: &'a mut [N], $($args: usize,)* rstride: usize, cstride: usize) -> Self { pub fn from_slice_with_strides_mut(data: &'a mut [T], $($args: usize,)* rstride: usize, cstride: usize) -> Self {
Self::from_slice_with_strides_generic( Self::from_slice_with_strides_generic(
data, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride)) data, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
} }
/// Creates, without bound checking, a new mutable matrix slice with the specified strides from the given data array. /// Creates, without bound checking, a new mutable matrix slice with the specified strides from the given data array.
#[inline] #[inline]
pub unsafe fn from_slice_with_strides_unchecked(data: &'a mut [N], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self { pub unsafe fn from_slice_with_strides_unchecked(data: &'a mut [T], start: usize, $($args: usize,)* rstride: usize, cstride: usize) -> Self {
Self::from_slice_with_strides_generic_unchecked( Self::from_slice_with_strides_generic_unchecked(
data, start, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride)) data, start, $($gargs,)* Dynamic::new(rstride), Dynamic::new(cstride))
} }
@ -280,8 +280,8 @@ macro_rules! impl_constructors_mut(
); );
// TODO: this is not very pretty. We could find a better call syntax. // TODO: this is not very pretty. We could find a better call syntax.
impl_constructors_mut!(R, C; // Arguments for Matrix<N, ..., S> impl_constructors_mut!(R, C; // Arguments for Matrix<T, ..., S>
=> R: DimName, => C: DimName; // Type parameters for impl<N, ..., S> => R: DimName, => C: DimName; // Type parameters for impl<T, ..., S>
R::name(), C::name(); // Arguments for `_generic` constructors. R::name(), C::name(); // Arguments for `_generic` constructors.
); // Arguments for non-generic constructors. ); // Arguments for non-generic constructors.

View File

@ -17,8 +17,8 @@ use crate::base::dimension::{
use crate::base::iter::{MatrixIter, MatrixIterMut}; use crate::base::iter::{MatrixIter, MatrixIterMut};
use crate::base::storage::{ContiguousStorage, ContiguousStorageMut, Storage, StorageMut}; use crate::base::storage::{ContiguousStorage, ContiguousStorageMut, Storage, StorageMut};
use crate::base::{ use crate::base::{
ArrayStorage, DVectorSlice, DVectorSliceMut, DefaultAllocator, Matrix, MatrixMN, MatrixSlice, ArrayStorage, DVectorSlice, DVectorSliceMut, DefaultAllocator, Matrix, MatrixSlice,
MatrixSliceMut, Scalar, MatrixSliceMut, OMatrix, Scalar,
}; };
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
use crate::base::{DVector, VecStorage}; use crate::base::{DVector, VecStorage};
@ -26,30 +26,30 @@ use crate::base::{SliceStorage, SliceStorageMut};
use crate::constraint::DimEq; use crate::constraint::DimEq;
// TODO: too bad this won't work allo slice conversions. // TODO: too bad this won't work allo slice conversions.
impl<N1, N2, R1, C1, R2, C2> SubsetOf<MatrixMN<N2, R2, C2>> for MatrixMN<N1, R1, C1> impl<T1, T2, R1, C1, R2, C2> SubsetOf<OMatrix<T2, R2, C2>> for OMatrix<T1, R1, C1>
where where
R1: Dim, R1: Dim,
C1: Dim, C1: Dim,
R2: Dim, R2: Dim,
C2: Dim, C2: Dim,
N1: Scalar, T1: Scalar,
N2: Scalar + SupersetOf<N1>, T2: Scalar + SupersetOf<T1>,
DefaultAllocator: DefaultAllocator:
Allocator<N2, R2, C2> + Allocator<N1, R1, C1> + SameShapeAllocator<N1, R1, C1, R2, C2>, Allocator<T2, R2, C2> + Allocator<T1, R1, C1> + SameShapeAllocator<T1, R1, C1, R2, C2>,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>, ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> MatrixMN<N2, R2, C2> { fn to_superset(&self) -> OMatrix<T2, R2, C2> {
let (nrows, ncols) = self.shape(); let (nrows, ncols) = self.shape();
let nrows2 = R2::from_usize(nrows); let nrows2 = R2::from_usize(nrows);
let ncols2 = C2::from_usize(ncols); let ncols2 = C2::from_usize(ncols);
let mut res: MatrixMN<N2, R2, C2> = let mut res: OMatrix<T2, R2, C2> =
unsafe { crate::unimplemented_or_uninitialized_generic!(nrows2, ncols2) }; unsafe { crate::unimplemented_or_uninitialized_generic!(nrows2, ncols2) };
for i in 0..nrows { for i in 0..nrows {
for j in 0..ncols { for j in 0..ncols {
unsafe { unsafe {
*res.get_unchecked_mut((i, j)) = N2::from_subset(self.get_unchecked((i, j))) *res.get_unchecked_mut((i, j)) = T2::from_subset(self.get_unchecked((i, j)))
} }
} }
} }
@ -58,12 +58,12 @@ where
} }
#[inline] #[inline]
fn is_in_subset(m: &MatrixMN<N2, R2, C2>) -> bool { fn is_in_subset(m: &OMatrix<T2, R2, C2>) -> bool {
m.iter().all(|e| e.is_in_subset()) m.iter().all(|e| e.is_in_subset())
} }
#[inline] #[inline]
fn from_superset_unchecked(m: &MatrixMN<N2, R2, C2>) -> Self { fn from_superset_unchecked(m: &OMatrix<T2, R2, C2>) -> Self {
let (nrows2, ncols2) = m.shape(); let (nrows2, ncols2) = m.shape();
let nrows = R1::from_usize(nrows2); let nrows = R1::from_usize(nrows2);
let ncols = C1::from_usize(ncols2); let ncols = C1::from_usize(ncols2);
@ -81,9 +81,9 @@ where
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> IntoIterator for &'a Matrix<N, R, C, S> { impl<'a, T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> IntoIterator for &'a Matrix<T, R, C, S> {
type Item = &'a N; type Item = &'a T;
type IntoIter = MatrixIter<'a, N, R, C, S>; type IntoIter = MatrixIter<'a, T, R, C, S>;
#[inline] #[inline]
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
@ -91,11 +91,11 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> IntoIterator for &'a Ma
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> IntoIterator impl<'a, T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> IntoIterator
for &'a mut Matrix<N, R, C, S> for &'a mut Matrix<T, R, C, S>
{ {
type Item = &'a mut N; type Item = &'a mut T;
type IntoIter = MatrixIterMut<'a, N, R, C, S>; type IntoIter = MatrixIterMut<'a, T, R, C, S>;
#[inline] #[inline]
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {
@ -105,11 +105,11 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> IntoIterator
macro_rules! impl_from_into_asref_1D( macro_rules! impl_from_into_asref_1D(
($(($NRows: ident, $NCols: ident) => $SZ: expr);* $(;)*) => {$( ($(($NRows: ident, $NCols: ident) => $SZ: expr);* $(;)*) => {$(
impl<N> From<[N; $SZ]> for MatrixMN<N, $NRows, $NCols> impl<T> From<[T; $SZ]> for OMatrix<T, $NRows, $NCols>
where N: Scalar, where T: Scalar,
DefaultAllocator: Allocator<N, $NRows, $NCols> { DefaultAllocator: Allocator<T, $NRows, $NCols> {
#[inline] #[inline]
fn from(arr: [N; $SZ]) -> Self { fn from(arr: [T; $SZ]) -> Self {
unsafe { unsafe {
let mut res = Self::new_uninitialized(); let mut res = Self::new_uninitialized();
ptr::copy_nonoverlapping(&arr[0], (*res.as_mut_ptr()).data.ptr_mut(), $SZ); ptr::copy_nonoverlapping(&arr[0], (*res.as_mut_ptr()).data.ptr_mut(), $SZ);
@ -119,35 +119,35 @@ macro_rules! impl_from_into_asref_1D(
} }
} }
impl<N, S> Into<[N; $SZ]> for Matrix<N, $NRows, $NCols, S> impl<T, S> Into<[T; $SZ]> for Matrix<T, $NRows, $NCols, S>
where N: Scalar, where T: Scalar,
S: ContiguousStorage<N, $NRows, $NCols> { S: ContiguousStorage<T, $NRows, $NCols> {
#[inline] #[inline]
fn into(self) -> [N; $SZ] { fn into(self) -> [T; $SZ] {
let mut res = mem::MaybeUninit::<[N; $SZ]>::uninit(); let mut res = mem::MaybeUninit::<[T; $SZ]>::uninit();
unsafe { ptr::copy_nonoverlapping(self.data.ptr(), res.as_mut_ptr() as *mut N, $SZ) }; unsafe { ptr::copy_nonoverlapping(self.data.ptr(), res.as_mut_ptr() as *mut T, $SZ) };
unsafe { res.assume_init() } unsafe { res.assume_init() }
} }
} }
impl<N, S> AsRef<[N; $SZ]> for Matrix<N, $NRows, $NCols, S> impl<T, S> AsRef<[T; $SZ]> for Matrix<T, $NRows, $NCols, S>
where N: Scalar, where T: Scalar,
S: ContiguousStorage<N, $NRows, $NCols> { S: ContiguousStorage<T, $NRows, $NCols> {
#[inline] #[inline]
fn as_ref(&self) -> &[N; $SZ] { fn as_ref(&self) -> &[T; $SZ] {
unsafe { unsafe {
mem::transmute(self.data.ptr()) mem::transmute(self.data.ptr())
} }
} }
} }
impl<N, S> AsMut<[N; $SZ]> for Matrix<N, $NRows, $NCols, S> impl<T, S> AsMut<[T; $SZ]> for Matrix<T, $NRows, $NCols, S>
where N: Scalar, where T: Scalar,
S: ContiguousStorageMut<N, $NRows, $NCols> { S: ContiguousStorageMut<T, $NRows, $NCols> {
#[inline] #[inline]
fn as_mut(&mut self) -> &mut [N; $SZ] { fn as_mut(&mut self) -> &mut [T; $SZ] {
unsafe { unsafe {
mem::transmute(self.data.ptr_mut()) mem::transmute(self.data.ptr_mut())
} }
@ -173,10 +173,10 @@ impl_from_into_asref_1D!(
macro_rules! impl_from_into_asref_2D( macro_rules! impl_from_into_asref_2D(
($(($NRows: ty, $NCols: ty) => ($SZRows: expr, $SZCols: expr));* $(;)*) => {$( ($(($NRows: ty, $NCols: ty) => ($SZRows: expr, $SZCols: expr));* $(;)*) => {$(
impl<N: Scalar> From<[[N; $SZRows]; $SZCols]> for MatrixMN<N, $NRows, $NCols> impl<T: Scalar> From<[[T; $SZRows]; $SZCols]> for OMatrix<T, $NRows, $NCols>
where DefaultAllocator: Allocator<N, $NRows, $NCols> { where DefaultAllocator: Allocator<T, $NRows, $NCols> {
#[inline] #[inline]
fn from(arr: [[N; $SZRows]; $SZCols]) -> Self { fn from(arr: [[T; $SZRows]; $SZCols]) -> Self {
unsafe { unsafe {
let mut res = Self::new_uninitialized(); let mut res = Self::new_uninitialized();
ptr::copy_nonoverlapping(&arr[0][0], (*res.as_mut_ptr()).data.ptr_mut(), $SZRows * $SZCols); ptr::copy_nonoverlapping(&arr[0][0], (*res.as_mut_ptr()).data.ptr_mut(), $SZRows * $SZCols);
@ -186,32 +186,32 @@ macro_rules! impl_from_into_asref_2D(
} }
} }
impl<N: Scalar, S> Into<[[N; $SZRows]; $SZCols]> for Matrix<N, $NRows, $NCols, S> impl<T: Scalar, S> Into<[[T; $SZRows]; $SZCols]> for Matrix<T, $NRows, $NCols, S>
where S: ContiguousStorage<N, $NRows, $NCols> { where S: ContiguousStorage<T, $NRows, $NCols> {
#[inline] #[inline]
fn into(self) -> [[N; $SZRows]; $SZCols] { fn into(self) -> [[T; $SZRows]; $SZCols] {
let mut res = mem::MaybeUninit::<[[N; $SZRows]; $SZCols]>::uninit(); let mut res = mem::MaybeUninit::<[[T; $SZRows]; $SZCols]>::uninit();
unsafe { ptr::copy_nonoverlapping(self.data.ptr(), res.as_mut_ptr() as *mut N, $SZRows * $SZCols) }; unsafe { ptr::copy_nonoverlapping(self.data.ptr(), res.as_mut_ptr() as *mut T, $SZRows * $SZCols) };
unsafe { res.assume_init() } unsafe { res.assume_init() }
} }
} }
impl<N: Scalar, S> AsRef<[[N; $SZRows]; $SZCols]> for Matrix<N, $NRows, $NCols, S> impl<T: Scalar, S> AsRef<[[T; $SZRows]; $SZCols]> for Matrix<T, $NRows, $NCols, S>
where S: ContiguousStorage<N, $NRows, $NCols> { where S: ContiguousStorage<T, $NRows, $NCols> {
#[inline] #[inline]
fn as_ref(&self) -> &[[N; $SZRows]; $SZCols] { fn as_ref(&self) -> &[[T; $SZRows]; $SZCols] {
unsafe { unsafe {
mem::transmute(self.data.ptr()) mem::transmute(self.data.ptr())
} }
} }
} }
impl<N: Scalar, S> AsMut<[[N; $SZRows]; $SZCols]> for Matrix<N, $NRows, $NCols, S> impl<T: Scalar, S> AsMut<[[T; $SZRows]; $SZCols]> for Matrix<T, $NRows, $NCols, S>
where S: ContiguousStorageMut<N, $NRows, $NCols> { where S: ContiguousStorageMut<T, $NRows, $NCols> {
#[inline] #[inline]
fn as_mut(&mut self) -> &mut [[N; $SZRows]; $SZCols] { fn as_mut(&mut self) -> &mut [[T; $SZRows]; $SZCols] {
unsafe { unsafe {
mem::transmute(self.data.ptr_mut()) mem::transmute(self.data.ptr_mut())
} }
@ -229,106 +229,105 @@ impl_from_into_asref_2D!(
(U6, U2) => (6, 2); (U6, U3) => (6, 3); (U6, U4) => (6, 4); (U6, U5) => (6, 5); (U6, U6) => (6, 6); (U6, U2) => (6, 2); (U6, U3) => (6, 3); (U6, U4) => (6, 4); (U6, U5) => (6, 5); (U6, U6) => (6, 6);
); );
impl<'a, T, RStride, CStride, const R: usize, const C: usize>
impl<'a, N, RStride, CStride, const R: usize, const C: usize> From<MatrixSlice<'a, T, Const<R>, Const<C>, RStride, CStride>>
From<MatrixSlice<'a, N, Const<R>, Const<C>, RStride, CStride>> for Matrix<T, Const<R>, Const<C>, ArrayStorage<T, R, C>>
for Matrix<N, Const<R>, Const<C>, ArrayStorage<N, R, C>>
where where
N: Scalar, T: Scalar,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
{ {
fn from(matrix_slice: MatrixSlice<'a, N, Const<R>, Const<C>, RStride, CStride>) -> Self { fn from(matrix_slice: MatrixSlice<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
matrix_slice.into_owned() matrix_slice.into_owned()
} }
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, N, C, RStride, CStride> From<MatrixSlice<'a, N, Dynamic, C, RStride, CStride>> impl<'a, T, C, RStride, CStride> From<MatrixSlice<'a, T, Dynamic, C, RStride, CStride>>
for Matrix<N, Dynamic, C, VecStorage<N, Dynamic, C>> for Matrix<T, Dynamic, C, VecStorage<T, Dynamic, C>>
where where
N: Scalar, T: Scalar,
C: Dim, C: Dim,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
{ {
fn from(matrix_slice: MatrixSlice<'a, N, Dynamic, C, RStride, CStride>) -> Self { fn from(matrix_slice: MatrixSlice<'a, T, Dynamic, C, RStride, CStride>) -> Self {
matrix_slice.into_owned() matrix_slice.into_owned()
} }
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, N, R, RStride, CStride> From<MatrixSlice<'a, N, R, Dynamic, RStride, CStride>> impl<'a, T, R, RStride, CStride> From<MatrixSlice<'a, T, R, Dynamic, RStride, CStride>>
for Matrix<N, R, Dynamic, VecStorage<N, R, Dynamic>> for Matrix<T, R, Dynamic, VecStorage<T, R, Dynamic>>
where where
N: Scalar, T: Scalar,
R: DimName, R: DimName,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
{ {
fn from(matrix_slice: MatrixSlice<'a, N, R, Dynamic, RStride, CStride>) -> Self { fn from(matrix_slice: MatrixSlice<'a, T, R, Dynamic, RStride, CStride>) -> Self {
matrix_slice.into_owned() matrix_slice.into_owned()
} }
} }
impl<'a, N, RStride, CStride, const R: usize, const C: usize> impl<'a, T, RStride, CStride, const R: usize, const C: usize>
From<MatrixSliceMut<'a, N, Const<R>, Const<C>, RStride, CStride>> From<MatrixSliceMut<'a, T, Const<R>, Const<C>, RStride, CStride>>
for Matrix<N, Const<R>, Const<C>, ArrayStorage<N, R, C>> for Matrix<T, Const<R>, Const<C>, ArrayStorage<T, R, C>>
where where
N: Scalar, T: Scalar,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
{ {
fn from(matrix_slice: MatrixSliceMut<'a, N, Const<R>, Const<C>, RStride, CStride>) -> Self { fn from(matrix_slice: MatrixSliceMut<'a, T, Const<R>, Const<C>, RStride, CStride>) -> Self {
matrix_slice.into_owned() matrix_slice.into_owned()
} }
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, N, C, RStride, CStride> From<MatrixSliceMut<'a, N, Dynamic, C, RStride, CStride>> impl<'a, T, C, RStride, CStride> From<MatrixSliceMut<'a, T, Dynamic, C, RStride, CStride>>
for Matrix<N, Dynamic, C, VecStorage<N, Dynamic, C>> for Matrix<T, Dynamic, C, VecStorage<T, Dynamic, C>>
where where
N: Scalar, T: Scalar,
C: Dim, C: Dim,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
{ {
fn from(matrix_slice: MatrixSliceMut<'a, N, Dynamic, C, RStride, CStride>) -> Self { fn from(matrix_slice: MatrixSliceMut<'a, T, Dynamic, C, RStride, CStride>) -> Self {
matrix_slice.into_owned() matrix_slice.into_owned()
} }
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, N, R, RStride, CStride> From<MatrixSliceMut<'a, N, R, Dynamic, RStride, CStride>> impl<'a, T, R, RStride, CStride> From<MatrixSliceMut<'a, T, R, Dynamic, RStride, CStride>>
for Matrix<N, R, Dynamic, VecStorage<N, R, Dynamic>> for Matrix<T, R, Dynamic, VecStorage<T, R, Dynamic>>
where where
N: Scalar, T: Scalar,
R: DimName, R: DimName,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
{ {
fn from(matrix_slice: MatrixSliceMut<'a, N, R, Dynamic, RStride, CStride>) -> Self { fn from(matrix_slice: MatrixSliceMut<'a, T, R, Dynamic, RStride, CStride>) -> Self {
matrix_slice.into_owned() matrix_slice.into_owned()
} }
} }
impl<'a, N, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a Matrix<N, R, C, S>> impl<'a, T, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a Matrix<T, R, C, S>>
for MatrixSlice<'a, N, RSlice, CSlice, RStride, CStride> for MatrixSlice<'a, T, RSlice, CSlice, RStride, CStride>
where where
N: Scalar, T: Scalar,
R: Dim, R: Dim,
C: Dim, C: Dim,
RSlice: Dim, RSlice: Dim,
CSlice: Dim, CSlice: Dim,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
S: Storage<N, R, C>, S: Storage<T, R, C>,
ShapeConstraint: DimEq<R, RSlice> ShapeConstraint: DimEq<R, RSlice>
+ DimEq<C, CSlice> + DimEq<C, CSlice>
+ DimEq<RStride, S::RStride> + DimEq<RStride, S::RStride>
+ DimEq<CStride, S::CStride>, + DimEq<CStride, S::CStride>,
{ {
fn from(m: &'a Matrix<N, R, C, S>) -> Self { fn from(m: &'a Matrix<T, R, C, S>) -> Self {
let (row, col) = m.data.shape(); let (row, col) = m.data.shape();
let row_slice = RSlice::from_usize(row.value()); let row_slice = RSlice::from_usize(row.value());
let col_slice = CSlice::from_usize(col.value()); let col_slice = CSlice::from_usize(col.value());
@ -349,23 +348,23 @@ where
} }
} }
impl<'a, N, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix<N, R, C, S>> impl<'a, T, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix<T, R, C, S>>
for MatrixSlice<'a, N, RSlice, CSlice, RStride, CStride> for MatrixSlice<'a, T, RSlice, CSlice, RStride, CStride>
where where
N: Scalar, T: Scalar,
R: Dim, R: Dim,
C: Dim, C: Dim,
RSlice: Dim, RSlice: Dim,
CSlice: Dim, CSlice: Dim,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
S: Storage<N, R, C>, S: Storage<T, R, C>,
ShapeConstraint: DimEq<R, RSlice> ShapeConstraint: DimEq<R, RSlice>
+ DimEq<C, CSlice> + DimEq<C, CSlice>
+ DimEq<RStride, S::RStride> + DimEq<RStride, S::RStride>
+ DimEq<CStride, S::CStride>, + DimEq<CStride, S::CStride>,
{ {
fn from(m: &'a mut Matrix<N, R, C, S>) -> Self { fn from(m: &'a mut Matrix<T, R, C, S>) -> Self {
let (row, col) = m.data.shape(); let (row, col) = m.data.shape();
let row_slice = RSlice::from_usize(row.value()); let row_slice = RSlice::from_usize(row.value());
let col_slice = CSlice::from_usize(col.value()); let col_slice = CSlice::from_usize(col.value());
@ -386,23 +385,23 @@ where
} }
} }
impl<'a, N, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix<N, R, C, S>> impl<'a, T, R, C, RSlice, CSlice, RStride, CStride, S> From<&'a mut Matrix<T, R, C, S>>
for MatrixSliceMut<'a, N, RSlice, CSlice, RStride, CStride> for MatrixSliceMut<'a, T, RSlice, CSlice, RStride, CStride>
where where
N: Scalar, T: Scalar,
R: Dim, R: Dim,
C: Dim, C: Dim,
RSlice: Dim, RSlice: Dim,
CSlice: Dim, CSlice: Dim,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
S: StorageMut<N, R, C>, S: StorageMut<T, R, C>,
ShapeConstraint: DimEq<R, RSlice> ShapeConstraint: DimEq<R, RSlice>
+ DimEq<C, CSlice> + DimEq<C, CSlice>
+ DimEq<RStride, S::RStride> + DimEq<RStride, S::RStride>
+ DimEq<CStride, S::CStride>, + DimEq<CStride, S::CStride>,
{ {
fn from(m: &'a mut Matrix<N, R, C, S>) -> Self { fn from(m: &'a mut Matrix<T, R, C, S>) -> Self {
let (row, col) = m.data.shape(); let (row, col) = m.data.shape();
let row_slice = RSlice::from_usize(row.value()); let row_slice = RSlice::from_usize(row.value());
let col_slice = CSlice::from_usize(col.value()); let col_slice = CSlice::from_usize(col.value());
@ -424,54 +423,54 @@ where
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, N: Scalar> From<Vec<N>> for DVector<N> { impl<'a, T: Scalar> From<Vec<T>> for DVector<T> {
#[inline] #[inline]
fn from(vec: Vec<N>) -> Self { fn from(vec: Vec<T>) -> Self {
Self::from_vec(vec) Self::from_vec(vec)
} }
} }
impl<'a, N: Scalar + Copy, R: Dim, C: Dim, S: ContiguousStorage<N, R, C>> Into<&'a [N]> impl<'a, T: Scalar + Copy, R: Dim, C: Dim, S: ContiguousStorage<T, R, C>> Into<&'a [T]>
for &'a Matrix<N, R, C, S> for &'a Matrix<T, R, C, S>
{ {
#[inline] #[inline]
fn into(self) -> &'a [N] { fn into(self) -> &'a [T] {
self.as_slice() self.as_slice()
} }
} }
impl<'a, N: Scalar + Copy, R: Dim, C: Dim, S: ContiguousStorageMut<N, R, C>> Into<&'a mut [N]> impl<'a, T: Scalar + Copy, R: Dim, C: Dim, S: ContiguousStorageMut<T, R, C>> Into<&'a mut [T]>
for &'a mut Matrix<N, R, C, S> for &'a mut Matrix<T, R, C, S>
{ {
#[inline] #[inline]
fn into(self) -> &'a mut [N] { fn into(self) -> &'a mut [T] {
self.as_mut_slice() self.as_mut_slice()
} }
} }
impl<'a, N: Scalar + Copy> From<&'a [N]> for DVectorSlice<'a, N> { impl<'a, T: Scalar + Copy> From<&'a [T]> for DVectorSlice<'a, T> {
#[inline] #[inline]
fn from(slice: &'a [N]) -> Self { fn from(slice: &'a [T]) -> Self {
Self::from_slice(slice, slice.len()) Self::from_slice(slice, slice.len())
} }
} }
impl<'a, N: Scalar + Copy> From<&'a mut [N]> for DVectorSliceMut<'a, N> { impl<'a, T: Scalar + Copy> From<&'a mut [T]> for DVectorSliceMut<'a, T> {
#[inline] #[inline]
fn from(slice: &'a mut [N]) -> Self { fn from(slice: &'a mut [T]) -> Self {
Self::from_slice(slice, slice.len()) Self::from_slice(slice, slice.len())
} }
} }
impl<N: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[MatrixMN<N::Element, R, C>; 2]> impl<T: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[OMatrix<T::Element, R, C>; 2]>
for MatrixMN<N, R, C> for OMatrix<T, R, C>
where where
N: From<[<N as SimdValue>::Element; 2]>, T: From<[<T as SimdValue>::Element; 2]>,
N::Element: Scalar + SimdValue, T::Element: Scalar + SimdValue,
DefaultAllocator: Allocator<N, R, C> + Allocator<N::Element, R, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{ {
#[inline] #[inline]
fn from(arr: [MatrixMN<N::Element, R, C>; 2]) -> Self { fn from(arr: [OMatrix<T::Element, R, C>; 2]) -> Self {
let (nrows, ncols) = arr[0].data.shape(); let (nrows, ncols) = arr[0].data.shape();
Self::from_fn_generic(nrows, ncols, |i, j| { Self::from_fn_generic(nrows, ncols, |i, j| {
@ -484,15 +483,15 @@ where
} }
} }
impl<N: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[MatrixMN<N::Element, R, C>; 4]> impl<T: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[OMatrix<T::Element, R, C>; 4]>
for MatrixMN<N, R, C> for OMatrix<T, R, C>
where where
N: From<[<N as SimdValue>::Element; 4]>, T: From<[<T as SimdValue>::Element; 4]>,
N::Element: Scalar + SimdValue, T::Element: Scalar + SimdValue,
DefaultAllocator: Allocator<N, R, C> + Allocator<N::Element, R, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{ {
#[inline] #[inline]
fn from(arr: [MatrixMN<N::Element, R, C>; 4]) -> Self { fn from(arr: [OMatrix<T::Element, R, C>; 4]) -> Self {
let (nrows, ncols) = arr[0].data.shape(); let (nrows, ncols) = arr[0].data.shape();
Self::from_fn_generic(nrows, ncols, |i, j| { Self::from_fn_generic(nrows, ncols, |i, j| {
@ -507,15 +506,15 @@ where
} }
} }
impl<N: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[MatrixMN<N::Element, R, C>; 8]> impl<T: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[OMatrix<T::Element, R, C>; 8]>
for MatrixMN<N, R, C> for OMatrix<T, R, C>
where where
N: From<[<N as SimdValue>::Element; 8]>, T: From<[<T as SimdValue>::Element; 8]>,
N::Element: Scalar + SimdValue, T::Element: Scalar + SimdValue,
DefaultAllocator: Allocator<N, R, C> + Allocator<N::Element, R, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{ {
#[inline] #[inline]
fn from(arr: [MatrixMN<N::Element, R, C>; 8]) -> Self { fn from(arr: [OMatrix<T::Element, R, C>; 8]) -> Self {
let (nrows, ncols) = arr[0].data.shape(); let (nrows, ncols) = arr[0].data.shape();
Self::from_fn_generic(nrows, ncols, |i, j| { Self::from_fn_generic(nrows, ncols, |i, j| {
@ -534,14 +533,14 @@ where
} }
} }
impl<N: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[MatrixMN<N::Element, R, C>; 16]> impl<T: Scalar + PrimitiveSimdValue, R: Dim, C: Dim> From<[OMatrix<T::Element, R, C>; 16]>
for MatrixMN<N, R, C> for OMatrix<T, R, C>
where where
N: From<[<N as SimdValue>::Element; 16]>, T: From<[<T as SimdValue>::Element; 16]>,
N::Element: Scalar + SimdValue, T::Element: Scalar + SimdValue,
DefaultAllocator: Allocator<N, R, C> + Allocator<N::Element, R, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{ {
fn from(arr: [MatrixMN<N::Element, R, C>; 16]) -> Self { fn from(arr: [OMatrix<T::Element, R, C>; 16]) -> Self {
let (nrows, ncols) = arr[0].data.shape(); let (nrows, ncols) = arr[0].data.shape();
Self::from_fn_generic(nrows, ncols, |i, j| { Self::from_fn_generic(nrows, ncols, |i, j| {

View File

@ -24,17 +24,17 @@ macro_rules! coords_impl(
#[repr(C)] #[repr(C)]
#[derive(Eq, PartialEq, Clone, Hash, Debug, Copy)] #[derive(Eq, PartialEq, Clone, Hash, Debug, Copy)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct $T<N: Scalar> { pub struct $T<T: Scalar> {
$(pub $comps: N),* $(pub $comps: T),*
} }
} }
); );
macro_rules! deref_impl( macro_rules! deref_impl(
($R: ty, $C: ty; $Target: ident) => { ($R: ty, $C: ty; $Target: ident) => {
impl<N: Scalar, S> Deref for Matrix<N, $R, $C, S> impl<T: Scalar, S> Deref for Matrix<T, $R, $C, S>
where S: ContiguousStorage<N, $R, $C> { where S: ContiguousStorage<T, $R, $C> {
type Target = $Target<N>; type Target = $Target<T>;
#[inline] #[inline]
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
@ -42,8 +42,8 @@ macro_rules! deref_impl(
} }
} }
impl<N: Scalar, S> DerefMut for Matrix<N, $R, $C, S> impl<T: Scalar, S> DerefMut for Matrix<T, $R, $C, S>
where S: ContiguousStorageMut<N, $R, $C> { where S: ContiguousStorageMut<T, $R, $C> {
#[inline] #[inline]
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { mem::transmute(self.data.ptr_mut()) } unsafe { mem::transmute(self.data.ptr_mut()) }

View File

@ -31,10 +31,10 @@ use crate::base::Scalar;
pub struct DefaultAllocator; pub struct DefaultAllocator;
// Static - Static // Static - Static
impl<N: Scalar, const R: usize, const C: usize> Allocator<N, Const<R>, Const<C>> impl<T: Scalar, const R: usize, const C: usize> Allocator<T, Const<R>, Const<C>>
for DefaultAllocator for DefaultAllocator
{ {
type Buffer = ArrayStorage<N, R, C>; type Buffer = ArrayStorage<T, R, C>;
#[inline] #[inline]
unsafe fn allocate_uninitialized(_: Const<R>, _: Const<C>) -> mem::MaybeUninit<Self::Buffer> { unsafe fn allocate_uninitialized(_: Const<R>, _: Const<C>) -> mem::MaybeUninit<Self::Buffer> {
@ -42,7 +42,7 @@ impl<N: Scalar, const R: usize, const C: usize> Allocator<N, Const<R>, Const<C>>
} }
#[inline] #[inline]
fn allocate_from_iterator<I: IntoIterator<Item = N>>( fn allocate_from_iterator<I: IntoIterator<Item = T>>(
nrows: Const<R>, nrows: Const<R>,
ncols: Const<C>, ncols: Const<C>,
iter: I, iter: I,
@ -70,8 +70,8 @@ impl<N: Scalar, const R: usize, const C: usize> Allocator<N, Const<R>, Const<C>>
// Dynamic - Static // Dynamic - Static
// Dynamic - Dynamic // Dynamic - Dynamic
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<N: Scalar, C: Dim> Allocator<N, Dynamic, C> for DefaultAllocator { impl<T: Scalar, C: Dim> Allocator<T, Dynamic, C> for DefaultAllocator {
type Buffer = VecStorage<N, Dynamic, C>; type Buffer = VecStorage<T, Dynamic, C>;
#[inline] #[inline]
unsafe fn allocate_uninitialized(nrows: Dynamic, ncols: C) -> mem::MaybeUninit<Self::Buffer> { unsafe fn allocate_uninitialized(nrows: Dynamic, ncols: C) -> mem::MaybeUninit<Self::Buffer> {
@ -84,13 +84,13 @@ impl<N: Scalar, C: Dim> Allocator<N, Dynamic, C> for DefaultAllocator {
} }
#[inline] #[inline]
fn allocate_from_iterator<I: IntoIterator<Item = N>>( fn allocate_from_iterator<I: IntoIterator<Item = T>>(
nrows: Dynamic, nrows: Dynamic,
ncols: C, ncols: C,
iter: I, iter: I,
) -> Self::Buffer { ) -> Self::Buffer {
let it = iter.into_iter(); let it = iter.into_iter();
let res: Vec<N> = it.collect(); let res: Vec<T> = it.collect();
assert!(res.len() == nrows.value() * ncols.value(), assert!(res.len() == nrows.value() * ncols.value(),
"Allocation from iterator error: the iterator did not yield the correct number of elements."); "Allocation from iterator error: the iterator did not yield the correct number of elements.");
@ -100,8 +100,8 @@ impl<N: Scalar, C: Dim> Allocator<N, Dynamic, C> for DefaultAllocator {
// Static - Dynamic // Static - Dynamic
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<N: Scalar, R: DimName> Allocator<N, R, Dynamic> for DefaultAllocator { impl<T: Scalar, R: DimName> Allocator<T, R, Dynamic> for DefaultAllocator {
type Buffer = VecStorage<N, R, Dynamic>; type Buffer = VecStorage<T, R, Dynamic>;
#[inline] #[inline]
unsafe fn allocate_uninitialized(nrows: R, ncols: Dynamic) -> mem::MaybeUninit<Self::Buffer> { unsafe fn allocate_uninitialized(nrows: R, ncols: Dynamic) -> mem::MaybeUninit<Self::Buffer> {
@ -114,13 +114,13 @@ impl<N: Scalar, R: DimName> Allocator<N, R, Dynamic> for DefaultAllocator {
} }
#[inline] #[inline]
fn allocate_from_iterator<I: IntoIterator<Item = N>>( fn allocate_from_iterator<I: IntoIterator<Item = T>>(
nrows: R, nrows: R,
ncols: Dynamic, ncols: Dynamic,
iter: I, iter: I,
) -> Self::Buffer { ) -> Self::Buffer {
let it = iter.into_iter(); let it = iter.into_iter();
let res: Vec<N> = it.collect(); let res: Vec<T> = it.collect();
assert!(res.len() == nrows.value() * ncols.value(), assert!(res.len() == nrows.value() * ncols.value(),
"Allocation from iterator error: the iterator did not yield the correct number of elements."); "Allocation from iterator error: the iterator did not yield the correct number of elements.");
@ -134,24 +134,24 @@ impl<N: Scalar, R: DimName> Allocator<N, R, Dynamic> for DefaultAllocator {
* *
*/ */
// Anything -> Static × Static // Anything -> Static × Static
impl<N: Scalar, RFrom, CFrom, const RTO: usize, const CTO: usize> impl<T: Scalar, RFrom, CFrom, const RTO: usize, const CTO: usize>
Reallocator<N, RFrom, CFrom, Const<RTO>, Const<CTO>> for DefaultAllocator Reallocator<T, RFrom, CFrom, Const<RTO>, Const<CTO>> for DefaultAllocator
where where
RFrom: Dim, RFrom: Dim,
CFrom: Dim, CFrom: Dim,
Self: Allocator<N, RFrom, CFrom>, Self: Allocator<T, RFrom, CFrom>,
{ {
#[inline] #[inline]
unsafe fn reallocate_copy( unsafe fn reallocate_copy(
rto: Const<RTO>, rto: Const<RTO>,
cto: Const<CTO>, cto: Const<CTO>,
buf: <Self as Allocator<N, RFrom, CFrom>>::Buffer, buf: <Self as Allocator<T, RFrom, CFrom>>::Buffer,
) -> ArrayStorage<N, RTO, CTO> { ) -> ArrayStorage<T, RTO, CTO> {
#[cfg(feature = "no_unsound_assume_init")] #[cfg(feature = "no_unsound_assume_init")]
let mut res: ArrayStorage<N, RTO, CTO> = unimplemented!(); let mut res: ArrayStorage<T, RTO, CTO> = unimplemented!();
#[cfg(not(feature = "no_unsound_assume_init"))] #[cfg(not(feature = "no_unsound_assume_init"))]
let mut res = let mut res =
<Self as Allocator<N, Const<RTO>, Const<CTO>>>::allocate_uninitialized(rto, cto) <Self as Allocator<T, Const<RTO>, Const<CTO>>>::allocate_uninitialized(rto, cto)
.assume_init(); .assume_init();
let (rfrom, cfrom) = buf.shape(); let (rfrom, cfrom) = buf.shape();
@ -166,8 +166,8 @@ where
// Static × Static -> Dynamic × Any // Static × Static -> Dynamic × Any
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<N: Scalar, CTo, const RFROM: usize, const CFROM: usize> impl<T: Scalar, CTo, const RFROM: usize, const CFROM: usize>
Reallocator<N, Const<RFROM>, Const<CFROM>, Dynamic, CTo> for DefaultAllocator Reallocator<T, Const<RFROM>, Const<CFROM>, Dynamic, CTo> for DefaultAllocator
where where
CTo: Dim, CTo: Dim,
{ {
@ -175,13 +175,13 @@ where
unsafe fn reallocate_copy( unsafe fn reallocate_copy(
rto: Dynamic, rto: Dynamic,
cto: CTo, cto: CTo,
buf: ArrayStorage<N, RFROM, CFROM>, buf: ArrayStorage<T, RFROM, CFROM>,
) -> VecStorage<N, Dynamic, CTo> { ) -> VecStorage<T, Dynamic, CTo> {
#[cfg(feature = "no_unsound_assume_init")] #[cfg(feature = "no_unsound_assume_init")]
let mut res: VecStorage<N, Dynamic, CTo> = unimplemented!(); let mut res: VecStorage<T, Dynamic, CTo> = unimplemented!();
#[cfg(not(feature = "no_unsound_assume_init"))] #[cfg(not(feature = "no_unsound_assume_init"))]
let mut res = let mut res =
<Self as Allocator<N, Dynamic, CTo>>::allocate_uninitialized(rto, cto).assume_init(); <Self as Allocator<T, Dynamic, CTo>>::allocate_uninitialized(rto, cto).assume_init();
let (rfrom, cfrom) = buf.shape(); let (rfrom, cfrom) = buf.shape();
@ -195,8 +195,8 @@ where
// Static × Static -> Static × Dynamic // Static × Static -> Static × Dynamic
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<N: Scalar, RTo, const RFROM: usize, const CFROM: usize> impl<T: Scalar, RTo, const RFROM: usize, const CFROM: usize>
Reallocator<N, Const<RFROM>, Const<CFROM>, RTo, Dynamic> for DefaultAllocator Reallocator<T, Const<RFROM>, Const<CFROM>, RTo, Dynamic> for DefaultAllocator
where where
RTo: DimName, RTo: DimName,
{ {
@ -204,13 +204,13 @@ where
unsafe fn reallocate_copy( unsafe fn reallocate_copy(
rto: RTo, rto: RTo,
cto: Dynamic, cto: Dynamic,
buf: ArrayStorage<N, RFROM, CFROM>, buf: ArrayStorage<T, RFROM, CFROM>,
) -> VecStorage<N, RTo, Dynamic> { ) -> VecStorage<T, RTo, Dynamic> {
#[cfg(feature = "no_unsound_assume_init")] #[cfg(feature = "no_unsound_assume_init")]
let mut res: VecStorage<N, RTo, Dynamic> = unimplemented!(); let mut res: VecStorage<T, RTo, Dynamic> = unimplemented!();
#[cfg(not(feature = "no_unsound_assume_init"))] #[cfg(not(feature = "no_unsound_assume_init"))]
let mut res = let mut res =
<Self as Allocator<N, RTo, Dynamic>>::allocate_uninitialized(rto, cto).assume_init(); <Self as Allocator<T, RTo, Dynamic>>::allocate_uninitialized(rto, cto).assume_init();
let (rfrom, cfrom) = buf.shape(); let (rfrom, cfrom) = buf.shape();
@ -224,60 +224,60 @@ where
// All conversion from a dynamic buffer to a dynamic buffer. // All conversion from a dynamic buffer to a dynamic buffer.
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<N: Scalar, CFrom: Dim, CTo: Dim> Reallocator<N, Dynamic, CFrom, Dynamic, CTo> impl<T: Scalar, CFrom: Dim, CTo: Dim> Reallocator<T, Dynamic, CFrom, Dynamic, CTo>
for DefaultAllocator for DefaultAllocator
{ {
#[inline] #[inline]
unsafe fn reallocate_copy( unsafe fn reallocate_copy(
rto: Dynamic, rto: Dynamic,
cto: CTo, cto: CTo,
buf: VecStorage<N, Dynamic, CFrom>, buf: VecStorage<T, Dynamic, CFrom>,
) -> VecStorage<N, Dynamic, CTo> { ) -> VecStorage<T, Dynamic, CTo> {
let new_buf = buf.resize(rto.value() * cto.value()); let new_buf = buf.resize(rto.value() * cto.value());
VecStorage::new(rto, cto, new_buf) VecStorage::new(rto, cto, new_buf)
} }
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<N: Scalar, CFrom: Dim, RTo: DimName> Reallocator<N, Dynamic, CFrom, RTo, Dynamic> impl<T: Scalar, CFrom: Dim, RTo: DimName> Reallocator<T, Dynamic, CFrom, RTo, Dynamic>
for DefaultAllocator for DefaultAllocator
{ {
#[inline] #[inline]
unsafe fn reallocate_copy( unsafe fn reallocate_copy(
rto: RTo, rto: RTo,
cto: Dynamic, cto: Dynamic,
buf: VecStorage<N, Dynamic, CFrom>, buf: VecStorage<T, Dynamic, CFrom>,
) -> VecStorage<N, RTo, Dynamic> { ) -> VecStorage<T, RTo, Dynamic> {
let new_buf = buf.resize(rto.value() * cto.value()); let new_buf = buf.resize(rto.value() * cto.value());
VecStorage::new(rto, cto, new_buf) VecStorage::new(rto, cto, new_buf)
} }
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<N: Scalar, RFrom: DimName, CTo: Dim> Reallocator<N, RFrom, Dynamic, Dynamic, CTo> impl<T: Scalar, RFrom: DimName, CTo: Dim> Reallocator<T, RFrom, Dynamic, Dynamic, CTo>
for DefaultAllocator for DefaultAllocator
{ {
#[inline] #[inline]
unsafe fn reallocate_copy( unsafe fn reallocate_copy(
rto: Dynamic, rto: Dynamic,
cto: CTo, cto: CTo,
buf: VecStorage<N, RFrom, Dynamic>, buf: VecStorage<T, RFrom, Dynamic>,
) -> VecStorage<N, Dynamic, CTo> { ) -> VecStorage<T, Dynamic, CTo> {
let new_buf = buf.resize(rto.value() * cto.value()); let new_buf = buf.resize(rto.value() * cto.value());
VecStorage::new(rto, cto, new_buf) VecStorage::new(rto, cto, new_buf)
} }
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<N: Scalar, RFrom: DimName, RTo: DimName> Reallocator<N, RFrom, Dynamic, RTo, Dynamic> impl<T: Scalar, RFrom: DimName, RTo: DimName> Reallocator<T, RFrom, Dynamic, RTo, Dynamic>
for DefaultAllocator for DefaultAllocator
{ {
#[inline] #[inline]
unsafe fn reallocate_copy( unsafe fn reallocate_copy(
rto: RTo, rto: RTo,
cto: Dynamic, cto: Dynamic,
buf: VecStorage<N, RFrom, Dynamic>, buf: VecStorage<T, RFrom, Dynamic>,
) -> VecStorage<N, RTo, Dynamic> { ) -> VecStorage<T, RTo, Dynamic> {
let new_buf = buf.resize(rto.value() * cto.value()); let new_buf = buf.resize(rto.value() * cto.value());
VecStorage::new(rto, cto, new_buf) VecStorage::new(rto, cto, new_buf)
} }

View File

@ -10,47 +10,45 @@ use crate::base::allocator::{Allocator, Reallocator};
use crate::base::constraint::{DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; use crate::base::constraint::{DimEq, SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
use crate::base::dimension::Dynamic; use crate::base::dimension::Dynamic;
use crate::base::dimension::{ use crate::base::dimension::{Const, Dim, DimAdd, DimDiff, DimMin, DimMinimum, DimSub, DimSum, U1};
Dim, DimAdd, DimDiff, DimMin, DimMinimum, DimName, DimSub, DimSum, U1,
};
use crate::base::storage::{ReshapableStorage, Storage, StorageMut}; use crate::base::storage::{ReshapableStorage, Storage, StorageMut};
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
use crate::base::DMatrix; use crate::base::DMatrix;
use crate::base::{DefaultAllocator, Matrix, MatrixMN, RowVector, Scalar, Vector}; use crate::base::{DefaultAllocator, Matrix, OMatrix, RowVector, SMatrix, Scalar, Vector};
/// # Rows and columns extraction /// # Rows and columns extraction
impl<N: Scalar + Zero, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> { impl<T: Scalar + Zero, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
/// Extracts the upper triangular part of this matrix (including the diagonal). /// Extracts the upper triangular part of this matrix (including the diagonal).
#[inline] #[inline]
pub fn upper_triangle(&self) -> MatrixMN<N, R, C> pub fn upper_triangle(&self) -> OMatrix<T, R, C>
where where
DefaultAllocator: Allocator<N, R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.fill_lower_triangle(N::zero(), 1); res.fill_lower_triangle(T::zero(), 1);
res res
} }
/// Extracts the lower triangular part of this matrix (including the diagonal). /// Extracts the lower triangular part of this matrix (including the diagonal).
#[inline] #[inline]
pub fn lower_triangle(&self) -> MatrixMN<N, R, C> pub fn lower_triangle(&self) -> OMatrix<T, R, C>
where where
DefaultAllocator: Allocator<N, R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.fill_upper_triangle(N::zero(), 1); res.fill_upper_triangle(T::zero(), 1);
res res
} }
/// Creates a new matrix by extracting the given set of rows from `self`. /// Creates a new matrix by extracting the given set of rows from `self`.
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn select_rows<'a, I>(&self, irows: I) -> MatrixMN<N, Dynamic, C> pub fn select_rows<'a, I>(&self, irows: I) -> OMatrix<T, Dynamic, C>
where where
I: IntoIterator<Item = &'a usize>, I: IntoIterator<Item = &'a usize>,
I::IntoIter: ExactSizeIterator + Clone, I::IntoIter: ExactSizeIterator + Clone,
DefaultAllocator: Allocator<N, Dynamic, C>, DefaultAllocator: Allocator<T, Dynamic, C>,
{ {
let irows = irows.into_iter(); let irows = irows.into_iter();
let ncols = self.data.shape().1; let ncols = self.data.shape().1;
@ -82,11 +80,11 @@ impl<N: Scalar + Zero, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// Creates a new matrix by extracting the given set of columns from `self`. /// Creates a new matrix by extracting the given set of columns from `self`.
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn select_columns<'a, I>(&self, icols: I) -> MatrixMN<N, R, Dynamic> pub fn select_columns<'a, I>(&self, icols: I) -> OMatrix<T, R, Dynamic>
where where
I: IntoIterator<Item = &'a usize>, I: IntoIterator<Item = &'a usize>,
I::IntoIter: ExactSizeIterator, I::IntoIter: ExactSizeIterator,
DefaultAllocator: Allocator<N, R, Dynamic>, DefaultAllocator: Allocator<T, R, Dynamic>,
{ {
let icols = icols.into_iter(); let icols = icols.into_iter();
let nrows = self.data.shape().0; let nrows = self.data.shape().0;
@ -103,13 +101,13 @@ impl<N: Scalar + Zero, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
} }
/// # Set rows, columns, and diagonal /// # Set rows, columns, and diagonal
impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> { impl<T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
/// Fills the diagonal of this matrix with the content of the given vector. /// Fills the diagonal of this matrix with the content of the given vector.
#[inline] #[inline]
pub fn set_diagonal<R2: Dim, S2>(&mut self, diag: &Vector<N, R2, S2>) pub fn set_diagonal<R2: Dim, S2>(&mut self, diag: &Vector<T, R2, S2>)
where where
R: DimMin<C>, R: DimMin<C>,
S2: Storage<N, R2>, S2: Storage<T, R2>,
ShapeConstraint: DimEq<DimMinimum<R, C>, R2>, ShapeConstraint: DimEq<DimMinimum<R, C>, R2>,
{ {
let (nrows, ncols) = self.shape(); let (nrows, ncols) = self.shape();
@ -127,7 +125,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
/// minimum of the number of rows and columns of `self`, and starting with the /// minimum of the number of rows and columns of `self`, and starting with the
/// diagonal element at index (0, 0). /// diagonal element at index (0, 0).
#[inline] #[inline]
pub fn set_partial_diagonal(&mut self, diag: impl Iterator<Item = N>) { pub fn set_partial_diagonal(&mut self, diag: impl Iterator<Item = T>) {
let (nrows, ncols) = self.shape(); let (nrows, ncols) = self.shape();
let min_nrows_ncols = cmp::min(nrows, ncols); let min_nrows_ncols = cmp::min(nrows, ncols);
@ -138,9 +136,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
/// Fills the selected row of this matrix with the content of the given vector. /// Fills the selected row of this matrix with the content of the given vector.
#[inline] #[inline]
pub fn set_row<C2: Dim, S2>(&mut self, i: usize, row: &RowVector<N, C2, S2>) pub fn set_row<C2: Dim, S2>(&mut self, i: usize, row: &RowVector<T, C2, S2>)
where where
S2: Storage<N, U1, C2>, S2: Storage<T, U1, C2>,
ShapeConstraint: SameNumberOfColumns<C, C2>, ShapeConstraint: SameNumberOfColumns<C, C2>,
{ {
self.row_mut(i).copy_from(row); self.row_mut(i).copy_from(row);
@ -148,9 +146,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
/// Fills the selected column of this matrix with the content of the given vector. /// Fills the selected column of this matrix with the content of the given vector.
#[inline] #[inline]
pub fn set_column<R2: Dim, S2>(&mut self, i: usize, column: &Vector<N, R2, S2>) pub fn set_column<R2: Dim, S2>(&mut self, i: usize, column: &Vector<T, R2, S2>)
where where
S2: Storage<N, R2, U1>, S2: Storage<T, R2, U1>,
ShapeConstraint: SameNumberOfRows<R, R2>, ShapeConstraint: SameNumberOfRows<R, R2>,
{ {
self.column_mut(i).copy_from(column); self.column_mut(i).copy_from(column);
@ -158,10 +156,10 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
} }
/// # In-place filling /// # In-place filling
impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> { impl<T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
/// Sets all the elements of this matrix to `val`. /// Sets all the elements of this matrix to `val`.
#[inline] #[inline]
pub fn fill(&mut self, val: N) { pub fn fill(&mut self, val: T) {
for e in self.iter_mut() { for e in self.iter_mut() {
*e = val.inlined_clone() *e = val.inlined_clone()
} }
@ -171,15 +169,15 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
#[inline] #[inline]
pub fn fill_with_identity(&mut self) pub fn fill_with_identity(&mut self)
where where
N: Zero + One, T: Zero + One,
{ {
self.fill(N::zero()); self.fill(T::zero());
self.fill_diagonal(N::one()); self.fill_diagonal(T::one());
} }
/// Sets all the diagonal elements of this matrix to `val`. /// Sets all the diagonal elements of this matrix to `val`.
#[inline] #[inline]
pub fn fill_diagonal(&mut self, val: N) { pub fn fill_diagonal(&mut self, val: T) {
let (nrows, ncols) = self.shape(); let (nrows, ncols) = self.shape();
let n = cmp::min(nrows, ncols); let n = cmp::min(nrows, ncols);
@ -190,7 +188,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
/// Sets all the elements of the selected row to `val`. /// Sets all the elements of the selected row to `val`.
#[inline] #[inline]
pub fn fill_row(&mut self, i: usize, val: N) { pub fn fill_row(&mut self, i: usize, val: T) {
assert!(i < self.nrows(), "Row index out of bounds."); assert!(i < self.nrows(), "Row index out of bounds.");
for j in 0..self.ncols() { for j in 0..self.ncols() {
unsafe { *self.get_unchecked_mut((i, j)) = val.inlined_clone() } unsafe { *self.get_unchecked_mut((i, j)) = val.inlined_clone() }
@ -199,7 +197,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
/// Sets all the elements of the selected column to `val`. /// Sets all the elements of the selected column to `val`.
#[inline] #[inline]
pub fn fill_column(&mut self, j: usize, val: N) { pub fn fill_column(&mut self, j: usize, val: T) {
assert!(j < self.ncols(), "Row index out of bounds."); assert!(j < self.ncols(), "Row index out of bounds.");
for i in 0..self.nrows() { for i in 0..self.nrows() {
unsafe { *self.get_unchecked_mut((i, j)) = val.inlined_clone() } unsafe { *self.get_unchecked_mut((i, j)) = val.inlined_clone() }
@ -214,7 +212,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
/// * If `shift > 1`, then the diagonal and the first `shift - 1` subdiagonals are left /// * If `shift > 1`, then the diagonal and the first `shift - 1` subdiagonals are left
/// untouched. /// untouched.
#[inline] #[inline]
pub fn fill_lower_triangle(&mut self, val: N, shift: usize) { pub fn fill_lower_triangle(&mut self, val: T, shift: usize) {
for j in 0..self.ncols() { for j in 0..self.ncols() {
for i in (j + shift)..self.nrows() { for i in (j + shift)..self.nrows() {
unsafe { *self.get_unchecked_mut((i, j)) = val.inlined_clone() } unsafe { *self.get_unchecked_mut((i, j)) = val.inlined_clone() }
@ -230,7 +228,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
/// * If `shift > 1`, then the diagonal and the first `shift - 1` superdiagonals are left /// * If `shift > 1`, then the diagonal and the first `shift - 1` superdiagonals are left
/// untouched. /// untouched.
#[inline] #[inline]
pub fn fill_upper_triangle(&mut self, val: N, shift: usize) { pub fn fill_upper_triangle(&mut self, val: T, shift: usize) {
for j in shift..self.ncols() { for j in shift..self.ncols() {
// TODO: is there a more efficient way to avoid the min ? // TODO: is there a more efficient way to avoid the min ?
// (necessary for rectangular matrices) // (necessary for rectangular matrices)
@ -241,7 +239,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
} }
} }
impl<N: Scalar, D: Dim, S: StorageMut<N, D, D>> Matrix<N, D, D, S> { impl<T: Scalar, D: Dim, S: StorageMut<T, D, D>> Matrix<T, D, D, S> {
/// Copies the upper-triangle of this matrix to its lower-triangular part. /// Copies the upper-triangle of this matrix to its lower-triangular part.
/// ///
/// This makes the matrix symmetric. Panics if the matrix is not square. /// This makes the matrix symmetric. Panics if the matrix is not square.
@ -275,7 +273,7 @@ impl<N: Scalar, D: Dim, S: StorageMut<N, D, D>> Matrix<N, D, D, S> {
} }
/// # In-place swapping /// # In-place swapping
impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> { impl<T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
/// Swaps two rows in-place. /// Swaps two rows in-place.
#[inline] #[inline]
pub fn swap_rows(&mut self, irow1: usize, irow2: usize) { pub fn swap_rows(&mut self, irow1: usize, irow2: usize) {
@ -311,7 +309,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
* *
*/ */
/// # Rows and columns removal /// # Rows and columns removal
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> { impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
/* /*
* *
* Column removal. * Column removal.
@ -319,20 +317,20 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
*/ */
/// Removes the `i`-th column from this matrix. /// Removes the `i`-th column from this matrix.
#[inline] #[inline]
pub fn remove_column(self, i: usize) -> MatrixMN<N, R, DimDiff<C, U1>> pub fn remove_column(self, i: usize) -> OMatrix<T, R, DimDiff<C, U1>>
where where
C: DimSub<U1>, C: DimSub<U1>,
DefaultAllocator: Reallocator<N, R, C, R, DimDiff<C, U1>>, DefaultAllocator: Reallocator<T, R, C, R, DimDiff<C, U1>>,
{ {
self.remove_fixed_columns::<U1>(i) self.remove_fixed_columns::<1>(i)
} }
/// Removes all columns in `indices` /// Removes all columns in `indices`
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn remove_columns_at(self, indices: &[usize]) -> MatrixMN<N, R, Dynamic> pub fn remove_columns_at(self, indices: &[usize]) -> OMatrix<T, R, Dynamic>
where where
C: DimSub<Dynamic, Output = Dynamic>, C: DimSub<Dynamic, Output = Dynamic>,
DefaultAllocator: Reallocator<N, R, C, R, Dynamic>, DefaultAllocator: Reallocator<T, R, C, R, Dynamic>,
{ {
let mut m = self.into_owned(); let mut m = self.into_owned();
let (nrows, ncols) = m.data.shape(); let (nrows, ncols) = m.data.shape();
@ -363,10 +361,10 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// Removes all rows in `indices` /// Removes all rows in `indices`
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn remove_rows_at(self, indices: &[usize]) -> MatrixMN<N, Dynamic, C> pub fn remove_rows_at(self, indices: &[usize]) -> OMatrix<T, Dynamic, C>
where where
R: DimSub<Dynamic, Output = Dynamic>, R: DimSub<Dynamic, Output = Dynamic>,
DefaultAllocator: Reallocator<N, R, C, Dynamic, C>, DefaultAllocator: Reallocator<T, R, C, Dynamic, C>,
{ {
let mut m = self.into_owned(); let mut m = self.into_owned();
let (nrows, ncols) = m.data.shape(); let (nrows, ncols) = m.data.shape();
@ -398,22 +396,24 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// Removes `D::dim()` consecutive columns from this matrix, starting with the `i`-th /// Removes `D::dim()` consecutive columns from this matrix, starting with the `i`-th
/// (included). /// (included).
#[inline] #[inline]
pub fn remove_fixed_columns<D>(self, i: usize) -> MatrixMN<N, R, DimDiff<C, D>> pub fn remove_fixed_columns<const D: usize>(
self,
i: usize,
) -> OMatrix<T, R, DimDiff<C, Const<D>>>
where where
D: DimName, C: DimSub<Const<D>>,
C: DimSub<D>, DefaultAllocator: Reallocator<T, R, C, R, DimDiff<C, Const<D>>>,
DefaultAllocator: Reallocator<N, R, C, R, DimDiff<C, D>>,
{ {
self.remove_columns_generic(i, D::name()) self.remove_columns_generic(i, Const::<D>)
} }
/// Removes `n` consecutive columns from this matrix, starting with the `i`-th (included). /// Removes `n` consecutive columns from this matrix, starting with the `i`-th (included).
#[inline] #[inline]
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn remove_columns(self, i: usize, n: usize) -> MatrixMN<N, R, Dynamic> pub fn remove_columns(self, i: usize, n: usize) -> OMatrix<T, R, Dynamic>
where where
C: DimSub<Dynamic, Output = Dynamic>, C: DimSub<Dynamic, Output = Dynamic>,
DefaultAllocator: Reallocator<N, R, C, R, Dynamic>, DefaultAllocator: Reallocator<T, R, C, R, Dynamic>,
{ {
self.remove_columns_generic(i, Dynamic::new(n)) self.remove_columns_generic(i, Dynamic::new(n))
} }
@ -423,11 +423,11 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// This is the generic implementation of `.remove_columns(...)` and /// This is the generic implementation of `.remove_columns(...)` and
/// `.remove_fixed_columns(...)` which have nicer API interfaces. /// `.remove_fixed_columns(...)` which have nicer API interfaces.
#[inline] #[inline]
pub fn remove_columns_generic<D>(self, i: usize, nremove: D) -> MatrixMN<N, R, DimDiff<C, D>> pub fn remove_columns_generic<D>(self, i: usize, nremove: D) -> OMatrix<T, R, DimDiff<C, D>>
where where
D: Dim, D: Dim,
C: DimSub<D>, C: DimSub<D>,
DefaultAllocator: Reallocator<N, R, C, R, DimDiff<C, D>>, DefaultAllocator: Reallocator<T, R, C, R, DimDiff<C, D>>,
{ {
let mut m = self.into_owned(); let mut m = self.into_owned();
let (nrows, ncols) = m.data.shape(); let (nrows, ncols) = m.data.shape();
@ -468,32 +468,31 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
*/ */
/// Removes the `i`-th row from this matrix. /// Removes the `i`-th row from this matrix.
#[inline] #[inline]
pub fn remove_row(self, i: usize) -> MatrixMN<N, DimDiff<R, U1>, C> pub fn remove_row(self, i: usize) -> OMatrix<T, DimDiff<R, U1>, C>
where where
R: DimSub<U1>, R: DimSub<U1>,
DefaultAllocator: Reallocator<N, R, C, DimDiff<R, U1>, C>, DefaultAllocator: Reallocator<T, R, C, DimDiff<R, U1>, C>,
{ {
self.remove_fixed_rows::<U1>(i) self.remove_fixed_rows::<1>(i)
} }
/// Removes `D::dim()` consecutive rows from this matrix, starting with the `i`-th (included). /// Removes `D::dim()` consecutive rows from this matrix, starting with the `i`-th (included).
#[inline] #[inline]
pub fn remove_fixed_rows<D>(self, i: usize) -> MatrixMN<N, DimDiff<R, D>, C> pub fn remove_fixed_rows<const D: usize>(self, i: usize) -> OMatrix<T, DimDiff<R, Const<D>>, C>
where where
D: DimName, R: DimSub<Const<D>>,
R: DimSub<D>, DefaultAllocator: Reallocator<T, R, C, DimDiff<R, Const<D>>, C>,
DefaultAllocator: Reallocator<N, R, C, DimDiff<R, D>, C>,
{ {
self.remove_rows_generic(i, D::name()) self.remove_rows_generic(i, Const::<D>)
} }
/// Removes `n` consecutive rows from this matrix, starting with the `i`-th (included). /// Removes `n` consecutive rows from this matrix, starting with the `i`-th (included).
#[inline] #[inline]
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn remove_rows(self, i: usize, n: usize) -> MatrixMN<N, Dynamic, C> pub fn remove_rows(self, i: usize, n: usize) -> OMatrix<T, Dynamic, C>
where where
R: DimSub<Dynamic, Output = Dynamic>, R: DimSub<Dynamic, Output = Dynamic>,
DefaultAllocator: Reallocator<N, R, C, Dynamic, C>, DefaultAllocator: Reallocator<T, R, C, Dynamic, C>,
{ {
self.remove_rows_generic(i, Dynamic::new(n)) self.remove_rows_generic(i, Dynamic::new(n))
} }
@ -503,11 +502,11 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// This is the generic implementation of `.remove_rows(...)` and `.remove_fixed_rows(...)` /// This is the generic implementation of `.remove_rows(...)` and `.remove_fixed_rows(...)`
/// which have nicer API interfaces. /// which have nicer API interfaces.
#[inline] #[inline]
pub fn remove_rows_generic<D>(self, i: usize, nremove: D) -> MatrixMN<N, DimDiff<R, D>, C> pub fn remove_rows_generic<D>(self, i: usize, nremove: D) -> OMatrix<T, DimDiff<R, D>, C>
where where
D: Dim, D: Dim,
R: DimSub<D>, R: DimSub<D>,
DefaultAllocator: Reallocator<N, R, C, DimDiff<R, D>, C>, DefaultAllocator: Reallocator<T, R, C, DimDiff<R, D>, C>,
{ {
let mut m = self.into_owned(); let mut m = self.into_owned();
let (nrows, ncols) = m.data.shape(); let (nrows, ncols) = m.data.shape();
@ -539,7 +538,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
} }
/// # Rows and columns insertion /// # Rows and columns insertion
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> { impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
/* /*
* *
* Columns insertion. * Columns insertion.
@ -547,23 +546,26 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
*/ */
/// Inserts a column filled with `val` at the `i-th` position. /// Inserts a column filled with `val` at the `i-th` position.
#[inline] #[inline]
pub fn insert_column(self, i: usize, val: N) -> MatrixMN<N, R, DimSum<C, U1>> pub fn insert_column(self, i: usize, val: T) -> OMatrix<T, R, DimSum<C, U1>>
where where
C: DimAdd<U1>, C: DimAdd<U1>,
DefaultAllocator: Reallocator<N, R, C, R, DimSum<C, U1>>, DefaultAllocator: Reallocator<T, R, C, R, DimSum<C, U1>>,
{ {
self.insert_fixed_columns::<U1>(i, val) self.insert_fixed_columns::<1>(i, val)
} }
/// Inserts `D::dim()` columns filled with `val` starting at the `i-th` position. /// Inserts `D` columns filled with `val` starting at the `i-th` position.
#[inline] #[inline]
pub fn insert_fixed_columns<D>(self, i: usize, val: N) -> MatrixMN<N, R, DimSum<C, D>> pub fn insert_fixed_columns<const D: usize>(
self,
i: usize,
val: T,
) -> OMatrix<T, R, DimSum<C, Const<D>>>
where where
D: DimName, C: DimAdd<Const<D>>,
C: DimAdd<D>, DefaultAllocator: Reallocator<T, R, C, R, DimSum<C, Const<D>>>,
DefaultAllocator: Reallocator<N, R, C, R, DimSum<C, D>>,
{ {
let mut res = unsafe { self.insert_columns_generic_uninitialized(i, D::name()) }; let mut res = unsafe { self.insert_columns_generic_uninitialized(i, Const::<D>) };
res.fixed_columns_mut::<D>(i).fill(val); res.fixed_columns_mut::<D>(i).fill(val);
res res
} }
@ -571,10 +573,10 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// Inserts `n` columns filled with `val` starting at the `i-th` position. /// Inserts `n` columns filled with `val` starting at the `i-th` position.
#[inline] #[inline]
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn insert_columns(self, i: usize, n: usize, val: N) -> MatrixMN<N, R, Dynamic> pub fn insert_columns(self, i: usize, n: usize, val: T) -> OMatrix<T, R, Dynamic>
where where
C: DimAdd<Dynamic, Output = Dynamic>, C: DimAdd<Dynamic, Output = Dynamic>,
DefaultAllocator: Reallocator<N, R, C, R, Dynamic>, DefaultAllocator: Reallocator<T, R, C, R, Dynamic>,
{ {
let mut res = unsafe { self.insert_columns_generic_uninitialized(i, Dynamic::new(n)) }; let mut res = unsafe { self.insert_columns_generic_uninitialized(i, Dynamic::new(n)) };
res.columns_mut(i, n).fill(val); res.columns_mut(i, n).fill(val);
@ -589,11 +591,11 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
self, self,
i: usize, i: usize,
ninsert: D, ninsert: D,
) -> MatrixMN<N, R, DimSum<C, D>> ) -> OMatrix<T, R, DimSum<C, D>>
where where
D: Dim, D: Dim,
C: DimAdd<D>, C: DimAdd<D>,
DefaultAllocator: Reallocator<N, R, C, R, DimSum<C, D>>, DefaultAllocator: Reallocator<T, R, C, R, DimSum<C, D>>,
{ {
let m = self.into_owned(); let m = self.into_owned();
let (nrows, ncols) = m.data.shape(); let (nrows, ncols) = m.data.shape();
@ -625,23 +627,26 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
*/ */
/// Inserts a row filled with `val` at the `i-th` position. /// Inserts a row filled with `val` at the `i-th` position.
#[inline] #[inline]
pub fn insert_row(self, i: usize, val: N) -> MatrixMN<N, DimSum<R, U1>, C> pub fn insert_row(self, i: usize, val: T) -> OMatrix<T, DimSum<R, U1>, C>
where where
R: DimAdd<U1>, R: DimAdd<U1>,
DefaultAllocator: Reallocator<N, R, C, DimSum<R, U1>, C>, DefaultAllocator: Reallocator<T, R, C, DimSum<R, U1>, C>,
{ {
self.insert_fixed_rows::<U1>(i, val) self.insert_fixed_rows::<1>(i, val)
} }
/// Inserts `D::dim()` rows filled with `val` starting at the `i-th` position. /// Inserts `D::dim()` rows filled with `val` starting at the `i-th` position.
#[inline] #[inline]
pub fn insert_fixed_rows<D>(self, i: usize, val: N) -> MatrixMN<N, DimSum<R, D>, C> pub fn insert_fixed_rows<const D: usize>(
self,
i: usize,
val: T,
) -> OMatrix<T, DimSum<R, Const<D>>, C>
where where
D: DimName, R: DimAdd<Const<D>>,
R: DimAdd<D>, DefaultAllocator: Reallocator<T, R, C, DimSum<R, Const<D>>, C>,
DefaultAllocator: Reallocator<N, R, C, DimSum<R, D>, C>,
{ {
let mut res = unsafe { self.insert_rows_generic_uninitialized(i, D::name()) }; let mut res = unsafe { self.insert_rows_generic_uninitialized(i, Const::<D>) };
res.fixed_rows_mut::<D>(i).fill(val); res.fixed_rows_mut::<D>(i).fill(val);
res res
} }
@ -649,10 +654,10 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// Inserts `n` rows filled with `val` starting at the `i-th` position. /// Inserts `n` rows filled with `val` starting at the `i-th` position.
#[inline] #[inline]
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn insert_rows(self, i: usize, n: usize, val: N) -> MatrixMN<N, Dynamic, C> pub fn insert_rows(self, i: usize, n: usize, val: T) -> OMatrix<T, Dynamic, C>
where where
R: DimAdd<Dynamic, Output = Dynamic>, R: DimAdd<Dynamic, Output = Dynamic>,
DefaultAllocator: Reallocator<N, R, C, Dynamic, C>, DefaultAllocator: Reallocator<T, R, C, Dynamic, C>,
{ {
let mut res = unsafe { self.insert_rows_generic_uninitialized(i, Dynamic::new(n)) }; let mut res = unsafe { self.insert_rows_generic_uninitialized(i, Dynamic::new(n)) };
res.rows_mut(i, n).fill(val); res.rows_mut(i, n).fill(val);
@ -669,11 +674,11 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
self, self,
i: usize, i: usize,
ninsert: D, ninsert: D,
) -> MatrixMN<N, DimSum<R, D>, C> ) -> OMatrix<T, DimSum<R, D>, C>
where where
D: Dim, D: Dim,
R: DimAdd<D>, R: DimAdd<D>,
DefaultAllocator: Reallocator<N, R, C, DimSum<R, D>, C>, DefaultAllocator: Reallocator<T, R, C, DimSum<R, D>, C>,
{ {
let m = self.into_owned(); let m = self.into_owned();
let (nrows, ncols) = m.data.shape(); let (nrows, ncols) = m.data.shape();
@ -700,15 +705,15 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
} }
/// # Resizing and reshaping /// # Resizing and reshaping
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> { impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
/// Resizes this matrix so that it contains `new_nrows` rows and `new_ncols` columns. /// Resizes this matrix so that it contains `new_nrows` rows and `new_ncols` columns.
/// ///
/// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more /// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more
/// rows and/or columns than `self`, then the extra rows or columns are filled with `val`. /// rows and/or columns than `self`, then the extra rows or columns are filled with `val`.
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn resize(self, new_nrows: usize, new_ncols: usize, val: N) -> DMatrix<N> pub fn resize(self, new_nrows: usize, new_ncols: usize, val: T) -> DMatrix<T>
where where
DefaultAllocator: Reallocator<N, R, C, Dynamic, Dynamic>, DefaultAllocator: Reallocator<T, R, C, Dynamic, Dynamic>,
{ {
self.resize_generic(Dynamic::new(new_nrows), Dynamic::new(new_ncols), val) self.resize_generic(Dynamic::new(new_nrows), Dynamic::new(new_ncols), val)
} }
@ -718,9 +723,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more /// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more
/// rows than `self`, then the extra rows are filled with `val`. /// rows than `self`, then the extra rows are filled with `val`.
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn resize_vertically(self, new_nrows: usize, val: N) -> MatrixMN<N, Dynamic, C> pub fn resize_vertically(self, new_nrows: usize, val: T) -> OMatrix<T, Dynamic, C>
where where
DefaultAllocator: Reallocator<N, R, C, Dynamic, C>, DefaultAllocator: Reallocator<T, R, C, Dynamic, C>,
{ {
let ncols = self.data.shape().1; let ncols = self.data.shape().1;
self.resize_generic(Dynamic::new(new_nrows), ncols, val) self.resize_generic(Dynamic::new(new_nrows), ncols, val)
@ -731,9 +736,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more /// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more
/// columns than `self`, then the extra columns are filled with `val`. /// columns than `self`, then the extra columns are filled with `val`.
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn resize_horizontally(self, new_ncols: usize, val: N) -> MatrixMN<N, R, Dynamic> pub fn resize_horizontally(self, new_ncols: usize, val: T) -> OMatrix<T, R, Dynamic>
where where
DefaultAllocator: Reallocator<N, R, C, R, Dynamic>, DefaultAllocator: Reallocator<T, R, C, R, Dynamic>,
{ {
let nrows = self.data.shape().0; let nrows = self.data.shape().0;
self.resize_generic(nrows, Dynamic::new(new_ncols), val) self.resize_generic(nrows, Dynamic::new(new_ncols), val)
@ -743,11 +748,11 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// ///
/// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more /// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more
/// rows and/or columns than `self`, then the extra rows or columns are filled with `val`. /// rows and/or columns than `self`, then the extra rows or columns are filled with `val`.
pub fn fixed_resize<R2: DimName, C2: DimName>(self, val: N) -> MatrixMN<N, R2, C2> pub fn fixed_resize<const R2: usize, const C2: usize>(self, val: T) -> SMatrix<T, R2, C2>
where where
DefaultAllocator: Reallocator<N, R, C, R2, C2>, DefaultAllocator: Reallocator<T, R, C, Const<R2>, Const<C2>>,
{ {
self.resize_generic(R2::name(), C2::name(), val) self.resize_generic(Const::<R2>, Const::<C2>, val)
} }
/// Resizes `self` such that it has dimensions `new_nrows × new_ncols`. /// Resizes `self` such that it has dimensions `new_nrows × new_ncols`.
@ -759,10 +764,10 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
self, self,
new_nrows: R2, new_nrows: R2,
new_ncols: C2, new_ncols: C2,
val: N, val: T,
) -> MatrixMN<N, R2, C2> ) -> OMatrix<T, R2, C2>
where where
DefaultAllocator: Reallocator<N, R, C, R2, C2>, DefaultAllocator: Reallocator<T, R, C, R2, C2>,
{ {
let (nrows, ncols) = self.shape(); let (nrows, ncols) = self.shape();
let mut data = self.data.into_owned(); let mut data = self.data.into_owned();
@ -874,11 +879,11 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
self, self,
new_nrows: R2, new_nrows: R2,
new_ncols: C2, new_ncols: C2,
) -> Matrix<N, R2, C2, S::Output> ) -> Matrix<T, R2, C2, S::Output>
where where
R2: Dim, R2: Dim,
C2: Dim, C2: Dim,
S: ReshapableStorage<N, R, C, R2, C2>, S: ReshapableStorage<T, R, C, R2, C2>,
{ {
let data = self.data.reshape_generic(new_nrows, new_ncols); let data = self.data.reshape_generic(new_nrows, new_ncols);
Matrix::from_data(data) Matrix::from_data(data)
@ -887,16 +892,16 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// # In-place resizing /// # In-place resizing
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<N: Scalar> DMatrix<N> { impl<T: Scalar> DMatrix<T> {
/// Resizes this matrix in-place. /// Resizes this matrix in-place.
/// ///
/// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more /// The values are copied such that `self[(i, j)] == result[(i, j)]`. If the result has more
/// rows and/or columns than `self`, then the extra rows or columns are filled with `val`. /// rows and/or columns than `self`, then the extra rows or columns are filled with `val`.
/// ///
/// Defined only for owned fully-dynamic matrices, i.e., `DMatrix`. /// Defined only for owned fully-dynamic matrices, i.e., `DMatrix`.
pub fn resize_mut(&mut self, new_nrows: usize, new_ncols: usize, val: N) pub fn resize_mut(&mut self, new_nrows: usize, new_ncols: usize, val: T)
where where
DefaultAllocator: Reallocator<N, Dynamic, Dynamic, Dynamic, Dynamic>, DefaultAllocator: Reallocator<T, Dynamic, Dynamic, Dynamic, Dynamic>,
{ {
let placeholder = unsafe { let placeholder = unsafe {
crate::unimplemented_or_uninitialized_generic!(Dynamic::new(0), Dynamic::new(0)) crate::unimplemented_or_uninitialized_generic!(Dynamic::new(0), Dynamic::new(0))
@ -908,9 +913,9 @@ impl<N: Scalar> DMatrix<N> {
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<N: Scalar, C: Dim> MatrixMN<N, Dynamic, C> impl<T: Scalar, C: Dim> OMatrix<T, Dynamic, C>
where where
DefaultAllocator: Allocator<N, Dynamic, C>, DefaultAllocator: Allocator<T, Dynamic, C>,
{ {
/// Changes the number of rows of this matrix in-place. /// Changes the number of rows of this matrix in-place.
/// ///
@ -919,9 +924,9 @@ where
/// ///
/// Defined only for owned matrices with a dynamic number of rows (for example, `DVector`). /// Defined only for owned matrices with a dynamic number of rows (for example, `DVector`).
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn resize_vertically_mut(&mut self, new_nrows: usize, val: N) pub fn resize_vertically_mut(&mut self, new_nrows: usize, val: T)
where where
DefaultAllocator: Reallocator<N, Dynamic, C, Dynamic, C>, DefaultAllocator: Reallocator<T, Dynamic, C, Dynamic, C>,
{ {
let placeholder = unsafe { let placeholder = unsafe {
crate::unimplemented_or_uninitialized_generic!(Dynamic::new(0), self.data.shape().1) crate::unimplemented_or_uninitialized_generic!(Dynamic::new(0), self.data.shape().1)
@ -933,9 +938,9 @@ where
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<N: Scalar, R: Dim> MatrixMN<N, R, Dynamic> impl<T: Scalar, R: Dim> OMatrix<T, R, Dynamic>
where where
DefaultAllocator: Allocator<N, R, Dynamic>, DefaultAllocator: Allocator<T, R, Dynamic>,
{ {
/// Changes the number of column of this matrix in-place. /// Changes the number of column of this matrix in-place.
/// ///
@ -944,9 +949,9 @@ where
/// ///
/// Defined only for owned matrices with a dynamic number of columns (for example, `DVector`). /// Defined only for owned matrices with a dynamic number of columns (for example, `DVector`).
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn resize_horizontally_mut(&mut self, new_ncols: usize, val: N) pub fn resize_horizontally_mut(&mut self, new_ncols: usize, val: T)
where where
DefaultAllocator: Reallocator<N, R, Dynamic, R, Dynamic>, DefaultAllocator: Reallocator<T, R, Dynamic, R, Dynamic>,
{ {
let placeholder = unsafe { let placeholder = unsafe {
crate::unimplemented_or_uninitialized_generic!(self.data.shape().0, Dynamic::new(0)) crate::unimplemented_or_uninitialized_generic!(self.data.shape().0, Dynamic::new(0))
@ -957,8 +962,8 @@ where
} }
} }
unsafe fn compress_rows<N: Scalar>( unsafe fn compress_rows<T: Scalar>(
data: &mut [N], data: &mut [T],
nrows: usize, nrows: usize,
ncols: usize, ncols: usize,
i: usize, i: usize,
@ -996,8 +1001,8 @@ unsafe fn compress_rows<N: Scalar>(
// Moves entries of a matrix buffer to make place for `ninsert` emty rows starting at the `i-th` row index. // Moves entries of a matrix buffer to make place for `ninsert` emty rows starting at the `i-th` row index.
// The `data` buffer is assumed to contained at least `(nrows + ninsert) * ncols` elements. // The `data` buffer is assumed to contained at least `(nrows + ninsert) * ncols` elements.
unsafe fn extend_rows<N: Scalar>( unsafe fn extend_rows<T: Scalar>(
data: &mut [N], data: &mut [T],
nrows: usize, nrows: usize,
ncols: usize, ncols: usize,
i: usize, i: usize,
@ -1032,18 +1037,18 @@ unsafe fn extend_rows<N: Scalar>(
/// Extend the number of columns of the `Matrix` with elements from /// Extend the number of columns of the `Matrix` with elements from
/// a given iterator. /// a given iterator.
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<N, R, S> Extend<N> for Matrix<N, R, Dynamic, S> impl<T, R, S> Extend<T> for Matrix<T, R, Dynamic, S>
where where
N: Scalar, T: Scalar,
R: Dim, R: Dim,
S: Extend<N>, S: Extend<T>,
{ {
/// Extend the number of columns of the `Matrix` with elements /// Extend the number of columns of the `Matrix` with elements
/// from the given iterator. /// from the given iterator.
/// ///
/// # Example /// # Example
/// ``` /// ```
/// # use nalgebra::{DMatrix, Dynamic, Matrix, MatrixMN, Matrix3}; /// # use nalgebra::{DMatrix, Dynamic, Matrix, OMatrix, Matrix3};
/// ///
/// let data = vec![0, 1, 2, // column 1 /// let data = vec![0, 1, 2, // column 1
/// 3, 4, 5]; // column 2 /// 3, 4, 5]; // column 2
@ -1063,7 +1068,7 @@ where
/// `Matrix`. /// `Matrix`.
/// ///
/// ```should_panic /// ```should_panic
/// # use nalgebra::{DMatrix, Dynamic, MatrixMN}; /// # use nalgebra::{DMatrix, Dynamic, OMatrix};
/// let data = vec![0, 1, 2, // column 1 /// let data = vec![0, 1, 2, // column 1
/// 3, 4, 5]; // column 2 /// 3, 4, 5]; // column 2
/// ///
@ -1072,7 +1077,7 @@ where
/// // The following panics because the vec length is not a multiple of 3. /// // The following panics because the vec length is not a multiple of 3.
/// matrix.extend(vec![6, 7, 8, 9]); /// matrix.extend(vec![6, 7, 8, 9]);
/// ``` /// ```
fn extend<I: IntoIterator<Item = N>>(&mut self, iter: I) { fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
self.data.extend(iter); self.data.extend(iter);
} }
} }
@ -1080,10 +1085,10 @@ where
/// Extend the number of rows of the `Vector` with elements from /// Extend the number of rows of the `Vector` with elements from
/// a given iterator. /// a given iterator.
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<N, S> Extend<N> for Matrix<N, Dynamic, U1, S> impl<T, S> Extend<T> for Matrix<T, Dynamic, U1, S>
where where
N: Scalar, T: Scalar,
S: Extend<N>, S: Extend<T>,
{ {
/// Extend the number of rows of a `Vector` with elements /// Extend the number of rows of a `Vector` with elements
/// from the given iterator. /// from the given iterator.
@ -1095,19 +1100,19 @@ where
/// vector.extend(vec![3, 4, 5]); /// vector.extend(vec![3, 4, 5]);
/// assert!(vector.eq(&DVector::from_vec(vec![0, 1, 2, 3, 4, 5]))); /// assert!(vector.eq(&DVector::from_vec(vec![0, 1, 2, 3, 4, 5])));
/// ``` /// ```
fn extend<I: IntoIterator<Item = N>>(&mut self, iter: I) { fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
self.data.extend(iter); self.data.extend(iter);
} }
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<N, R, S, RV, SV> Extend<Vector<N, RV, SV>> for Matrix<N, R, Dynamic, S> impl<T, R, S, RV, SV> Extend<Vector<T, RV, SV>> for Matrix<T, R, Dynamic, S>
where where
N: Scalar, T: Scalar,
R: Dim, R: Dim,
S: Extend<Vector<N, RV, SV>>, S: Extend<Vector<T, RV, SV>>,
RV: Dim, RV: Dim,
SV: Storage<N, RV>, SV: Storage<T, RV>,
ShapeConstraint: SameNumberOfRows<R, RV>, ShapeConstraint: SameNumberOfRows<R, RV>,
{ {
/// Extends the number of columns of a `Matrix` with `Vector`s /// Extends the number of columns of a `Matrix` with `Vector`s
@ -1159,7 +1164,7 @@ where
/// matrix.extend( /// matrix.extend(
/// vec![Vector4::new(6, 7, 8, 9)]); // too few dimensions! /// vec![Vector4::new(6, 7, 8, 9)]); // too few dimensions!
/// ``` /// ```
fn extend<I: IntoIterator<Item = Vector<N, RV, SV>>>(&mut self, iter: I) { fn extend<I: IntoIterator<Item = Vector<T, RV, SV>>>(&mut self, iter: I) {
self.data.extend(iter); self.data.extend(iter);
} }
} }

View File

@ -7,7 +7,7 @@ use crate::base::{
use std::ops; use std::ops;
// N.B.: Not a public trait! // T.B.: Not a public trait!
trait DimRange<D: Dim> { trait DimRange<D: Dim> {
/// The number of elements indexed by this range. /// The number of elements indexed by this range.
type Length: Dim; type Length: Dim;
@ -315,19 +315,19 @@ fn dimrange_rangetoinclusive_usize() {
} }
/// A helper trait used for indexing operations. /// A helper trait used for indexing operations.
pub trait MatrixIndex<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>>: Sized { pub trait MatrixIndex<'a, T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>>: Sized {
/// The output type returned by methods. /// The output type returned by methods.
type Output: 'a; type Output: 'a;
/// Produces true if the given matrix is contained by this index. /// Produces true if the given matrix is contained by this index.
#[doc(hidden)] #[doc(hidden)]
fn contained_by(&self, matrix: &Matrix<N, R, C, S>) -> bool; fn contained_by(&self, matrix: &Matrix<T, R, C, S>) -> bool;
/// Produces a shared view of the data at this location if in bounds, /// Produces a shared view of the data at this location if in bounds,
/// or `None`, otherwise. /// or `None`, otherwise.
#[doc(hidden)] #[doc(hidden)]
#[inline(always)] #[inline(always)]
fn get(self, matrix: &'a Matrix<N, R, C, S>) -> Option<Self::Output> { fn get(self, matrix: &'a Matrix<T, R, C, S>) -> Option<Self::Output> {
if self.contained_by(matrix) { if self.contained_by(matrix) {
Some(unsafe { self.get_unchecked(matrix) }) Some(unsafe { self.get_unchecked(matrix) })
} else { } else {
@ -338,20 +338,20 @@ pub trait MatrixIndex<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>>: Sized
/// Produces a shared view of the data at this location if in bounds /// Produces a shared view of the data at this location if in bounds
/// without any bounds checking. /// without any bounds checking.
#[doc(hidden)] #[doc(hidden)]
unsafe fn get_unchecked(self, matrix: &'a Matrix<N, R, C, S>) -> Self::Output; unsafe fn get_unchecked(self, matrix: &'a Matrix<T, R, C, S>) -> Self::Output;
/// Produces a shared view to the data at this location, or panics /// Produces a shared view to the data at this location, or panics
/// if out of bounds. /// if out of bounds.
#[doc(hidden)] #[doc(hidden)]
#[inline(always)] #[inline(always)]
fn index(self, matrix: &'a Matrix<N, R, C, S>) -> Self::Output { fn index(self, matrix: &'a Matrix<T, R, C, S>) -> Self::Output {
self.get(matrix).expect("Index out of bounds.") self.get(matrix).expect("Index out of bounds.")
} }
} }
/// A helper trait used for indexing operations. /// A helper trait used for indexing operations.
pub trait MatrixIndexMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>>: pub trait MatrixIndexMut<'a, T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>>:
MatrixIndex<'a, N, R, C, S> MatrixIndex<'a, T, R, C, S>
{ {
/// The output type returned by methods. /// The output type returned by methods.
type OutputMut: 'a; type OutputMut: 'a;
@ -359,13 +359,13 @@ pub trait MatrixIndexMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>>:
/// Produces a mutable view of the data at this location, without /// Produces a mutable view of the data at this location, without
/// performing any bounds checking. /// performing any bounds checking.
#[doc(hidden)] #[doc(hidden)]
unsafe fn get_unchecked_mut(self, matrix: &'a mut Matrix<N, R, C, S>) -> Self::OutputMut; unsafe fn get_unchecked_mut(self, matrix: &'a mut Matrix<T, R, C, S>) -> Self::OutputMut;
/// Produces a mutable view of the data at this location, if in /// Produces a mutable view of the data at this location, if in
/// bounds. /// bounds.
#[doc(hidden)] #[doc(hidden)]
#[inline(always)] #[inline(always)]
fn get_mut(self, matrix: &'a mut Matrix<N, R, C, S>) -> Option<Self::OutputMut> { fn get_mut(self, matrix: &'a mut Matrix<T, R, C, S>) -> Option<Self::OutputMut> {
if self.contained_by(matrix) { if self.contained_by(matrix) {
Some(unsafe { self.get_unchecked_mut(matrix) }) Some(unsafe { self.get_unchecked_mut(matrix) })
} else { } else {
@ -377,7 +377,7 @@ pub trait MatrixIndexMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>>:
/// if out of bounds. /// if out of bounds.
#[doc(hidden)] #[doc(hidden)]
#[inline(always)] #[inline(always)]
fn index_mut(self, matrix: &'a mut Matrix<N, R, C, S>) -> Self::OutputMut { fn index_mut(self, matrix: &'a mut Matrix<T, R, C, S>) -> Self::OutputMut {
self.get_mut(matrix).expect("Index out of bounds.") self.get_mut(matrix).expect("Index out of bounds.")
} }
} }
@ -481,13 +481,13 @@ pub trait MatrixIndexMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>>:
/// 4, 7, /// 4, 7,
/// 5, 8))); /// 5, 8)));
/// ``` /// ```
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> { impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
/// Produces a view of the data at the given index, or /// Produces a view of the data at the given index, or
/// `None` if the index is out of bounds. /// `None` if the index is out of bounds.
#[inline] #[inline]
pub fn get<'a, I>(&'a self, index: I) -> Option<I::Output> pub fn get<'a, I>(&'a self, index: I) -> Option<I::Output>
where where
I: MatrixIndex<'a, N, R, C, S>, I: MatrixIndex<'a, T, R, C, S>,
{ {
index.get(self) index.get(self)
} }
@ -497,8 +497,8 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
#[inline] #[inline]
pub fn get_mut<'a, I>(&'a mut self, index: I) -> Option<I::OutputMut> pub fn get_mut<'a, I>(&'a mut self, index: I) -> Option<I::OutputMut>
where where
S: StorageMut<N, R, C>, S: StorageMut<T, R, C>,
I: MatrixIndexMut<'a, N, R, C, S>, I: MatrixIndexMut<'a, T, R, C, S>,
{ {
index.get_mut(self) index.get_mut(self)
} }
@ -508,7 +508,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
#[inline] #[inline]
pub fn index<'a, I>(&'a self, index: I) -> I::Output pub fn index<'a, I>(&'a self, index: I) -> I::Output
where where
I: MatrixIndex<'a, N, R, C, S>, I: MatrixIndex<'a, T, R, C, S>,
{ {
index.index(self) index.index(self)
} }
@ -518,8 +518,8 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
#[inline] #[inline]
pub fn index_mut<'a, I>(&'a mut self, index: I) -> I::OutputMut pub fn index_mut<'a, I>(&'a mut self, index: I) -> I::OutputMut
where where
S: StorageMut<N, R, C>, S: StorageMut<T, R, C>,
I: MatrixIndexMut<'a, N, R, C, S>, I: MatrixIndexMut<'a, T, R, C, S>,
{ {
index.index_mut(self) index.index_mut(self)
} }
@ -529,7 +529,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
#[inline] #[inline]
pub unsafe fn get_unchecked<'a, I>(&'a self, index: I) -> I::Output pub unsafe fn get_unchecked<'a, I>(&'a self, index: I) -> I::Output
where where
I: MatrixIndex<'a, N, R, C, S>, I: MatrixIndex<'a, T, R, C, S>,
{ {
index.get_unchecked(self) index.get_unchecked(self)
} }
@ -539,8 +539,8 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
#[inline] #[inline]
pub unsafe fn get_unchecked_mut<'a, I>(&'a mut self, index: I) -> I::OutputMut pub unsafe fn get_unchecked_mut<'a, I>(&'a mut self, index: I) -> I::OutputMut
where where
S: StorageMut<N, R, C>, S: StorageMut<T, R, C>,
I: MatrixIndexMut<'a, N, R, C, S>, I: MatrixIndexMut<'a, T, R, C, S>,
{ {
index.get_unchecked_mut(self) index.get_unchecked_mut(self)
} }
@ -548,42 +548,42 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
// EXTRACT A SINGLE ELEMENT BY 1D LINEAR ADDRESS // EXTRACT A SINGLE ELEMENT BY 1D LINEAR ADDRESS
impl<'a, N, R, C, S> MatrixIndex<'a, N, R, C, S> for usize impl<'a, T, R, C, S> MatrixIndex<'a, T, R, C, S> for usize
where where
N: Scalar, T: Scalar,
R: Dim, R: Dim,
C: Dim, C: Dim,
S: Storage<N, R, C>, S: Storage<T, R, C>,
{ {
type Output = &'a N; type Output = &'a T;
#[doc(hidden)] #[doc(hidden)]
#[inline(always)] #[inline(always)]
fn contained_by(&self, matrix: &Matrix<N, R, C, S>) -> bool { fn contained_by(&self, matrix: &Matrix<T, R, C, S>) -> bool {
*self < matrix.len() *self < matrix.len()
} }
#[doc(hidden)] #[doc(hidden)]
#[inline(always)] #[inline(always)]
unsafe fn get_unchecked(self, matrix: &'a Matrix<N, R, C, S>) -> Self::Output { unsafe fn get_unchecked(self, matrix: &'a Matrix<T, R, C, S>) -> Self::Output {
matrix.data.get_unchecked_linear(self) matrix.data.get_unchecked_linear(self)
} }
} }
impl<'a, N, R, C, S> MatrixIndexMut<'a, N, R, C, S> for usize impl<'a, T, R, C, S> MatrixIndexMut<'a, T, R, C, S> for usize
where where
N: Scalar, T: Scalar,
R: Dim, R: Dim,
C: Dim, C: Dim,
S: StorageMut<N, R, C>, S: StorageMut<T, R, C>,
{ {
type OutputMut = &'a mut N; type OutputMut = &'a mut T;
#[doc(hidden)] #[doc(hidden)]
#[inline(always)] #[inline(always)]
unsafe fn get_unchecked_mut(self, matrix: &'a mut Matrix<N, R, C, S>) -> Self::OutputMut unsafe fn get_unchecked_mut(self, matrix: &'a mut Matrix<T, R, C, S>) -> Self::OutputMut
where where
S: StorageMut<N, R, C>, S: StorageMut<T, R, C>,
{ {
matrix.data.get_unchecked_linear_mut(self) matrix.data.get_unchecked_linear_mut(self)
} }
@ -591,18 +591,18 @@ where
// EXTRACT A SINGLE ELEMENT BY 2D COORDINATES // EXTRACT A SINGLE ELEMENT BY 2D COORDINATES
impl<'a, N, R, C, S> MatrixIndex<'a, N, R, C, S> for (usize, usize) impl<'a, T, R, C, S> MatrixIndex<'a, T, R, C, S> for (usize, usize)
where where
N: Scalar, T: Scalar,
R: Dim, R: Dim,
C: Dim, C: Dim,
S: Storage<N, R, C>, S: Storage<T, R, C>,
{ {
type Output = &'a N; type Output = &'a T;
#[doc(hidden)] #[doc(hidden)]
#[inline(always)] #[inline(always)]
fn contained_by(&self, matrix: &Matrix<N, R, C, S>) -> bool { fn contained_by(&self, matrix: &Matrix<T, R, C, S>) -> bool {
let (rows, cols) = self; let (rows, cols) = self;
let (nrows, ncols) = matrix.data.shape(); let (nrows, ncols) = matrix.data.shape();
DimRange::contained_by(rows, nrows) && DimRange::contained_by(cols, ncols) DimRange::contained_by(rows, nrows) && DimRange::contained_by(cols, ncols)
@ -610,26 +610,26 @@ where
#[doc(hidden)] #[doc(hidden)]
#[inline(always)] #[inline(always)]
unsafe fn get_unchecked(self, matrix: &'a Matrix<N, R, C, S>) -> Self::Output { unsafe fn get_unchecked(self, matrix: &'a Matrix<T, R, C, S>) -> Self::Output {
let (row, col) = self; let (row, col) = self;
matrix.data.get_unchecked(row, col) matrix.data.get_unchecked(row, col)
} }
} }
impl<'a, N, R, C, S> MatrixIndexMut<'a, N, R, C, S> for (usize, usize) impl<'a, T, R, C, S> MatrixIndexMut<'a, T, R, C, S> for (usize, usize)
where where
N: Scalar, T: Scalar,
R: Dim, R: Dim,
C: Dim, C: Dim,
S: StorageMut<N, R, C>, S: StorageMut<T, R, C>,
{ {
type OutputMut = &'a mut N; type OutputMut = &'a mut T;
#[doc(hidden)] #[doc(hidden)]
#[inline(always)] #[inline(always)]
unsafe fn get_unchecked_mut(self, matrix: &'a mut Matrix<N, R, C, S>) -> Self::OutputMut unsafe fn get_unchecked_mut(self, matrix: &'a mut Matrix<T, R, C, S>) -> Self::OutputMut
where where
S: StorageMut<N, R, C>, S: StorageMut<T, R, C>,
{ {
let (row, col) = self; let (row, col) = self;
matrix.data.get_unchecked_mut(row, col) matrix.data.get_unchecked_mut(row, col)
@ -655,20 +655,20 @@ macro_rules! impl_index_pair {
$(where $CConstraintType: ty: $CConstraintBound: ident $(<$($CConstraintBoundParams: ty $( = $CEqBound: ty )*),*>)* )*] $(where $CConstraintType: ty: $CConstraintBound: ident $(<$($CConstraintBoundParams: ty $( = $CEqBound: ty )*),*>)* )*]
) => ) =>
{ {
impl<'a, N, $R, $C, S, $($RTyP : $RTyPB,)* $($CTyP : $CTyPB),*> MatrixIndex<'a, N, $R, $C, S> for ($RIdx, $CIdx) impl<'a, T, $R, $C, S, $($RTyP : $RTyPB,)* $($CTyP : $CTyPB),*> MatrixIndex<'a, T, $R, $C, S> for ($RIdx, $CIdx)
where where
N: Scalar, T: Scalar,
$R: Dim, $R: Dim,
$C: Dim, $C: Dim,
S: Storage<N, R, C>, S: Storage<T, R, C>,
$( $RConstraintType: $RConstraintBound $(<$( $RConstraintBoundParams $( = $REqBound )*),*>)* ,)* $( $RConstraintType: $RConstraintBound $(<$( $RConstraintBoundParams $( = $REqBound )*),*>)* ,)*
$( $CConstraintType: $CConstraintBound $(<$( $CConstraintBoundParams $( = $CEqBound )*),*>)* ),* $( $CConstraintType: $CConstraintBound $(<$( $CConstraintBoundParams $( = $CEqBound )*),*>)* ),*
{ {
type Output = MatrixSlice<'a, N, $ROut, $COut, S::RStride, S::CStride>; type Output = MatrixSlice<'a, T, $ROut, $COut, S::RStride, S::CStride>;
#[doc(hidden)] #[doc(hidden)]
#[inline(always)] #[inline(always)]
fn contained_by(&self, matrix: &Matrix<N, $R, $C, S>) -> bool { fn contained_by(&self, matrix: &Matrix<T, $R, $C, S>) -> bool {
let (rows, cols) = self; let (rows, cols) = self;
let (nrows, ncols) = matrix.data.shape(); let (nrows, ncols) = matrix.data.shape();
DimRange::contained_by(rows, nrows) && DimRange::contained_by(cols, ncols) DimRange::contained_by(rows, nrows) && DimRange::contained_by(cols, ncols)
@ -676,7 +676,7 @@ macro_rules! impl_index_pair {
#[doc(hidden)] #[doc(hidden)]
#[inline(always)] #[inline(always)]
unsafe fn get_unchecked(self, matrix: &'a Matrix<N, $R, $C, S>) -> Self::Output { unsafe fn get_unchecked(self, matrix: &'a Matrix<T, $R, $C, S>) -> Self::Output {
use crate::base::SliceStorage; use crate::base::SliceStorage;
let (rows, cols) = self; let (rows, cols) = self;
@ -691,20 +691,20 @@ macro_rules! impl_index_pair {
} }
} }
impl<'a, N, $R, $C, S, $($RTyP : $RTyPB,)* $($CTyP : $CTyPB),*> MatrixIndexMut<'a, N, $R, $C, S> for ($RIdx, $CIdx) impl<'a, T, $R, $C, S, $($RTyP : $RTyPB,)* $($CTyP : $CTyPB),*> MatrixIndexMut<'a, T, $R, $C, S> for ($RIdx, $CIdx)
where where
N: Scalar, T: Scalar,
$R: Dim, $R: Dim,
$C: Dim, $C: Dim,
S: StorageMut<N, R, C>, S: StorageMut<T, R, C>,
$( $RConstraintType: $RConstraintBound $(<$( $RConstraintBoundParams $( = $REqBound )*),*>)* ,)* $( $RConstraintType: $RConstraintBound $(<$( $RConstraintBoundParams $( = $REqBound )*),*>)* ,)*
$( $CConstraintType: $CConstraintBound $(<$( $CConstraintBoundParams $( = $CEqBound )*),*>)* ),* $( $CConstraintType: $CConstraintBound $(<$( $CConstraintBoundParams $( = $CEqBound )*),*>)* ),*
{ {
type OutputMut = MatrixSliceMut<'a, N, $ROut, $COut, S::RStride, S::CStride>; type OutputMut = MatrixSliceMut<'a, T, $ROut, $COut, S::RStride, S::CStride>;
#[doc(hidden)] #[doc(hidden)]
#[inline(always)] #[inline(always)]
unsafe fn get_unchecked_mut(self, matrix: &'a mut Matrix<N, $R, $C, S>) -> Self::OutputMut { unsafe fn get_unchecked_mut(self, matrix: &'a mut Matrix<T, $R, $C, S>) -> Self::OutputMut {
use crate::base::SliceStorageMut; use crate::base::SliceStorageMut;
let (rows, cols) = self; let (rows, cols) = self;

View File

@ -1,12 +1,12 @@
use crate::storage::Storage; use crate::storage::Storage;
use crate::{ use crate::{
Allocator, DefaultAllocator, Dim, One, RealField, Scalar, Unit, Vector, VectorN, Zero, Allocator, DefaultAllocator, Dim, OVector, One, RealField, Scalar, Unit, Vector, Zero,
}; };
use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub}; use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub};
/// # Interpolation /// # Interpolation
impl<N: Scalar + Zero + One + ClosedAdd + ClosedSub + ClosedMul, D: Dim, S: Storage<N, D>> impl<T: Scalar + Zero + One + ClosedAdd + ClosedSub + ClosedMul, D: Dim, S: Storage<T, D>>
Vector<N, D, S> Vector<T, D, S>
{ {
/// Returns `self * (1.0 - t) + rhs * t`, i.e., the linear blend of the vectors x and y using the scalar value a. /// Returns `self * (1.0 - t) + rhs * t`, i.e., the linear blend of the vectors x and y using the scalar value a.
/// ///
@ -20,12 +20,12 @@ impl<N: Scalar + Zero + One + ClosedAdd + ClosedSub + ClosedMul, D: Dim, S: Stor
/// let y = Vector3::new(10.0, 20.0, 30.0); /// let y = Vector3::new(10.0, 20.0, 30.0);
/// assert_eq!(x.lerp(&y, 0.1), Vector3::new(1.9, 3.8, 5.7)); /// assert_eq!(x.lerp(&y, 0.1), Vector3::new(1.9, 3.8, 5.7));
/// ``` /// ```
pub fn lerp<S2: Storage<N, D>>(&self, rhs: &Vector<N, D, S2>, t: N) -> VectorN<N, D> pub fn lerp<S2: Storage<T, D>>(&self, rhs: &Vector<T, D, S2>, t: T) -> OVector<T, D>
where where
DefaultAllocator: Allocator<N, D>, DefaultAllocator: Allocator<T, D>,
{ {
let mut res = self.clone_owned(); let mut res = self.clone_owned();
res.axpy(t.inlined_clone(), rhs, N::one() - t); res.axpy(t.inlined_clone(), rhs, T::one() - t);
res res
} }
@ -45,10 +45,10 @@ impl<N: Scalar + Zero + One + ClosedAdd + ClosedSub + ClosedMul, D: Dim, S: Stor
/// ///
/// assert_eq!(v, v2.normalize()); /// assert_eq!(v, v2.normalize());
/// ``` /// ```
pub fn slerp<S2: Storage<N, D>>(&self, rhs: &Vector<N, D, S2>, t: N) -> VectorN<N, D> pub fn slerp<S2: Storage<T, D>>(&self, rhs: &Vector<T, D, S2>, t: T) -> OVector<T, D>
where where
N: RealField, T: RealField,
DefaultAllocator: Allocator<N, D>, DefaultAllocator: Allocator<T, D>,
{ {
let me = Unit::new_normalize(self.clone_owned()); let me = Unit::new_normalize(self.clone_owned());
let rhs = Unit::new_normalize(rhs.clone_owned()); let rhs = Unit::new_normalize(rhs.clone_owned());
@ -57,7 +57,7 @@ impl<N: Scalar + Zero + One + ClosedAdd + ClosedSub + ClosedMul, D: Dim, S: Stor
} }
/// # Interpolation between two unit vectors /// # Interpolation between two unit vectors
impl<N: RealField, D: Dim, S: Storage<N, D>> Unit<Vector<N, D, S>> { impl<T: RealField, D: Dim, S: Storage<T, D>> Unit<Vector<T, D, S>> {
/// Computes the spherical linear interpolation between two unit vectors. /// Computes the spherical linear interpolation between two unit vectors.
/// ///
/// # Examples: /// # Examples:
@ -72,16 +72,16 @@ impl<N: RealField, D: Dim, S: Storage<N, D>> Unit<Vector<N, D, S>> {
/// ///
/// assert_eq!(v, v2); /// assert_eq!(v, v2);
/// ``` /// ```
pub fn slerp<S2: Storage<N, D>>( pub fn slerp<S2: Storage<T, D>>(
&self, &self,
rhs: &Unit<Vector<N, D, S2>>, rhs: &Unit<Vector<T, D, S2>>,
t: N, t: T,
) -> Unit<VectorN<N, D>> ) -> Unit<OVector<T, D>>
where where
DefaultAllocator: Allocator<N, D>, DefaultAllocator: Allocator<T, D>,
{ {
// TODO: the result is wrong when self and rhs are collinear with opposite direction. // TODO: the result is wrong when self and rhs are collinear with opposite direction.
self.try_slerp(rhs, t, N::default_epsilon()) self.try_slerp(rhs, t, T::default_epsilon())
.unwrap_or_else(|| Unit::new_unchecked(self.clone_owned())) .unwrap_or_else(|| Unit::new_unchecked(self.clone_owned()))
} }
@ -89,33 +89,33 @@ impl<N: RealField, D: Dim, S: Storage<N, D>> Unit<Vector<N, D, S>> {
/// ///
/// Returns `None` if the two vectors are almost collinear and with opposite direction /// Returns `None` if the two vectors are almost collinear and with opposite direction
/// (in this case, there is an infinity of possible results). /// (in this case, there is an infinity of possible results).
pub fn try_slerp<S2: Storage<N, D>>( pub fn try_slerp<S2: Storage<T, D>>(
&self, &self,
rhs: &Unit<Vector<N, D, S2>>, rhs: &Unit<Vector<T, D, S2>>,
t: N, t: T,
epsilon: N, epsilon: T,
) -> Option<Unit<VectorN<N, D>>> ) -> Option<Unit<OVector<T, D>>>
where where
DefaultAllocator: Allocator<N, D>, DefaultAllocator: Allocator<T, D>,
{ {
let c_hang = self.dot(rhs); let c_hang = self.dot(rhs);
// self == other // self == other
if c_hang >= N::one() { if c_hang >= T::one() {
return Some(Unit::new_unchecked(self.clone_owned())); return Some(Unit::new_unchecked(self.clone_owned()));
} }
let hang = c_hang.acos(); let hang = c_hang.acos();
let s_hang = (N::one() - c_hang * c_hang).sqrt(); let s_hang = (T::one() - c_hang * c_hang).sqrt();
// TODO: what if s_hang is 0.0 ? The result is not well-defined. // TODO: what if s_hang is 0.0 ? The result is not well-defined.
if relative_eq!(s_hang, N::zero(), epsilon = epsilon) { if relative_eq!(s_hang, T::zero(), epsilon = epsilon) {
None None
} else { } else {
let ta = ((N::one() - t) * hang).sin() / s_hang; let ta = ((T::one() - t) * hang).sin() / s_hang;
let tb = (t * hang).sin() / s_hang; let tb = (t * hang).sin() / s_hang;
let mut res = self.scale(ta); let mut res = self.scale(ta);
res.axpy(tb, &**rhs, N::one()); res.axpy(tb, &**rhs, T::one());
Some(Unit::new_unchecked(res)) Some(Unit::new_unchecked(res))
} }

View File

@ -11,7 +11,7 @@ use crate::base::{Matrix, MatrixSlice, MatrixSliceMut, Scalar};
macro_rules! iterator { macro_rules! iterator {
(struct $Name:ident for $Storage:ident.$ptr: ident -> $Ptr:ty, $Ref:ty, $SRef: ty) => { (struct $Name:ident for $Storage:ident.$ptr: ident -> $Ptr:ty, $Ref:ty, $SRef: ty) => {
/// An iterator through a dense matrix with arbitrary strides matrix. /// An iterator through a dense matrix with arbitrary strides matrix.
pub struct $Name<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage<N, R, C>> { pub struct $Name<'a, T: Scalar, R: Dim, C: Dim, S: 'a + $Storage<T, R, C>> {
ptr: $Ptr, ptr: $Ptr,
inner_ptr: $Ptr, inner_ptr: $Ptr,
inner_end: $Ptr, inner_end: $Ptr,
@ -22,9 +22,9 @@ macro_rules! iterator {
// TODO: we need to specialize for the case where the matrix storage is owned (in which // TODO: we need to specialize for the case where the matrix storage is owned (in which
// case the iterator is trivial because it does not have any stride). // case the iterator is trivial because it does not have any stride).
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage<N, R, C>> $Name<'a, N, R, C, S> { impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + $Storage<T, R, C>> $Name<'a, T, R, C, S> {
/// Creates a new iterator for the given matrix storage. /// Creates a new iterator for the given matrix storage.
pub fn new(storage: $SRef) -> $Name<'a, N, R, C, S> { pub fn new(storage: $SRef) -> $Name<'a, T, R, C, S> {
let shape = storage.shape(); let shape = storage.shape();
let strides = storage.strides(); let strides = storage.strides();
let inner_offset = shape.0.value() * strides.0.value(); let inner_offset = shape.0.value() * strides.0.value();
@ -59,8 +59,8 @@ macro_rules! iterator {
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage<N, R, C>> Iterator impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + $Storage<T, R, C>> Iterator
for $Name<'a, N, R, C, S> for $Name<'a, T, R, C, S>
{ {
type Item = $Ref; type Item = $Ref;
@ -112,8 +112,8 @@ macro_rules! iterator {
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage<N, R, C>> DoubleEndedIterator impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + $Storage<T, R, C>> DoubleEndedIterator
for $Name<'a, N, R, C, S> for $Name<'a, T, R, C, S>
{ {
#[inline] #[inline]
fn next_back(&mut self) -> Option<$Ref> { fn next_back(&mut self) -> Option<$Ref> {
@ -152,8 +152,8 @@ macro_rules! iterator {
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage<N, R, C>> ExactSizeIterator impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + $Storage<T, R, C>> ExactSizeIterator
for $Name<'a, N, R, C, S> for $Name<'a, T, R, C, S>
{ {
#[inline] #[inline]
fn len(&self) -> usize { fn len(&self) -> usize {
@ -161,15 +161,15 @@ macro_rules! iterator {
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + $Storage<N, R, C>> FusedIterator impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + $Storage<T, R, C>> FusedIterator
for $Name<'a, N, R, C, S> for $Name<'a, T, R, C, S>
{ {
} }
}; };
} }
iterator!(struct MatrixIter for Storage.ptr -> *const N, &'a N, &'a S); iterator!(struct MatrixIter for Storage.ptr -> *const T, &'a T, &'a S);
iterator!(struct MatrixIterMut for StorageMut.ptr_mut -> *mut N, &'a mut N, &'a mut S); iterator!(struct MatrixIterMut for StorageMut.ptr_mut -> *mut T, &'a mut T, &'a mut S);
/* /*
* *
@ -178,19 +178,19 @@ iterator!(struct MatrixIterMut for StorageMut.ptr_mut -> *mut N, &'a mut N, &'a
*/ */
#[derive(Clone)] #[derive(Clone)]
/// An iterator through the rows of a matrix. /// An iterator through the rows of a matrix.
pub struct RowIter<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> { pub struct RowIter<'a, T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> {
mat: &'a Matrix<N, R, C, S>, mat: &'a Matrix<T, R, C, S>,
curr: usize, curr: usize,
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> RowIter<'a, N, R, C, S> { impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + Storage<T, R, C>> RowIter<'a, T, R, C, S> {
pub(crate) fn new(mat: &'a Matrix<N, R, C, S>) -> Self { pub(crate) fn new(mat: &'a Matrix<T, R, C, S>) -> Self {
RowIter { mat, curr: 0 } RowIter { mat, curr: 0 }
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> Iterator for RowIter<'a, N, R, C, S> { impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + Storage<T, R, C>> Iterator for RowIter<'a, T, R, C, S> {
type Item = MatrixSlice<'a, N, U1, C, S::RStride, S::CStride>; type Item = MatrixSlice<'a, T, U1, C, S::RStride, S::CStride>;
#[inline] #[inline]
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
@ -217,8 +217,8 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> Iterator for RowIt
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> ExactSizeIterator impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + Storage<T, R, C>> ExactSizeIterator
for RowIter<'a, N, R, C, S> for RowIter<'a, T, R, C, S>
{ {
#[inline] #[inline]
fn len(&self) -> usize { fn len(&self) -> usize {
@ -227,14 +227,14 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> ExactSizeIterator
} }
/// An iterator through the mutable rows of a matrix. /// An iterator through the mutable rows of a matrix.
pub struct RowIterMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> { pub struct RowIterMut<'a, T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> {
mat: *mut Matrix<N, R, C, S>, mat: *mut Matrix<T, R, C, S>,
curr: usize, curr: usize,
phantom: PhantomData<&'a mut Matrix<N, R, C, S>>, phantom: PhantomData<&'a mut Matrix<T, R, C, S>>,
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> RowIterMut<'a, N, R, C, S> { impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<T, R, C>> RowIterMut<'a, T, R, C, S> {
pub(crate) fn new(mat: &'a mut Matrix<N, R, C, S>) -> Self { pub(crate) fn new(mat: &'a mut Matrix<T, R, C, S>) -> Self {
RowIterMut { RowIterMut {
mat, mat,
curr: 0, curr: 0,
@ -247,10 +247,10 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> RowIterMut<'a,
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> Iterator impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<T, R, C>> Iterator
for RowIterMut<'a, N, R, C, S> for RowIterMut<'a, T, R, C, S>
{ {
type Item = MatrixSliceMut<'a, N, U1, C, S::RStride, S::CStride>; type Item = MatrixSliceMut<'a, T, U1, C, S::RStride, S::CStride>;
#[inline] #[inline]
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
@ -274,8 +274,8 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> Iterator
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ExactSizeIterator impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<T, R, C>> ExactSizeIterator
for RowIterMut<'a, N, R, C, S> for RowIterMut<'a, T, R, C, S>
{ {
#[inline] #[inline]
fn len(&self) -> usize { fn len(&self) -> usize {
@ -290,21 +290,21 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ExactSizeIterat
*/ */
#[derive(Clone)] #[derive(Clone)]
/// An iterator through the columns of a matrix. /// An iterator through the columns of a matrix.
pub struct ColumnIter<'a, N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> { pub struct ColumnIter<'a, T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> {
mat: &'a Matrix<N, R, C, S>, mat: &'a Matrix<T, R, C, S>,
curr: usize, curr: usize,
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> ColumnIter<'a, N, R, C, S> { impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + Storage<T, R, C>> ColumnIter<'a, T, R, C, S> {
pub(crate) fn new(mat: &'a Matrix<N, R, C, S>) -> Self { pub(crate) fn new(mat: &'a Matrix<T, R, C, S>) -> Self {
ColumnIter { mat, curr: 0 } ColumnIter { mat, curr: 0 }
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> Iterator impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + Storage<T, R, C>> Iterator
for ColumnIter<'a, N, R, C, S> for ColumnIter<'a, T, R, C, S>
{ {
type Item = MatrixSlice<'a, N, R, U1, S::RStride, S::CStride>; type Item = MatrixSlice<'a, T, R, U1, S::RStride, S::CStride>;
#[inline] #[inline]
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
@ -331,8 +331,8 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> Iterator
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> ExactSizeIterator impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + Storage<T, R, C>> ExactSizeIterator
for ColumnIter<'a, N, R, C, S> for ColumnIter<'a, T, R, C, S>
{ {
#[inline] #[inline]
fn len(&self) -> usize { fn len(&self) -> usize {
@ -341,14 +341,14 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + Storage<N, R, C>> ExactSizeIterator
} }
/// An iterator through the mutable columns of a matrix. /// An iterator through the mutable columns of a matrix.
pub struct ColumnIterMut<'a, N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> { pub struct ColumnIterMut<'a, T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> {
mat: *mut Matrix<N, R, C, S>, mat: *mut Matrix<T, R, C, S>,
curr: usize, curr: usize,
phantom: PhantomData<&'a mut Matrix<N, R, C, S>>, phantom: PhantomData<&'a mut Matrix<T, R, C, S>>,
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ColumnIterMut<'a, N, R, C, S> { impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<T, R, C>> ColumnIterMut<'a, T, R, C, S> {
pub(crate) fn new(mat: &'a mut Matrix<N, R, C, S>) -> Self { pub(crate) fn new(mat: &'a mut Matrix<T, R, C, S>) -> Self {
ColumnIterMut { ColumnIterMut {
mat, mat,
curr: 0, curr: 0,
@ -361,10 +361,10 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ColumnIterMut<'
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> Iterator impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<T, R, C>> Iterator
for ColumnIterMut<'a, N, R, C, S> for ColumnIterMut<'a, T, R, C, S>
{ {
type Item = MatrixSliceMut<'a, N, R, U1, S::RStride, S::CStride>; type Item = MatrixSliceMut<'a, T, R, U1, S::RStride, S::CStride>;
#[inline] #[inline]
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
@ -388,8 +388,8 @@ impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> Iterator
} }
} }
impl<'a, N: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<N, R, C>> ExactSizeIterator impl<'a, T: Scalar, R: Dim, C: Dim, S: 'a + StorageMut<T, R, C>> ExactSizeIterator
for ColumnIterMut<'a, N, R, C, S> for ColumnIterMut<'a, T, R, C, S>
{ {
#[inline] #[inline]
fn len(&self) -> usize { fn len(&self) -> usize {

File diff suppressed because it is too large Load Diff

View File

@ -2,32 +2,32 @@ use simba::simd::SimdValue;
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::Dim; use crate::base::dimension::Dim;
use crate::base::{DefaultAllocator, MatrixMN, Scalar}; use crate::base::{DefaultAllocator, OMatrix, Scalar};
/* /*
* *
* Simd structures. * Simd structures.
* *
*/ */
impl<N, R, C> SimdValue for MatrixMN<N, R, C> impl<T, R, C> SimdValue for OMatrix<T, R, C>
where where
N: Scalar + SimdValue, T: Scalar + SimdValue,
R: Dim, R: Dim,
C: Dim, C: Dim,
N::Element: Scalar, T::Element: Scalar,
DefaultAllocator: Allocator<N, R, C> + Allocator<N::Element, R, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{ {
type Element = MatrixMN<N::Element, R, C>; type Element = OMatrix<T::Element, R, C>;
type SimdBool = N::SimdBool; type SimdBool = T::SimdBool;
#[inline] #[inline]
fn lanes() -> usize { fn lanes() -> usize {
N::lanes() T::lanes()
} }
#[inline] #[inline]
fn splat(val: Self::Element) -> Self { fn splat(val: Self::Element) -> Self {
val.map(N::splat) val.map(T::splat)
} }
#[inline] #[inline]

View File

@ -13,22 +13,22 @@ macro_rules! slice_storage_impl(
($doc: expr; $Storage: ident as $SRef: ty; $T: ident.$get_addr: ident ($Ptr: ty as $Ref: ty)) => { ($doc: expr; $Storage: ident as $SRef: ty; $T: ident.$get_addr: ident ($Ptr: ty as $Ref: ty)) => {
#[doc = $doc] #[doc = $doc]
#[derive(Debug)] #[derive(Debug)]
pub struct $T<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> { pub struct $T<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> {
ptr: $Ptr, ptr: $Ptr,
shape: (R, C), shape: (R, C),
strides: (RStride, CStride), strides: (RStride, CStride),
_phantoms: PhantomData<$Ref>, _phantoms: PhantomData<$Ref>,
} }
unsafe impl<'a, N: Scalar + Send, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Send unsafe impl<'a, T: Scalar + Send, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Send
for $T<'a, N, R, C, RStride, CStride> for $T<'a, T, R, C, RStride, CStride>
{} {}
unsafe impl<'a, N: Scalar + Sync, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Sync unsafe impl<'a, T: Scalar + Sync, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Sync
for $T<'a, N, R, C, RStride, CStride> for $T<'a, T, R, C, RStride, CStride>
{} {}
impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> $T<'a, N, R, C, RStride, CStride> { impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> $T<'a, T, R, C, RStride, CStride> {
/// Create a new matrix slice without bound checking and from a raw pointer. /// Create a new matrix slice without bound checking and from a raw pointer.
#[inline] #[inline]
pub unsafe fn from_raw_parts(ptr: $Ptr, pub unsafe fn from_raw_parts(ptr: $Ptr,
@ -48,14 +48,14 @@ macro_rules! slice_storage_impl(
} }
// Dynamic is arbitrary. It's just to be able to call the constructors with `Slice::` // Dynamic is arbitrary. It's just to be able to call the constructors with `Slice::`
impl<'a, N: Scalar, R: Dim, C: Dim> $T<'a, N, R, C, Dynamic, Dynamic> { impl<'a, T: Scalar, R: Dim, C: Dim> $T<'a, T, R, C, Dynamic, Dynamic> {
/// Create a new matrix slice without bound checking. /// Create a new matrix slice without bound checking.
#[inline] #[inline]
pub unsafe fn new_unchecked<RStor, CStor, S>(storage: $SRef, start: (usize, usize), shape: (R, C)) pub unsafe fn new_unchecked<RStor, CStor, S>(storage: $SRef, start: (usize, usize), shape: (R, C))
-> $T<'a, N, R, C, S::RStride, S::CStride> -> $T<'a, T, R, C, S::RStride, S::CStride>
where RStor: Dim, where RStor: Dim,
CStor: Dim, CStor: Dim,
S: $Storage<N, RStor, CStor> { S: $Storage<T, RStor, CStor> {
let strides = storage.strides(); let strides = storage.strides();
$T::new_with_strides_unchecked(storage, start, shape, strides) $T::new_with_strides_unchecked(storage, start, shape, strides)
@ -67,10 +67,10 @@ macro_rules! slice_storage_impl(
start: (usize, usize), start: (usize, usize),
shape: (R, C), shape: (R, C),
strides: (RStride, CStride)) strides: (RStride, CStride))
-> $T<'a, N, R, C, RStride, CStride> -> $T<'a, T, R, C, RStride, CStride>
where RStor: Dim, where RStor: Dim,
CStor: Dim, CStor: Dim,
S: $Storage<N, RStor, CStor>, S: $Storage<T, RStor, CStor>,
RStride: Dim, RStride: Dim,
CStride: Dim { CStride: Dim {
@ -82,20 +82,20 @@ macro_rules! slice_storage_impl(
slice_storage_impl!("A matrix data storage for a matrix slice. Only contains an internal reference \ slice_storage_impl!("A matrix data storage for a matrix slice. Only contains an internal reference \
to another matrix data storage."; to another matrix data storage.";
Storage as &'a S; SliceStorage.get_address_unchecked(*const N as &'a N)); Storage as &'a S; SliceStorage.get_address_unchecked(*const T as &'a T));
slice_storage_impl!("A mutable matrix data storage for mutable matrix slice. Only contains an \ slice_storage_impl!("A mutable matrix data storage for mutable matrix slice. Only contains an \
internal mutable reference to another matrix data storage."; internal mutable reference to another matrix data storage.";
StorageMut as &'a mut S; SliceStorageMut.get_address_unchecked_mut(*mut N as &'a mut N) StorageMut as &'a mut S; SliceStorageMut.get_address_unchecked_mut(*mut T as &'a mut T)
); );
impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Copy impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Copy
for SliceStorage<'a, N, R, C, RStride, CStride> for SliceStorage<'a, T, R, C, RStride, CStride>
{ {
} }
impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Clone impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Clone
for SliceStorage<'a, N, R, C, RStride, CStride> for SliceStorage<'a, T, R, C, RStride, CStride>
{ {
#[inline] #[inline]
fn clone(&self) -> Self { fn clone(&self) -> Self {
@ -110,14 +110,14 @@ impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Clone
macro_rules! storage_impl( macro_rules! storage_impl(
($($T: ident),* $(,)*) => {$( ($($T: ident),* $(,)*) => {$(
unsafe impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Storage<N, R, C> unsafe impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> Storage<T, R, C>
for $T<'a, N, R, C, RStride, CStride> { for $T<'a, T, R, C, RStride, CStride> {
type RStride = RStride; type RStride = RStride;
type CStride = CStride; type CStride = CStride;
#[inline] #[inline]
fn ptr(&self) -> *const N { fn ptr(&self) -> *const T {
self.ptr self.ptr
} }
@ -148,21 +148,21 @@ macro_rules! storage_impl(
} }
#[inline] #[inline]
fn into_owned(self) -> Owned<N, R, C> fn into_owned(self) -> Owned<T, R, C>
where DefaultAllocator: Allocator<N, R, C> { where DefaultAllocator: Allocator<T, R, C> {
self.clone_owned() self.clone_owned()
} }
#[inline] #[inline]
fn clone_owned(&self) -> Owned<N, R, C> fn clone_owned(&self) -> Owned<T, R, C>
where DefaultAllocator: Allocator<N, R, C> { where DefaultAllocator: Allocator<T, R, C> {
let (nrows, ncols) = self.shape(); let (nrows, ncols) = self.shape();
let it = MatrixIter::new(self).cloned(); let it = MatrixIter::new(self).cloned();
DefaultAllocator::allocate_from_iterator(nrows, ncols, it) DefaultAllocator::allocate_from_iterator(nrows, ncols, it)
} }
#[inline] #[inline]
fn as_slice(&self) -> &[N] { fn as_slice(&self) -> &[T] {
let (nrows, ncols) = self.shape(); let (nrows, ncols) = self.shape();
if nrows.value() != 0 && ncols.value() != 0 { if nrows.value() != 0 && ncols.value() != 0 {
let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1); let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1);
@ -178,16 +178,16 @@ macro_rules! storage_impl(
storage_impl!(SliceStorage, SliceStorageMut); storage_impl!(SliceStorage, SliceStorageMut);
unsafe impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> StorageMut<N, R, C> unsafe impl<'a, T: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> StorageMut<T, R, C>
for SliceStorageMut<'a, N, R, C, RStride, CStride> for SliceStorageMut<'a, T, R, C, RStride, CStride>
{ {
#[inline] #[inline]
fn ptr_mut(&mut self) -> *mut N { fn ptr_mut(&mut self) -> *mut T {
self.ptr self.ptr
} }
#[inline] #[inline]
fn as_mut_slice(&mut self) -> &mut [N] { fn as_mut_slice(&mut self) -> &mut [T] {
let (nrows, ncols) = self.shape(); let (nrows, ncols) = self.shape();
if nrows.value() != 0 && ncols.value() != 0 { if nrows.value() != 0 && ncols.value() != 0 {
let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1); let sz = self.linear_index(nrows.value() - 1, ncols.value() - 1);
@ -198,33 +198,33 @@ unsafe impl<'a, N: Scalar, R: Dim, C: Dim, RStride: Dim, CStride: Dim> StorageMu
} }
} }
unsafe impl<'a, N: Scalar, R: Dim, CStride: Dim> ContiguousStorage<N, R, U1> unsafe impl<'a, T: Scalar, R: Dim, CStride: Dim> ContiguousStorage<T, R, U1>
for SliceStorage<'a, N, R, U1, U1, CStride> for SliceStorage<'a, T, R, U1, U1, CStride>
{ {
} }
unsafe impl<'a, N: Scalar, R: Dim, CStride: Dim> ContiguousStorage<N, R, U1> unsafe impl<'a, T: Scalar, R: Dim, CStride: Dim> ContiguousStorage<T, R, U1>
for SliceStorageMut<'a, N, R, U1, U1, CStride> for SliceStorageMut<'a, T, R, U1, U1, CStride>
{ {
} }
unsafe impl<'a, N: Scalar, R: Dim, CStride: Dim> ContiguousStorageMut<N, R, U1> unsafe impl<'a, T: Scalar, R: Dim, CStride: Dim> ContiguousStorageMut<T, R, U1>
for SliceStorageMut<'a, N, R, U1, U1, CStride> for SliceStorageMut<'a, T, R, U1, U1, CStride>
{ {
} }
unsafe impl<'a, N: Scalar, R: DimName, C: Dim + IsNotStaticOne> ContiguousStorage<N, R, C> unsafe impl<'a, T: Scalar, R: DimName, C: Dim + IsNotStaticOne> ContiguousStorage<T, R, C>
for SliceStorage<'a, N, R, C, U1, R> for SliceStorage<'a, T, R, C, U1, R>
{ {
} }
unsafe impl<'a, N: Scalar, R: DimName, C: Dim + IsNotStaticOne> ContiguousStorage<N, R, C> unsafe impl<'a, T: Scalar, R: DimName, C: Dim + IsNotStaticOne> ContiguousStorage<T, R, C>
for SliceStorageMut<'a, N, R, C, U1, R> for SliceStorageMut<'a, T, R, C, U1, R>
{ {
} }
unsafe impl<'a, N: Scalar, R: DimName, C: Dim + IsNotStaticOne> ContiguousStorageMut<N, R, C> unsafe impl<'a, T: Scalar, R: DimName, C: Dim + IsNotStaticOne> ContiguousStorageMut<T, R, C>
for SliceStorageMut<'a, N, R, C, U1, R> for SliceStorageMut<'a, T, R, C, U1, R>
{ {
} }
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> { impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
#[inline] #[inline]
fn assert_slice_index( fn assert_slice_index(
&self, &self,
@ -281,20 +281,20 @@ macro_rules! matrix_slice_impl(
*/ */
/// Returns a slice containing the i-th row of this matrix. /// Returns a slice containing the i-th row of this matrix.
#[inline] #[inline]
pub fn $row($me: $Me, i: usize) -> $MatrixSlice<N, U1, C, S::RStride, S::CStride> { pub fn $row($me: $Me, i: usize) -> $MatrixSlice<T, U1, C, S::RStride, S::CStride> {
$me.$fixed_rows::<U1>(i) $me.$fixed_rows::<1>(i)
} }
/// Returns a slice containing the `n` first elements of the i-th row of this matrix. /// Returns a slice containing the `n` first elements of the i-th row of this matrix.
#[inline] #[inline]
pub fn $row_part($me: $Me, i: usize, n: usize) -> $MatrixSlice<N, U1, Dynamic, S::RStride, S::CStride> { pub fn $row_part($me: $Me, i: usize, n: usize) -> $MatrixSlice<T, U1, Dynamic, S::RStride, S::CStride> {
$me.$generic_slice((i, 0), (Const::<1>, Dynamic::new(n))) $me.$generic_slice((i, 0), (Const::<1>, Dynamic::new(n)))
} }
/// Extracts from this matrix a set of consecutive rows. /// Extracts from this matrix a set of consecutive rows.
#[inline] #[inline]
pub fn $rows($me: $Me, first_row: usize, nrows: usize) pub fn $rows($me: $Me, first_row: usize, nrows: usize)
-> $MatrixSlice<N, Dynamic, C, S::RStride, S::CStride> { -> $MatrixSlice<T, Dynamic, C, S::RStride, S::CStride> {
$me.$rows_generic(first_row, Dynamic::new(nrows)) $me.$rows_generic(first_row, Dynamic::new(nrows))
} }
@ -302,33 +302,33 @@ macro_rules! matrix_slice_impl(
/// Extracts from this matrix a set of consecutive rows regularly skipping `step` rows. /// Extracts from this matrix a set of consecutive rows regularly skipping `step` rows.
#[inline] #[inline]
pub fn $rows_with_step($me: $Me, first_row: usize, nrows: usize, step: usize) pub fn $rows_with_step($me: $Me, first_row: usize, nrows: usize, step: usize)
-> $MatrixSlice<N, Dynamic, C, Dynamic, S::CStride> { -> $MatrixSlice<T, Dynamic, C, Dynamic, S::CStride> {
$me.$rows_generic_with_step(first_row, Dynamic::new(nrows), step) $me.$rows_generic_with_step(first_row, Dynamic::new(nrows), step)
} }
/// Extracts a compile-time number of consecutive rows from this matrix. /// Extracts a compile-time number of consecutive rows from this matrix.
#[inline] #[inline]
pub fn $fixed_rows<RSlice: DimName>($me: $Me, first_row: usize) pub fn $fixed_rows<const RSLICE: usize>($me: $Me, first_row: usize)
-> $MatrixSlice<N, RSlice, C, S::RStride, S::CStride> { -> $MatrixSlice<T, Const<RSLICE>, C, S::RStride, S::CStride> {
$me.$rows_generic(first_row, RSlice::name()) $me.$rows_generic(first_row, Const::<RSLICE>)
} }
/// Extracts from this matrix a compile-time number of rows regularly skipping `step` /// Extracts from this matrix a compile-time number of rows regularly skipping `step`
/// rows. /// rows.
#[inline] #[inline]
pub fn $fixed_rows_with_step<RSlice: DimName>($me: $Me, first_row: usize, step: usize) pub fn $fixed_rows_with_step<const RSLICE: usize>($me: $Me, first_row: usize, step: usize)
-> $MatrixSlice<N, RSlice, C, Dynamic, S::CStride> { -> $MatrixSlice<T, Const<RSLICE>, C, Dynamic, S::CStride> {
$me.$rows_generic_with_step(first_row, RSlice::name(), step) $me.$rows_generic_with_step(first_row, Const::<RSLICE>, step)
} }
/// Extracts from this matrix `nrows` rows regularly skipping `step` rows. Both /// Extracts from this matrix `nrows` rows regularly skipping `step` rows. Both
/// argument may or may not be values known at compile-time. /// argument may or may not be values known at compile-time.
#[inline] #[inline]
pub fn $rows_generic<RSlice: Dim>($me: $Me, row_start: usize, nrows: RSlice) pub fn $rows_generic<RSlice: Dim>($me: $Me, row_start: usize, nrows: RSlice)
-> $MatrixSlice<N, RSlice, C, S::RStride, S::CStride> { -> $MatrixSlice<T, RSlice, C, S::RStride, S::CStride> {
let my_shape = $me.data.shape(); let my_shape = $me.data.shape();
$me.assert_slice_index((row_start, 0), (nrows.value(), my_shape.1.value()), (0, 0)); $me.assert_slice_index((row_start, 0), (nrows.value(), my_shape.1.value()), (0, 0));
@ -345,7 +345,7 @@ macro_rules! matrix_slice_impl(
/// argument may or may not be values known at compile-time. /// argument may or may not be values known at compile-time.
#[inline] #[inline]
pub fn $rows_generic_with_step<RSlice>($me: $Me, row_start: usize, nrows: RSlice, step: usize) pub fn $rows_generic_with_step<RSlice>($me: $Me, row_start: usize, nrows: RSlice, step: usize)
-> $MatrixSlice<N, RSlice, C, Dynamic, S::CStride> -> $MatrixSlice<T, RSlice, C, Dynamic, S::CStride>
where RSlice: Dim { where RSlice: Dim {
let my_shape = $me.data.shape(); let my_shape = $me.data.shape();
@ -368,20 +368,20 @@ macro_rules! matrix_slice_impl(
*/ */
/// Returns a slice containing the i-th column of this matrix. /// Returns a slice containing the i-th column of this matrix.
#[inline] #[inline]
pub fn $column($me: $Me, i: usize) -> $MatrixSlice<N, R, U1, S::RStride, S::CStride> { pub fn $column($me: $Me, i: usize) -> $MatrixSlice<T, R, U1, S::RStride, S::CStride> {
$me.$fixed_columns::<U1>(i) $me.$fixed_columns::<1>(i)
} }
/// Returns a slice containing the `n` first elements of the i-th column of this matrix. /// Returns a slice containing the `n` first elements of the i-th column of this matrix.
#[inline] #[inline]
pub fn $column_part($me: $Me, i: usize, n: usize) -> $MatrixSlice<N, Dynamic, U1, S::RStride, S::CStride> { pub fn $column_part($me: $Me, i: usize, n: usize) -> $MatrixSlice<T, Dynamic, U1, S::RStride, S::CStride> {
$me.$generic_slice((0, i), (Dynamic::new(n), Const::<1>)) $me.$generic_slice((0, i), (Dynamic::new(n), Const::<1>))
} }
/// Extracts from this matrix a set of consecutive columns. /// Extracts from this matrix a set of consecutive columns.
#[inline] #[inline]
pub fn $columns($me: $Me, first_col: usize, ncols: usize) pub fn $columns($me: $Me, first_col: usize, ncols: usize)
-> $MatrixSlice<N, R, Dynamic, S::RStride, S::CStride> { -> $MatrixSlice<T, R, Dynamic, S::RStride, S::CStride> {
$me.$columns_generic(first_col, Dynamic::new(ncols)) $me.$columns_generic(first_col, Dynamic::new(ncols))
} }
@ -390,33 +390,33 @@ macro_rules! matrix_slice_impl(
/// columns. /// columns.
#[inline] #[inline]
pub fn $columns_with_step($me: $Me, first_col: usize, ncols: usize, step: usize) pub fn $columns_with_step($me: $Me, first_col: usize, ncols: usize, step: usize)
-> $MatrixSlice<N, R, Dynamic, S::RStride, Dynamic> { -> $MatrixSlice<T, R, Dynamic, S::RStride, Dynamic> {
$me.$columns_generic_with_step(first_col, Dynamic::new(ncols), step) $me.$columns_generic_with_step(first_col, Dynamic::new(ncols), step)
} }
/// Extracts a compile-time number of consecutive columns from this matrix. /// Extracts a compile-time number of consecutive columns from this matrix.
#[inline] #[inline]
pub fn $fixed_columns<CSlice: DimName>($me: $Me, first_col: usize) pub fn $fixed_columns<const CSLICE: usize>($me: $Me, first_col: usize)
-> $MatrixSlice<N, R, CSlice, S::RStride, S::CStride> { -> $MatrixSlice<T, R, Const<CSLICE>, S::RStride, S::CStride> {
$me.$columns_generic(first_col, CSlice::name()) $me.$columns_generic(first_col, Const::<CSLICE>)
} }
/// Extracts from this matrix a compile-time number of columns regularly skipping /// Extracts from this matrix a compile-time number of columns regularly skipping
/// `step` columns. /// `step` columns.
#[inline] #[inline]
pub fn $fixed_columns_with_step<CSlice: DimName>($me: $Me, first_col: usize, step: usize) pub fn $fixed_columns_with_step<const CSLICE: usize>($me: $Me, first_col: usize, step: usize)
-> $MatrixSlice<N, R, CSlice, S::RStride, Dynamic> { -> $MatrixSlice<T, R, Const<CSLICE>, S::RStride, Dynamic> {
$me.$columns_generic_with_step(first_col, CSlice::name(), step) $me.$columns_generic_with_step(first_col, Const::<CSLICE>, step)
} }
/// Extracts from this matrix `ncols` columns. The number of columns may or may not be /// Extracts from this matrix `ncols` columns. The number of columns may or may not be
/// known at compile-time. /// known at compile-time.
#[inline] #[inline]
pub fn $columns_generic<CSlice: Dim>($me: $Me, first_col: usize, ncols: CSlice) pub fn $columns_generic<CSlice: Dim>($me: $Me, first_col: usize, ncols: CSlice)
-> $MatrixSlice<N, R, CSlice, S::RStride, S::CStride> { -> $MatrixSlice<T, R, CSlice, S::RStride, S::CStride> {
let my_shape = $me.data.shape(); let my_shape = $me.data.shape();
$me.assert_slice_index((0, first_col), (my_shape.0.value(), ncols.value()), (0, 0)); $me.assert_slice_index((0, first_col), (my_shape.0.value(), ncols.value()), (0, 0));
@ -433,7 +433,7 @@ macro_rules! matrix_slice_impl(
/// or may not be values known at compile-time. /// or may not be values known at compile-time.
#[inline] #[inline]
pub fn $columns_generic_with_step<CSlice: Dim>($me: $Me, first_col: usize, ncols: CSlice, step: usize) pub fn $columns_generic_with_step<CSlice: Dim>($me: $Me, first_col: usize, ncols: CSlice, step: usize)
-> $MatrixSlice<N, R, CSlice, S::RStride, Dynamic> { -> $MatrixSlice<T, R, CSlice, S::RStride, Dynamic> {
let my_shape = $me.data.shape(); let my_shape = $me.data.shape();
let my_strides = $me.data.strides(); let my_strides = $me.data.strides();
@ -458,7 +458,7 @@ macro_rules! matrix_slice_impl(
/// consecutive elements. /// consecutive elements.
#[inline] #[inline]
pub fn $slice($me: $Me, start: (usize, usize), shape: (usize, usize)) pub fn $slice($me: $Me, start: (usize, usize), shape: (usize, usize))
-> $MatrixSlice<N, Dynamic, Dynamic, S::RStride, S::CStride> { -> $MatrixSlice<T, Dynamic, Dynamic, S::RStride, S::CStride> {
$me.assert_slice_index(start, shape, (0, 0)); $me.assert_slice_index(start, shape, (0, 0));
let shape = (Dynamic::new(shape.0), Dynamic::new(shape.1)); let shape = (Dynamic::new(shape.0), Dynamic::new(shape.1));
@ -476,7 +476,7 @@ macro_rules! matrix_slice_impl(
/// original matrix. /// original matrix.
#[inline] #[inline]
pub fn $slice_with_steps($me: $Me, start: (usize, usize), shape: (usize, usize), steps: (usize, usize)) pub fn $slice_with_steps($me: $Me, start: (usize, usize), shape: (usize, usize), steps: (usize, usize))
-> $MatrixSlice<N, Dynamic, Dynamic, Dynamic, Dynamic> { -> $MatrixSlice<T, Dynamic, Dynamic, Dynamic, Dynamic> {
let shape = (Dynamic::new(shape.0), Dynamic::new(shape.1)); let shape = (Dynamic::new(shape.0), Dynamic::new(shape.1));
$me.$generic_slice_with_steps(start, shape, steps) $me.$generic_slice_with_steps(start, shape, steps)
@ -485,13 +485,11 @@ macro_rules! matrix_slice_impl(
/// Slices this matrix starting at its component `(irow, icol)` and with `(R::dim(), /// Slices this matrix starting at its component `(irow, icol)` and with `(R::dim(),
/// CSlice::dim())` consecutive components. /// CSlice::dim())` consecutive components.
#[inline] #[inline]
pub fn $fixed_slice<RSlice, CSlice>($me: $Me, irow: usize, icol: usize) pub fn $fixed_slice<const RSLICE: usize, const CSLICE: usize>($me: $Me, irow: usize, icol: usize)
-> $MatrixSlice<N, RSlice, CSlice, S::RStride, S::CStride> -> $MatrixSlice<T, Const<RSLICE>, Const<CSLICE>, S::RStride, S::CStride> {
where RSlice: DimName,
CSlice: DimName {
$me.assert_slice_index((irow, icol), (RSlice::dim(), CSlice::dim()), (0, 0)); $me.assert_slice_index((irow, icol), (RSLICE, CSLICE), (0, 0));
let shape = (RSlice::name(), CSlice::name()); let shape = (Const::<RSLICE>, Const::<CSLICE>);
unsafe { unsafe {
let data = $SliceStorage::new_unchecked($data, (irow, icol), shape); let data = $SliceStorage::new_unchecked($data, (irow, icol), shape);
@ -500,22 +498,20 @@ macro_rules! matrix_slice_impl(
} }
/// Slices this matrix starting at its component `(start.0, start.1)` and with /// Slices this matrix starting at its component `(start.0, start.1)` and with
/// `(R::dim(), CSlice::dim())` components. Each row (resp. column) of the sliced /// `(RSLICE, CSLICE)` components. Each row (resp. column) of the sliced
/// matrix is separated by `steps.0` (resp. `steps.1`) ignored rows (resp. columns) of /// matrix is separated by `steps.0` (resp. `steps.1`) ignored rows (resp. columns) of
/// the original matrix. /// the original matrix.
#[inline] #[inline]
pub fn $fixed_slice_with_steps<RSlice, CSlice>($me: $Me, start: (usize, usize), steps: (usize, usize)) pub fn $fixed_slice_with_steps<const RSLICE: usize, const CSLICE: usize>($me: $Me, start: (usize, usize), steps: (usize, usize))
-> $MatrixSlice<N, RSlice, CSlice, Dynamic, Dynamic> -> $MatrixSlice<T, Const<RSLICE>, Const<CSLICE>, Dynamic, Dynamic> {
where RSlice: DimName, let shape = (Const::<RSLICE>, Const::<CSLICE>);
CSlice: DimName {
let shape = (RSlice::name(), CSlice::name());
$me.$generic_slice_with_steps(start, shape, steps) $me.$generic_slice_with_steps(start, shape, steps)
} }
/// Creates a slice that may or may not have a fixed size and stride. /// Creates a slice that may or may not have a fixed size and stride.
#[inline] #[inline]
pub fn $generic_slice<RSlice, CSlice>($me: $Me, start: (usize, usize), shape: (RSlice, CSlice)) pub fn $generic_slice<RSlice, CSlice>($me: $Me, start: (usize, usize), shape: (RSlice, CSlice))
-> $MatrixSlice<N, RSlice, CSlice, S::RStride, S::CStride> -> $MatrixSlice<T, RSlice, CSlice, S::RStride, S::CStride>
where RSlice: Dim, where RSlice: Dim,
CSlice: Dim { CSlice: Dim {
@ -533,7 +529,7 @@ macro_rules! matrix_slice_impl(
start: (usize, usize), start: (usize, usize),
shape: (RSlice, CSlice), shape: (RSlice, CSlice),
steps: (usize, usize)) steps: (usize, usize))
-> $MatrixSlice<N, RSlice, CSlice, Dynamic, Dynamic> -> $MatrixSlice<T, RSlice, CSlice, Dynamic, Dynamic>
where RSlice: Dim, where RSlice: Dim,
CSlice: Dim { CSlice: Dim {
@ -559,8 +555,8 @@ macro_rules! matrix_slice_impl(
/// Panics if the ranges overlap or if the first range is empty. /// Panics if the ranges overlap or if the first range is empty.
#[inline] #[inline]
pub fn $rows_range_pair<Range1: SliceRange<R>, Range2: SliceRange<R>>($me: $Me, r1: Range1, r2: Range2) pub fn $rows_range_pair<Range1: SliceRange<R>, Range2: SliceRange<R>>($me: $Me, r1: Range1, r2: Range2)
-> ($MatrixSlice<N, Range1::Size, C, S::RStride, S::CStride>, -> ($MatrixSlice<T, Range1::Size, C, S::RStride, S::CStride>,
$MatrixSlice<N, Range2::Size, C, S::RStride, S::CStride>) { $MatrixSlice<T, Range2::Size, C, S::RStride, S::CStride>) {
let (nrows, ncols) = $me.data.shape(); let (nrows, ncols) = $me.data.shape();
let strides = $me.data.strides(); let strides = $me.data.strides();
@ -595,8 +591,8 @@ macro_rules! matrix_slice_impl(
/// Panics if the ranges overlap or if the first range is empty. /// Panics if the ranges overlap or if the first range is empty.
#[inline] #[inline]
pub fn $columns_range_pair<Range1: SliceRange<C>, Range2: SliceRange<C>>($me: $Me, r1: Range1, r2: Range2) pub fn $columns_range_pair<Range1: SliceRange<C>, Range2: SliceRange<C>>($me: $Me, r1: Range1, r2: Range2)
-> ($MatrixSlice<N, R, Range1::Size, S::RStride, S::CStride>, -> ($MatrixSlice<T, R, Range1::Size, S::RStride, S::CStride>,
$MatrixSlice<N, R, Range2::Size, S::RStride, S::CStride>) { $MatrixSlice<T, R, Range2::Size, S::RStride, S::CStride>) {
let (nrows, ncols) = $me.data.shape(); let (nrows, ncols) = $me.data.shape();
let strides = $me.data.strides(); let strides = $me.data.strides();
@ -629,14 +625,14 @@ macro_rules! matrix_slice_impl(
); );
/// A matrix slice. /// A matrix slice.
pub type MatrixSlice<'a, N, R, C, RStride, CStride> = pub type MatrixSlice<'a, T, R, C, RStride = U1, CStride = R> =
Matrix<N, R, C, SliceStorage<'a, N, R, C, RStride, CStride>>; Matrix<T, R, C, SliceStorage<'a, T, R, C, RStride, CStride>>;
/// A mutable matrix slice. /// A mutable matrix slice.
pub type MatrixSliceMut<'a, N, R, C, RStride, CStride> = pub type MatrixSliceMut<'a, T, R, C, RStride = U1, CStride = R> =
Matrix<N, R, C, SliceStorageMut<'a, N, R, C, RStride, CStride>>; Matrix<T, R, C, SliceStorageMut<'a, T, R, C, RStride, CStride>>;
/// # Slicing based on index and length /// # Slicing based on index and length
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> { impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
matrix_slice_impl!( matrix_slice_impl!(
self: &Self, MatrixSlice, SliceStorage, Storage.get_address_unchecked(), &self.data; self: &Self, MatrixSlice, SliceStorage, Storage.get_address_unchecked(), &self.data;
row, row,
@ -666,7 +662,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
} }
/// # Mutable slicing based on index and length /// # Mutable slicing based on index and length
impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> { impl<T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
matrix_slice_impl!( matrix_slice_impl!(
self: &mut Self, MatrixSliceMut, SliceStorageMut, StorageMut.get_address_unchecked_mut(), &mut self.data; self: &mut Self, MatrixSliceMut, SliceStorageMut, StorageMut.get_address_unchecked_mut(), &mut self.data;
row_mut, row_mut,
@ -812,7 +808,7 @@ impl<D: Dim> SliceRange<D> for RangeFull {
// TODO: see how much of this overlaps with the general indexing // TODO: see how much of this overlaps with the general indexing
// methods from indexing.rs. // methods from indexing.rs.
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> { impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
/// Slices a sub-matrix containing the rows indexed by the range `rows` and the columns indexed /// Slices a sub-matrix containing the rows indexed by the range `rows` and the columns indexed
/// by the range `cols`. /// by the range `cols`.
#[inline] #[inline]
@ -820,7 +816,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
&self, &self,
rows: RowRange, rows: RowRange,
cols: ColRange, cols: ColRange,
) -> MatrixSlice<N, RowRange::Size, ColRange::Size, S::RStride, S::CStride> ) -> MatrixSlice<T, RowRange::Size, ColRange::Size, S::RStride, S::CStride>
where where
RowRange: SliceRange<R>, RowRange: SliceRange<R>,
ColRange: SliceRange<C>, ColRange: SliceRange<C>,
@ -837,7 +833,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
pub fn rows_range<RowRange: SliceRange<R>>( pub fn rows_range<RowRange: SliceRange<R>>(
&self, &self,
rows: RowRange, rows: RowRange,
) -> MatrixSlice<N, RowRange::Size, C, S::RStride, S::CStride> { ) -> MatrixSlice<T, RowRange::Size, C, S::RStride, S::CStride> {
self.slice_range(rows, ..) self.slice_range(rows, ..)
} }
@ -846,21 +842,21 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
pub fn columns_range<ColRange: SliceRange<C>>( pub fn columns_range<ColRange: SliceRange<C>>(
&self, &self,
cols: ColRange, cols: ColRange,
) -> MatrixSlice<N, R, ColRange::Size, S::RStride, S::CStride> { ) -> MatrixSlice<T, R, ColRange::Size, S::RStride, S::CStride> {
self.slice_range(.., cols) self.slice_range(.., cols)
} }
} }
// TODO: see how much of this overlaps with the general indexing // TODO: see how much of this overlaps with the general indexing
// methods from indexing.rs. // methods from indexing.rs.
impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> { impl<T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
/// Slices a mutable sub-matrix containing the rows indexed by the range `rows` and the columns /// Slices a mutable sub-matrix containing the rows indexed by the range `rows` and the columns
/// indexed by the range `cols`. /// indexed by the range `cols`.
pub fn slice_range_mut<RowRange, ColRange>( pub fn slice_range_mut<RowRange, ColRange>(
&mut self, &mut self,
rows: RowRange, rows: RowRange,
cols: ColRange, cols: ColRange,
) -> MatrixSliceMut<N, RowRange::Size, ColRange::Size, S::RStride, S::CStride> ) -> MatrixSliceMut<T, RowRange::Size, ColRange::Size, S::RStride, S::CStride>
where where
RowRange: SliceRange<R>, RowRange: SliceRange<R>,
ColRange: SliceRange<C>, ColRange: SliceRange<C>,
@ -877,7 +873,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
pub fn rows_range_mut<RowRange: SliceRange<R>>( pub fn rows_range_mut<RowRange: SliceRange<R>>(
&mut self, &mut self,
rows: RowRange, rows: RowRange,
) -> MatrixSliceMut<N, RowRange::Size, C, S::RStride, S::CStride> { ) -> MatrixSliceMut<T, RowRange::Size, C, S::RStride, S::CStride> {
self.slice_range_mut(rows, ..) self.slice_range_mut(rows, ..)
} }
@ -886,21 +882,21 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
pub fn columns_range_mut<ColRange: SliceRange<C>>( pub fn columns_range_mut<ColRange: SliceRange<C>>(
&mut self, &mut self,
cols: ColRange, cols: ColRange,
) -> MatrixSliceMut<N, R, ColRange::Size, S::RStride, S::CStride> { ) -> MatrixSliceMut<T, R, ColRange::Size, S::RStride, S::CStride> {
self.slice_range_mut(.., cols) self.slice_range_mut(.., cols)
} }
} }
impl<'a, N, R, C, RStride, CStride> From<MatrixSliceMut<'a, N, R, C, RStride, CStride>> impl<'a, T, R, C, RStride, CStride> From<MatrixSliceMut<'a, T, R, C, RStride, CStride>>
for MatrixSlice<'a, N, R, C, RStride, CStride> for MatrixSlice<'a, T, R, C, RStride, CStride>
where where
N: Scalar, T: Scalar,
R: Dim, R: Dim,
C: Dim, C: Dim,
RStride: Dim, RStride: Dim,
CStride: Dim, CStride: Dim,
{ {
fn from(slice_mut: MatrixSliceMut<'a, N, R, C, RStride, CStride>) -> Self { fn from(slice_mut: MatrixSliceMut<'a, T, R, C, RStride, CStride>) -> Self {
let data = SliceStorage { let data = SliceStorage {
ptr: slice_mut.data.ptr, ptr: slice_mut.data.ptr,
shape: slice_mut.data.shape, shape: slice_mut.data.shape,

View File

@ -4,7 +4,7 @@ use num::{Signed, Zero};
use simba::simd::SimdSigned; use simba::simd::SimdSigned;
/// # Find the min and max components /// # Find the min and max components
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> { impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
/// Returns the absolute value of the component with the largest absolute value. /// Returns the absolute value of the component with the largest absolute value.
/// # Example /// # Example
/// ``` /// ```
@ -13,12 +13,12 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// assert_eq!(Vector3::new(-1.0, -2.0, -3.0).amax(), 3.0); /// assert_eq!(Vector3::new(-1.0, -2.0, -3.0).amax(), 3.0);
/// ``` /// ```
#[inline] #[inline]
pub fn amax(&self) -> N pub fn amax(&self) -> T
where where
N: Zero + SimdSigned + SimdPartialOrd, T: Zero + SimdSigned + SimdPartialOrd,
{ {
self.fold_with( self.fold_with(
|e| e.unwrap_or(&N::zero()).simd_abs(), |e| e.unwrap_or(&T::zero()).simd_abs(),
|a, b| a.simd_max(b.simd_abs()), |a, b| a.simd_max(b.simd_abs()),
) )
} }
@ -33,12 +33,12 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// Complex::new(1.0, 3.0)).camax(), 5.0); /// Complex::new(1.0, 3.0)).camax(), 5.0);
/// ``` /// ```
#[inline] #[inline]
pub fn camax(&self) -> N::SimdRealField pub fn camax(&self) -> T::SimdRealField
where where
N: SimdComplexField, T: SimdComplexField,
{ {
self.fold_with( self.fold_with(
|e| e.unwrap_or(&N::zero()).simd_norm1(), |e| e.unwrap_or(&T::zero()).simd_norm1(),
|a, b| a.simd_max(b.simd_norm1()), |a, b| a.simd_max(b.simd_norm1()),
) )
} }
@ -52,12 +52,12 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// assert_eq!(Vector3::new(5u32, 2, 3).max(), 5); /// assert_eq!(Vector3::new(5u32, 2, 3).max(), 5);
/// ``` /// ```
#[inline] #[inline]
pub fn max(&self) -> N pub fn max(&self) -> T
where where
N: SimdPartialOrd + Zero, T: SimdPartialOrd + Zero,
{ {
self.fold_with( self.fold_with(
|e| e.map(|e| e.inlined_clone()).unwrap_or_else(N::zero), |e| e.map(|e| e.inlined_clone()).unwrap_or_else(T::zero),
|a, b| a.simd_max(b.inlined_clone()), |a, b| a.simd_max(b.inlined_clone()),
) )
} }
@ -70,12 +70,12 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// assert_eq!(Vector3::new(10.0, 2.0, 30.0).amin(), 2.0); /// assert_eq!(Vector3::new(10.0, 2.0, 30.0).amin(), 2.0);
/// ``` /// ```
#[inline] #[inline]
pub fn amin(&self) -> N pub fn amin(&self) -> T
where where
N: Zero + SimdPartialOrd + SimdSigned, T: Zero + SimdPartialOrd + SimdSigned,
{ {
self.fold_with( self.fold_with(
|e| e.map(|e| e.simd_abs()).unwrap_or_else(N::zero), |e| e.map(|e| e.simd_abs()).unwrap_or_else(T::zero),
|a, b| a.simd_min(b.simd_abs()), |a, b| a.simd_min(b.simd_abs()),
) )
} }
@ -90,14 +90,14 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// Complex::new(1.0, 3.0)).camin(), 3.0); /// Complex::new(1.0, 3.0)).camin(), 3.0);
/// ``` /// ```
#[inline] #[inline]
pub fn camin(&self) -> N::SimdRealField pub fn camin(&self) -> T::SimdRealField
where where
N: SimdComplexField, T: SimdComplexField,
{ {
self.fold_with( self.fold_with(
|e| { |e| {
e.map(|e| e.simd_norm1()) e.map(|e| e.simd_norm1())
.unwrap_or_else(N::SimdRealField::zero) .unwrap_or_else(T::SimdRealField::zero)
}, },
|a, b| a.simd_min(b.simd_norm1()), |a, b| a.simd_min(b.simd_norm1()),
) )
@ -112,12 +112,12 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// assert_eq!(Vector3::new(5u32, 2, 3).min(), 2); /// assert_eq!(Vector3::new(5u32, 2, 3).min(), 2);
/// ``` /// ```
#[inline] #[inline]
pub fn min(&self) -> N pub fn min(&self) -> T
where where
N: SimdPartialOrd + Zero, T: SimdPartialOrd + Zero,
{ {
self.fold_with( self.fold_with(
|e| e.map(|e| e.inlined_clone()).unwrap_or_else(N::zero), |e| e.map(|e| e.inlined_clone()).unwrap_or_else(T::zero),
|a, b| a.simd_min(b.inlined_clone()), |a, b| a.simd_min(b.inlined_clone()),
) )
} }
@ -138,7 +138,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
#[inline] #[inline]
pub fn icamax_full(&self) -> (usize, usize) pub fn icamax_full(&self) -> (usize, usize)
where where
N: ComplexField, T: ComplexField,
{ {
assert!(!self.is_empty(), "The input matrix must not be empty."); assert!(!self.is_empty(), "The input matrix must not be empty.");
@ -160,7 +160,7 @@ impl<N: Scalar, 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> { impl<T: Scalar + PartialOrd + Signed, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, 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.
/// ///
/// # Examples: /// # Examples:
@ -195,7 +195,7 @@ impl<N: Scalar + PartialOrd + Signed, R: Dim, C: Dim, S: Storage<N, R, C>> Matri
// TODO: find a way to avoid code duplication just for complex number support. // TODO: find a way to avoid code duplication just for complex number support.
/// # Find the min and max components (vector-specific methods) /// # Find the min and max components (vector-specific methods)
impl<N: Scalar, D: Dim, S: Storage<N, D>> Vector<N, D, S> { impl<T: Scalar, D: Dim, S: Storage<T, D>> Vector<T, D, S> {
/// Computes the index of the vector component with the largest complex or real absolute value. /// Computes the index of the vector component with the largest complex or real absolute value.
/// ///
/// # Examples: /// # Examples:
@ -211,7 +211,7 @@ impl<N: Scalar, D: Dim, S: Storage<N, D>> Vector<N, D, S> {
#[inline] #[inline]
pub fn icamax(&self) -> usize pub fn icamax(&self) -> usize
where where
N: ComplexField, T: ComplexField,
{ {
assert!(!self.is_empty(), "The input vector must not be empty."); assert!(!self.is_empty(), "The input vector must not be empty.");
@ -240,9 +240,9 @@ impl<N: Scalar, D: Dim, S: Storage<N, D>> Vector<N, D, S> {
/// assert_eq!(vec.argmax(), (2, 13)); /// assert_eq!(vec.argmax(), (2, 13));
/// ``` /// ```
#[inline] #[inline]
pub fn argmax(&self) -> (usize, N) pub fn argmax(&self) -> (usize, T)
where where
N: PartialOrd, T: PartialOrd,
{ {
assert!(!self.is_empty(), "The input vector must not be empty."); assert!(!self.is_empty(), "The input vector must not be empty.");
@ -273,7 +273,7 @@ impl<N: Scalar, D: Dim, S: Storage<N, D>> Vector<N, D, S> {
#[inline] #[inline]
pub fn imax(&self) -> usize pub fn imax(&self) -> usize
where where
N: PartialOrd, T: PartialOrd,
{ {
self.argmax().0 self.argmax().0
} }
@ -290,7 +290,7 @@ impl<N: Scalar, D: Dim, S: Storage<N, D>> Vector<N, D, S> {
#[inline] #[inline]
pub fn iamax(&self) -> usize pub fn iamax(&self) -> usize
where where
N: PartialOrd + Signed, T: PartialOrd + Signed,
{ {
assert!(!self.is_empty(), "The input vector must not be empty."); assert!(!self.is_empty(), "The input vector must not be empty.");
@ -319,9 +319,9 @@ impl<N: Scalar, D: Dim, S: Storage<N, D>> Vector<N, D, S> {
/// assert_eq!(vec.argmin(), (1, -15)); /// assert_eq!(vec.argmin(), (1, -15));
/// ``` /// ```
#[inline] #[inline]
pub fn argmin(&self) -> (usize, N) pub fn argmin(&self) -> (usize, T)
where where
N: PartialOrd, T: PartialOrd,
{ {
assert!(!self.is_empty(), "The input vector must not be empty."); assert!(!self.is_empty(), "The input vector must not be empty.");
@ -352,7 +352,7 @@ impl<N: Scalar, D: Dim, S: Storage<N, D>> Vector<N, D, S> {
#[inline] #[inline]
pub fn imin(&self) -> usize pub fn imin(&self) -> usize
where where
N: PartialOrd, T: PartialOrd,
{ {
self.argmin().0 self.argmin().0
} }
@ -369,7 +369,7 @@ impl<N: Scalar, D: Dim, S: Storage<N, D>> Vector<N, D, S> {
#[inline] #[inline]
pub fn iamin(&self) -> usize pub fn iamin(&self) -> usize
where where
N: PartialOrd + Signed, T: PartialOrd + Signed,
{ {
assert!(!self.is_empty(), "The input vector must not be empty."); assert!(!self.is_empty(), "The input vector must not be empty.");

View File

@ -5,7 +5,7 @@ use num::Zero;
use std::ops::Neg; use std::ops::Neg;
use crate::allocator::Allocator; use crate::allocator::Allocator;
use crate::base::{DefaultAllocator, Dim, DimName, Matrix, MatrixMN, Normed, VectorN}; use crate::base::{DefaultAllocator, Dim, DimName, Matrix, Normed, OMatrix, OVector};
use crate::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; use crate::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint};
use crate::storage::{Storage, StorageMut}; use crate::storage::{Storage, StorageMut};
use crate::{ComplexField, Scalar, SimdComplexField, Unit}; use crate::{ComplexField, Scalar, SimdComplexField, Unit};
@ -16,26 +16,26 @@ use simba::simd::{SimdOption, SimdPartialOrd, SimdValue};
/// A trait for abstract matrix norms. /// A trait for abstract matrix norms.
/// ///
/// This may be moved to the alga crate in the future. /// This may be moved to the alga crate in the future.
pub trait Norm<N: SimdComplexField> { pub trait Norm<T: SimdComplexField> {
/// Apply this norm to the given matrix. /// Apply this norm to the given matrix.
fn norm<R, C, S>(&self, m: &Matrix<N, R, C, S>) -> N::SimdRealField fn norm<R, C, S>(&self, m: &Matrix<T, R, C, S>) -> T::SimdRealField
where where
R: Dim, R: Dim,
C: Dim, C: Dim,
S: Storage<N, R, C>; S: Storage<T, R, C>;
/// Use the metric induced by this norm to compute the metric distance between the two given matrices. /// Use the metric induced by this norm to compute the metric distance between the two given matrices.
fn metric_distance<R1, C1, S1, R2, C2, S2>( fn metric_distance<R1, C1, S1, R2, C2, S2>(
&self, &self,
m1: &Matrix<N, R1, C1, S1>, m1: &Matrix<T, R1, C1, S1>,
m2: &Matrix<N, R2, C2, S2>, m2: &Matrix<T, R2, C2, S2>,
) -> N::SimdRealField ) -> T::SimdRealField
where where
R1: Dim, R1: Dim,
C1: Dim, C1: Dim,
S1: Storage<N, R1, C1>, S1: Storage<T, R1, C1>,
R2: Dim, R2: Dim,
C2: Dim, C2: Dim,
S2: Storage<N, R2, C2>, S2: Storage<T, R2, C2>,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>; ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>;
} }
@ -46,13 +46,13 @@ pub struct LpNorm(pub i32);
/// L-infinite norm aka. Chebytchev norm aka. uniform norm aka. suppremum norm. /// L-infinite norm aka. Chebytchev norm aka. uniform norm aka. suppremum norm.
pub struct UniformNorm; pub struct UniformNorm;
impl<N: SimdComplexField> Norm<N> for EuclideanNorm { impl<T: SimdComplexField> Norm<T> for EuclideanNorm {
#[inline] #[inline]
fn norm<R, C, S>(&self, m: &Matrix<N, R, C, S>) -> N::SimdRealField fn norm<R, C, S>(&self, m: &Matrix<T, R, C, S>) -> T::SimdRealField
where where
R: Dim, R: Dim,
C: Dim, C: Dim,
S: Storage<N, R, C>, S: Storage<T, R, C>,
{ {
m.norm_squared().simd_sqrt() m.norm_squared().simd_sqrt()
} }
@ -60,19 +60,19 @@ impl<N: SimdComplexField> Norm<N> for EuclideanNorm {
#[inline] #[inline]
fn metric_distance<R1, C1, S1, R2, C2, S2>( fn metric_distance<R1, C1, S1, R2, C2, S2>(
&self, &self,
m1: &Matrix<N, R1, C1, S1>, m1: &Matrix<T, R1, C1, S1>,
m2: &Matrix<N, R2, C2, S2>, m2: &Matrix<T, R2, C2, S2>,
) -> N::SimdRealField ) -> T::SimdRealField
where where
R1: Dim, R1: Dim,
C1: Dim, C1: Dim,
S1: Storage<N, R1, C1>, S1: Storage<T, R1, C1>,
R2: Dim, R2: Dim,
C2: Dim, C2: Dim,
S2: Storage<N, R2, C2>, S2: Storage<T, R2, C2>,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>, ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>,
{ {
m1.zip_fold(m2, N::SimdRealField::zero(), |acc, a, b| { m1.zip_fold(m2, T::SimdRealField::zero(), |acc, a, b| {
let diff = a - b; let diff = a - b;
acc + diff.simd_modulus_squared() acc + diff.simd_modulus_squared()
}) })
@ -80,15 +80,15 @@ impl<N: SimdComplexField> Norm<N> for EuclideanNorm {
} }
} }
impl<N: SimdComplexField> Norm<N> for LpNorm { impl<T: SimdComplexField> Norm<T> for LpNorm {
#[inline] #[inline]
fn norm<R, C, S>(&self, m: &Matrix<N, R, C, S>) -> N::SimdRealField fn norm<R, C, S>(&self, m: &Matrix<T, R, C, S>) -> T::SimdRealField
where where
R: Dim, R: Dim,
C: Dim, C: Dim,
S: Storage<N, R, C>, S: Storage<T, R, C>,
{ {
m.fold(N::SimdRealField::zero(), |a, b| { m.fold(T::SimdRealField::zero(), |a, b| {
a + b.simd_modulus().simd_powi(self.0) a + b.simd_modulus().simd_powi(self.0)
}) })
.simd_powf(crate::convert(1.0 / (self.0 as f64))) .simd_powf(crate::convert(1.0 / (self.0 as f64)))
@ -97,19 +97,19 @@ impl<N: SimdComplexField> Norm<N> for LpNorm {
#[inline] #[inline]
fn metric_distance<R1, C1, S1, R2, C2, S2>( fn metric_distance<R1, C1, S1, R2, C2, S2>(
&self, &self,
m1: &Matrix<N, R1, C1, S1>, m1: &Matrix<T, R1, C1, S1>,
m2: &Matrix<N, R2, C2, S2>, m2: &Matrix<T, R2, C2, S2>,
) -> N::SimdRealField ) -> T::SimdRealField
where where
R1: Dim, R1: Dim,
C1: Dim, C1: Dim,
S1: Storage<N, R1, C1>, S1: Storage<T, R1, C1>,
R2: Dim, R2: Dim,
C2: Dim, C2: Dim,
S2: Storage<N, R2, C2>, S2: Storage<T, R2, C2>,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>, ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>,
{ {
m1.zip_fold(m2, N::SimdRealField::zero(), |acc, a, b| { m1.zip_fold(m2, T::SimdRealField::zero(), |acc, a, b| {
let diff = a - b; let diff = a - b;
acc + diff.simd_modulus().simd_powi(self.0) acc + diff.simd_modulus().simd_powi(self.0)
}) })
@ -117,17 +117,17 @@ impl<N: SimdComplexField> Norm<N> for LpNorm {
} }
} }
impl<N: SimdComplexField> Norm<N> for UniformNorm { impl<T: SimdComplexField> Norm<T> for UniformNorm {
#[inline] #[inline]
fn norm<R, C, S>(&self, m: &Matrix<N, R, C, S>) -> N::SimdRealField fn norm<R, C, S>(&self, m: &Matrix<T, R, C, S>) -> T::SimdRealField
where where
R: Dim, R: Dim,
C: Dim, C: Dim,
S: Storage<N, R, C>, S: Storage<T, R, C>,
{ {
// NOTE: we don't use `m.amax()` here because for the complex // NOTE: we don't use `m.amax()` here because for the complex
// numbers this will return the max norm1 instead of the modulus. // numbers this will return the max norm1 instead of the modulus.
m.fold(N::SimdRealField::zero(), |acc, a| { m.fold(T::SimdRealField::zero(), |acc, a| {
acc.simd_max(a.simd_modulus()) acc.simd_max(a.simd_modulus())
}) })
} }
@ -135,19 +135,19 @@ impl<N: SimdComplexField> Norm<N> for UniformNorm {
#[inline] #[inline]
fn metric_distance<R1, C1, S1, R2, C2, S2>( fn metric_distance<R1, C1, S1, R2, C2, S2>(
&self, &self,
m1: &Matrix<N, R1, C1, S1>, m1: &Matrix<T, R1, C1, S1>,
m2: &Matrix<N, R2, C2, S2>, m2: &Matrix<T, R2, C2, S2>,
) -> N::SimdRealField ) -> T::SimdRealField
where where
R1: Dim, R1: Dim,
C1: Dim, C1: Dim,
S1: Storage<N, R1, C1>, S1: Storage<T, R1, C1>,
R2: Dim, R2: Dim,
C2: Dim, C2: Dim,
S2: Storage<N, R2, C2>, S2: Storage<T, R2, C2>,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>, ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2>,
{ {
m1.zip_fold(m2, N::SimdRealField::zero(), |acc, a, b| { m1.zip_fold(m2, T::SimdRealField::zero(), |acc, a, b| {
let val = (a - b).simd_modulus(); let val = (a - b).simd_modulus();
acc.simd_max(val) acc.simd_max(val)
}) })
@ -155,14 +155,14 @@ impl<N: SimdComplexField> Norm<N> for UniformNorm {
} }
/// # Magnitude and norms /// # Magnitude and norms
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> { impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
/// The squared L2 norm of this vector. /// The squared L2 norm of this vector.
#[inline] #[inline]
pub fn norm_squared(&self) -> N::SimdRealField pub fn norm_squared(&self) -> T::SimdRealField
where where
N: SimdComplexField, T: SimdComplexField,
{ {
let mut res = N::SimdRealField::zero(); let mut res = T::SimdRealField::zero();
for i in 0..self.ncols() { for i in 0..self.ncols() {
let col = self.column(i); let col = self.column(i);
@ -176,9 +176,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// ///
/// Use `.apply_norm` to apply a custom norm. /// Use `.apply_norm` to apply a custom norm.
#[inline] #[inline]
pub fn norm(&self) -> N::SimdRealField pub fn norm(&self) -> T::SimdRealField
where where
N: SimdComplexField, T: SimdComplexField,
{ {
self.norm_squared().simd_sqrt() self.norm_squared().simd_sqrt()
} }
@ -187,12 +187,12 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// ///
/// Use `.apply_metric_distance` to apply a custom norm. /// Use `.apply_metric_distance` to apply a custom norm.
#[inline] #[inline]
pub fn metric_distance<R2, C2, S2>(&self, rhs: &Matrix<N, R2, C2, S2>) -> N::SimdRealField pub fn metric_distance<R2, C2, S2>(&self, rhs: &Matrix<T, R2, C2, S2>) -> T::SimdRealField
where where
N: SimdComplexField, T: SimdComplexField,
R2: Dim, R2: Dim,
C2: Dim, C2: Dim,
S2: Storage<N, R2, C2>, S2: Storage<T, R2, C2>,
ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>, ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
{ {
self.apply_metric_distance(rhs, &EuclideanNorm) self.apply_metric_distance(rhs, &EuclideanNorm)
@ -211,9 +211,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// assert_eq!(v.apply_norm(&EuclideanNorm), v.norm()); /// assert_eq!(v.apply_norm(&EuclideanNorm), v.norm());
/// ``` /// ```
#[inline] #[inline]
pub fn apply_norm(&self, norm: &impl Norm<N>) -> N::SimdRealField pub fn apply_norm(&self, norm: &impl Norm<T>) -> T::SimdRealField
where where
N: SimdComplexField, T: SimdComplexField,
{ {
norm.norm(self) norm.norm(self)
} }
@ -235,14 +235,14 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
#[inline] #[inline]
pub fn apply_metric_distance<R2, C2, S2>( pub fn apply_metric_distance<R2, C2, S2>(
&self, &self,
rhs: &Matrix<N, R2, C2, S2>, rhs: &Matrix<T, R2, C2, S2>,
norm: &impl Norm<N>, norm: &impl Norm<T>,
) -> N::SimdRealField ) -> T::SimdRealField
where where
N: SimdComplexField, T: SimdComplexField,
R2: Dim, R2: Dim,
C2: Dim, C2: Dim,
S2: Storage<N, R2, C2>, S2: Storage<T, R2, C2>,
ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>, ShapeConstraint: SameNumberOfRows<R, R2> + SameNumberOfColumns<C, C2>,
{ {
norm.metric_distance(self, rhs) norm.metric_distance(self, rhs)
@ -254,9 +254,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// ///
/// This function is simply implemented as a call to `norm()` /// This function is simply implemented as a call to `norm()`
#[inline] #[inline]
pub fn magnitude(&self) -> N::SimdRealField pub fn magnitude(&self) -> T::SimdRealField
where where
N: SimdComplexField, T: SimdComplexField,
{ {
self.norm() self.norm()
} }
@ -267,19 +267,19 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// ///
/// This function is simply implemented as a call to `norm_squared()` /// This function is simply implemented as a call to `norm_squared()`
#[inline] #[inline]
pub fn magnitude_squared(&self) -> N::SimdRealField pub fn magnitude_squared(&self) -> T::SimdRealField
where where
N: SimdComplexField, T: SimdComplexField,
{ {
self.norm_squared() self.norm_squared()
} }
/// Sets the magnitude of this vector. /// Sets the magnitude of this vector.
#[inline] #[inline]
pub fn set_magnitude(&mut self, magnitude: N::SimdRealField) pub fn set_magnitude(&mut self, magnitude: T::SimdRealField)
where where
N: SimdComplexField, T: SimdComplexField,
S: StorageMut<N, R, C>, S: StorageMut<T, R, C>,
{ {
let n = self.norm(); let n = self.norm();
self.scale_mut(magnitude / n) self.scale_mut(magnitude / n)
@ -288,19 +288,19 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// Returns a normalized version of this matrix. /// Returns a normalized version of this matrix.
#[inline] #[inline]
#[must_use = "Did you mean to use normalize_mut()?"] #[must_use = "Did you mean to use normalize_mut()?"]
pub fn normalize(&self) -> MatrixMN<N, R, C> pub fn normalize(&self) -> OMatrix<T, R, C>
where where
N: SimdComplexField, T: SimdComplexField,
DefaultAllocator: Allocator<N, R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
self.unscale(self.norm()) self.unscale(self.norm())
} }
/// The Lp norm of this matrix. /// The Lp norm of this matrix.
#[inline] #[inline]
pub fn lp_norm(&self, p: i32) -> N::SimdRealField pub fn lp_norm(&self, p: i32) -> T::SimdRealField
where where
N: SimdComplexField, T: SimdComplexField,
{ {
self.apply_norm(&LpNorm(p)) self.apply_norm(&LpNorm(p))
} }
@ -310,11 +310,11 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// The components of this matrix can be SIMD types. /// The components of this matrix can be SIMD types.
#[inline] #[inline]
#[must_use = "Did you mean to use simd_try_normalize_mut()?"] #[must_use = "Did you mean to use simd_try_normalize_mut()?"]
pub fn simd_try_normalize(&self, min_norm: N::SimdRealField) -> SimdOption<MatrixMN<N, R, C>> pub fn simd_try_normalize(&self, min_norm: T::SimdRealField) -> SimdOption<OMatrix<T, R, C>>
where where
N: SimdComplexField, T: SimdComplexField,
N::Element: Scalar, T::Element: Scalar,
DefaultAllocator: Allocator<N, R, C> + Allocator<N::Element, R, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{ {
let n = self.norm(); let n = self.norm();
let le = n.simd_le(min_norm); let le = n.simd_le(min_norm);
@ -327,10 +327,10 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// If `self.magnitude()` is smaller than `min_magnitude`, it will be left unchanged. /// If `self.magnitude()` is smaller than `min_magnitude`, it will be left unchanged.
/// Otherwise this is equivalent to: `*self = self.normalize() * magnitude. /// Otherwise this is equivalent to: `*self = self.normalize() * magnitude.
#[inline] #[inline]
pub fn try_set_magnitude(&mut self, magnitude: N::RealField, min_magnitude: N::RealField) pub fn try_set_magnitude(&mut self, magnitude: T::RealField, min_magnitude: T::RealField)
where where
N: ComplexField, T: ComplexField,
S: StorageMut<N, R, C>, S: StorageMut<T, R, C>,
{ {
let n = self.norm(); let n = self.norm();
@ -341,10 +341,10 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// Returns a new vector with the same magnitude as `self` clamped between `0.0` and `max`. /// Returns a new vector with the same magnitude as `self` clamped between `0.0` and `max`.
#[inline] #[inline]
pub fn cap_magnitude(&self, max: N::RealField) -> MatrixMN<N, R, C> pub fn cap_magnitude(&self, max: T::RealField) -> OMatrix<T, R, C>
where where
N: ComplexField, T: ComplexField,
DefaultAllocator: Allocator<N, R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
let n = self.norm(); let n = self.norm();
@ -357,11 +357,11 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// Returns a new vector with the same magnitude as `self` clamped between `0.0` and `max`. /// Returns a new vector with the same magnitude as `self` clamped between `0.0` and `max`.
#[inline] #[inline]
pub fn simd_cap_magnitude(&self, max: N::SimdRealField) -> MatrixMN<N, R, C> pub fn simd_cap_magnitude(&self, max: T::SimdRealField) -> OMatrix<T, R, C>
where where
N: SimdComplexField, T: SimdComplexField,
N::Element: Scalar, T::Element: Scalar,
DefaultAllocator: Allocator<N, R, C> + Allocator<N::Element, R, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{ {
let n = self.norm(); let n = self.norm();
let scaled = self.scale(max / n); let scaled = self.scale(max / n);
@ -374,10 +374,10 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// The components of this matrix cannot be SIMD types (see `simd_try_normalize`) instead. /// The components of this matrix cannot be SIMD types (see `simd_try_normalize`) instead.
#[inline] #[inline]
#[must_use = "Did you mean to use try_normalize_mut()?"] #[must_use = "Did you mean to use try_normalize_mut()?"]
pub fn try_normalize(&self, min_norm: N::RealField) -> Option<MatrixMN<N, R, C>> pub fn try_normalize(&self, min_norm: T::RealField) -> Option<OMatrix<T, R, C>>
where where
N: ComplexField, T: ComplexField,
DefaultAllocator: Allocator<N, R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
let n = self.norm(); let n = self.norm();
@ -390,14 +390,14 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
} }
/// # In-place normalization /// # In-place normalization
impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> { impl<T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> Matrix<T, R, C, S> {
/// Normalizes this matrix in-place and returns its norm. /// Normalizes this matrix in-place and returns its norm.
/// ///
/// The components of the matrix cannot be SIMD types (see `simd_try_normalize_mut` instead). /// The components of the matrix cannot be SIMD types (see `simd_try_normalize_mut` instead).
#[inline] #[inline]
pub fn normalize_mut(&mut self) -> N::SimdRealField pub fn normalize_mut(&mut self) -> T::SimdRealField
where where
N: SimdComplexField, T: SimdComplexField,
{ {
let n = self.norm(); let n = self.norm();
self.unscale_mut(n); self.unscale_mut(n);
@ -412,12 +412,12 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
#[must_use = "Did you mean to use simd_try_normalize_mut()?"] #[must_use = "Did you mean to use simd_try_normalize_mut()?"]
pub fn simd_try_normalize_mut( pub fn simd_try_normalize_mut(
&mut self, &mut self,
min_norm: N::SimdRealField, min_norm: T::SimdRealField,
) -> SimdOption<N::SimdRealField> ) -> SimdOption<T::SimdRealField>
where where
N: SimdComplexField, T: SimdComplexField,
N::Element: Scalar, T::Element: Scalar,
DefaultAllocator: Allocator<N, R, C> + Allocator<N::Element, R, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{ {
let n = self.norm(); let n = self.norm();
let le = n.simd_le(min_norm); let le = n.simd_le(min_norm);
@ -429,9 +429,9 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
/// ///
/// If the normalization succeeded, returns the old norm of this matrix. /// If the normalization succeeded, returns the old norm of this matrix.
#[inline] #[inline]
pub fn try_normalize_mut(&mut self, min_norm: N::RealField) -> Option<N::RealField> pub fn try_normalize_mut(&mut self, min_norm: T::RealField) -> Option<T::RealField>
where where
N: ComplexField, T: ComplexField,
{ {
let n = self.norm(); let n = self.norm();
@ -444,19 +444,19 @@ impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
} }
} }
impl<N: SimdComplexField, R: Dim, C: Dim> Normed for MatrixMN<N, R, C> impl<T: SimdComplexField, R: Dim, C: Dim> Normed for OMatrix<T, R, C>
where where
DefaultAllocator: Allocator<N, R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
type Norm = N::SimdRealField; type Norm = T::SimdRealField;
#[inline] #[inline]
fn norm(&self) -> N::SimdRealField { fn norm(&self) -> T::SimdRealField {
self.norm() self.norm()
} }
#[inline] #[inline]
fn norm_squared(&self) -> N::SimdRealField { fn norm_squared(&self) -> T::SimdRealField {
self.norm_squared() self.norm_squared()
} }
@ -471,11 +471,11 @@ where
} }
} }
impl<N: Scalar + ClosedNeg, R: Dim, C: Dim> Neg for Unit<MatrixMN<N, R, C>> impl<T: Scalar + ClosedNeg, R: Dim, C: Dim> Neg for Unit<OMatrix<T, R, C>>
where where
DefaultAllocator: Allocator<N, R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
type Output = Unit<MatrixMN<N, R, C>>; type Output = Unit<OMatrix<T, R, C>>;
#[inline] #[inline]
fn neg(self) -> Self::Output { fn neg(self) -> Self::Output {
@ -488,9 +488,9 @@ where
// use `x()` instead of `::canonical_basis_element` // use `x()` instead of `::canonical_basis_element`
// use `::new(x, y, z)` instead of `::from_slice` // use `::new(x, y, z)` instead of `::from_slice`
/// # Basis and orthogonalization /// # Basis and orthogonalization
impl<N: ComplexField, D: DimName> VectorN<N, D> impl<T: ComplexField, D: DimName> OVector<T, D>
where where
DefaultAllocator: Allocator<N, D>, DefaultAllocator: Allocator<T, D>,
{ {
/// The i-the canonical basis element. /// The i-the canonical basis element.
#[inline] #[inline]
@ -499,7 +499,7 @@ where
let mut res = Self::zero(); let mut res = Self::zero();
unsafe { unsafe {
*res.data.get_unchecked_linear_mut(i) = N::one(); *res.data.get_unchecked_linear_mut(i) = T::one();
} }
res res
@ -521,7 +521,7 @@ where
} }
} }
if vs[i].try_normalize_mut(N::RealField::zero()).is_some() { if vs[i].try_normalize_mut(T::RealField::zero()).is_some() {
// TODO: this will be efficient on dynamically-allocated vectors but for // TODO: this will be efficient on dynamically-allocated vectors but for
// statically-allocated ones, `.clone_from` would be better. // statically-allocated ones, `.clone_from` would be better.
vs.swap(nbasis_elements, i); vs.swap(nbasis_elements, i);
@ -581,9 +581,9 @@ where
let mut a; let mut a;
if v[0].norm1() > v[1].norm1() { if v[0].norm1() > v[1].norm1() {
a = Self::from_column_slice(&[v[2], N::zero(), -v[0]]); a = Self::from_column_slice(&[v[2], T::zero(), -v[0]]);
} else { } else {
a = Self::from_column_slice(&[N::zero(), -v[2], v[1]]); a = Self::from_column_slice(&[T::zero(), -v[2], v[1]]);
}; };
let _ = a.normalize_mut(); let _ = a.normalize_mut();
@ -612,7 +612,7 @@ where
elt -= v * elt.dot(v) elt -= v * elt.dot(v)
} }
if let Some(subsp_elt) = elt.try_normalize(N::RealField::zero()) { if let Some(subsp_elt) = elt.try_normalize(T::RealField::zero()) {
if !f(&subsp_elt) { if !f(&subsp_elt) {
return; return;
}; };

View File

@ -12,7 +12,7 @@ use crate::base::constraint::{
}; };
use crate::base::dimension::{Dim, DimMul, DimName, DimProd, Dynamic}; use crate::base::dimension::{Dim, DimMul, DimName, DimProd, Dynamic};
use crate::base::storage::{ContiguousStorageMut, Storage, StorageMut}; use crate::base::storage::{ContiguousStorageMut, Storage, StorageMut};
use crate::base::{DefaultAllocator, Matrix, MatrixMN, MatrixN, MatrixSum, Scalar, VectorSliceN}; use crate::base::{DefaultAllocator, Matrix, MatrixSum, OMatrix, Scalar, VectorSlice};
use crate::SimdComplexField; use crate::SimdComplexField;
/* /*
@ -20,8 +20,8 @@ use crate::SimdComplexField;
* Indexing. * Indexing.
* *
*/ */
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Index<usize> for Matrix<N, R, C, S> { impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Index<usize> for Matrix<T, R, C, S> {
type Output = N; type Output = T;
#[inline] #[inline]
fn index(&self, i: usize) -> &Self::Output { fn index(&self, i: usize) -> &Self::Output {
@ -30,12 +30,12 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Index<usize> for Matrix<N,
} }
} }
impl<N, R: Dim, C: Dim, S> Index<(usize, usize)> for Matrix<N, R, C, S> impl<T, R: Dim, C: Dim, S> Index<(usize, usize)> for Matrix<T, R, C, S>
where where
N: Scalar, T: Scalar,
S: Storage<N, R, C>, S: Storage<T, R, C>,
{ {
type Output = N; type Output = T;
#[inline] #[inline]
fn index(&self, ij: (usize, usize)) -> &Self::Output { fn index(&self, ij: (usize, usize)) -> &Self::Output {
@ -50,21 +50,21 @@ where
} }
// Mutable versions. // Mutable versions.
impl<N: Scalar, R: Dim, C: Dim, S: StorageMut<N, R, C>> IndexMut<usize> for Matrix<N, R, C, S> { impl<T: Scalar, R: Dim, C: Dim, S: StorageMut<T, R, C>> IndexMut<usize> for Matrix<T, R, C, S> {
#[inline] #[inline]
fn index_mut(&mut self, i: usize) -> &mut N { fn index_mut(&mut self, i: usize) -> &mut T {
let ij = self.vector_to_matrix_index(i); let ij = self.vector_to_matrix_index(i);
&mut self[ij] &mut self[ij]
} }
} }
impl<N, R: Dim, C: Dim, S> IndexMut<(usize, usize)> for Matrix<N, R, C, S> impl<T, R: Dim, C: Dim, S> IndexMut<(usize, usize)> for Matrix<T, R, C, S>
where where
N: Scalar, T: Scalar,
S: StorageMut<N, R, C>, S: StorageMut<T, R, C>,
{ {
#[inline] #[inline]
fn index_mut(&mut self, ij: (usize, usize)) -> &mut N { fn index_mut(&mut self, ij: (usize, usize)) -> &mut T {
let shape = self.shape(); let shape = self.shape();
assert!( assert!(
ij.0 < shape.0 && ij.1 < shape.1, ij.0 < shape.0 && ij.1 < shape.1,
@ -80,13 +80,13 @@ where
* Neg * Neg
* *
*/ */
impl<N, R: Dim, C: Dim, S> Neg for Matrix<N, R, C, S> impl<T, R: Dim, C: Dim, S> Neg for Matrix<T, R, C, S>
where where
N: Scalar + ClosedNeg, T: Scalar + ClosedNeg,
S: Storage<N, R, C>, S: Storage<T, R, C>,
DefaultAllocator: Allocator<N, R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
type Output = MatrixMN<N, R, C>; type Output = OMatrix<T, R, C>;
#[inline] #[inline]
fn neg(self) -> Self::Output { fn neg(self) -> Self::Output {
@ -96,13 +96,13 @@ where
} }
} }
impl<'a, N, R: Dim, C: Dim, S> Neg for &'a Matrix<N, R, C, S> impl<'a, T, R: Dim, C: Dim, S> Neg for &'a Matrix<T, R, C, S>
where where
N: Scalar + ClosedNeg, T: Scalar + ClosedNeg,
S: Storage<N, R, C>, S: Storage<T, R, C>,
DefaultAllocator: Allocator<N, R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
type Output = MatrixMN<N, R, C>; type Output = OMatrix<T, R, C>;
#[inline] #[inline]
fn neg(self) -> Self::Output { fn neg(self) -> Self::Output {
@ -110,10 +110,10 @@ where
} }
} }
impl<N, R: Dim, C: Dim, S> Matrix<N, R, C, S> impl<T, R: Dim, C: Dim, S> Matrix<T, R, C, S>
where where
N: Scalar + ClosedNeg, T: Scalar + ClosedNeg,
S: StorageMut<N, R, C>, S: StorageMut<T, R, C>,
{ {
/// Negates `self` in-place. /// Negates `self` in-place.
#[inline] #[inline]
@ -136,8 +136,8 @@ macro_rules! componentwise_binop_impl(
$method_assign_statically_unchecked_rhs: ident; $method_assign_statically_unchecked_rhs: ident;
$method_to: ident, $method_to_statically_unchecked: ident) => { $method_to: ident, $method_to_statically_unchecked: ident) => {
impl<N, R1: Dim, C1: Dim, SA: Storage<N, R1, C1>> Matrix<N, R1, C1, SA> impl<T, R1: Dim, C1: Dim, SA: Storage<T, R1, C1>> Matrix<T, R1, C1, SA>
where N: Scalar + $bound { where T: Scalar + $bound {
/* /*
* *
@ -149,10 +149,10 @@ macro_rules! componentwise_binop_impl(
#[inline] #[inline]
fn $method_to_statically_unchecked<R2: Dim, C2: Dim, SB, fn $method_to_statically_unchecked<R2: Dim, C2: Dim, SB,
R3: Dim, C3: Dim, SC>(&self, R3: Dim, C3: Dim, SC>(&self,
rhs: &Matrix<N, R2, C2, SB>, rhs: &Matrix<T, R2, C2, SB>,
out: &mut Matrix<N, R3, C3, SC>) out: &mut Matrix<T, R3, C3, SC>)
where SB: Storage<N, R2, C2>, where SB: Storage<T, R2, C2>,
SC: StorageMut<N, R3, C3> { SC: StorageMut<T, R3, C3> {
assert_eq!(self.shape(), rhs.shape(), "Matrix addition/subtraction dimensions mismatch."); assert_eq!(self.shape(), rhs.shape(), "Matrix addition/subtraction dimensions mismatch.");
assert_eq!(self.shape(), out.shape(), "Matrix addition/subtraction output dimensions mismatch."); assert_eq!(self.shape(), out.shape(), "Matrix addition/subtraction output dimensions mismatch.");
@ -182,11 +182,11 @@ macro_rules! componentwise_binop_impl(
#[inline] #[inline]
fn $method_assign_statically_unchecked<R2, C2, SB>(&mut self, rhs: &Matrix<N, R2, C2, SB>) fn $method_assign_statically_unchecked<R2, C2, SB>(&mut self, rhs: &Matrix<T, R2, C2, SB>)
where R2: Dim, where R2: Dim,
C2: Dim, C2: Dim,
SA: StorageMut<N, R1, C1>, SA: StorageMut<T, R1, C1>,
SB: Storage<N, R2, C2> { SB: Storage<T, R2, C2> {
assert_eq!(self.shape(), rhs.shape(), "Matrix addition/subtraction dimensions mismatch."); assert_eq!(self.shape(), rhs.shape(), "Matrix addition/subtraction dimensions mismatch.");
// This is the most common case and should be deduced at compile-time. // This is the most common case and should be deduced at compile-time.
@ -213,10 +213,10 @@ macro_rules! componentwise_binop_impl(
#[inline] #[inline]
fn $method_assign_statically_unchecked_rhs<R2, C2, SB>(&self, rhs: &mut Matrix<N, R2, C2, SB>) fn $method_assign_statically_unchecked_rhs<R2, C2, SB>(&self, rhs: &mut Matrix<T, R2, C2, SB>)
where R2: Dim, where R2: Dim,
C2: Dim, C2: Dim,
SB: StorageMut<N, R2, C2> { SB: StorageMut<T, R2, C2> {
assert_eq!(self.shape(), rhs.shape(), "Matrix addition/subtraction dimensions mismatch."); assert_eq!(self.shape(), rhs.shape(), "Matrix addition/subtraction dimensions mismatch.");
// This is the most common case and should be deduced at compile-time. // This is the most common case and should be deduced at compile-time.
@ -255,27 +255,27 @@ macro_rules! componentwise_binop_impl(
#[inline] #[inline]
pub fn $method_to<R2: Dim, C2: Dim, SB, pub fn $method_to<R2: Dim, C2: Dim, SB,
R3: Dim, C3: Dim, SC>(&self, R3: Dim, C3: Dim, SC>(&self,
rhs: &Matrix<N, R2, C2, SB>, rhs: &Matrix<T, R2, C2, SB>,
out: &mut Matrix<N, R3, C3, SC>) out: &mut Matrix<T, R3, C3, SC>)
where SB: Storage<N, R2, C2>, where SB: Storage<T, R2, C2>,
SC: StorageMut<N, R3, C3>, SC: StorageMut<T, R3, C3>,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> + ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> +
SameNumberOfRows<R1, R3> + SameNumberOfColumns<C1, C3> { SameNumberOfRows<R1, R3> + SameNumberOfColumns<C1, C3> {
self.$method_to_statically_unchecked(rhs, out) self.$method_to_statically_unchecked(rhs, out)
} }
} }
impl<'b, N, R1, C1, R2, C2, SA, SB> $Trait<&'b Matrix<N, R2, C2, SB>> for Matrix<N, R1, C1, SA> impl<'b, T, R1, C1, R2, C2, SA, SB> $Trait<&'b Matrix<T, R2, C2, SB>> for Matrix<T, R1, C1, SA>
where R1: Dim, C1: Dim, R2: Dim, C2: Dim, where R1: Dim, C1: Dim, R2: Dim, C2: Dim,
N: Scalar + $bound, T: Scalar + $bound,
SA: Storage<N, R1, C1>, SA: Storage<T, R1, C1>,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
DefaultAllocator: SameShapeAllocator<N, R1, C1, R2, C2>, DefaultAllocator: SameShapeAllocator<T, R1, C1, R2, C2>,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> { ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> {
type Output = MatrixSum<N, R1, C1, R2, C2>; type Output = MatrixSum<T, R1, C1, R2, C2>;
#[inline] #[inline]
fn $method(self, rhs: &'b Matrix<N, R2, C2, SB>) -> Self::Output { fn $method(self, rhs: &'b Matrix<T, R2, C2, SB>) -> Self::Output {
assert_eq!(self.shape(), rhs.shape(), "Matrix addition/subtraction dimensions mismatch."); assert_eq!(self.shape(), rhs.shape(), "Matrix addition/subtraction dimensions mismatch.");
let mut res = self.into_owned_sum::<R2, C2>(); let mut res = self.into_owned_sum::<R2, C2>();
res.$method_assign_statically_unchecked(rhs); res.$method_assign_statically_unchecked(rhs);
@ -283,17 +283,17 @@ macro_rules! componentwise_binop_impl(
} }
} }
impl<'a, N, R1, C1, R2, C2, SA, SB> $Trait<Matrix<N, R2, C2, SB>> for &'a Matrix<N, R1, C1, SA> impl<'a, T, R1, C1, R2, C2, SA, SB> $Trait<Matrix<T, R2, C2, SB>> for &'a Matrix<T, R1, C1, SA>
where R1: Dim, C1: Dim, R2: Dim, C2: Dim, where R1: Dim, C1: Dim, R2: Dim, C2: Dim,
N: Scalar + $bound, T: Scalar + $bound,
SA: Storage<N, R1, C1>, SA: Storage<T, R1, C1>,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
DefaultAllocator: SameShapeAllocator<N, R2, C2, R1, C1>, DefaultAllocator: SameShapeAllocator<T, R2, C2, R1, C1>,
ShapeConstraint: SameNumberOfRows<R2, R1> + SameNumberOfColumns<C2, C1> { ShapeConstraint: SameNumberOfRows<R2, R1> + SameNumberOfColumns<C2, C1> {
type Output = MatrixSum<N, R2, C2, R1, C1>; type Output = MatrixSum<T, R2, C2, R1, C1>;
#[inline] #[inline]
fn $method(self, rhs: Matrix<N, R2, C2, SB>) -> Self::Output { fn $method(self, rhs: Matrix<T, R2, C2, SB>) -> Self::Output {
let mut rhs = rhs.into_owned_sum::<R1, C1>(); let mut rhs = rhs.into_owned_sum::<R1, C1>();
assert_eq!(self.shape(), rhs.shape(), "Matrix addition/subtraction dimensions mismatch."); assert_eq!(self.shape(), rhs.shape(), "Matrix addition/subtraction dimensions mismatch.");
self.$method_assign_statically_unchecked_rhs(&mut rhs); self.$method_assign_statically_unchecked_rhs(&mut rhs);
@ -301,32 +301,32 @@ macro_rules! componentwise_binop_impl(
} }
} }
impl<N, R1, C1, R2, C2, SA, SB> $Trait<Matrix<N, R2, C2, SB>> for Matrix<N, R1, C1, SA> impl<T, R1, C1, R2, C2, SA, SB> $Trait<Matrix<T, R2, C2, SB>> for Matrix<T, R1, C1, SA>
where R1: Dim, C1: Dim, R2: Dim, C2: Dim, where R1: Dim, C1: Dim, R2: Dim, C2: Dim,
N: Scalar + $bound, T: Scalar + $bound,
SA: Storage<N, R1, C1>, SA: Storage<T, R1, C1>,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
DefaultAllocator: SameShapeAllocator<N, R1, C1, R2, C2>, DefaultAllocator: SameShapeAllocator<T, R1, C1, R2, C2>,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> { ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> {
type Output = MatrixSum<N, R1, C1, R2, C2>; type Output = MatrixSum<T, R1, C1, R2, C2>;
#[inline] #[inline]
fn $method(self, rhs: Matrix<N, R2, C2, SB>) -> Self::Output { fn $method(self, rhs: Matrix<T, R2, C2, SB>) -> Self::Output {
self.$method(&rhs) self.$method(&rhs)
} }
} }
impl<'a, 'b, N, R1, C1, R2, C2, SA, SB> $Trait<&'b Matrix<N, R2, C2, SB>> for &'a Matrix<N, R1, C1, SA> impl<'a, 'b, T, R1, C1, R2, C2, SA, SB> $Trait<&'b Matrix<T, R2, C2, SB>> for &'a Matrix<T, R1, C1, SA>
where R1: Dim, C1: Dim, R2: Dim, C2: Dim, where R1: Dim, C1: Dim, R2: Dim, C2: Dim,
N: Scalar + $bound, T: Scalar + $bound,
SA: Storage<N, R1, C1>, SA: Storage<T, R1, C1>,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
DefaultAllocator: SameShapeAllocator<N, R1, C1, R2, C2>, DefaultAllocator: SameShapeAllocator<T, R1, C1, R2, C2>,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> { ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> {
type Output = MatrixSum<N, R1, C1, R2, C2>; type Output = MatrixSum<T, R1, C1, R2, C2>;
#[inline] #[inline]
fn $method(self, rhs: &'b Matrix<N, R2, C2, SB>) -> Self::Output { fn $method(self, rhs: &'b Matrix<T, R2, C2, SB>) -> Self::Output {
let mut res = unsafe { let mut res = unsafe {
let (nrows, ncols) = self.shape(); let (nrows, ncols) = self.shape();
let nrows: SameShapeR<R1, R2> = Dim::from_usize(nrows); let nrows: SameShapeR<R1, R2> = Dim::from_usize(nrows);
@ -339,28 +339,28 @@ macro_rules! componentwise_binop_impl(
} }
} }
impl<'b, N, R1, C1, R2, C2, SA, SB> $TraitAssign<&'b Matrix<N, R2, C2, SB>> for Matrix<N, R1, C1, SA> impl<'b, T, R1, C1, R2, C2, SA, SB> $TraitAssign<&'b Matrix<T, R2, C2, SB>> for Matrix<T, R1, C1, SA>
where R1: Dim, C1: Dim, R2: Dim, C2: Dim, where R1: Dim, C1: Dim, R2: Dim, C2: Dim,
N: Scalar + $bound, T: Scalar + $bound,
SA: StorageMut<N, R1, C1>, SA: StorageMut<T, R1, C1>,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> { ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> {
#[inline] #[inline]
fn $method_assign(&mut self, rhs: &'b Matrix<N, R2, C2, SB>) { fn $method_assign(&mut self, rhs: &'b Matrix<T, R2, C2, SB>) {
self.$method_assign_statically_unchecked(rhs) self.$method_assign_statically_unchecked(rhs)
} }
} }
impl<N, R1, C1, R2, C2, SA, SB> $TraitAssign<Matrix<N, R2, C2, SB>> for Matrix<N, R1, C1, SA> impl<T, R1, C1, R2, C2, SA, SB> $TraitAssign<Matrix<T, R2, C2, SB>> for Matrix<T, R1, C1, SA>
where R1: Dim, C1: Dim, R2: Dim, C2: Dim, where R1: Dim, C1: Dim, R2: Dim, C2: Dim,
N: Scalar + $bound, T: Scalar + $bound,
SA: StorageMut<N, R1, C1>, SA: StorageMut<T, R1, C1>,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> { ShapeConstraint: SameNumberOfRows<R1, R2> + SameNumberOfColumns<C1, C2> {
#[inline] #[inline]
fn $method_assign(&mut self, rhs: Matrix<N, R2, C2, SB>) { fn $method_assign(&mut self, rhs: Matrix<T, R2, C2, SB>) {
self.$method_assign(&rhs) self.$method_assign(&rhs)
} }
} }
@ -374,20 +374,20 @@ componentwise_binop_impl!(Sub, sub, ClosedSub;
SubAssign, sub_assign, sub_assign_statically_unchecked, sub_assign_statically_unchecked_mut; SubAssign, sub_assign, sub_assign_statically_unchecked, sub_assign_statically_unchecked_mut;
sub_to, sub_to_statically_unchecked); sub_to, sub_to_statically_unchecked);
impl<N, R: DimName, C: DimName> iter::Sum for MatrixMN<N, R, C> impl<T, R: DimName, C: DimName> iter::Sum for OMatrix<T, R, C>
where where
N: Scalar + ClosedAdd + Zero, T: Scalar + ClosedAdd + Zero,
DefaultAllocator: Allocator<N, R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
fn sum<I: Iterator<Item = MatrixMN<N, R, C>>>(iter: I) -> MatrixMN<N, R, C> { fn sum<I: Iterator<Item = OMatrix<T, R, C>>>(iter: I) -> OMatrix<T, R, C> {
iter.fold(Matrix::zero(), |acc, x| acc + x) iter.fold(Matrix::zero(), |acc, x| acc + x)
} }
} }
impl<N, C: Dim> iter::Sum for MatrixMN<N, Dynamic, C> impl<T, C: Dim> iter::Sum for OMatrix<T, Dynamic, C>
where where
N: Scalar + ClosedAdd + Zero, T: Scalar + ClosedAdd + Zero,
DefaultAllocator: Allocator<N, Dynamic, C>, DefaultAllocator: Allocator<T, Dynamic, C>,
{ {
/// # Example /// # Example
/// ``` /// ```
@ -405,7 +405,7 @@ where
/// # use nalgebra::DMatrix; /// # use nalgebra::DMatrix;
/// iter::empty::<DMatrix<f64>>().sum::<DMatrix<f64>>(); // panics! /// iter::empty::<DMatrix<f64>>().sum::<DMatrix<f64>>(); // panics!
/// ``` /// ```
fn sum<I: Iterator<Item = MatrixMN<N, Dynamic, C>>>(mut iter: I) -> MatrixMN<N, Dynamic, C> { fn sum<I: Iterator<Item = OMatrix<T, Dynamic, C>>>(mut iter: I) -> OMatrix<T, Dynamic, C> {
if let Some(first) = iter.next() { if let Some(first) = iter.next() {
iter.fold(first, |acc, x| acc + x) iter.fold(first, |acc, x| acc + x)
} else { } else {
@ -414,20 +414,20 @@ where
} }
} }
impl<'a, N, R: DimName, C: DimName> iter::Sum<&'a MatrixMN<N, R, C>> for MatrixMN<N, R, C> impl<'a, T, R: DimName, C: DimName> iter::Sum<&'a OMatrix<T, R, C>> for OMatrix<T, R, C>
where where
N: Scalar + ClosedAdd + Zero, T: Scalar + ClosedAdd + Zero,
DefaultAllocator: Allocator<N, R, C>, DefaultAllocator: Allocator<T, R, C>,
{ {
fn sum<I: Iterator<Item = &'a MatrixMN<N, R, C>>>(iter: I) -> MatrixMN<N, R, C> { fn sum<I: Iterator<Item = &'a OMatrix<T, R, C>>>(iter: I) -> OMatrix<T, R, C> {
iter.fold(Matrix::zero(), |acc, x| acc + x) iter.fold(Matrix::zero(), |acc, x| acc + x)
} }
} }
impl<'a, N, C: Dim> iter::Sum<&'a MatrixMN<N, Dynamic, C>> for MatrixMN<N, Dynamic, C> impl<'a, T, C: Dim> iter::Sum<&'a OMatrix<T, Dynamic, C>> for OMatrix<T, Dynamic, C>
where where
N: Scalar + ClosedAdd + Zero, T: Scalar + ClosedAdd + Zero,
DefaultAllocator: Allocator<N, Dynamic, C>, DefaultAllocator: Allocator<T, Dynamic, C>,
{ {
/// # Example /// # Example
/// ``` /// ```
@ -445,9 +445,7 @@ where
/// # use nalgebra::DMatrix; /// # use nalgebra::DMatrix;
/// iter::empty::<&DMatrix<f64>>().sum::<DMatrix<f64>>(); // panics! /// iter::empty::<&DMatrix<f64>>().sum::<DMatrix<f64>>(); // panics!
/// ``` /// ```
fn sum<I: Iterator<Item = &'a MatrixMN<N, Dynamic, C>>>( fn sum<I: Iterator<Item = &'a OMatrix<T, Dynamic, C>>>(mut iter: I) -> OMatrix<T, Dynamic, C> {
mut iter: I,
) -> MatrixMN<N, Dynamic, C> {
if let Some(first) = iter.next() { if let Some(first) = iter.next() {
iter.fold(first.clone(), |acc, x| acc + x) iter.fold(first.clone(), |acc, x| acc + x)
} else { } else {
@ -467,14 +465,14 @@ where
macro_rules! componentwise_scalarop_impl( macro_rules! componentwise_scalarop_impl(
($Trait: ident, $method: ident, $bound: ident; ($Trait: ident, $method: ident, $bound: ident;
$TraitAssign: ident, $method_assign: ident) => { $TraitAssign: ident, $method_assign: ident) => {
impl<N, R: Dim, C: Dim, S> $Trait<N> for Matrix<N, R, C, S> impl<T, R: Dim, C: Dim, S> $Trait<T> for Matrix<T, R, C, S>
where N: Scalar + $bound, where T: Scalar + $bound,
S: Storage<N, R, C>, S: Storage<T, R, C>,
DefaultAllocator: Allocator<N, R, C> { DefaultAllocator: Allocator<T, R, C> {
type Output = MatrixMN<N, R, C>; type Output = OMatrix<T, R, C>;
#[inline] #[inline]
fn $method(self, rhs: N) -> Self::Output { fn $method(self, rhs: T) -> Self::Output {
let mut res = self.into_owned(); let mut res = self.into_owned();
// XXX: optimize our iterator! // XXX: optimize our iterator!
@ -491,23 +489,23 @@ macro_rules! componentwise_scalarop_impl(
} }
} }
impl<'a, N, R: Dim, C: Dim, S> $Trait<N> for &'a Matrix<N, R, C, S> impl<'a, T, R: Dim, C: Dim, S> $Trait<T> for &'a Matrix<T, R, C, S>
where N: Scalar + $bound, where T: Scalar + $bound,
S: Storage<N, R, C>, S: Storage<T, R, C>,
DefaultAllocator: Allocator<N, R, C> { DefaultAllocator: Allocator<T, R, C> {
type Output = MatrixMN<N, R, C>; type Output = OMatrix<T, R, C>;
#[inline] #[inline]
fn $method(self, rhs: N) -> Self::Output { fn $method(self, rhs: T) -> Self::Output {
self.clone_owned().$method(rhs) self.clone_owned().$method(rhs)
} }
} }
impl<N, R: Dim, C: Dim, S> $TraitAssign<N> for Matrix<N, R, C, S> impl<T, R: Dim, C: Dim, S> $TraitAssign<T> for Matrix<T, R, C, S>
where N: Scalar + $bound, where T: Scalar + $bound,
S: StorageMut<N, R, C> { S: StorageMut<T, R, C> {
#[inline] #[inline]
fn $method_assign(&mut self, rhs: N) { fn $method_assign(&mut self, rhs: T) {
for j in 0 .. self.ncols() { for j in 0 .. self.ncols() {
for i in 0 .. self.nrows() { for i in 0 .. self.nrows() {
unsafe { self.get_unchecked_mut((i, j)).$method_assign(rhs.inlined_clone()) }; unsafe { self.get_unchecked_mut((i, j)).$method_assign(rhs.inlined_clone()) };
@ -525,7 +523,7 @@ macro_rules! left_scalar_mul_impl(
($($T: ty),* $(,)*) => {$( ($($T: ty),* $(,)*) => {$(
impl<R: Dim, C: Dim, S: Storage<$T, R, C>> Mul<Matrix<$T, R, C, S>> for $T impl<R: Dim, C: Dim, S: Storage<$T, R, C>> Mul<Matrix<$T, R, C, S>> for $T
where DefaultAllocator: Allocator<$T, R, C> { where DefaultAllocator: Allocator<$T, R, C> {
type Output = MatrixMN<$T, R, C>; type Output = OMatrix<$T, R, C>;
#[inline] #[inline]
fn mul(self, rhs: Matrix<$T, R, C, S>) -> Self::Output { fn mul(self, rhs: Matrix<$T, R, C, S>) -> Self::Output {
@ -547,7 +545,7 @@ macro_rules! left_scalar_mul_impl(
impl<'b, R: Dim, C: Dim, S: Storage<$T, R, C>> Mul<&'b Matrix<$T, R, C, S>> for $T impl<'b, R: Dim, C: Dim, S: Storage<$T, R, C>> Mul<&'b Matrix<$T, R, C, S>> for $T
where DefaultAllocator: Allocator<$T, R, C> { where DefaultAllocator: Allocator<$T, R, C> {
type Output = MatrixMN<$T, R, C>; type Output = OMatrix<$T, R, C>;
#[inline] #[inline]
fn mul(self, rhs: &'b Matrix<$T, R, C, S>) -> Self::Output { fn mul(self, rhs: &'b Matrix<$T, R, C, S>) -> Self::Output {
@ -560,19 +558,19 @@ macro_rules! left_scalar_mul_impl(
left_scalar_mul_impl!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize, f32, f64); left_scalar_mul_impl!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize, f32, f64);
// Matrix × Matrix // Matrix × Matrix
impl<'a, 'b, N, R1: Dim, C1: Dim, R2: Dim, C2: Dim, SA, SB> Mul<&'b Matrix<N, R2, C2, SB>> impl<'a, 'b, T, R1: Dim, C1: Dim, R2: Dim, C2: Dim, SA, SB> Mul<&'b Matrix<T, R2, C2, SB>>
for &'a Matrix<N, R1, C1, SA> for &'a Matrix<T, R1, C1, SA>
where where
N: Scalar + Zero + One + ClosedAdd + ClosedMul, T: Scalar + Zero + One + ClosedAdd + ClosedMul,
SA: Storage<N, R1, C1>, SA: Storage<T, R1, C1>,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
DefaultAllocator: Allocator<N, R1, C2>, DefaultAllocator: Allocator<T, R1, C2>,
ShapeConstraint: AreMultipliable<R1, C1, R2, C2>, ShapeConstraint: AreMultipliable<R1, C1, R2, C2>,
{ {
type Output = MatrixMN<N, R1, C2>; type Output = OMatrix<T, R1, C2>;
#[inline] #[inline]
fn mul(self, rhs: &'b Matrix<N, R2, C2, SB>) -> Self::Output { fn mul(self, rhs: &'b Matrix<T, R2, C2, SB>) -> Self::Output {
let mut res = unsafe { let mut res = unsafe {
crate::unimplemented_or_uninitialized_generic!(self.data.shape().0, rhs.data.shape().1) crate::unimplemented_or_uninitialized_generic!(self.data.shape().0, rhs.data.shape().1)
}; };
@ -581,53 +579,53 @@ where
} }
} }
impl<'a, N, R1: Dim, C1: Dim, R2: Dim, C2: Dim, SA, SB> Mul<Matrix<N, R2, C2, SB>> impl<'a, T, R1: Dim, C1: Dim, R2: Dim, C2: Dim, SA, SB> Mul<Matrix<T, R2, C2, SB>>
for &'a Matrix<N, R1, C1, SA> for &'a Matrix<T, R1, C1, SA>
where where
N: Scalar + Zero + One + ClosedAdd + ClosedMul, T: Scalar + Zero + One + ClosedAdd + ClosedMul,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
SA: Storage<N, R1, C1>, SA: Storage<T, R1, C1>,
DefaultAllocator: Allocator<N, R1, C2>, DefaultAllocator: Allocator<T, R1, C2>,
ShapeConstraint: AreMultipliable<R1, C1, R2, C2>, ShapeConstraint: AreMultipliable<R1, C1, R2, C2>,
{ {
type Output = MatrixMN<N, R1, C2>; type Output = OMatrix<T, R1, C2>;
#[inline] #[inline]
fn mul(self, rhs: Matrix<N, R2, C2, SB>) -> Self::Output { fn mul(self, rhs: Matrix<T, R2, C2, SB>) -> Self::Output {
self * &rhs self * &rhs
} }
} }
impl<'b, N, R1: Dim, C1: Dim, R2: Dim, C2: Dim, SA, SB> Mul<&'b Matrix<N, R2, C2, SB>> impl<'b, T, R1: Dim, C1: Dim, R2: Dim, C2: Dim, SA, SB> Mul<&'b Matrix<T, R2, C2, SB>>
for Matrix<N, R1, C1, SA> for Matrix<T, R1, C1, SA>
where where
N: Scalar + Zero + One + ClosedAdd + ClosedMul, T: Scalar + Zero + One + ClosedAdd + ClosedMul,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
SA: Storage<N, R1, C1>, SA: Storage<T, R1, C1>,
DefaultAllocator: Allocator<N, R1, C2>, DefaultAllocator: Allocator<T, R1, C2>,
ShapeConstraint: AreMultipliable<R1, C1, R2, C2>, ShapeConstraint: AreMultipliable<R1, C1, R2, C2>,
{ {
type Output = MatrixMN<N, R1, C2>; type Output = OMatrix<T, R1, C2>;
#[inline] #[inline]
fn mul(self, rhs: &'b Matrix<N, R2, C2, SB>) -> Self::Output { fn mul(self, rhs: &'b Matrix<T, R2, C2, SB>) -> Self::Output {
&self * rhs &self * rhs
} }
} }
impl<N, R1: Dim, C1: Dim, R2: Dim, C2: Dim, SA, SB> Mul<Matrix<N, R2, C2, SB>> impl<T, R1: Dim, C1: Dim, R2: Dim, C2: Dim, SA, SB> Mul<Matrix<T, R2, C2, SB>>
for Matrix<N, R1, C1, SA> for Matrix<T, R1, C1, SA>
where where
N: Scalar + Zero + One + ClosedAdd + ClosedMul, T: Scalar + Zero + One + ClosedAdd + ClosedMul,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
SA: Storage<N, R1, C1>, SA: Storage<T, R1, C1>,
DefaultAllocator: Allocator<N, R1, C2>, DefaultAllocator: Allocator<T, R1, C2>,
ShapeConstraint: AreMultipliable<R1, C1, R2, C2>, ShapeConstraint: AreMultipliable<R1, C1, R2, C2>,
{ {
type Output = MatrixMN<N, R1, C2>; type Output = OMatrix<T, R1, C2>;
#[inline] #[inline]
fn mul(self, rhs: Matrix<N, R2, C2, SB>) -> Self::Output { fn mul(self, rhs: Matrix<T, R2, C2, SB>) -> Self::Output {
&self * &rhs &self * &rhs
} }
} }
@ -635,53 +633,53 @@ where
// TODO: this is too restrictive: // TODO: this is too restrictive:
// we can't use `a *= b` when `a` is a mutable slice. // we can't use `a *= b` when `a` is a mutable slice.
// we can't use `a *= b` when C2 is not equal to C1. // we can't use `a *= b` when C2 is not equal to C1.
impl<N, R1, C1, R2, SA, SB> MulAssign<Matrix<N, R2, C1, SB>> for Matrix<N, R1, C1, SA> impl<T, R1, C1, R2, SA, SB> MulAssign<Matrix<T, R2, C1, SB>> for Matrix<T, R1, C1, SA>
where where
R1: Dim, R1: Dim,
C1: Dim, C1: Dim,
R2: Dim, R2: Dim,
N: Scalar + Zero + One + ClosedAdd + ClosedMul, T: Scalar + Zero + One + ClosedAdd + ClosedMul,
SB: Storage<N, R2, C1>, SB: Storage<T, R2, C1>,
SA: ContiguousStorageMut<N, R1, C1> + Clone, SA: ContiguousStorageMut<T, R1, C1> + Clone,
ShapeConstraint: AreMultipliable<R1, C1, R2, C1>, ShapeConstraint: AreMultipliable<R1, C1, R2, C1>,
DefaultAllocator: Allocator<N, R1, C1, Buffer = SA>, DefaultAllocator: Allocator<T, R1, C1, Buffer = SA>,
{ {
#[inline] #[inline]
fn mul_assign(&mut self, rhs: Matrix<N, R2, C1, SB>) { fn mul_assign(&mut self, rhs: Matrix<T, R2, C1, SB>) {
*self = &*self * rhs *self = &*self * rhs
} }
} }
impl<'b, N, R1, C1, R2, SA, SB> MulAssign<&'b Matrix<N, R2, C1, SB>> for Matrix<N, R1, C1, SA> impl<'b, T, R1, C1, R2, SA, SB> MulAssign<&'b Matrix<T, R2, C1, SB>> for Matrix<T, R1, C1, SA>
where where
R1: Dim, R1: Dim,
C1: Dim, C1: Dim,
R2: Dim, R2: Dim,
N: Scalar + Zero + One + ClosedAdd + ClosedMul, T: Scalar + Zero + One + ClosedAdd + ClosedMul,
SB: Storage<N, R2, C1>, SB: Storage<T, R2, C1>,
SA: ContiguousStorageMut<N, R1, C1> + Clone, SA: ContiguousStorageMut<T, R1, C1> + Clone,
ShapeConstraint: AreMultipliable<R1, C1, R2, C1>, ShapeConstraint: AreMultipliable<R1, C1, R2, C1>,
// TODO: this is too restrictive. See comments for the non-ref version. // TODO: this is too restrictive. See comments for the non-ref version.
DefaultAllocator: Allocator<N, R1, C1, Buffer = SA>, DefaultAllocator: Allocator<T, R1, C1, Buffer = SA>,
{ {
#[inline] #[inline]
fn mul_assign(&mut self, rhs: &'b Matrix<N, R2, C1, SB>) { fn mul_assign(&mut self, rhs: &'b Matrix<T, R2, C1, SB>) {
*self = &*self * rhs *self = &*self * rhs
} }
} }
/// # Special multiplications. /// # Special multiplications.
impl<N, R1: Dim, C1: Dim, SA> Matrix<N, R1, C1, SA> impl<T, R1: Dim, C1: Dim, SA> Matrix<T, R1, C1, SA>
where where
N: Scalar + Zero + One + ClosedAdd + ClosedMul, T: Scalar + Zero + One + ClosedAdd + ClosedMul,
SA: Storage<N, R1, C1>, SA: Storage<T, R1, C1>,
{ {
/// Equivalent to `self.transpose() * rhs`. /// Equivalent to `self.transpose() * rhs`.
#[inline] #[inline]
pub fn tr_mul<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> MatrixMN<N, C1, C2> pub fn tr_mul<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> OMatrix<T, C1, C2>
where where
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
DefaultAllocator: Allocator<N, C1, C2>, DefaultAllocator: Allocator<T, C1, C2>,
ShapeConstraint: SameNumberOfRows<R1, R2>, ShapeConstraint: SameNumberOfRows<R1, R2>,
{ {
let mut res = unsafe { let mut res = unsafe {
@ -694,11 +692,11 @@ where
/// Equivalent to `self.adjoint() * rhs`. /// Equivalent to `self.adjoint() * rhs`.
#[inline] #[inline]
pub fn ad_mul<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<N, R2, C2, SB>) -> MatrixMN<N, C1, C2> pub fn ad_mul<R2: Dim, C2: Dim, SB>(&self, rhs: &Matrix<T, R2, C2, SB>) -> OMatrix<T, C1, C2>
where where
N: SimdComplexField, T: SimdComplexField,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
DefaultAllocator: Allocator<N, C1, C2>, DefaultAllocator: Allocator<T, C1, C2>,
ShapeConstraint: SameNumberOfRows<R1, R2>, ShapeConstraint: SameNumberOfRows<R1, R2>,
{ {
let mut res = unsafe { let mut res = unsafe {
@ -712,15 +710,15 @@ where
#[inline(always)] #[inline(always)]
fn xx_mul_to<R2: Dim, C2: Dim, SB, R3: Dim, C3: Dim, SC>( fn xx_mul_to<R2: Dim, C2: Dim, SB, R3: Dim, C3: Dim, SC>(
&self, &self,
rhs: &Matrix<N, R2, C2, SB>, rhs: &Matrix<T, R2, C2, SB>,
out: &mut Matrix<N, R3, C3, SC>, out: &mut Matrix<T, R3, C3, SC>,
dot: impl Fn( dot: impl Fn(
&VectorSliceN<N, R1, SA::RStride, SA::CStride>, &VectorSlice<T, R1, SA::RStride, SA::CStride>,
&VectorSliceN<N, R2, SB::RStride, SB::CStride>, &VectorSlice<T, R2, SB::RStride, SB::CStride>,
) -> N, ) -> T,
) where ) where
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
SC: StorageMut<N, R3, C3>, SC: StorageMut<T, R3, C3>,
ShapeConstraint: SameNumberOfRows<R1, R2> + DimEq<C1, R3> + DimEq<C2, C3>, ShapeConstraint: SameNumberOfRows<R1, R2> + DimEq<C1, R3> + DimEq<C2, C3>,
{ {
let (nrows1, ncols1) = self.shape(); let (nrows1, ncols1) = self.shape();
@ -759,11 +757,11 @@ where
#[inline] #[inline]
pub fn tr_mul_to<R2: Dim, C2: Dim, SB, R3: Dim, C3: Dim, SC>( pub fn tr_mul_to<R2: Dim, C2: Dim, SB, R3: Dim, C3: Dim, SC>(
&self, &self,
rhs: &Matrix<N, R2, C2, SB>, rhs: &Matrix<T, R2, C2, SB>,
out: &mut Matrix<N, R3, C3, SC>, out: &mut Matrix<T, R3, C3, SC>,
) where ) where
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
SC: StorageMut<N, R3, C3>, SC: StorageMut<T, R3, C3>,
ShapeConstraint: SameNumberOfRows<R1, R2> + DimEq<C1, R3> + DimEq<C2, C3>, ShapeConstraint: SameNumberOfRows<R1, R2> + DimEq<C1, R3> + DimEq<C2, C3>,
{ {
self.xx_mul_to(rhs, out, |a, b| a.dot(b)) self.xx_mul_to(rhs, out, |a, b| a.dot(b))
@ -774,12 +772,12 @@ where
#[inline] #[inline]
pub fn ad_mul_to<R2: Dim, C2: Dim, SB, R3: Dim, C3: Dim, SC>( pub fn ad_mul_to<R2: Dim, C2: Dim, SB, R3: Dim, C3: Dim, SC>(
&self, &self,
rhs: &Matrix<N, R2, C2, SB>, rhs: &Matrix<T, R2, C2, SB>,
out: &mut Matrix<N, R3, C3, SC>, out: &mut Matrix<T, R3, C3, SC>,
) where ) where
N: SimdComplexField, T: SimdComplexField,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
SC: StorageMut<N, R3, C3>, SC: StorageMut<T, R3, C3>,
ShapeConstraint: SameNumberOfRows<R1, R2> + DimEq<C1, R3> + DimEq<C2, C3>, ShapeConstraint: SameNumberOfRows<R1, R2> + DimEq<C1, R3> + DimEq<C2, C3>,
{ {
self.xx_mul_to(rhs, out, |a, b| a.dotc(b)) self.xx_mul_to(rhs, out, |a, b| a.dotc(b))
@ -789,30 +787,30 @@ where
#[inline] #[inline]
pub fn mul_to<R2: Dim, C2: Dim, SB, R3: Dim, C3: Dim, SC>( pub fn mul_to<R2: Dim, C2: Dim, SB, R3: Dim, C3: Dim, SC>(
&self, &self,
rhs: &Matrix<N, R2, C2, SB>, rhs: &Matrix<T, R2, C2, SB>,
out: &mut Matrix<N, R3, C3, SC>, out: &mut Matrix<T, R3, C3, SC>,
) where ) where
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
SC: StorageMut<N, R3, C3>, SC: StorageMut<T, R3, C3>,
ShapeConstraint: SameNumberOfRows<R3, R1> ShapeConstraint: SameNumberOfRows<R3, R1>
+ SameNumberOfColumns<C3, C2> + SameNumberOfColumns<C3, C2>
+ AreMultipliable<R1, C1, R2, C2>, + AreMultipliable<R1, C1, R2, C2>,
{ {
out.gemm(N::one(), self, rhs, N::zero()); out.gemm(T::one(), self, rhs, T::zero());
} }
/// The kronecker product of two matrices (aka. tensor product of the corresponding linear /// The kronecker product of two matrices (aka. tensor product of the corresponding linear
/// maps). /// maps).
pub fn kronecker<R2: Dim, C2: Dim, SB>( pub fn kronecker<R2: Dim, C2: Dim, SB>(
&self, &self,
rhs: &Matrix<N, R2, C2, SB>, rhs: &Matrix<T, R2, C2, SB>,
) -> MatrixMN<N, DimProd<R1, R2>, DimProd<C1, C2>> ) -> OMatrix<T, DimProd<R1, R2>, DimProd<C1, C2>>
where where
N: ClosedMul, T: ClosedMul,
R1: DimMul<R2>, R1: DimMul<R2>,
C1: DimMul<C2>, C1: DimMul<C2>,
SB: Storage<N, R2, C2>, SB: Storage<T, R2, C2>,
DefaultAllocator: Allocator<N, DimProd<R1, R2>, DimProd<C1, C2>>, DefaultAllocator: Allocator<T, DimProd<R1, R2>, DimProd<C1, C2>>,
{ {
let (nrows1, ncols1) = self.data.shape(); let (nrows1, ncols1) = self.data.shape();
let (nrows2, ncols2) = rhs.data.shape(); let (nrows2, ncols2) = rhs.data.shape();
@ -845,22 +843,22 @@ where
} }
} }
impl<N, D: DimName> iter::Product for MatrixN<N, D> impl<T, D: DimName> iter::Product for OMatrix<T, D, D>
where where
N: Scalar + Zero + One + ClosedMul + ClosedAdd, T: Scalar + Zero + One + ClosedMul + ClosedAdd,
DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
fn product<I: Iterator<Item = MatrixN<N, D>>>(iter: I) -> MatrixN<N, D> { fn product<I: Iterator<Item = OMatrix<T, D, D>>>(iter: I) -> OMatrix<T, D, D> {
iter.fold(Matrix::one(), |acc, x| acc * x) iter.fold(Matrix::one(), |acc, x| acc * x)
} }
} }
impl<'a, N, D: DimName> iter::Product<&'a MatrixN<N, D>> for MatrixN<N, D> impl<'a, T, D: DimName> iter::Product<&'a OMatrix<T, D, D>> for OMatrix<T, D, D>
where where
N: Scalar + Zero + One + ClosedMul + ClosedAdd, T: Scalar + Zero + One + ClosedMul + ClosedAdd,
DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
fn product<I: Iterator<Item = &'a MatrixN<N, D>>>(iter: I) -> MatrixN<N, D> { fn product<I: Iterator<Item = &'a OMatrix<T, D, D>>>(iter: I) -> OMatrix<T, D, D> {
iter.fold(Matrix::one(), |acc, x| acc * x) iter.fold(Matrix::one(), |acc, x| acc * x)
} }
} }

View File

@ -9,7 +9,7 @@ use crate::base::dimension::{Dim, DimMin};
use crate::base::storage::Storage; use crate::base::storage::Storage;
use crate::base::{DefaultAllocator, Matrix, Scalar, SquareMatrix}; use crate::base::{DefaultAllocator, Matrix, Scalar, SquareMatrix};
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> { impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
/// The total number of elements of this matrix. /// The total number of elements of this matrix.
/// ///
/// # Examples: /// # Examples:
@ -52,10 +52,10 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// If the matrix is diagonal, this checks that diagonal elements (i.e. at coordinates `(i, i)` /// If the matrix is diagonal, this checks that diagonal elements (i.e. at coordinates `(i, i)`
/// for i from `0` to `min(R, C)`) are equal one; and that all other elements are zero. /// for i from `0` to `min(R, C)`) are equal one; and that all other elements are zero.
#[inline] #[inline]
pub fn is_identity(&self, eps: N::Epsilon) -> bool pub fn is_identity(&self, eps: T::Epsilon) -> bool
where where
N: Zero + One + RelativeEq, T: Zero + One + RelativeEq,
N::Epsilon: Copy, T::Epsilon: Copy,
{ {
let (nrows, ncols) = self.shape(); let (nrows, ncols) = self.shape();
let d; let d;
@ -65,7 +65,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
for i in d..nrows { for i in d..nrows {
for j in 0..ncols { for j in 0..ncols {
if !relative_eq!(self[(i, j)], N::zero(), epsilon = eps) { if !relative_eq!(self[(i, j)], T::zero(), epsilon = eps) {
return false; return false;
} }
} }
@ -76,7 +76,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
for i in 0..nrows { for i in 0..nrows {
for j in d..ncols { for j in d..ncols {
if !relative_eq!(self[(i, j)], N::zero(), epsilon = eps) { if !relative_eq!(self[(i, j)], T::zero(), epsilon = eps) {
return false; return false;
} }
} }
@ -87,8 +87,8 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
for i in 1..d { for i in 1..d {
for j in 0..i { for j in 0..i {
// TODO: use unsafe indexing. // TODO: use unsafe indexing.
if !relative_eq!(self[(i, j)], N::zero(), epsilon = eps) if !relative_eq!(self[(i, j)], T::zero(), epsilon = eps)
|| !relative_eq!(self[(j, i)], N::zero(), epsilon = eps) || !relative_eq!(self[(j, i)], T::zero(), epsilon = eps)
{ {
return false; return false;
} }
@ -97,7 +97,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
// Diagonal elements of the sub-square matrix. // Diagonal elements of the sub-square matrix.
for i in 0..d { for i in 0..d {
if !relative_eq!(self[(i, i)], N::one(), epsilon = eps) { if !relative_eq!(self[(i, i)], T::one(), epsilon = eps) {
return false; return false;
} }
} }
@ -106,35 +106,35 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
} }
} }
impl<N: ComplexField, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> { impl<T: ComplexField, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
/// Checks that `Mᵀ × M = Id`. /// Checks that `Mᵀ × M = Id`.
/// ///
/// In this definition `Id` is approximately equal to the identity matrix with a relative error /// In this definition `Id` is approximately equal to the identity matrix with a relative error
/// equal to `eps`. /// equal to `eps`.
#[inline] #[inline]
pub fn is_orthogonal(&self, eps: N::Epsilon) -> bool pub fn is_orthogonal(&self, eps: T::Epsilon) -> bool
where where
N: Zero + One + ClosedAdd + ClosedMul + RelativeEq, T: Zero + One + ClosedAdd + ClosedMul + RelativeEq,
S: Storage<N, R, C>, S: Storage<T, R, C>,
N::Epsilon: Copy, T::Epsilon: Copy,
DefaultAllocator: Allocator<N, R, C> + Allocator<N, C, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T, C, C>,
{ {
(self.ad_mul(self)).is_identity(eps) (self.ad_mul(self)).is_identity(eps)
} }
} }
impl<N: RealField, D: Dim, S: Storage<N, D, D>> SquareMatrix<N, D, S> impl<T: RealField, D: Dim, S: Storage<T, D, D>> SquareMatrix<T, D, S>
where where
DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
/// Checks that this matrix is orthogonal and has a determinant equal to 1. /// Checks that this matrix is orthogonal and has a determinant equal to 1.
#[inline] #[inline]
pub fn is_special_orthogonal(&self, eps: N) -> bool pub fn is_special_orthogonal(&self, eps: T) -> bool
where where
D: DimMin<D, Output = D>, D: DimMin<D, Output = D>,
DefaultAllocator: Allocator<(usize, usize), D>, DefaultAllocator: Allocator<(usize, usize), D>,
{ {
self.is_square() && self.is_orthogonal(eps) && self.determinant() > N::zero() self.is_square() && self.is_orthogonal(eps) && self.determinant() > T::zero()
} }
/// Returns `true` if this matrix is invertible. /// Returns `true` if this matrix is invertible.

View File

@ -9,7 +9,7 @@ pub trait Scalar: Clone + PartialEq + Debug + Any {
#[inline] #[inline]
/// Tests if `Self` the same as the type `T` /// Tests if `Self` the same as the type `T`
/// ///
/// Typically used to test of `Self` is a f32 or a f64 with `N::is::<f32>()`. /// Typically used to test of `Self` is a f32 or a f64 with `T::is::<f32>()`.
fn is<T: Scalar>() -> bool { fn is<T: Scalar>() -> bool {
TypeId::of::<Self>() == TypeId::of::<T>() TypeId::of::<Self>() == TypeId::of::<T>()
} }

View File

@ -1,23 +1,23 @@
use crate::allocator::Allocator; use crate::allocator::Allocator;
use crate::storage::Storage; use crate::storage::Storage;
use crate::{Const, DefaultAllocator, Dim, Matrix, RowVectorN, Scalar, VectorN, VectorSliceN, U1}; use crate::{Const, DefaultAllocator, Dim, Matrix, OVector, RowOVector, Scalar, VectorSlice, U1};
use num::Zero; use num::Zero;
use simba::scalar::{ClosedAdd, Field, SupersetOf}; use simba::scalar::{ClosedAdd, Field, SupersetOf};
/// # Folding on columns and rows /// # Folding on columns and rows
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> { impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
/// Returns a row vector where each element is the result of the application of `f` on the /// Returns a row vector where each element is the result of the application of `f` on the
/// corresponding column of the original matrix. /// corresponding column of the original matrix.
#[inline] #[inline]
pub fn compress_rows( pub fn compress_rows(
&self, &self,
f: impl Fn(VectorSliceN<N, R, S::RStride, S::CStride>) -> N, f: impl Fn(VectorSlice<T, R, S::RStride, S::CStride>) -> T,
) -> RowVectorN<N, C> ) -> RowOVector<T, C>
where where
DefaultAllocator: Allocator<N, U1, C>, DefaultAllocator: Allocator<T, U1, C>,
{ {
let ncols = self.data.shape().1; let ncols = self.data.shape().1;
let mut res: RowVectorN<N, C> = let mut res: RowOVector<T, C> =
unsafe { crate::unimplemented_or_uninitialized_generic!(Const::<1>, ncols) }; unsafe { crate::unimplemented_or_uninitialized_generic!(Const::<1>, ncols) };
for i in 0..ncols.value() { for i in 0..ncols.value() {
@ -37,13 +37,13 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
#[inline] #[inline]
pub fn compress_rows_tr( pub fn compress_rows_tr(
&self, &self,
f: impl Fn(VectorSliceN<N, R, S::RStride, S::CStride>) -> N, f: impl Fn(VectorSlice<T, R, S::RStride, S::CStride>) -> T,
) -> VectorN<N, C> ) -> OVector<T, C>
where where
DefaultAllocator: Allocator<N, C>, DefaultAllocator: Allocator<T, C>,
{ {
let ncols = self.data.shape().1; let ncols = self.data.shape().1;
let mut res: VectorN<N, C> = let mut res: OVector<T, C> =
unsafe { crate::unimplemented_or_uninitialized_generic!(ncols, Const::<1>) }; unsafe { crate::unimplemented_or_uninitialized_generic!(ncols, Const::<1>) };
for i in 0..ncols.value() { for i in 0..ncols.value() {
@ -60,11 +60,11 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
#[inline] #[inline]
pub fn compress_columns( pub fn compress_columns(
&self, &self,
init: VectorN<N, R>, init: OVector<T, R>,
f: impl Fn(&mut VectorN<N, R>, VectorSliceN<N, R, S::RStride, S::CStride>), f: impl Fn(&mut OVector<T, R>, VectorSlice<T, R, S::RStride, S::CStride>),
) -> VectorN<N, R> ) -> OVector<T, R>
where where
DefaultAllocator: Allocator<N, R>, DefaultAllocator: Allocator<T, R>,
{ {
let mut res = init; let mut res = init;
@ -77,7 +77,7 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
} }
/// # Common statistics operations /// # Common statistics operations
impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> { impl<T: Scalar, R: Dim, C: Dim, S: Storage<T, R, C>> Matrix<T, R, C, S> {
/* /*
* *
* Sum computation. * Sum computation.
@ -95,11 +95,11 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// assert_eq!(m.sum(), 21.0); /// assert_eq!(m.sum(), 21.0);
/// ``` /// ```
#[inline] #[inline]
pub fn sum(&self) -> N pub fn sum(&self) -> T
where where
N: ClosedAdd + Zero, T: ClosedAdd + Zero,
{ {
self.iter().cloned().fold(N::zero(), |a, b| a + b) self.iter().cloned().fold(T::zero(), |a, b| a + b)
} }
/// The sum of all the rows of this matrix. /// The sum of all the rows of this matrix.
@ -120,10 +120,10 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// assert_eq!(mint.row_sum(), RowVector2::new(9,12)); /// assert_eq!(mint.row_sum(), RowVector2::new(9,12));
/// ``` /// ```
#[inline] #[inline]
pub fn row_sum(&self) -> RowVectorN<N, C> pub fn row_sum(&self) -> RowOVector<T, C>
where where
N: ClosedAdd + Zero, T: ClosedAdd + Zero,
DefaultAllocator: Allocator<N, U1, C>, DefaultAllocator: Allocator<T, U1, C>,
{ {
self.compress_rows(|col| col.sum()) self.compress_rows(|col| col.sum())
} }
@ -144,10 +144,10 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// assert_eq!(mint.row_sum_tr(), Vector2::new(9,12)); /// assert_eq!(mint.row_sum_tr(), Vector2::new(9,12));
/// ``` /// ```
#[inline] #[inline]
pub fn row_sum_tr(&self) -> VectorN<N, C> pub fn row_sum_tr(&self) -> OVector<T, C>
where where
N: ClosedAdd + Zero, T: ClosedAdd + Zero,
DefaultAllocator: Allocator<N, C>, DefaultAllocator: Allocator<T, C>,
{ {
self.compress_rows_tr(|col| col.sum()) self.compress_rows_tr(|col| col.sum())
} }
@ -168,13 +168,13 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// assert_eq!(mint.column_sum(), Vector3::new(3,7,11)); /// assert_eq!(mint.column_sum(), Vector3::new(3,7,11));
/// ``` /// ```
#[inline] #[inline]
pub fn column_sum(&self) -> VectorN<N, R> pub fn column_sum(&self) -> OVector<T, R>
where where
N: ClosedAdd + Zero, T: ClosedAdd + Zero,
DefaultAllocator: Allocator<N, R>, DefaultAllocator: Allocator<T, R>,
{ {
let nrows = self.data.shape().0; let nrows = self.data.shape().0;
self.compress_columns(VectorN::zeros_generic(nrows, Const::<1>), |out, col| { self.compress_columns(OVector::zeros_generic(nrows, Const::<1>), |out, col| {
*out += col; *out += col;
}) })
} }
@ -197,17 +197,17 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// assert_relative_eq!(m.variance(), 35.0 / 12.0, epsilon = 1.0e-8); /// assert_relative_eq!(m.variance(), 35.0 / 12.0, epsilon = 1.0e-8);
/// ``` /// ```
#[inline] #[inline]
pub fn variance(&self) -> N pub fn variance(&self) -> T
where where
N: Field + SupersetOf<f64>, T: Field + SupersetOf<f64>,
{ {
if self.is_empty() { if self.is_empty() {
N::zero() T::zero()
} else { } else {
let val = self.iter().cloned().fold((N::zero(), N::zero()), |a, b| { let val = self.iter().cloned().fold((T::zero(), T::zero()), |a, b| {
(a.0 + b.inlined_clone() * b.inlined_clone(), a.1 + b) (a.0 + b.inlined_clone() * b.inlined_clone(), a.1 + b)
}); });
let denom = N::one() / crate::convert::<_, N>(self.len() as f64); let denom = T::one() / crate::convert::<_, T>(self.len() as f64);
let vd = val.1 * denom.inlined_clone(); let vd = val.1 * denom.inlined_clone();
val.0 * denom - vd.inlined_clone() * vd val.0 * denom - vd.inlined_clone() * vd
} }
@ -226,10 +226,10 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// assert_eq!(m.row_variance(), RowVector3::new(2.25, 2.25, 2.25)); /// assert_eq!(m.row_variance(), RowVector3::new(2.25, 2.25, 2.25));
/// ``` /// ```
#[inline] #[inline]
pub fn row_variance(&self) -> RowVectorN<N, C> pub fn row_variance(&self) -> RowOVector<T, C>
where where
N: Field + SupersetOf<f64>, T: Field + SupersetOf<f64>,
DefaultAllocator: Allocator<N, U1, C>, DefaultAllocator: Allocator<T, U1, C>,
{ {
self.compress_rows(|col| col.variance()) self.compress_rows(|col| col.variance())
} }
@ -246,10 +246,10 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// assert_eq!(m.row_variance_tr(), Vector3::new(2.25, 2.25, 2.25)); /// assert_eq!(m.row_variance_tr(), Vector3::new(2.25, 2.25, 2.25));
/// ``` /// ```
#[inline] #[inline]
pub fn row_variance_tr(&self) -> VectorN<N, C> pub fn row_variance_tr(&self) -> OVector<T, C>
where where
N: Field + SupersetOf<f64>, T: Field + SupersetOf<f64>,
DefaultAllocator: Allocator<N, C>, DefaultAllocator: Allocator<T, C>,
{ {
self.compress_rows_tr(|col| col.variance()) self.compress_rows_tr(|col| col.variance())
} }
@ -267,17 +267,17 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// assert_relative_eq!(m.column_variance(), Vector2::new(2.0 / 3.0, 2.0 / 3.0), epsilon = 1.0e-8); /// assert_relative_eq!(m.column_variance(), Vector2::new(2.0 / 3.0, 2.0 / 3.0), epsilon = 1.0e-8);
/// ``` /// ```
#[inline] #[inline]
pub fn column_variance(&self) -> VectorN<N, R> pub fn column_variance(&self) -> OVector<T, R>
where where
N: Field + SupersetOf<f64>, T: Field + SupersetOf<f64>,
DefaultAllocator: Allocator<N, R>, DefaultAllocator: Allocator<T, R>,
{ {
let (nrows, ncols) = self.data.shape(); let (nrows, ncols) = self.data.shape();
let mut mean = self.column_mean(); let mut mean = self.column_mean();
mean.apply(|e| -(e.inlined_clone() * e)); mean.apply(|e| -(e.inlined_clone() * e));
let denom = N::one() / crate::convert::<_, N>(ncols.value() as f64); let denom = T::one() / crate::convert::<_, T>(ncols.value() as f64);
self.compress_columns(mean, |out, col| { self.compress_columns(mean, |out, col| {
for i in 0..nrows.value() { for i in 0..nrows.value() {
unsafe { unsafe {
@ -306,12 +306,12 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// assert_eq!(m.mean(), 3.5); /// assert_eq!(m.mean(), 3.5);
/// ``` /// ```
#[inline] #[inline]
pub fn mean(&self) -> N pub fn mean(&self) -> T
where where
N: Field + SupersetOf<f64>, T: Field + SupersetOf<f64>,
{ {
if self.is_empty() { if self.is_empty() {
N::zero() T::zero()
} else { } else {
self.sum() / crate::convert(self.len() as f64) self.sum() / crate::convert(self.len() as f64)
} }
@ -331,10 +331,10 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// assert_eq!(m.row_mean(), RowVector3::new(2.5, 3.5, 4.5)); /// assert_eq!(m.row_mean(), RowVector3::new(2.5, 3.5, 4.5));
/// ``` /// ```
#[inline] #[inline]
pub fn row_mean(&self) -> RowVectorN<N, C> pub fn row_mean(&self) -> RowOVector<T, C>
where where
N: Field + SupersetOf<f64>, T: Field + SupersetOf<f64>,
DefaultAllocator: Allocator<N, U1, C>, DefaultAllocator: Allocator<T, U1, C>,
{ {
self.compress_rows(|col| col.mean()) self.compress_rows(|col| col.mean())
} }
@ -351,10 +351,10 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// assert_eq!(m.row_mean_tr(), Vector3::new(2.5, 3.5, 4.5)); /// assert_eq!(m.row_mean_tr(), Vector3::new(2.5, 3.5, 4.5));
/// ``` /// ```
#[inline] #[inline]
pub fn row_mean_tr(&self) -> VectorN<N, C> pub fn row_mean_tr(&self) -> OVector<T, C>
where where
N: Field + SupersetOf<f64>, T: Field + SupersetOf<f64>,
DefaultAllocator: Allocator<N, C>, DefaultAllocator: Allocator<T, C>,
{ {
self.compress_rows_tr(|col| col.mean()) self.compress_rows_tr(|col| col.mean())
} }
@ -371,15 +371,15 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
/// assert_eq!(m.column_mean(), Vector2::new(2.0, 5.0)); /// assert_eq!(m.column_mean(), Vector2::new(2.0, 5.0));
/// ``` /// ```
#[inline] #[inline]
pub fn column_mean(&self) -> VectorN<N, R> pub fn column_mean(&self) -> OVector<T, R>
where where
N: Field + SupersetOf<f64>, T: Field + SupersetOf<f64>,
DefaultAllocator: Allocator<N, R>, DefaultAllocator: Allocator<T, R>,
{ {
let (nrows, ncols) = self.data.shape(); let (nrows, ncols) = self.data.shape();
let denom = N::one() / crate::convert::<_, N>(ncols.value() as f64); let denom = T::one() / crate::convert::<_, T>(ncols.value() as f64);
self.compress_columns(VectorN::zeros_generic(nrows, Const::<1>), |out, col| { self.compress_columns(OVector::zeros_generic(nrows, Const::<1>), |out, col| {
out.axpy(denom.inlined_clone(), &col, N::one()) out.axpy(denom.inlined_clone(), &col, T::one())
}) })
} }
} }

View File

@ -12,20 +12,20 @@ use crate::base::Scalar;
* Aliases for allocation results. * Aliases for allocation results.
*/ */
/// The data storage for the sum of two matrices with dimensions `(R1, C1)` and `(R2, C2)`. /// The data storage for the sum of two matrices with dimensions `(R1, C1)` and `(R2, C2)`.
pub type SameShapeStorage<N, R1, C1, R2, C2> = pub type SameShapeStorage<T, R1, C1, R2, C2> =
<DefaultAllocator as Allocator<N, SameShapeR<R1, R2>, SameShapeC<C1, C2>>>::Buffer; <DefaultAllocator as Allocator<T, SameShapeR<R1, R2>, SameShapeC<C1, C2>>>::Buffer;
// TODO: better name than Owned ? // TODO: better name than Owned ?
/// The owned data storage that can be allocated from `S`. /// The owned data storage that can be allocated from `S`.
pub type Owned<N, R, C = U1> = <DefaultAllocator as Allocator<N, R, C>>::Buffer; pub type Owned<T, R, C = U1> = <DefaultAllocator as Allocator<T, R, C>>::Buffer;
/// The row-stride of the owned data storage for a buffer of dimension `(R, C)`. /// The row-stride of the owned data storage for a buffer of dimension `(R, C)`.
pub type RStride<N, R, C = U1> = pub type RStride<T, R, C = U1> =
<<DefaultAllocator as Allocator<N, R, C>>::Buffer as Storage<N, R, C>>::RStride; <<DefaultAllocator as Allocator<T, R, C>>::Buffer as Storage<T, R, C>>::RStride;
/// The column-stride of the owned data storage for a buffer of dimension `(R, C)`. /// The column-stride of the owned data storage for a buffer of dimension `(R, C)`.
pub type CStride<N, R, C = U1> = pub type CStride<T, R, C = U1> =
<<DefaultAllocator as Allocator<N, R, C>>::Buffer as Storage<N, R, C>>::CStride; <<DefaultAllocator as Allocator<T, R, C>>::Buffer as Storage<T, R, C>>::CStride;
/// The trait shared by all matrix data storage. /// The trait shared by all matrix data storage.
/// ///
@ -36,7 +36,7 @@ pub type CStride<N, R, C = U1> =
/// should **not** allow the user to modify the size of the underlying buffer with safe methods /// should **not** allow the user to modify the size of the underlying buffer with safe methods
/// (for example the `VecStorage::data_mut` method is unsafe because the user could change the /// (for example the `VecStorage::data_mut` method is unsafe because the user could change the
/// vector's size so that it no longer contains enough elements: this will lead to UB. /// vector's size so that it no longer contains enough elements: this will lead to UB.
pub unsafe trait Storage<N: Scalar, R: Dim, C: Dim = U1>: Debug + Sized { pub unsafe trait Storage<T: Scalar, R: Dim, C: Dim = U1>: Debug + Sized {
/// The static stride of this storage's rows. /// The static stride of this storage's rows.
type RStride: Dim; type RStride: Dim;
@ -44,7 +44,7 @@ pub unsafe trait Storage<N: Scalar, R: Dim, C: Dim = U1>: Debug + Sized {
type CStride: Dim; type CStride: Dim;
/// The matrix data pointer. /// The matrix data pointer.
fn ptr(&self) -> *const N; fn ptr(&self) -> *const T;
/// The dimension of the matrix at run-time. Arr length of zero indicates the additive identity /// The dimension of the matrix at run-time. Arr length of zero indicates the additive identity
/// element of any dimension. Must be equal to `Self::dimension()` if it is not `None`. /// element of any dimension. Must be equal to `Self::dimension()` if it is not `None`.
@ -71,25 +71,25 @@ pub unsafe trait Storage<N: Scalar, R: Dim, C: Dim = U1>: Debug + Sized {
/// Gets the address of the i-th matrix component without performing bound-checking. /// Gets the address of the i-th matrix component without performing bound-checking.
#[inline] #[inline]
unsafe fn get_address_unchecked_linear(&self, i: usize) -> *const N { unsafe fn get_address_unchecked_linear(&self, i: usize) -> *const T {
self.ptr().wrapping_add(i) self.ptr().wrapping_add(i)
} }
/// Gets the address of the i-th matrix component without performing bound-checking. /// Gets the address of the i-th matrix component without performing bound-checking.
#[inline] #[inline]
unsafe fn get_address_unchecked(&self, irow: usize, icol: usize) -> *const N { unsafe fn get_address_unchecked(&self, irow: usize, icol: usize) -> *const T {
self.get_address_unchecked_linear(self.linear_index(irow, icol)) self.get_address_unchecked_linear(self.linear_index(irow, icol))
} }
/// Retrieves a reference to the i-th element without bound-checking. /// Retrieves a reference to the i-th element without bound-checking.
#[inline] #[inline]
unsafe fn get_unchecked_linear(&self, i: usize) -> &N { unsafe fn get_unchecked_linear(&self, i: usize) -> &T {
&*self.get_address_unchecked_linear(i) &*self.get_address_unchecked_linear(i)
} }
/// Retrieves a reference to the i-th element without bound-checking. /// Retrieves a reference to the i-th element without bound-checking.
#[inline] #[inline]
unsafe fn get_unchecked(&self, irow: usize, icol: usize) -> &N { unsafe fn get_unchecked(&self, irow: usize, icol: usize) -> &T {
self.get_unchecked_linear(self.linear_index(irow, icol)) self.get_unchecked_linear(self.linear_index(irow, icol))
} }
@ -99,17 +99,17 @@ pub unsafe trait Storage<N: Scalar, R: Dim, C: Dim = U1>: Debug + Sized {
/// Retrieves the data buffer as a contiguous slice. /// Retrieves the data buffer as a contiguous slice.
/// ///
/// The matrix components may not be stored in a contiguous way, depending on the strides. /// The matrix components may not be stored in a contiguous way, depending on the strides.
fn as_slice(&self) -> &[N]; fn as_slice(&self) -> &[T];
/// Builds a matrix data storage that does not contain any reference. /// Builds a matrix data storage that does not contain any reference.
fn into_owned(self) -> Owned<N, R, C> fn into_owned(self) -> Owned<T, R, C>
where where
DefaultAllocator: Allocator<N, R, C>; DefaultAllocator: Allocator<T, R, C>;
/// Clones this data storage to one that does not contain any reference. /// Clones this data storage to one that does not contain any reference.
fn clone_owned(&self) -> Owned<N, R, C> fn clone_owned(&self) -> Owned<T, R, C>
where where
DefaultAllocator: Allocator<N, R, C>; DefaultAllocator: Allocator<T, R, C>;
} }
/// Trait implemented by matrix data storage that can provide a mutable access to its elements. /// Trait implemented by matrix data storage that can provide a mutable access to its elements.
@ -117,31 +117,31 @@ pub unsafe trait Storage<N: Scalar, R: Dim, C: Dim = U1>: Debug + Sized {
/// Note that a mutable access does not mean that the matrix owns its data. For example, a mutable /// Note that a mutable access does not mean that the matrix owns its data. For example, a mutable
/// matrix slice can provide mutable access to its elements even if it does not own its data (it /// matrix slice can provide mutable access to its elements even if it does not own its data (it
/// contains only an internal reference to them). /// contains only an internal reference to them).
pub unsafe trait StorageMut<N: Scalar, R: Dim, C: Dim = U1>: Storage<N, R, C> { pub unsafe trait StorageMut<T: Scalar, R: Dim, C: Dim = U1>: Storage<T, R, C> {
/// The matrix mutable data pointer. /// The matrix mutable data pointer.
fn ptr_mut(&mut self) -> *mut N; fn ptr_mut(&mut self) -> *mut T;
/// Gets the mutable address of the i-th matrix component without performing bound-checking. /// Gets the mutable address of the i-th matrix component without performing bound-checking.
#[inline] #[inline]
unsafe fn get_address_unchecked_linear_mut(&mut self, i: usize) -> *mut N { unsafe fn get_address_unchecked_linear_mut(&mut self, i: usize) -> *mut T {
self.ptr_mut().wrapping_add(i) self.ptr_mut().wrapping_add(i)
} }
/// Gets the mutable address of the i-th matrix component without performing bound-checking. /// Gets the mutable address of the i-th matrix component without performing bound-checking.
#[inline] #[inline]
unsafe fn get_address_unchecked_mut(&mut self, irow: usize, icol: usize) -> *mut N { unsafe fn get_address_unchecked_mut(&mut self, irow: usize, icol: usize) -> *mut T {
let lid = self.linear_index(irow, icol); let lid = self.linear_index(irow, icol);
self.get_address_unchecked_linear_mut(lid) self.get_address_unchecked_linear_mut(lid)
} }
/// Retrieves a mutable reference to the i-th element without bound-checking. /// Retrieves a mutable reference to the i-th element without bound-checking.
unsafe fn get_unchecked_linear_mut(&mut self, i: usize) -> &mut N { unsafe fn get_unchecked_linear_mut(&mut self, i: usize) -> &mut T {
&mut *self.get_address_unchecked_linear_mut(i) &mut *self.get_address_unchecked_linear_mut(i)
} }
/// Retrieves a mutable reference to the element at `(irow, icol)` without bound-checking. /// Retrieves a mutable reference to the element at `(irow, icol)` without bound-checking.
#[inline] #[inline]
unsafe fn get_unchecked_mut(&mut self, irow: usize, icol: usize) -> &mut N { unsafe fn get_unchecked_mut(&mut self, irow: usize, icol: usize) -> &mut T {
&mut *self.get_address_unchecked_mut(irow, icol) &mut *self.get_address_unchecked_mut(irow, icol)
} }
@ -166,7 +166,7 @@ pub unsafe trait StorageMut<N: Scalar, R: Dim, C: Dim = U1>: Storage<N, R, C> {
/// Retrieves the mutable data buffer as a contiguous slice. /// Retrieves the mutable data buffer as a contiguous slice.
/// ///
/// Matrix components may not be contiguous, depending on its strides. /// Matrix components may not be contiguous, depending on its strides.
fn as_mut_slice(&mut self) -> &mut [N]; fn as_mut_slice(&mut self) -> &mut [T];
} }
/// A matrix storage that is stored contiguously in memory. /// A matrix storage that is stored contiguously in memory.
@ -174,8 +174,8 @@ pub unsafe trait StorageMut<N: Scalar, R: Dim, C: Dim = U1>: Storage<N, R, C> {
/// The storage requirement means that for any value of `i` in `[0, nrows * ncols - 1]`, the value /// The storage requirement means that for any value of `i` in `[0, nrows * ncols - 1]`, the value
/// `.get_unchecked_linear` returns one of the matrix component. This trait is unsafe because /// `.get_unchecked_linear` returns one of the matrix component. This trait is unsafe because
/// failing to comply to this may cause Undefined Behaviors. /// failing to comply to this may cause Undefined Behaviors.
pub unsafe trait ContiguousStorage<N: Scalar, R: Dim, C: Dim = U1>: pub unsafe trait ContiguousStorage<T: Scalar, R: Dim, C: Dim = U1>:
Storage<N, R, C> Storage<T, R, C>
{ {
} }
@ -184,22 +184,22 @@ pub unsafe trait ContiguousStorage<N: Scalar, R: Dim, C: Dim = U1>:
/// The storage requirement means that for any value of `i` in `[0, nrows * ncols - 1]`, the value /// The storage requirement means that for any value of `i` in `[0, nrows * ncols - 1]`, the value
/// `.get_unchecked_linear` returns one of the matrix component. This trait is unsafe because /// `.get_unchecked_linear` returns one of the matrix component. This trait is unsafe because
/// failing to comply to this may cause Undefined Behaviors. /// failing to comply to this may cause Undefined Behaviors.
pub unsafe trait ContiguousStorageMut<N: Scalar, R: Dim, C: Dim = U1>: pub unsafe trait ContiguousStorageMut<T: Scalar, R: Dim, C: Dim = U1>:
ContiguousStorage<N, R, C> + StorageMut<N, R, C> ContiguousStorage<T, R, C> + StorageMut<T, R, C>
{ {
} }
/// A matrix storage that can be reshaped in-place. /// A matrix storage that can be reshaped in-place.
pub trait ReshapableStorage<N, R1, C1, R2, C2>: Storage<N, R1, C1> pub trait ReshapableStorage<T, R1, C1, R2, C2>: Storage<T, R1, C1>
where where
N: Scalar, T: Scalar,
R1: Dim, R1: Dim,
C1: Dim, C1: Dim,
R2: Dim, R2: Dim,
C2: Dim, C2: Dim,
{ {
/// The reshaped storage type. /// The reshaped storage type.
type Output: Storage<N, R2, C2>; type Output: Storage<T, R2, C2>;
/// Reshapes the storage into the output storage type. /// Reshapes the storage into the output storage type.
fn reshape_generic(self, nrows: R2, ncols: C2) -> Self::Output; fn reshape_generic(self, nrows: R2, ncols: C2) -> Self::Output;

View File

@ -8,7 +8,7 @@ macro_rules! impl_swizzle {
$( $(
/// Builds a new vector from components of `self`. /// Builds a new vector from components of `self`.
#[inline] #[inline]
pub fn $name(&self) -> $Result<N> pub fn $name(&self) -> $Result<T>
where D::Typenum: Cmp<typenum::$BaseDim, Output=Greater> { where D::Typenum: Cmp<typenum::$BaseDim, Output=Greater> {
$Result::new($(self[$i].inlined_clone()),*) $Result::new($(self[$i].inlined_clone()),*)
} }
@ -18,7 +18,7 @@ macro_rules! impl_swizzle {
} }
/// # Swizzling /// # Swizzling
impl<N: Scalar, D, S: Storage<N, D>> Vector<N, D, S> impl<T: Scalar, D, S: Storage<T, D>> Vector<T, D, S>
where where
D: DimName + ToTypenum, D: DimName + ToTypenum,
{ {

View File

@ -12,7 +12,7 @@ use abomonation::Abomonation;
use crate::allocator::Allocator; use crate::allocator::Allocator;
use crate::base::DefaultAllocator; use crate::base::DefaultAllocator;
use crate::storage::Storage; use crate::storage::Storage;
use crate::{Dim, Matrix, MatrixMN, RealField, Scalar, SimdComplexField, SimdRealField}; use crate::{Dim, Matrix, OMatrix, RealField, Scalar, SimdComplexField, SimdRealField};
/// A wrapper that ensures the underlying algebraic entity has a unit norm. /// A wrapper that ensures the underlying algebraic entity has a unit norm.
/// ///
@ -71,12 +71,12 @@ impl<T: Abomonation> Abomonation for Unit<T> {
} }
} }
impl<N, R, C, S> PartialEq for Unit<Matrix<N, R, C, S>> impl<T, R, C, S> PartialEq for Unit<Matrix<T, R, C, S>>
where where
N: Scalar + PartialEq, T: Scalar + PartialEq,
R: Dim, R: Dim,
C: Dim, C: Dim,
S: Storage<N, R, C>, S: Storage<T, R, C>,
{ {
#[inline] #[inline]
fn eq(&self, rhs: &Self) -> bool { fn eq(&self, rhs: &Self) -> bool {
@ -84,12 +84,12 @@ where
} }
} }
impl<N, R, C, S> Eq for Unit<Matrix<N, R, C, S>> impl<T, R, C, S> Eq for Unit<Matrix<T, R, C, S>>
where where
N: Scalar + Eq, T: Scalar + Eq,
R: Dim, R: Dim,
C: Dim, C: Dim,
S: Storage<N, R, C>, S: Storage<T, R, C>,
{ {
} }
@ -298,32 +298,32 @@ impl<T> Deref for Unit<T> {
// NOTE: we can't use a generic implementation for `Unit<T>` because // NOTE: we can't use a generic implementation for `Unit<T>` because
// num_complex::Complex does not implement `From[Complex<...>...]` (and can't // num_complex::Complex does not implement `From[Complex<...>...]` (and can't
// because of the orphan rules). // because of the orphan rules).
impl<N: Scalar + simba::simd::PrimitiveSimdValue, R: Dim, C: Dim> impl<T: Scalar + simba::simd::PrimitiveSimdValue, R: Dim, C: Dim>
From<[Unit<MatrixMN<N::Element, R, C>>; 2]> for Unit<MatrixMN<N, R, C>> From<[Unit<OMatrix<T::Element, R, C>>; 2]> for Unit<OMatrix<T, R, C>>
where where
N: From<[<N as simba::simd::SimdValue>::Element; 2]>, T: From<[<T as simba::simd::SimdValue>::Element; 2]>,
N::Element: Scalar, T::Element: Scalar,
DefaultAllocator: Allocator<N, R, C> + Allocator<N::Element, R, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{ {
#[inline] #[inline]
fn from(arr: [Unit<MatrixMN<N::Element, R, C>>; 2]) -> Self { fn from(arr: [Unit<OMatrix<T::Element, R, C>>; 2]) -> Self {
Self::new_unchecked(MatrixMN::from([ Self::new_unchecked(OMatrix::from([
arr[0].clone().into_inner(), arr[0].clone().into_inner(),
arr[1].clone().into_inner(), arr[1].clone().into_inner(),
])) ]))
} }
} }
impl<N: Scalar + simba::simd::PrimitiveSimdValue, R: Dim, C: Dim> impl<T: Scalar + simba::simd::PrimitiveSimdValue, R: Dim, C: Dim>
From<[Unit<MatrixMN<N::Element, R, C>>; 4]> for Unit<MatrixMN<N, R, C>> From<[Unit<OMatrix<T::Element, R, C>>; 4]> for Unit<OMatrix<T, R, C>>
where where
N: From<[<N as simba::simd::SimdValue>::Element; 4]>, T: From<[<T as simba::simd::SimdValue>::Element; 4]>,
N::Element: Scalar, T::Element: Scalar,
DefaultAllocator: Allocator<N, R, C> + Allocator<N::Element, R, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{ {
#[inline] #[inline]
fn from(arr: [Unit<MatrixMN<N::Element, R, C>>; 4]) -> Self { fn from(arr: [Unit<OMatrix<T::Element, R, C>>; 4]) -> Self {
Self::new_unchecked(MatrixMN::from([ Self::new_unchecked(OMatrix::from([
arr[0].clone().into_inner(), arr[0].clone().into_inner(),
arr[1].clone().into_inner(), arr[1].clone().into_inner(),
arr[2].clone().into_inner(), arr[2].clone().into_inner(),
@ -332,16 +332,16 @@ where
} }
} }
impl<N: Scalar + simba::simd::PrimitiveSimdValue, R: Dim, C: Dim> impl<T: Scalar + simba::simd::PrimitiveSimdValue, R: Dim, C: Dim>
From<[Unit<MatrixMN<N::Element, R, C>>; 8]> for Unit<MatrixMN<N, R, C>> From<[Unit<OMatrix<T::Element, R, C>>; 8]> for Unit<OMatrix<T, R, C>>
where where
N: From<[<N as simba::simd::SimdValue>::Element; 8]>, T: From<[<T as simba::simd::SimdValue>::Element; 8]>,
N::Element: Scalar, T::Element: Scalar,
DefaultAllocator: Allocator<N, R, C> + Allocator<N::Element, R, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{ {
#[inline] #[inline]
fn from(arr: [Unit<MatrixMN<N::Element, R, C>>; 8]) -> Self { fn from(arr: [Unit<OMatrix<T::Element, R, C>>; 8]) -> Self {
Self::new_unchecked(MatrixMN::from([ Self::new_unchecked(OMatrix::from([
arr[0].clone().into_inner(), arr[0].clone().into_inner(),
arr[1].clone().into_inner(), arr[1].clone().into_inner(),
arr[2].clone().into_inner(), arr[2].clone().into_inner(),
@ -354,16 +354,16 @@ where
} }
} }
impl<N: Scalar + simba::simd::PrimitiveSimdValue, R: Dim, C: Dim> impl<T: Scalar + simba::simd::PrimitiveSimdValue, R: Dim, C: Dim>
From<[Unit<MatrixMN<N::Element, R, C>>; 16]> for Unit<MatrixMN<N, R, C>> From<[Unit<OMatrix<T::Element, R, C>>; 16]> for Unit<OMatrix<T, R, C>>
where where
N: From<[<N as simba::simd::SimdValue>::Element; 16]>, T: From<[<T as simba::simd::SimdValue>::Element; 16]>,
N::Element: Scalar, T::Element: Scalar,
DefaultAllocator: Allocator<N, R, C> + Allocator<N::Element, R, C>, DefaultAllocator: Allocator<T, R, C> + Allocator<T::Element, R, C>,
{ {
#[inline] #[inline]
fn from(arr: [Unit<MatrixMN<N::Element, R, C>>; 16]) -> Self { fn from(arr: [Unit<OMatrix<T::Element, R, C>>; 16]) -> Self {
Self::new_unchecked(MatrixMN::from([ Self::new_unchecked(OMatrix::from([
arr[0].clone().into_inner(), arr[0].clone().into_inner(),
arr[1].clone().into_inner(), arr[1].clone().into_inner(),
arr[2].clone().into_inner(), arr[2].clone().into_inner(),

View File

@ -25,20 +25,20 @@ use abomonation::Abomonation;
#[repr(C)] #[repr(C)]
#[derive(Eq, Debug, Clone, PartialEq)] #[derive(Eq, Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
pub struct VecStorage<N, R: Dim, C: Dim> { pub struct VecStorage<T, R: Dim, C: Dim> {
data: Vec<N>, data: Vec<T>,
nrows: R, nrows: R,
ncols: C, ncols: C,
} }
#[deprecated(note = "renamed to `VecStorage`")] #[deprecated(note = "renamed to `VecStorage`")]
/// Renamed to [VecStorage]. /// Renamed to [VecStorage].
pub type MatrixVec<N, R, C> = VecStorage<N, R, C>; pub type MatrixVec<T, R, C> = VecStorage<T, R, C>;
impl<N, R: Dim, C: Dim> VecStorage<N, R, C> { impl<T, R: Dim, C: Dim> VecStorage<T, R, C> {
/// Creates a new dynamic matrix data storage from the given vector and shape. /// Creates a new dynamic matrix data storage from the given vector and shape.
#[inline] #[inline]
pub fn new(nrows: R, ncols: C, data: Vec<N>) -> Self { pub fn new(nrows: R, ncols: C, data: Vec<T>) -> Self {
assert!( assert!(
nrows.value() * ncols.value() == data.len(), nrows.value() * ncols.value() == data.len(),
"Data storage buffer dimension mismatch." "Data storage buffer dimension mismatch."
@ -48,7 +48,7 @@ impl<N, R: Dim, C: Dim> VecStorage<N, R, C> {
/// The underlying data storage. /// The underlying data storage.
#[inline] #[inline]
pub fn as_vec(&self) -> &Vec<N> { pub fn as_vec(&self) -> &Vec<T> {
&self.data &self.data
} }
@ -57,7 +57,7 @@ impl<N, R: Dim, C: Dim> VecStorage<N, R, C> {
/// This is unsafe because this may cause UB if the size of the vector is changed /// This is unsafe because this may cause UB if the size of the vector is changed
/// by the user. /// by the user.
#[inline] #[inline]
pub unsafe fn as_vec_mut(&mut self) -> &mut Vec<N> { pub unsafe fn as_vec_mut(&mut self) -> &mut Vec<T> {
&mut self.data &mut self.data
} }
@ -66,7 +66,7 @@ impl<N, R: Dim, C: Dim> VecStorage<N, R, C> {
/// If `sz` is larger than the current size, additional elements are uninitialized. /// If `sz` is larger than the current size, additional elements are uninitialized.
/// If `sz` is smaller than the current size, additional elements are truncated. /// If `sz` is smaller than the current size, additional elements are truncated.
#[inline] #[inline]
pub unsafe fn resize(mut self, sz: usize) -> Vec<N> { pub unsafe fn resize(mut self, sz: usize) -> Vec<T> {
let len = self.len(); let len = self.len();
if sz < len { if sz < len {
@ -93,8 +93,8 @@ impl<N, R: Dim, C: Dim> VecStorage<N, R, C> {
} }
} }
impl<N, R: Dim, C: Dim> Into<Vec<N>> for VecStorage<N, R, C> { impl<T, R: Dim, C: Dim> Into<Vec<T>> for VecStorage<T, R, C> {
fn into(self) -> Vec<N> { fn into(self) -> Vec<T> {
self.data self.data
} }
} }
@ -105,15 +105,15 @@ impl<N, R: Dim, C: Dim> Into<Vec<N>> for VecStorage<N, R, C> {
* Dynamic Dynamic * Dynamic Dynamic
* *
*/ */
unsafe impl<N: Scalar, C: Dim> Storage<N, Dynamic, C> for VecStorage<N, Dynamic, C> unsafe impl<T: Scalar, C: Dim> Storage<T, Dynamic, C> for VecStorage<T, Dynamic, C>
where where
DefaultAllocator: Allocator<N, Dynamic, C, Buffer = Self>, DefaultAllocator: Allocator<T, Dynamic, C, Buffer = Self>,
{ {
type RStride = U1; type RStride = U1;
type CStride = Dynamic; type CStride = Dynamic;
#[inline] #[inline]
fn ptr(&self) -> *const N { fn ptr(&self) -> *const T {
self.data.as_ptr() self.data.as_ptr()
} }
@ -133,36 +133,36 @@ where
} }
#[inline] #[inline]
fn into_owned(self) -> Owned<N, Dynamic, C> fn into_owned(self) -> Owned<T, Dynamic, C>
where where
DefaultAllocator: Allocator<N, Dynamic, C>, DefaultAllocator: Allocator<T, Dynamic, C>,
{ {
self self
} }
#[inline] #[inline]
fn clone_owned(&self) -> Owned<N, Dynamic, C> fn clone_owned(&self) -> Owned<T, Dynamic, C>
where where
DefaultAllocator: Allocator<N, Dynamic, C>, DefaultAllocator: Allocator<T, Dynamic, C>,
{ {
self.clone() self.clone()
} }
#[inline] #[inline]
fn as_slice(&self) -> &[N] { fn as_slice(&self) -> &[T] {
&self.data &self.data
} }
} }
unsafe impl<N: Scalar, R: DimName> Storage<N, R, Dynamic> for VecStorage<N, R, Dynamic> unsafe impl<T: Scalar, R: DimName> Storage<T, R, Dynamic> for VecStorage<T, R, Dynamic>
where where
DefaultAllocator: Allocator<N, R, Dynamic, Buffer = Self>, DefaultAllocator: Allocator<T, R, Dynamic, Buffer = Self>,
{ {
type RStride = U1; type RStride = U1;
type CStride = R; type CStride = R;
#[inline] #[inline]
fn ptr(&self) -> *const N { fn ptr(&self) -> *const T {
self.data.as_ptr() self.data.as_ptr()
} }
@ -182,23 +182,23 @@ where
} }
#[inline] #[inline]
fn into_owned(self) -> Owned<N, R, Dynamic> fn into_owned(self) -> Owned<T, R, Dynamic>
where where
DefaultAllocator: Allocator<N, R, Dynamic>, DefaultAllocator: Allocator<T, R, Dynamic>,
{ {
self self
} }
#[inline] #[inline]
fn clone_owned(&self) -> Owned<N, R, Dynamic> fn clone_owned(&self) -> Owned<T, R, Dynamic>
where where
DefaultAllocator: Allocator<N, R, Dynamic>, DefaultAllocator: Allocator<T, R, Dynamic>,
{ {
self.clone() self.clone()
} }
#[inline] #[inline]
fn as_slice(&self) -> &[N] { fn as_slice(&self) -> &[T] {
&self.data &self.data
} }
} }
@ -208,38 +208,38 @@ where
* StorageMut, ContiguousStorage. * StorageMut, ContiguousStorage.
* *
*/ */
unsafe impl<N: Scalar, C: Dim> StorageMut<N, Dynamic, C> for VecStorage<N, Dynamic, C> unsafe impl<T: Scalar, C: Dim> StorageMut<T, Dynamic, C> for VecStorage<T, Dynamic, C>
where where
DefaultAllocator: Allocator<N, Dynamic, C, Buffer = Self>, DefaultAllocator: Allocator<T, Dynamic, C, Buffer = Self>,
{ {
#[inline] #[inline]
fn ptr_mut(&mut self) -> *mut N { fn ptr_mut(&mut self) -> *mut T {
self.data.as_mut_ptr() self.data.as_mut_ptr()
} }
#[inline] #[inline]
fn as_mut_slice(&mut self) -> &mut [N] { fn as_mut_slice(&mut self) -> &mut [T] {
&mut self.data[..] &mut self.data[..]
} }
} }
unsafe impl<N: Scalar, C: Dim> ContiguousStorage<N, Dynamic, C> for VecStorage<N, Dynamic, C> where unsafe impl<T: Scalar, C: Dim> ContiguousStorage<T, Dynamic, C> for VecStorage<T, Dynamic, C> where
DefaultAllocator: Allocator<N, Dynamic, C, Buffer = Self> DefaultAllocator: Allocator<T, Dynamic, C, Buffer = Self>
{ {
} }
unsafe impl<N: Scalar, C: Dim> ContiguousStorageMut<N, Dynamic, C> for VecStorage<N, Dynamic, C> where unsafe impl<T: Scalar, C: Dim> ContiguousStorageMut<T, Dynamic, C> for VecStorage<T, Dynamic, C> where
DefaultAllocator: Allocator<N, Dynamic, C, Buffer = Self> DefaultAllocator: Allocator<T, Dynamic, C, Buffer = Self>
{ {
} }
impl<N, C1, C2> ReshapableStorage<N, Dynamic, C1, Dynamic, C2> for VecStorage<N, Dynamic, C1> impl<T, C1, C2> ReshapableStorage<T, Dynamic, C1, Dynamic, C2> for VecStorage<T, Dynamic, C1>
where where
N: Scalar, T: Scalar,
C1: Dim, C1: Dim,
C2: Dim, C2: Dim,
{ {
type Output = VecStorage<N, Dynamic, C2>; type Output = VecStorage<T, Dynamic, C2>;
fn reshape_generic(self, nrows: Dynamic, ncols: C2) -> Self::Output { fn reshape_generic(self, nrows: Dynamic, ncols: C2) -> Self::Output {
assert_eq!(nrows.value() * ncols.value(), self.data.len()); assert_eq!(nrows.value() * ncols.value(), self.data.len());
@ -251,13 +251,13 @@ where
} }
} }
impl<N, C1, R2> ReshapableStorage<N, Dynamic, C1, R2, Dynamic> for VecStorage<N, Dynamic, C1> impl<T, C1, R2> ReshapableStorage<T, Dynamic, C1, R2, Dynamic> for VecStorage<T, Dynamic, C1>
where where
N: Scalar, T: Scalar,
C1: Dim, C1: Dim,
R2: DimName, R2: DimName,
{ {
type Output = VecStorage<N, R2, Dynamic>; type Output = VecStorage<T, R2, Dynamic>;
fn reshape_generic(self, nrows: R2, ncols: Dynamic) -> Self::Output { fn reshape_generic(self, nrows: R2, ncols: Dynamic) -> Self::Output {
assert_eq!(nrows.value() * ncols.value(), self.data.len()); assert_eq!(nrows.value() * ncols.value(), self.data.len());
@ -269,28 +269,28 @@ where
} }
} }
unsafe impl<N: Scalar, R: DimName> StorageMut<N, R, Dynamic> for VecStorage<N, R, Dynamic> unsafe impl<T: Scalar, R: DimName> StorageMut<T, R, Dynamic> for VecStorage<T, R, Dynamic>
where where
DefaultAllocator: Allocator<N, R, Dynamic, Buffer = Self>, DefaultAllocator: Allocator<T, R, Dynamic, Buffer = Self>,
{ {
#[inline] #[inline]
fn ptr_mut(&mut self) -> *mut N { fn ptr_mut(&mut self) -> *mut T {
self.data.as_mut_ptr() self.data.as_mut_ptr()
} }
#[inline] #[inline]
fn as_mut_slice(&mut self) -> &mut [N] { fn as_mut_slice(&mut self) -> &mut [T] {
&mut self.data[..] &mut self.data[..]
} }
} }
impl<N, R1, C2> ReshapableStorage<N, R1, Dynamic, Dynamic, C2> for VecStorage<N, R1, Dynamic> impl<T, R1, C2> ReshapableStorage<T, R1, Dynamic, Dynamic, C2> for VecStorage<T, R1, Dynamic>
where where
N: Scalar, T: Scalar,
R1: DimName, R1: DimName,
C2: Dim, C2: Dim,
{ {
type Output = VecStorage<N, Dynamic, C2>; type Output = VecStorage<T, Dynamic, C2>;
fn reshape_generic(self, nrows: Dynamic, ncols: C2) -> Self::Output { fn reshape_generic(self, nrows: Dynamic, ncols: C2) -> Self::Output {
assert_eq!(nrows.value() * ncols.value(), self.data.len()); assert_eq!(nrows.value() * ncols.value(), self.data.len());
@ -302,13 +302,13 @@ where
} }
} }
impl<N, R1, R2> ReshapableStorage<N, R1, Dynamic, R2, Dynamic> for VecStorage<N, R1, Dynamic> impl<T, R1, R2> ReshapableStorage<T, R1, Dynamic, R2, Dynamic> for VecStorage<T, R1, Dynamic>
where where
N: Scalar, T: Scalar,
R1: DimName, R1: DimName,
R2: DimName, R2: DimName,
{ {
type Output = VecStorage<N, R2, Dynamic>; type Output = VecStorage<T, R2, Dynamic>;
fn reshape_generic(self, nrows: R2, ncols: Dynamic) -> Self::Output { fn reshape_generic(self, nrows: R2, ncols: Dynamic) -> Self::Output {
assert_eq!(nrows.value() * ncols.value(), self.data.len()); assert_eq!(nrows.value() * ncols.value(), self.data.len());
@ -321,7 +321,7 @@ where
} }
#[cfg(feature = "abomonation-serialize")] #[cfg(feature = "abomonation-serialize")]
impl<N: Abomonation, R: Dim, C: Dim> Abomonation for VecStorage<N, R, C> { impl<T: Abomonation, R: Dim, C: Dim> Abomonation for VecStorage<T, R, C> {
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> { unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
self.data.entomb(writer) self.data.entomb(writer)
} }
@ -335,17 +335,17 @@ impl<N: Abomonation, R: Dim, C: Dim> Abomonation for VecStorage<N, R, C> {
} }
} }
unsafe impl<N: Scalar, R: DimName> ContiguousStorage<N, R, Dynamic> for VecStorage<N, R, Dynamic> where unsafe impl<T: Scalar, R: DimName> ContiguousStorage<T, R, Dynamic> for VecStorage<T, R, Dynamic> where
DefaultAllocator: Allocator<N, R, Dynamic, Buffer = Self> DefaultAllocator: Allocator<T, R, Dynamic, Buffer = Self>
{ {
} }
unsafe impl<N: Scalar, R: DimName> ContiguousStorageMut<N, R, Dynamic> for VecStorage<N, R, Dynamic> where unsafe impl<T: Scalar, R: DimName> ContiguousStorageMut<T, R, Dynamic> for VecStorage<T, R, Dynamic> where
DefaultAllocator: Allocator<N, R, Dynamic, Buffer = Self> DefaultAllocator: Allocator<T, R, Dynamic, Buffer = Self>
{ {
} }
impl<N, R: Dim> Extend<N> for VecStorage<N, R, Dynamic> { impl<T, R: Dim> Extend<T> for VecStorage<T, R, Dynamic> {
/// Extends the number of columns of the `VecStorage` with elements /// Extends the number of columns of the `VecStorage` with elements
/// from the given iterator. /// from the given iterator.
/// ///
@ -353,7 +353,7 @@ impl<N, R: Dim> Extend<N> for VecStorage<N, R, Dynamic> {
/// This function panics if the number of elements yielded by the /// This function panics if the number of elements yielded by the
/// given iterator is not a multiple of the number of rows of the /// given iterator is not a multiple of the number of rows of the
/// `VecStorage`. /// `VecStorage`.
fn extend<I: IntoIterator<Item = N>>(&mut self, iter: I) { fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
self.data.extend(iter); self.data.extend(iter);
self.ncols = Dynamic::new(self.data.len() / self.nrows.value()); self.ncols = Dynamic::new(self.data.len() / self.nrows.value());
assert!(self.data.len() % self.nrows.value() == 0, assert!(self.data.len() % self.nrows.value() == 0,
@ -361,7 +361,7 @@ impl<N, R: Dim> Extend<N> for VecStorage<N, R, Dynamic> {
} }
} }
impl<'a, N: 'a + Copy, R: Dim> Extend<&'a N> for VecStorage<N, R, Dynamic> { impl<'a, T: 'a + Copy, R: Dim> Extend<&'a T> for VecStorage<T, R, Dynamic> {
/// Extends the number of columns of the `VecStorage` with elements /// Extends the number of columns of the `VecStorage` with elements
/// from the given iterator. /// from the given iterator.
/// ///
@ -369,17 +369,17 @@ impl<'a, N: 'a + Copy, R: Dim> Extend<&'a N> for VecStorage<N, R, Dynamic> {
/// This function panics if the number of elements yielded by the /// This function panics if the number of elements yielded by the
/// given iterator is not a multiple of the number of rows of the /// given iterator is not a multiple of the number of rows of the
/// `VecStorage`. /// `VecStorage`.
fn extend<I: IntoIterator<Item = &'a N>>(&mut self, iter: I) { fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
self.extend(iter.into_iter().copied()) self.extend(iter.into_iter().copied())
} }
} }
impl<N, R, RV, SV> Extend<Vector<N, RV, SV>> for VecStorage<N, R, Dynamic> impl<T, R, RV, SV> Extend<Vector<T, RV, SV>> for VecStorage<T, R, Dynamic>
where where
N: Scalar, T: Scalar,
R: Dim, R: Dim,
RV: Dim, RV: Dim,
SV: Storage<N, RV>, SV: Storage<T, RV>,
ShapeConstraint: SameNumberOfRows<R, RV>, ShapeConstraint: SameNumberOfRows<R, RV>,
{ {
/// Extends the number of columns of the `VecStorage` with vectors /// Extends the number of columns of the `VecStorage` with vectors
@ -389,7 +389,7 @@ where
/// This function panics if the number of rows of each `Vector` /// This function panics if the number of rows of each `Vector`
/// yielded by the iterator is not equal to the number of rows /// yielded by the iterator is not equal to the number of rows
/// of this `VecStorage`. /// of this `VecStorage`.
fn extend<I: IntoIterator<Item = Vector<N, RV, SV>>>(&mut self, iter: I) { fn extend<I: IntoIterator<Item = Vector<T, RV, SV>>>(&mut self, iter: I) {
let nrows = self.nrows.value(); let nrows = self.nrows.value();
let iter = iter.into_iter(); let iter = iter.into_iter();
let (lower, _upper) = iter.size_hint(); let (lower, _upper) = iter.size_hint();
@ -402,10 +402,10 @@ where
} }
} }
impl<N> Extend<N> for VecStorage<N, Dynamic, U1> { impl<T> Extend<T> for VecStorage<T, Dynamic, U1> {
/// Extends the number of rows of the `VecStorage` with elements /// Extends the number of rows of the `VecStorage` with elements
/// from the given iterator. /// from the given iterator.
fn extend<I: IntoIterator<Item = N>>(&mut self, iter: I) { fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
self.data.extend(iter); self.data.extend(iter);
self.nrows = Dynamic::new(self.data.len()); self.nrows = Dynamic::new(self.data.len());
} }

View File

@ -4,38 +4,38 @@ use crate::base::storage::Owned;
use quickcheck::{Arbitrary, Gen}; use quickcheck::{Arbitrary, Gen};
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{Dim, Dynamic, U2}; use crate::base::dimension::{Dim, Dynamic};
use crate::base::Scalar; use crate::base::Scalar;
use crate::base::{DefaultAllocator, MatrixN}; use crate::base::{DefaultAllocator, OMatrix};
use crate::linalg::givens::GivensRotation; use crate::linalg::givens::GivensRotation;
use simba::scalar::ComplexField; use simba::scalar::ComplexField;
/// A random orthogonal matrix. /// A random orthogonal matrix.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct RandomOrthogonal<N: Scalar, D: Dim = Dynamic> pub struct RandomOrthogonal<T: Scalar, D: Dim = Dynamic>
where where
DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
m: MatrixN<N, D>, m: OMatrix<T, D, D>,
} }
impl<N: ComplexField, D: Dim> RandomOrthogonal<N, D> impl<T: ComplexField, D: Dim> RandomOrthogonal<T, D>
where where
DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
/// Retrieve the generated matrix. /// Retrieve the generated matrix.
pub fn unwrap(self) -> MatrixN<N, D> { pub fn unwrap(self) -> OMatrix<T, D, D> {
self.m self.m
} }
/// Creates a new random orthogonal matrix from its dimension and a random reals generators. /// Creates a new random orthogonal matrix from its dimension and a random reals generators.
pub fn new<Rand: FnMut() -> N>(dim: D, mut rand: Rand) -> Self { pub fn new<Rand: FnMut() -> T>(dim: D, mut rand: Rand) -> Self {
let mut res = MatrixN::identity_generic(dim, dim); let mut res = OMatrix::identity_generic(dim, dim);
// Create an orthogonal matrix by composing random Givens rotations rotations. // Create an orthogonal matrix by composing random Givens rotations rotations.
for i in 0..dim.value() - 1 { for i in 0..dim.value() - 1 {
let rot = GivensRotation::new(rand(), rand()).0; let rot = GivensRotation::new(rand(), rand()).0;
rot.rotate(&mut res.fixed_rows_mut::<U2>(i)); rot.rotate(&mut res.fixed_rows_mut::<2>(i));
} }
RandomOrthogonal { m: res } RandomOrthogonal { m: res }
@ -43,13 +43,13 @@ where
} }
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
impl<N: ComplexField + Arbitrary + Send, D: Dim> Arbitrary for RandomOrthogonal<N, D> impl<T: ComplexField + Arbitrary + Send, D: Dim> Arbitrary for RandomOrthogonal<T, D>
where where
DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<T, D, D>,
Owned<N, D, D>: Clone + Send, Owned<T, D, D>: Clone + Send,
{ {
fn arbitrary(g: &mut Gen) -> Self { fn arbitrary(g: &mut Gen) -> Self {
let dim = D::try_to_usize().unwrap_or(1 + usize::arbitrary(g) % 50); let dim = D::try_to_usize().unwrap_or(1 + usize::arbitrary(g) % 50);
Self::new(D::from_usize(dim), || N::arbitrary(g)) Self::new(D::from_usize(dim), || T::arbitrary(g))
} }
} }

View File

@ -6,38 +6,38 @@ use quickcheck::{Arbitrary, Gen};
use crate::base::allocator::Allocator; use crate::base::allocator::Allocator;
use crate::base::dimension::{Dim, Dynamic}; use crate::base::dimension::{Dim, Dynamic};
use crate::base::Scalar; use crate::base::Scalar;
use crate::base::{DefaultAllocator, MatrixN}; use crate::base::{DefaultAllocator, OMatrix};
use simba::scalar::ComplexField; use simba::scalar::ComplexField;
use crate::debug::RandomOrthogonal; use crate::debug::RandomOrthogonal;
/// A random, well-conditioned, symmetric definite-positive matrix. /// A random, well-conditioned, symmetric definite-positive matrix.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct RandomSDP<N: Scalar, D: Dim = Dynamic> pub struct RandomSDP<T: Scalar, D: Dim = Dynamic>
where where
DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
m: MatrixN<N, D>, m: OMatrix<T, D, D>,
} }
impl<N: ComplexField, D: Dim> RandomSDP<N, D> impl<T: ComplexField, D: Dim> RandomSDP<T, D>
where where
DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<T, D, D>,
{ {
/// Retrieve the generated matrix. /// Retrieve the generated matrix.
pub fn unwrap(self) -> MatrixN<N, D> { pub fn unwrap(self) -> OMatrix<T, D, D> {
self.m self.m
} }
/// Creates a new well conditioned symmetric definite-positive matrix from its dimension and a /// Creates a new well conditioned symmetric definite-positive matrix from its dimension and a
/// random reals generators. /// random reals generators.
pub fn new<Rand: FnMut() -> N>(dim: D, mut rand: Rand) -> Self { pub fn new<Rand: FnMut() -> T>(dim: D, mut rand: Rand) -> Self {
let mut m = RandomOrthogonal::new(dim, || rand()).unwrap(); let mut m = RandomOrthogonal::new(dim, || rand()).unwrap();
let mt = m.adjoint(); let mt = m.adjoint();
for i in 0..dim.value() { for i in 0..dim.value() {
let mut col = m.column_mut(i); let mut col = m.column_mut(i);
let eigenval = N::one() + N::from_real(rand().modulus()); let eigenval = T::one() + T::from_real(rand().modulus());
col *= eigenval; col *= eigenval;
} }
@ -46,13 +46,13 @@ where
} }
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
impl<N: ComplexField + Arbitrary + Send, D: Dim> Arbitrary for RandomSDP<N, D> impl<T: ComplexField + Arbitrary + Send, D: Dim> Arbitrary for RandomSDP<T, D>
where where
DefaultAllocator: Allocator<N, D, D>, DefaultAllocator: Allocator<T, D, D>,
Owned<N, D, D>: Clone + Send, Owned<T, D, D>: Clone + Send,
{ {
fn arbitrary(g: &mut Gen) -> Self { fn arbitrary(g: &mut Gen) -> Self {
let dim = D::try_to_usize().unwrap_or(1 + usize::arbitrary(g) % 50); let dim = D::try_to_usize().unwrap_or(1 + usize::arbitrary(g) % 50);
Self::new(D::from_usize(dim), || N::arbitrary(g)) Self::new(D::from_usize(dim), || T::arbitrary(g))
} }
} }

View File

@ -1,10 +1,10 @@
use crate::geometry::{Rotation, UnitComplex, UnitQuaternion}; use crate::geometry::{Rotation, UnitComplex, UnitQuaternion};
use crate::{CVectorN, Const, Point, Scalar, SimdRealField, Unit, VectorN}; use crate::{Const, OVector, Point, SVector, Scalar, SimdRealField, Unit};
use simba::scalar::ClosedMul; use simba::scalar::ClosedMul;
/// Trait implemented by rotations that can be used inside of an `Isometry` or `Similarity`. /// Trait implemented by rotations that can be used inside of an `Isometry` or `Similarity`.
pub trait AbstractRotation<N: Scalar, const D: usize>: PartialEq + ClosedMul + Clone { pub trait AbstractRotation<T: Scalar, const D: usize>: PartialEq + ClosedMul + Clone {
/// The rotation identity. /// The rotation identity.
fn identity() -> Self; fn identity() -> Self;
/// The rotation inverse. /// The rotation inverse.
@ -12,33 +12,22 @@ pub trait AbstractRotation<N: Scalar, const D: usize>: PartialEq + ClosedMul + C
/// Change `self` to its inverse. /// Change `self` to its inverse.
fn inverse_mut(&mut self); fn inverse_mut(&mut self);
/// Apply the rotation to the given vector. /// Apply the rotation to the given vector.
fn transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D>; fn transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D>;
// where
// DefaultAllocator: Allocator<N, D>;
/// Apply the rotation to the given point. /// Apply the rotation to the given point.
fn transform_point(&self, p: &Point<N, D>) -> Point<N, D>; fn transform_point(&self, p: &Point<T, D>) -> Point<T, D>;
// where
// DefaultAllocator: Allocator<N, D>;
/// Apply the inverse rotation to the given vector. /// Apply the inverse rotation to the given vector.
fn inverse_transform_vector(&self, v: &VectorN<N, Const<D>>) -> VectorN<N, Const<D>>; fn inverse_transform_vector(&self, v: &OVector<T, Const<D>>) -> OVector<T, Const<D>>;
// where
// DefaultAllocator: Allocator<N, D>;
/// Apply the inverse rotation to the given unit vector. /// Apply the inverse rotation to the given unit vector.
fn inverse_transform_unit_vector(&self, v: &Unit<CVectorN<N, D>>) -> Unit<CVectorN<N, D>> fn inverse_transform_unit_vector(&self, v: &Unit<SVector<T, D>>) -> Unit<SVector<T, D>> {
// where
// DefaultAllocator: Allocator<N, D>,
{
Unit::new_unchecked(self.inverse_transform_vector(&**v)) Unit::new_unchecked(self.inverse_transform_vector(&**v))
} }
/// Apply the inverse rotation to the given point. /// Apply the inverse rotation to the given point.
fn inverse_transform_point(&self, p: &Point<N, D>) -> Point<N, D>; fn inverse_transform_point(&self, p: &Point<T, D>) -> Point<T, D>;
// where
// DefaultAllocator: Allocator<N, D>;
} }
impl<N: SimdRealField, const D: usize> AbstractRotation<N, D> for Rotation<N, D> impl<T: SimdRealField, const D: usize> AbstractRotation<T, D> for Rotation<T, D>
where where
N::Element: SimdRealField, T::Element: SimdRealField,
{ {
#[inline] #[inline]
fn identity() -> Self { fn identity() -> Self {
@ -56,49 +45,34 @@ where
} }
#[inline] #[inline]
fn transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D> fn transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
// where
// DefaultAllocator: Allocator<N, D>,
{
self * v self * v
} }
#[inline] #[inline]
fn transform_point(&self, p: &Point<N, D>) -> Point<N, D> fn transform_point(&self, p: &Point<T, D>) -> Point<T, D> {
// where
// DefaultAllocator: Allocator<N, D>,
{
self * p self * p
} }
#[inline] #[inline]
fn inverse_transform_vector(&self, v: &CVectorN<N, D>) -> CVectorN<N, D> fn inverse_transform_vector(&self, v: &SVector<T, D>) -> SVector<T, D> {
// where
// DefaultAllocator: Allocator<N, D>,
{
self.inverse_transform_vector(v) self.inverse_transform_vector(v)
} }
#[inline] #[inline]
fn inverse_transform_unit_vector(&self, v: &Unit<CVectorN<N, D>>) -> Unit<CVectorN<N, D>> fn inverse_transform_unit_vector(&self, v: &Unit<SVector<T, D>>) -> Unit<SVector<T, D>> {
// where
// DefaultAllocator: Allocator<N, D>,
{
self.inverse_transform_unit_vector(v) self.inverse_transform_unit_vector(v)
} }
#[inline] #[inline]
fn inverse_transform_point(&self, p: &Point<N, D>) -> Point<N, D> fn inverse_transform_point(&self, p: &Point<T, D>) -> Point<T, D> {
// where
// DefaultAllocator: Allocator<N, D>,
{
self.inverse_transform_point(p) self.inverse_transform_point(p)
} }
} }
impl<N: SimdRealField> AbstractRotation<N, 3> for UnitQuaternion<N> impl<T: SimdRealField> AbstractRotation<T, 3> for UnitQuaternion<T>
where where
N::Element: SimdRealField, T::Element: SimdRealField,
{ {
#[inline] #[inline]
fn identity() -> Self { fn identity() -> Self {
@ -116,29 +90,29 @@ where
} }
#[inline] #[inline]
fn transform_vector(&self, v: &CVectorN<N, 3>) -> CVectorN<N, 3> { fn transform_vector(&self, v: &SVector<T, 3>) -> SVector<T, 3> {
self * v self * v
} }
#[inline] #[inline]
fn transform_point(&self, p: &Point<N, 3>) -> Point<N, 3> { fn transform_point(&self, p: &Point<T, 3>) -> Point<T, 3> {
self * p self * p
} }
#[inline] #[inline]
fn inverse_transform_vector(&self, v: &CVectorN<N, 3>) -> CVectorN<N, 3> { fn inverse_transform_vector(&self, v: &SVector<T, 3>) -> SVector<T, 3> {
self.inverse_transform_vector(v) self.inverse_transform_vector(v)
} }
#[inline] #[inline]
fn inverse_transform_point(&self, p: &Point<N, 3>) -> Point<N, 3> { fn inverse_transform_point(&self, p: &Point<T, 3>) -> Point<T, 3> {
self.inverse_transform_point(p) self.inverse_transform_point(p)
} }
} }
impl<N: SimdRealField> AbstractRotation<N, 2> for UnitComplex<N> impl<T: SimdRealField> AbstractRotation<T, 2> for UnitComplex<T>
where where
N::Element: SimdRealField, T::Element: SimdRealField,
{ {
#[inline] #[inline]
fn identity() -> Self { fn identity() -> Self {
@ -156,22 +130,22 @@ where
} }
#[inline] #[inline]
fn transform_vector(&self, v: &CVectorN<N, 2>) -> CVectorN<N, 2> { fn transform_vector(&self, v: &SVector<T, 2>) -> SVector<T, 2> {
self * v self * v
} }
#[inline] #[inline]
fn transform_point(&self, p: &Point<N, 2>) -> Point<N, 2> { fn transform_point(&self, p: &Point<T, 2>) -> Point<T, 2> {
self * p self * p
} }
#[inline] #[inline]
fn inverse_transform_vector(&self, v: &CVectorN<N, 2>) -> CVectorN<N, 2> { fn inverse_transform_vector(&self, v: &SVector<T, 2>) -> SVector<T, 2> {
self.inverse_transform_vector(v) self.inverse_transform_vector(v)
} }
#[inline] #[inline]
fn inverse_transform_point(&self, p: &Point<N, 2>) -> Point<N, 2> { fn inverse_transform_point(&self, p: &Point<T, 2>) -> Point<T, 2> {
self.inverse_transform_point(p) self.inverse_transform_point(p)
} }
} }

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