diff --git a/src/lib.rs b/src/lib.rs index acc43fba..9c10add5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -92,7 +92,7 @@ extern crate num; extern crate quickcheck; use std::cmp; -use std::ops::{Neg, Mul}; +use std::ops::Neg; use num::{Zero, One}; pub use traits::{ Absolute, @@ -132,6 +132,7 @@ pub use traits::{ POrd, POrdering, PntAsVec, + Repeat, Rotate, Rotation, RotationMatrix, RotationWithTranslation, Row, Shape, @@ -575,9 +576,8 @@ pub fn append_rotation_wrt_center + Copy, /// Builds a rotation matrix from `r`. #[inline(always)] pub fn to_rot_mat(r: &R) -> M - where R: RotationMatrix, - M: Mat + Rotation + Col + Copy, - LV: Mul + Copy, + where R: RotationMatrix, + M: SquareMat + Rotation + Copy { // FIXME: rust-lang/rust#20413 r.to_rot_mat() @@ -678,7 +678,7 @@ pub fn det, N>(m: &M) -> N { /// Computes the cross product of two vectors. #[inline(always)] -pub fn cross(a: &LV, b: &LV) -> LV::Output { +pub fn cross(a: &LV, b: &LV) -> LV::CrossProductType { Cross::cross(a, b) } @@ -785,7 +785,7 @@ pub fn transpose(m: &M) -> M { /// Computes the outer product of two vectors. #[inline(always)] -pub fn outer, M>(a: &V, b: &V) -> M { +pub fn outer(a: &V, b: &V) -> V::OuterProductType { Outer::outer(a, b) } @@ -833,6 +833,18 @@ pub fn new_identity(dim: usize) -> M { Eye::new_identity(dim) } + +/* + * Repeat + */ +/// Create an object by repeating a value. +/// +/// Same as `Identity::new()`. +#[inline(always)] +pub fn repeat>(val: N) -> T { + Repeat::repeat(val) +} + /* * Basis */ diff --git a/src/structs/dmat.rs b/src/structs/dmat.rs index fa74d6c3..6d23b842 100644 --- a/src/structs/dmat.rs +++ b/src/structs/dmat.rs @@ -10,7 +10,7 @@ use rand::{self, Rand}; use num::{Zero, One}; use structs::dvec::DVec; use traits::operations::{ApproxEq, Inv, Transpose, Mean, Cov}; -use traits::structure::{Cast, ColSlice, RowSlice, Diag, Eye, Indexable, Shape, BaseNum}; +use traits::structure::{Cast, ColSlice, RowSlice, Diag, DiagMut, Eye, Indexable, Shape, BaseNum}; #[cfg(feature="arbitrary")] use quickcheck::{Arbitrary, Gen}; @@ -555,17 +555,6 @@ impl Diag> for DMat { res } - #[inline] - fn set_diag(&mut self, diag: &DVec) { - let smallest_dim = cmp::min(self.nrows, self.ncols); - - assert!(diag.len() == smallest_dim); - - for i in 0..smallest_dim { - unsafe { self.unsafe_set((i, i), diag.unsafe_at(i)) } - } - } - #[inline] fn diag(&self) -> DVec { let smallest_dim = cmp::min(self.nrows, self.ncols); @@ -580,6 +569,19 @@ impl Diag> for DMat { } } +impl DiagMut> for DMat { + #[inline] + fn set_diag(&mut self, diag: &DVec) { + let smallest_dim = cmp::min(self.nrows, self.ncols); + + assert!(diag.len() == smallest_dim); + + for i in 0..smallest_dim { + unsafe { self.unsafe_set((i, i), diag.unsafe_at(i)) } + } + } +} + impl> ApproxEq for DMat { #[inline] fn approx_epsilon(_: Option>) -> N { diff --git a/src/structs/mat.rs b/src/structs/mat.rs index c434d2bd..40604e9b 100644 --- a/src/structs/mat.rs +++ b/src/structs/mat.rs @@ -12,8 +12,8 @@ use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6}; use structs::pnt::{Pnt1, Pnt4, Pnt5, Pnt6}; use structs::dvec::{DVec1, DVec2, DVec3, DVec4, DVec5, DVec6}; -use traits::structure::{Cast, Row, Col, Iterable, IterableMut, Dim, Indexable, - Eye, ColSlice, RowSlice, Diag, Shape, BaseFloat, BaseNum}; +use traits::structure::{Cast, Row, Col, Iterable, IterableMut, Dim, Indexable, Eye, ColSlice, + RowSlice, Diag, DiagMut, Shape, BaseFloat, BaseNum, Repeat}; use traits::operations::{Absolute, Transpose, Inv, Outer, EigenQR}; use traits::geometry::{ToHomogeneous, FromHomogeneous, Orig}; use linalg; @@ -23,7 +23,7 @@ use quickcheck::{Arbitrary, Gen}; /// Special identity matrix. All its operation are no-ops. #[repr(C)] -#[derive(Eq, PartialEq, RustcDecodable, Clone, Debug, Copy)] +#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Debug, Copy)] pub struct Identity; impl Identity { @@ -44,6 +44,7 @@ pub struct Mat1 { eye_impl!(Mat1, 1, m11); mat_impl!(Mat1, m11); +repeat_impl!(Mat1, m11); as_array_impl!(Mat1, 1); mat_cast_impl!(Mat1, m11); add_impl!(Mat1, m11); @@ -93,6 +94,8 @@ eye_impl!(Mat2, 2, m11, m22); mat_impl!(Mat2, m11, m12, m21, m22); +repeat_impl!(Mat2, m11, m12, + m21, m22); as_array_impl!(Mat2, 2); mat_cast_impl!(Mat2, m11, m12, m21, m22); @@ -146,6 +149,9 @@ eye_impl!(Mat3, 3, m11, m22, m33); mat_impl!(Mat3, m11, m12, m13, m21, m22, m23, m31, m32, m33); +repeat_impl!(Mat3, m11, m12, m13, + m21, m22, m23, + m31, m32, m33); as_array_impl!(Mat3, 3); mat_cast_impl!(Mat3, m11, m12, m13, m21, m22, m23, @@ -243,6 +249,12 @@ mat_impl!(Mat4, m31, m32, m33, m34, m41, m42, m43, m44 ); +repeat_impl!(Mat4, + m11, m12, m13, m14, + m21, m22, m23, m24, + m31, m32, m33, m34, + m41, m42, m43, m44 +); as_array_impl!(Mat4, 4); mat_cast_impl!(Mat4, m11, m12, m13, m14, @@ -358,6 +370,13 @@ mat_impl!(Mat5, m41, m42, m43, m44, m45, m51, m52, m53, m54, m55 ); +repeat_impl!(Mat5, + m11, m12, m13, m14, m15, + m21, m22, m23, m24, m25, + m31, m32, m33, m34, m35, + m41, m42, m43, m44, m45, + m51, m52, m53, m54, m55 +); as_array_impl!(Mat5, 5); mat_cast_impl!(Mat5, m11, m12, m13, m14, m15, @@ -489,6 +508,14 @@ mat_impl!(Mat6, m51, m52, m53, m54, m55, m56, m61, m62, m63, m64, m65, m66 ); +repeat_impl!(Mat6, + m11, m12, m13, m14, m15, m16, + m21, m22, m23, m24, m25, m26, + m31, m32, m33, m34, m35, m36, + m41, m42, m43, m44, m45, m46, + m51, m52, m53, m54, m55, m56, + m61, m62, m63, m64, m65, m66 +); as_array_impl!(Mat6, 6); mat_cast_impl!(Mat6, m11, m12, m13, m14, m15, m16, diff --git a/src/structs/mat_macros.rs b/src/structs/mat_macros.rs index 5f268004..d95ffd2d 100644 --- a/src/structs/mat_macros.rs +++ b/src/structs/mat_macros.rs @@ -164,6 +164,18 @@ macro_rules! eye_impl( ) ); +macro_rules! repeat_impl( + ($t: ident, $($compN: ident),+) => ( + impl Repeat for $t { + fn repeat(val: N) -> $t { + $t { + $($compN: val ),+ + } + } + } + ) +); + macro_rules! mat_sub_scalar_impl( ($t: ident, $($compN: ident),+) => ( impl Sub for $t { @@ -401,13 +413,6 @@ macro_rules! diag_impl( res } - #[inline] - fn set_diag(&mut self, diag: &$tv) { - for i in 0..$dim { - unsafe { self.unsafe_set((i, i), diag.unsafe_at(i)) } - } - } - #[inline] fn diag(&self) -> $tv { let mut diag: $tv = ::zero(); @@ -419,6 +424,15 @@ macro_rules! diag_impl( diag } } + + impl DiagMut<$tv> for $t { + #[inline] + fn set_diag(&mut self, diag: &$tv) { + for i in 0..$dim { + unsafe { self.unsafe_set((i, i), diag.unsafe_at(i)) } + } + } + } ) ); @@ -688,7 +702,9 @@ macro_rules! from_homogeneous_impl( macro_rules! outer_impl( ($t: ident, $m: ident) => ( - impl + Zero> Outer<$m> for $t { + impl + Zero> Outer for $t { + type OuterProductType = $m; + #[inline] fn outer(&self, other: &$t) -> $m { let mut res: $m = ::zero(); diff --git a/src/structs/pnt.rs b/src/structs/pnt.rs index fb01e1cd..b7452f19 100644 --- a/src/structs/pnt.rs +++ b/src/structs/pnt.rs @@ -11,7 +11,7 @@ use rand::{Rand, Rng}; use num::{Zero, One}; use traits::operations::{ApproxEq, POrd, POrdering, Axpy}; use traits::structure::{Cast, Dim, Indexable, Iterable, IterableMut, PntAsVec, Shape, - NumPnt, FloatPnt, BaseFloat, BaseNum, Bounded}; + NumPnt, FloatPnt, BaseFloat, BaseNum, Bounded, Repeat}; use traits::geometry::{Orig, FromHomogeneous, ToHomogeneous}; use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6}; #[cfg(feature="arbitrary")] @@ -29,10 +29,11 @@ impl Pnt0 { pub fn new() -> Pnt0 { Pnt0(PhantomData) } +} - /// Creates a new point. The parameter is not taken in account. +impl Repeat for Pnt0 { #[inline] - pub fn new_repeat(_: N) -> Pnt0 { + fn repeat(_: N) -> Pnt0 { Pnt0(PhantomData) } } @@ -57,7 +58,7 @@ as_array_impl!(Pnt1, 1); index_impl!(Pnt1); indexable_impl!(Pnt1, 1); at_fast_impl!(Pnt1, 1); -new_repeat_impl!(Pnt1, val, x); +repeat_impl!(Pnt1, val, x); dim_impl!(Pnt1, 1); container_impl!(Pnt1); pnt_as_vec_impl!(Pnt1, Vec1, x); @@ -99,7 +100,7 @@ as_array_impl!(Pnt2, 2); index_impl!(Pnt2); indexable_impl!(Pnt2, 2); at_fast_impl!(Pnt2, 2); -new_repeat_impl!(Pnt2, val, x, y); +repeat_impl!(Pnt2, val, x, y); dim_impl!(Pnt2, 2); container_impl!(Pnt2); pnt_as_vec_impl!(Pnt2, Vec2, x, y); @@ -143,7 +144,7 @@ as_array_impl!(Pnt3, 3); index_impl!(Pnt3); indexable_impl!(Pnt3, 3); at_fast_impl!(Pnt3, 3); -new_repeat_impl!(Pnt3, val, x, y, z); +repeat_impl!(Pnt3, val, x, y, z); dim_impl!(Pnt3, 3); container_impl!(Pnt3); pnt_as_vec_impl!(Pnt3, Vec3, x, y, z); @@ -189,7 +190,7 @@ as_array_impl!(Pnt4, 4); index_impl!(Pnt4); indexable_impl!(Pnt4, 4); at_fast_impl!(Pnt4, 4); -new_repeat_impl!(Pnt4, val, x, y, z, w); +repeat_impl!(Pnt4, val, x, y, z, w); dim_impl!(Pnt4, 4); container_impl!(Pnt4); pnt_as_vec_impl!(Pnt4, Vec4, x, y, z, w); @@ -237,7 +238,7 @@ as_array_impl!(Pnt5, 5); index_impl!(Pnt5); indexable_impl!(Pnt5, 5); at_fast_impl!(Pnt5, 5); -new_repeat_impl!(Pnt5, val, x, y, z, w, a); +repeat_impl!(Pnt5, val, x, y, z, w, a); dim_impl!(Pnt5, 5); container_impl!(Pnt5); pnt_as_vec_impl!(Pnt5, Vec5, x, y, z, w, a); @@ -287,7 +288,7 @@ as_array_impl!(Pnt6, 6); index_impl!(Pnt6); indexable_impl!(Pnt6, 6); at_fast_impl!(Pnt6, 6); -new_repeat_impl!(Pnt6, val, x, y, z, w, a, b); +repeat_impl!(Pnt6, val, x, y, z, w, a, b); dim_impl!(Pnt6, 6); container_impl!(Pnt6); pnt_as_vec_impl!(Pnt6, Vec6, x, y, z, w, a, b); diff --git a/src/structs/quat.rs b/src/structs/quat.rs index 5c24e93a..24f70bc1 100644 --- a/src/structs/quat.rs +++ b/src/structs/quat.rs @@ -11,7 +11,7 @@ use num::{Zero, One}; use structs::{Vec3, Pnt3, Rot3, Mat3}; use traits::operations::{ApproxEq, Inv, POrd, POrdering, Axpy}; use traits::structure::{Cast, Indexable, Iterable, IterableMut, Dim, Shape, BaseFloat, BaseNum, - Bounded}; + Bounded, Repeat}; use traits::geometry::{Norm, Rotation, Rotate, Transform}; #[cfg(feature="arbitrary")] @@ -495,7 +495,7 @@ as_array_impl!(Quat, 4); index_impl!(Quat); indexable_impl!(Quat, 4); at_fast_impl!(Quat, 4); -new_repeat_impl!(Quat, val, w, i, j, k); +repeat_impl!(Quat, val, w, i, j, k); dim_impl!(Quat, 3); container_impl!(Quat); add_impl!(Quat, w, i, j, k); diff --git a/src/structs/rot.rs b/src/structs/rot.rs index 2b97fdc3..dca149b4 100644 --- a/src/structs/rot.rs +++ b/src/structs/rot.rs @@ -7,7 +7,7 @@ use rand::{Rand, Rng}; use num::{Zero, One}; use traits::geometry::{Rotate, Rotation, AbsoluteRotate, RotationMatrix, Transform, ToHomogeneous, Norm, Cross}; -use traits::structure::{Cast, Dim, Row, Col, BaseFloat, BaseNum, }; +use traits::structure::{Cast, Dim, Row, Col, BaseFloat, BaseNum, Eye, Diag}; use traits::operations::{Absolute, Inv, Transpose, ApproxEq}; use structs::vec::{Vec1, Vec2, Vec3, Vec4}; use structs::pnt::{Pnt2, Pnt3, Pnt4}; @@ -408,6 +408,7 @@ vec_mul_rot_impl!(Rot2, Vec2); rot_mul_pnt_impl!(Rot2, Pnt2); pnt_mul_rot_impl!(Rot2, Pnt2); one_impl!(Rot2); +eye_impl!(Rot2); rotation_matrix_impl!(Rot2, Vec2, Vec1); col_impl!(Rot2, Vec2); row_impl!(Rot2, Vec2); @@ -417,6 +418,7 @@ to_homogeneous_impl!(Rot2, Mat3); inv_impl!(Rot2); transpose_impl!(Rot2); approx_eq_impl!(Rot2); +diag_impl!(Rot2, Vec2); submat_impl!(Rot3, Mat3); rotate_impl!(Rot3, Vec3, Pnt3); @@ -428,6 +430,7 @@ vec_mul_rot_impl!(Rot3, Vec3); rot_mul_pnt_impl!(Rot3, Pnt3); pnt_mul_rot_impl!(Rot3, Pnt3); one_impl!(Rot3); +eye_impl!(Rot3); rotation_matrix_impl!(Rot3, Vec3, Vec3); col_impl!(Rot3, Vec3); row_impl!(Rot3, Vec3); @@ -437,6 +440,7 @@ to_homogeneous_impl!(Rot3, Mat4); inv_impl!(Rot3); transpose_impl!(Rot3); approx_eq_impl!(Rot3); +diag_impl!(Rot3, Vec3); submat_impl!(Rot4, Mat4); rotate_impl!(Rot4, Vec4, Pnt4); @@ -448,6 +452,7 @@ vec_mul_rot_impl!(Rot4, Vec4); rot_mul_pnt_impl!(Rot4, Pnt4); pnt_mul_rot_impl!(Rot4, Pnt4); one_impl!(Rot4); +eye_impl!(Rot4); rotation_matrix_impl!(Rot4, Vec4, Vec4); col_impl!(Rot4, Vec4); row_impl!(Rot4, Vec4); @@ -457,3 +462,4 @@ to_homogeneous_impl!(Rot4, Mat5); inv_impl!(Rot4); transpose_impl!(Rot4); approx_eq_impl!(Rot4); +diag_impl!(Rot4, Vec4); diff --git a/src/structs/rot_macros.rs b/src/structs/rot_macros.rs index 94928481..a9c38326 100644 --- a/src/structs/rot_macros.rs +++ b/src/structs/rot_macros.rs @@ -102,6 +102,38 @@ macro_rules! one_impl( ) ); +macro_rules! eye_impl( + ($t: ident) => ( + impl Eye for $t { + #[inline] + fn new_identity(dim: usize) -> $t { + if dim != ::dim::<$t>() { + panic!("Dimension mismatch: should be {}, got {}.", ::dim::<$t>(), dim); + } + else { + ::one() + } + } + } + ) +); + +macro_rules! diag_impl( + ($t: ident, $tv: ident) => ( + impl Diag<$tv> for $t { + #[inline] + fn from_diag(diag: &$tv) -> $t { + $t { submat: Diag::from_diag(diag) } + } + + #[inline] + fn diag(&self) -> $tv { + self.submat.diag() + } + } + ) +); + macro_rules! rot_mul_rot_impl( ($t: ident) => ( impl Mul<$t> for $t { diff --git a/src/structs/spec/vec.rs b/src/structs/spec/vec.rs index 59c1983b..fcb0fa1c 100644 --- a/src/structs/spec/vec.rs +++ b/src/structs/spec/vec.rs @@ -6,7 +6,7 @@ use structs::vec::{Vec1, Vec2, Vec3, Vec4}; use structs::mat::Mat3; impl + Sub> Cross for Vec2 { - type Output = Vec1; + type CrossProductType = Vec1; #[inline] fn cross(&self, other: &Vec2) -> Vec1 { @@ -23,7 +23,7 @@ impl + Copy> CrossMatrix> for Vec2 { } impl + Sub> Cross for Vec3 { - type Output = Vec3; + type CrossProductType = Vec3; #[inline] fn cross(&self, other: &Vec3) -> Vec3 { diff --git a/src/structs/vec.rs b/src/structs/vec.rs index 618689ad..318bcfad 100644 --- a/src/structs/vec.rs +++ b/src/structs/vec.rs @@ -13,7 +13,7 @@ use traits::operations::{ApproxEq, POrd, POrdering, Axpy, Absolute}; use traits::geometry::{Transform, Rotate, FromHomogeneous, ToHomogeneous, Dot, Norm, Translation, Translate}; use traits::structure::{Basis, Cast, Dim, Indexable, Iterable, IterableMut, Shape, NumVec, - FloatVec, BaseFloat, BaseNum, Bounded}; + FloatVec, BaseFloat, BaseNum, Bounded, Repeat}; use structs::pnt::{Pnt1, Pnt2, Pnt3, Pnt4, Pnt5, Pnt6}; #[cfg(feature="arbitrary")] @@ -31,10 +31,11 @@ impl Vec0 { pub fn new() -> Vec0 { Vec0(PhantomData) } +} - /// Creates a new vector. The parameter is not taken in account. +impl Repeat for Vec0 { #[inline] - pub fn new_repeat(_: N) -> Vec0 { + fn repeat(_: N) -> Vec0 { Vec0(PhantomData) } } @@ -55,7 +56,7 @@ as_array_impl!(Vec1, 1); index_impl!(Vec1); indexable_impl!(Vec1, 1); at_fast_impl!(Vec1, 1); -new_repeat_impl!(Vec1, val, x); +repeat_impl!(Vec1, val, x); dim_impl!(Vec1, 1); container_impl!(Vec1); // (specialized); basis_impl!(Vec1, 1); @@ -108,7 +109,7 @@ as_array_impl!(Vec2, 2); index_impl!(Vec2); indexable_impl!(Vec2, 2); at_fast_impl!(Vec2, 2); -new_repeat_impl!(Vec2, val, x, y); +repeat_impl!(Vec2, val, x, y); dim_impl!(Vec2, 2); container_impl!(Vec2); // (specialized); basis_impl!(Vec2, 1); @@ -163,7 +164,7 @@ as_array_impl!(Vec3, 3); index_impl!(Vec3); indexable_impl!(Vec3, 3); at_fast_impl!(Vec3, 3); -new_repeat_impl!(Vec3, val, x, y, z); +repeat_impl!(Vec3, val, x, y, z); dim_impl!(Vec3, 3); container_impl!(Vec3); // (specialized); basis_impl!(Vec3, 1); @@ -221,7 +222,7 @@ as_array_impl!(Vec4, 4); index_impl!(Vec4); indexable_impl!(Vec4, 4); at_fast_impl!(Vec4, 4); -new_repeat_impl!(Vec4, val, x, y, z, w); +repeat_impl!(Vec4, val, x, y, z, w); dim_impl!(Vec4, 4); container_impl!(Vec4); basis_impl!(Vec4, 4); @@ -280,7 +281,7 @@ as_array_impl!(Vec5, 5); index_impl!(Vec5); indexable_impl!(Vec5, 5); at_fast_impl!(Vec5, 5); -new_repeat_impl!(Vec5, val, x, y, z, w, a); +repeat_impl!(Vec5, val, x, y, z, w, a); dim_impl!(Vec5, 5); container_impl!(Vec5); basis_impl!(Vec5, 5); @@ -341,7 +342,7 @@ as_array_impl!(Vec6, 6); index_impl!(Vec6); indexable_impl!(Vec6, 6); at_fast_impl!(Vec6, 6); -new_repeat_impl!(Vec6, val, x, y, z, w, a, b); +repeat_impl!(Vec6, val, x, y, z, w, a, b); dim_impl!(Vec6, 6); container_impl!(Vec6); basis_impl!(Vec6, 6); diff --git a/src/structs/vec_macros.rs b/src/structs/vec_macros.rs index 42ecaf1d..8b92dd09 100644 --- a/src/structs/vec_macros.rs +++ b/src/structs/vec_macros.rs @@ -227,12 +227,12 @@ macro_rules! index_impl( ) ); -macro_rules! new_repeat_impl( +macro_rules! repeat_impl( ($t: ident, $param: ident, $($compN: ident),+) => ( - impl $t { + impl Repeat for $t { /// Creates a new vector with all its components equal to a given value. #[inline] - pub fn new_repeat($param: N) -> $t { + fn repeat($param: N) -> $t { $t{ $($compN: $param ),+ } diff --git a/src/traits/geometry.rs b/src/traits/geometry.rs index e9c22678..29b3a51a 100644 --- a/src/traits/geometry.rs +++ b/src/traits/geometry.rs @@ -1,7 +1,7 @@ //! Traits of operations having a well-known or explicit geometric meaning. use std::ops::Neg; -use traits::structure::{BaseFloat, Mat}; +use traits::structure::{BaseFloat, SquareMat}; /// Trait of object which represent a translation, and to wich new translation /// can be appended. @@ -143,7 +143,7 @@ impl + Copy, AV, M: Rotation + Translation> Rotatio /// be implemented by quaternions to convert them to a rotation matrix. pub trait RotationMatrix : Rotation { /// The output rotation matrix type. - type Output: Mat + Rotation; + type Output: SquareMat + Rotation; /// Gets the rotation matrix represented by `self`. fn to_rot_mat(&self) -> Self::Output; @@ -232,10 +232,10 @@ pub trait Norm { */ pub trait Cross { /// The cross product output. - type Output; + type CrossProductType; /// Computes the cross product between two elements (usually vectors). - fn cross(&self, other: &Self) -> Self::Output; + fn cross(&self, other: &Self) -> Self::CrossProductType; } /** diff --git a/src/traits/mod.rs b/src/traits/mod.rs index 39d29c00..30506892 100644 --- a/src/traits/mod.rs +++ b/src/traits/mod.rs @@ -6,7 +6,8 @@ pub use traits::geometry::{AbsoluteRotate, Cross, CrossMatrix, Dot, FromHomogene pub use traits::structure::{FloatVec, FloatPnt, Basis, Cast, Col, Dim, Indexable, Iterable, IterableMut, Mat, SquareMat, Row, NumVec, NumPnt, PntAsVec, ColSlice, - RowSlice, Diag, Eye, Shape, BaseFloat, BaseNum, Bounded}; + RowSlice, Diag, DiagMut, Eye, Repeat, Shape, BaseFloat, BaseNum, + Bounded}; pub use traits::operations::{Absolute, ApproxEq, Axpy, Cov, Det, Inv, Mean, Outer, POrd, Transpose, EigenQR}; diff --git a/src/traits/operations.rs b/src/traits/operations.rs index b3bfeb54..f8a7ca74 100644 --- a/src/traits/operations.rs +++ b/src/traits/operations.rs @@ -299,9 +299,12 @@ pub trait Transpose { } /// Traits of objects having an outer product. -pub trait Outer { +pub trait Outer { + /// Result type of the outer product. + type OuterProductType; + /// Computes the outer product: `a * b` - fn outer(&self, other: &Self) -> M; + fn outer(&self, other: &Self) -> Self::OuterProductType; } /// Trait for computing the covariance of a set of data. diff --git a/src/traits/structure.rs b/src/traits/structure.rs index 79b4af4b..f579cdbe 100644 --- a/src/traits/structure.rs +++ b/src/traits/structure.rs @@ -59,12 +59,14 @@ pub trait Cast { /// Trait of matrices. /// /// A matrix has rows and columns and are able to multiply them. -pub trait Mat>: Row + Col + Mul + Index<(usize, usize), Output = N> { } +pub trait Mat>: Row + Col + Mul + + Index<(usize, usize), Output = N> +{ } impl Mat for M - where M: Row + Col + Mul + Index<(usize, usize), Output = N>, - C: Mul, -{} + where M: Row + Col + Mul + Index<(usize, usize), Output = N>, + C: Mul, +{ } /// Trait implemented by square matrices. pub trait SquareMat: Mat + @@ -81,6 +83,12 @@ pub trait Eye { fn new_identity(dim: usize) -> Self; } +/// Trait for constructiong an object repeating a value. +pub trait Repeat { + /// Returns a value with filled by `val`. + fn repeat(val: N) -> Self; +} + /// Types that have maximum and minimum value. pub trait Bounded { /// The minimum value. @@ -155,13 +163,16 @@ pub trait Diag { /// Creates a new matrix with the given diagonal. fn from_diag(diag: &V) -> Self; - /// Sets the diagonal of this matrix. - fn set_diag(&mut self, diag: &V); - /// The diagonal of this matrix. fn diag(&self) -> V; } +/// Trait to set the diagonal of square matrices. +pub trait DiagMut: Diag { + /// Sets the diagonal of this matrix. + fn set_diag(&mut self, diag: &V); +} + /// The shape of an indexable object. pub trait Shape: Index { /// Returns the shape of an indexable object.