diff --git a/src/lib.rs b/src/lib.rs index 9354f010..aefd89ca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -108,18 +108,17 @@ extern crate serialize; #[cfg(test)] extern crate test; -use std::num::{Zero, One}; use std::cmp; pub use traits::{PartialLess, PartialEqual, PartialGreater, NotComparable}; pub use traits::{ Absolute, AbsoluteRotate, - NumPnt, - NumVec, ApproxEq, Axpy, Basis, BaseFloat, + BaseNum, + Bounded, Cast, Col, ColSlice, RowSlice, @@ -143,6 +142,9 @@ pub use traits::{ Mat, Mean, Norm, + NumPnt, + NumVec, + One, Orig, Outer, POrd, @@ -160,7 +162,8 @@ pub use traits::{ Translate, Translation, Transpose, UniformSphereSample, - VecAsPnt + VecAsPnt, + Zero }; pub use structs::{ @@ -336,6 +339,12 @@ pub fn zero() -> T { Zero::zero() } +/// Tests is a value is iqual to zero. +#[inline(always)] +pub fn is_zero(val: &T) -> bool { + val.is_zero() +} + /// Create a one-valued value. /// /// This is the same as `std::num::one()`. diff --git a/src/linalg/decompositions.rs b/src/linalg/decompositions.rs index 63f68043..f9f6beff 100644 --- a/src/linalg/decompositions.rs +++ b/src/linalg/decompositions.rs @@ -1,4 +1,3 @@ -use std::num::Zero; use traits::operations::{Transpose, ApproxEq}; use traits::structure::{ColSlice, Eye, Indexable, Diag, SquareMat, BaseFloat}; use traits::geometry::Norm; @@ -52,7 +51,7 @@ pub fn qr(m: &M) -> (M, M) for ite in range(0u, iterations) { let mut v = r.col_slice(ite, ite, rows); let alpha = - if unsafe { v.unsafe_at(ite) } >= Zero::zero() { + if unsafe { v.unsafe_at(ite) } >= ::zero() { -Norm::norm(&v) } else { @@ -62,7 +61,7 @@ pub fn qr(m: &M) -> (M, M) let x = v.unsafe_at(0); v.unsafe_set(0, x - alpha); } - if !v.normalize().is_zero() { + if !::is_zero(&v.normalize()) { let qk: M = householder_matrix(rows, ite, v); r = qk * r; q = q * Transpose::transpose_cpy(&qk); diff --git a/src/structs/chol.rs b/src/structs/chol.rs deleted file mode 100644 index 64f938ab..00000000 --- a/src/structs/chol.rs +++ /dev/null @@ -1,27 +0,0 @@ -// use lower_triangular::LowerTriangularMat; -// -// /// Choleski factorization. -// pub trait Chol { -// /// Choleski LL* factorization for a symetric definite positive matrix. -// fn chol(self) -> LowerTriangularMat; -// } -// -// impl Chol for DMat { -// fn chol(self) -> LowerTriangularMat { -// } -// } -// -// impl Chol for LowerTriangularMat { -// fn chol(self) -> LowerTriangularMat { -// } -// } -// -// impl Chol for UpperTriangularMat { -// fn chol(self) -> LowerTriangularMat { -// } -// } -// -// impl Chol for DiagonalMat { -// fn chol(self) -> LowerTriangularMat { -// } -// } diff --git a/src/structs/crout.rs b/src/structs/crout.rs deleted file mode 100644 index db43a5b8..00000000 --- a/src/structs/crout.rs +++ /dev/null @@ -1,6 +0,0 @@ -use lower_triangular::LowerTriangularMat; - -pub trait Crout { - /// Crout LDL* factorization for a symmetric definite indefinite matrix. - fn crout(self, &mut DiagonalMat) -> LowerTriangularMat; -} diff --git a/src/structs/dmat.rs b/src/structs/dmat.rs index 174676d3..15815318 100644 --- a/src/structs/dmat.rs +++ b/src/structs/dmat.rs @@ -5,12 +5,11 @@ use std::cmp; use std::rand::Rand; use std::rand; -use std::num::{One, Zero, Num}; use traits::operations::ApproxEq; use std::mem; use structs::dvec::{DVec, DVecMulRhs}; use traits::operations::{Inv, Transpose, Mean, Cov}; -use traits::structure::{Cast, ColSlice, RowSlice, Diag, Eye, Indexable, Shape}; +use traits::structure::{Cast, ColSlice, RowSlice, Diag, Eye, Indexable, Shape, Zero, One, BaseNum}; use std::fmt::{Show, Formatter, Result}; @@ -55,7 +54,7 @@ impl DMat { /// components. #[inline] pub fn new_zeros(nrows: uint, ncols: uint) -> DMat { - DMat::from_elem(nrows, ncols, Zero::zero()) + DMat::from_elem(nrows, ncols, ::zero()) } /// Tests if all components of the matrix are zeroes. @@ -67,7 +66,7 @@ impl DMat { #[inline] pub fn reset(&mut self) { for mij in self.mij.iter_mut() { - *mij = Zero::zero(); + *mij = ::zero(); } } } @@ -84,7 +83,7 @@ impl DMat { /// Builds a matrix filled with a given constant. #[inline] pub fn new_ones(nrows: uint, ncols: uint) -> DMat { - DMat::from_elem(nrows, ncols, One::one()) + DMat::from_elem(nrows, ncols, ::one()) } } @@ -191,7 +190,7 @@ impl Eye for DMat { let mut res = DMat::new_zeros(dim, dim); for i in range(0u, dim) { - let _1: N = One::one(); + let _1: N = ::one(); res[(i, i)] = _1; } @@ -302,7 +301,7 @@ impl + Add + Zero> DMatMulRhs> for DMat for i in range(0u, left.nrows) { for j in range(0u, right.ncols) { - let mut acc: N = Zero::zero(); + let mut acc: N = ::zero(); unsafe { for k in range(0u, left.ncols) { @@ -327,7 +326,7 @@ DMatMulRhs> for DVec { let mut res : DVec = unsafe { DVec::new_uninitialized(left.nrows) }; for i in range(0u, left.nrows) { - let mut acc: N = Zero::zero(); + let mut acc: N = ::zero(); for j in range(0u, left.ncols) { unsafe { @@ -351,7 +350,7 @@ DVecMulRhs> for DMat { let mut res : DVec = unsafe { DVec::new_uninitialized(right.ncols) }; for i in range(0u, right.ncols) { - let mut acc: N = Zero::zero(); + let mut acc: N = ::zero(); for j in range(0u, right.nrows) { unsafe { @@ -366,8 +365,7 @@ DVecMulRhs> for DMat { } } -impl -Inv for DMat { +impl Inv for DMat { #[inline] fn inv_cpy(m: &DMat) -> Option> { let mut res : DMat = m.clone(); @@ -395,7 +393,7 @@ Inv for DMat { let mut n0 = k; // index of a non-zero entry while n0 != dim { - if unsafe { self.unsafe_at((n0, k)) } != Zero::zero() { + if unsafe { self.unsafe_at((n0, k)) } != ::zero() { break; } @@ -500,7 +498,7 @@ impl Transpose for DMat { } } -impl + Clone> Mean> for DMat { +impl + Zero + Clone> Mean> for DMat { fn mean(m: &DMat) -> DVec { let mut res: DVec = DVec::new_zeros(m.ncols); let normalizer: N = Cast::from(1.0f64 / Cast::from(m.nrows)); @@ -518,7 +516,7 @@ impl + Clone> Mean> for DMat { } } -impl + DMatDivRhs>> Cov> for DMat { +impl + DMatDivRhs>> Cov> for DMat { // FIXME: this could be heavily optimized, removing all temporaries by merging loops. fn cov(m: &DMat) -> DMat { assert!(m.nrows > 1); diff --git a/src/structs/dvec.rs b/src/structs/dvec.rs index f7a643a2..e32594d7 100644 --- a/src/structs/dvec.rs +++ b/src/structs/dvec.rs @@ -2,14 +2,13 @@ #![allow(missing_docs)] // we hide doc to not have to document the $trhs double dispatch trait. -use std::num::{Zero, One, Num}; use std::rand::Rand; use std::rand; use std::slice::{Items, MutItems}; use traits::operations::ApproxEq; use std::iter::FromIterator; use traits::geometry::{Dot, Norm}; -use traits::structure::{Iterable, IterableMut, Indexable, Shape, BaseFloat}; +use traits::structure::{Iterable, IterableMut, Indexable, Shape, BaseFloat, BaseNum, Zero, One}; /// Heap allocated, dynamically sized vector. #[deriving(Eq, PartialEq, Show, Clone)] @@ -87,7 +86,7 @@ pub struct DVec1 { } small_dvec_impl!(DVec1, 1, DVec1MulRhs, DVec1DivRhs, DVec1AddRhs, DVec1SubRhs, 0) -small_dvec_from_impl!(DVec1, 1, Zero::zero()) +small_dvec_from_impl!(DVec1, 1, ::zero()) /// Stack-allocated, dynamically sized vector with a maximum size of 2. @@ -97,7 +96,7 @@ pub struct DVec2 { } small_dvec_impl!(DVec2, 2, DVec2MulRhs, DVec2DivRhs, DVec2AddRhs, DVec2SubRhs, 0, 1) -small_dvec_from_impl!(DVec2, 2, Zero::zero(), Zero::zero()) +small_dvec_from_impl!(DVec2, 2, ::zero(), ::zero()) /// Stack-allocated, dynamically sized vector with a maximum size of 3. @@ -107,7 +106,7 @@ pub struct DVec3 { } small_dvec_impl!(DVec3, 3, DVec3MulRhs, DVec3DivRhs, DVec3AddRhs, DVec3SubRhs, 0, 1, 2) -small_dvec_from_impl!(DVec3, 3, Zero::zero(), Zero::zero(), Zero::zero()) +small_dvec_from_impl!(DVec3, 3, ::zero(), ::zero(), ::zero()) /// Stack-allocated, dynamically sized vector with a maximum size of 4. @@ -117,7 +116,7 @@ pub struct DVec4 { } small_dvec_impl!(DVec4, 4, DVec4MulRhs, DVec4DivRhs, DVec4AddRhs, DVec4SubRhs, 0, 1, 2, 3) -small_dvec_from_impl!(DVec4, 4, Zero::zero(), Zero::zero(), Zero::zero(), Zero::zero()) +small_dvec_from_impl!(DVec4, 4, ::zero(), ::zero(), ::zero(), ::zero()) /// Stack-allocated, dynamically sized vector with a maximum size of 5. @@ -127,7 +126,7 @@ pub struct DVec5 { } small_dvec_impl!(DVec5, 5, DVec5MulRhs, DVec5DivRhs, DVec5AddRhs, DVec5SubRhs, 0, 1, 2, 3, 4) -small_dvec_from_impl!(DVec5, 5, Zero::zero(), Zero::zero(), Zero::zero(), Zero::zero(), Zero::zero()) +small_dvec_from_impl!(DVec5, 5, ::zero(), ::zero(), ::zero(), ::zero(), ::zero()) /// Stack-allocated, dynamically sized vector with a maximum size of 6. @@ -137,4 +136,4 @@ pub struct DVec6 { } small_dvec_impl!(DVec6, 6, DVec6MulRhs, DVec6DivRhs, DVec6AddRhs, DVec6SubRhs, 0, 1, 2, 3, 4, 5) -small_dvec_from_impl!(DVec6, 6, Zero::zero(), Zero::zero(), Zero::zero(), Zero::zero(), Zero::zero(), Zero::zero()) +small_dvec_from_impl!(DVec6, 6, ::zero(), ::zero(), ::zero(), ::zero(), ::zero(), ::zero()) diff --git a/src/structs/dvec_macros.rs b/src/structs/dvec_macros.rs index f033d374..5a6d9b3c 100644 --- a/src/structs/dvec_macros.rs +++ b/src/structs/dvec_macros.rs @@ -19,7 +19,7 @@ macro_rules! dvec_impl( /// * `dim` - The dimension of the vector. #[inline] pub fn new_zeros(dim: uint) -> $dvec { - $dvec::from_elem(dim, Zero::zero()) + $dvec::from_elem(dim, ::zero()) } /// Tests if all components of the vector are zeroes. @@ -106,7 +106,7 @@ macro_rules! dvec_impl( /// * `dim` - The dimension of the vector. #[inline] pub fn new_ones(dim: uint) -> $dvec { - $dvec::from_elem(dim, One::one()) + $dvec::from_elem(dim, ::one()) } } @@ -142,7 +142,7 @@ macro_rules! dvec_impl( for i in range(0u, dim) { let mut basis_element : $dvec = $dvec::new_zeros(dim); - basis_element.set(i, One::one()); + basis_element.set(i, ::one()); res.push(basis_element); } @@ -161,7 +161,7 @@ macro_rules! dvec_impl( for i in range(0u, dim) { let mut basis_element : $dvec = $dvec::new_zeros(self.len()); - basis_element.set(i, One::one()); + basis_element.set(i, ::one()); if res.len() == dim - 1 { break; @@ -175,7 +175,7 @@ macro_rules! dvec_impl( elt = elt - *v * Dot::dot(&elt, v) }; - if !ApproxEq::approx_eq(&Norm::sqnorm(&elt), &Zero::zero()) { + if !ApproxEq::approx_eq(&Norm::sqnorm(&elt), &::zero()) { res.push(Norm::normalize_cpy(&elt)); } } @@ -225,12 +225,12 @@ macro_rules! dvec_impl( } } - impl Dot for $dvec { + impl Dot for $dvec { #[inline] fn dot(a: &$dvec, b: &$dvec) -> N { assert!(a.len() == b.len()); - let mut res: N = Zero::zero(); + let mut res: N = ::zero(); for i in range(0u, a.len()) { res = res + unsafe { a.unsafe_at(i) * b.unsafe_at(i) }; diff --git a/src/structs/iso.rs b/src/structs/iso.rs index b85d9040..3ee23e57 100644 --- a/src/structs/iso.rs +++ b/src/structs/iso.rs @@ -2,11 +2,10 @@ #![allow(missing_docs)] -use std::num::{Zero, One, Num}; use std::rand::{Rand, Rng}; use structs::mat::{Mat3, Mat4, Mat5}; -use traits::structure::{Cast, Dim, Col, BaseFloat}; -use traits::operations::{Inv, ApproxEq, Absolute}; +use traits::structure::{Cast, Dim, Col, BaseFloat, BaseNum, One}; +use traits::operations::{Inv, ApproxEq}; use traits::geometry::{RotationMatrix, Rotation, Rotate, AbsoluteRotate, Transform, Transformation, Translate, Translation, ToHomogeneous}; diff --git a/src/structs/iso_macros.rs b/src/structs/iso_macros.rs index 9faa1097..50d83de4 100644 --- a/src/structs/iso_macros.rs +++ b/src/structs/iso_macros.rs @@ -2,7 +2,7 @@ macro_rules! iso_impl( ($t: ident, $submat: ident, $subvec: ident, $subrotvec: ident) => ( - impl $t { + impl $t { /// Creates a new isometry from a rotation matrix and a vector. #[inline] pub fn new(translation: $subvec, rotation: $subrotvec) -> $t { @@ -26,7 +26,7 @@ macro_rules! iso_impl( macro_rules! rotation_matrix_impl( ($t: ident, $trot: ident, $tlv: ident, $tav: ident) => ( - impl + BaseFloat + Num + Clone> + impl + BaseFloat + BaseNum + Clone> RotationMatrix, $tav, $trot> for $t { #[inline] fn to_rot_mat(&self) -> $trot { @@ -53,7 +53,7 @@ macro_rules! one_impl( impl One for $t { #[inline] fn one() -> $t { - $t::new_with_rotmat(Zero::zero(), One::one()) + $t::new_with_rotmat(::zero(), ::one()) } } ) @@ -74,7 +74,7 @@ macro_rules! iso_mul_iso_impl( macro_rules! iso_mul_pnt_impl( ($t: ident, $tv: ident, $tmul: ident) => ( - impl $tmul> for $tv { + impl $tmul> for $tv { #[inline] fn binop(left: &$t, right: &$tv) -> $tv { left.rotation * *right + left.translation @@ -85,7 +85,7 @@ macro_rules! iso_mul_pnt_impl( macro_rules! pnt_mul_iso_impl( ($t: ident, $tv: ident, $tmul: ident) => ( - impl $tmul> for $t { + impl $tmul> for $t { #[inline] fn binop(left: &$tv, right: &$t) -> $tv { (*left + right.translation) * right.rotation @@ -204,7 +204,7 @@ macro_rules! rotation_impl( macro_rules! rotate_impl( ($t: ident, $tv: ident) => ( - impl Rotate<$tv> for $t { + impl Rotate<$tv> for $t { #[inline] fn rotate(&self, v: &$tv) -> $tv { self.rotation.rotate(v) @@ -276,7 +276,7 @@ macro_rules! transform_impl( } } - impl $trhs for $tp { + impl $trhs for $tp { #[inline] fn transform(t: &$t, p: &$tp) -> $tp { t.rotation.transform(p) + t.translation @@ -292,7 +292,7 @@ macro_rules! transform_impl( macro_rules! inv_impl( ($t: ident) => ( - impl Inv for $t { + impl Inv for $t { #[inline] fn inv(&mut self) -> bool { self.rotation.inv(); @@ -317,7 +317,7 @@ macro_rules! inv_impl( macro_rules! to_homogeneous_impl( ($t: ident, $th: ident) => ( - impl ToHomogeneous<$th> for $t { + impl ToHomogeneous<$th> for $t { fn to_homogeneous(m: &$t) -> $th { let mut res = ToHomogeneous::to_homogeneous(&m.rotation); diff --git a/src/structs/lower_triangular.rs b/src/structs/lower_triangular.rs deleted file mode 100644 index 787bfd3c..00000000 --- a/src/structs/lower_triangular.rs +++ /dev/null @@ -1,153 +0,0 @@ -use rand::Rand; -use rand; -use std::num::{One, Zero}; -use std::vec; - -/// A structure optimized to store lower triangular matrices. -pub struct LowerTriangularMat { - priv dim: uint, - priv mij: ~[N] -} - -/// Trait to be implemented by objects which can be left-multiplied by a lower triangular array. -pub trait LowerTriangularMatMulRhs { - /// Apply the muliplicitaion. - fn binop(left: &LowerTriangularMat, right: &Self) -> Res; -} - -impl, Res> Mul for LowerTriangularMat { - #[inline(always)] - fn mul(&self, other: &Rhs) -> Res { - LowerTriangularMatMulRhs::binop(self, other) - } -} - -impl LowerTriangularMat { - /// Creates a lower triangular matrix without initializing its arguments. - #[inline] - pub unsafe fn new_uninitialized(dim: uint) -> LowerTriangularMat { - let mut vec = vec::with_capacity(dim * (dim + 1) / 2); - vec::raw::set_len(&mut vec, dim * (dim + 1) / 2); - - LowerTriangularMat { - dim: dim, - mij: vec - } - } -} - -impl LowerTriangularMat { - /// Creates a lower triangular matrix filled with zeros. - #[inline] - pub fn new_zeros(dim: uint) -> LowerTriangularMat { - LowerTriangularMat::from_elem(dim, Zero::zero()) - } - - /// Tests if every entry of the matrix are exactly zeros. - #[inline] - pub fn is_zero(&self) -> bool { - self.mij.iter().all(|e| e.is_zero()) - } -} - -impl LowerTriangularMat { - /// Creates a lower triangular matrix filled with random elements. - #[inline] - pub fn new_random(dim: uint) -> LowerTriangularMat { - LowerTriangularMat::from_fn(dim, |_, _| rand::random()) - } -} - -impl LowerTriangularMat { - /// Creates a lower triangular matrix filled with ones. - #[inline] - pub fn new_ones(dim: uint) -> LowerTriangularMat { - LowerTriangularMat::from_elem(dim, One::one()) - } -} - -impl LowerTriangularMat { - /// Creates a lower triangular matrix filled with a given value. - #[inline] - pub fn from_elem(dim: uint, val: N) -> LowerTriangularMat { - LowerTriangularMat { - dim: dim, - mij: vec::from_elem(dim * (dim + 1) / 2, val) - } - } -} - -impl LowerTriangularMat { - /// Creates a lower triangular matrix filled by a function. - #[inline(always)] - pub fn from_fn(dim: uint, f: &fn(uint, uint) -> N) -> LowerTriangularMat { - let mij = do vec::from_fn(dim * (dim + 1) / 2) |i| { - let l = (((1.0f64 + 8.0f64 * i as f64).sqrt() - 1.) / 2.0f64).floor() as uint; - let c = i - l * (l + 1) / 2; - - f(l, c) - }; - - LowerTriangularMat { - dim: dim, - mij: mij - } - } - - #[inline] - fn offset(&self, i: uint, j: uint) -> uint { - i * (i + 1) / 2 + j + 1 - } - - /// Transforms this matrix into an array. This consumes the matrix and is O(1). - #[inline] - pub fn to_array(self) -> ~[N] { - self.mij - } -} - -impl LowerTriangularMat { - /// Changes the value of a component of the matrix. - /// Fails if the indices point outside of the lower-triangular part of the matrix. - /// - /// # Arguments - /// * `row` - 0-based index of the line to be changed - /// * `col` - 0-based index of the column to be changed - #[inline] - pub fn set(&mut self, row: uint, col: uint, val: N) { - assert!(row < self.dim); - assert!(col < self.dim); - assert!(col <= row); - unsafe { self.set_fast(row, col, val) } - } - - /// Just like `set` without bounds checking. - #[inline] - pub unsafe fn set_fast(&mut self, row: uint, col: uint, val: N) { - let offset = self.offset(row, col); - *self.mij.unsafe_mut_ref(offset) = val - } - - /// Reads the value of a component of the matrix. - /// Fails if the indices point outside of the lower-triangular part of the matrix. - /// - /// # Arguments - /// * `row` - 0-based index of the line to be read - /// * `col` - 0-based index of the column to be read - #[inline] - pub fn at(&self, row: uint, col: uint) -> N { - assert!(row < self.dim); - assert!(col < self.dim); - unsafe { self.at_fast(row, col) } - } - - /// Just like `at` without bounds checking. - #[inline] - pub unsafe fn at_fast(&self, row: uint, col: uint) -> N { - if col > row { - Zero::zero() - } - - vec::raw::get(self.mij, self.offset(row, col)) - } -} diff --git a/src/structs/mat.rs b/src/structs/mat.rs index 66c44ea7..2e3539f1 100644 --- a/src/structs/mat.rs +++ b/src/structs/mat.rs @@ -3,7 +3,6 @@ #![allow(missing_docs)] // we allow missing to avoid having to document the mij components. use std::mem; -use std::num::{One, Zero, Num}; use traits::operations::ApproxEq; use std::slice::{Items, MutItems}; use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6, @@ -12,7 +11,7 @@ use structs::pnt::{Pnt1, Pnt4, Pnt5, Pnt6, Pnt1MulRhs, Pnt4MulRhs, Pnt5MulRhs, P 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}; + Eye, ColSlice, RowSlice, Diag, Shape, BaseFloat, BaseNum, Zero, One}; use traits::operations::{Absolute, Transpose, Inv, Outer, EigenQR}; use traits::geometry::{ToHomogeneous, FromHomogeneous, Orig}; use linalg; @@ -31,7 +30,7 @@ impl Identity { } /// Square matrix of dimension 1. -#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Zero, Show)] +#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Show)] pub struct Mat1 { pub m11: N } @@ -106,7 +105,8 @@ mat_sub_scalar_impl!(Mat1, uint, Mat1SubRhs, m11) mat_sub_scalar_impl!(Mat1, int, Mat1SubRhs, m11) absolute_impl!(Mat1, m11) -one_impl!(Mat1, One::one) +zero_impl!(Mat1, m11) +one_impl!(Mat1, ::one) iterable_impl!(Mat1, 1) iterable_mut_impl!(Mat1, 1) at_fast_impl!(Mat1, 1) @@ -114,8 +114,8 @@ dim_impl!(Mat1, 1) indexable_impl!(Mat1, 1) index_impl!(Mat1, 1) mat_mul_mat_impl!(Mat1, Mat1MulRhs, 1) -mat_mul_vec_impl!(Mat1, Vec1, Mat1MulRhs, 1, Zero::zero) -vec_mul_mat_impl!(Mat1, Vec1, Vec1MulRhs, 1, Zero::zero) +mat_mul_vec_impl!(Mat1, Vec1, Mat1MulRhs, 1, ::zero) +vec_mul_mat_impl!(Mat1, Vec1, Vec1MulRhs, 1, ::zero) mat_mul_pnt_impl!(Mat1, Pnt1, Mat1MulRhs, 1, Orig::orig) pnt_mul_mat_impl!(Mat1, Pnt1, Pnt1MulRhs, 1, Orig::orig) // (specialized) inv_impl!(Mat1, 1) @@ -132,7 +132,7 @@ outer_impl!(Vec1, Mat1) eigen_qr_impl!(Mat1, Vec1) /// Square matrix of dimension 2. -#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Zero, Show)] +#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Show)] pub struct Mat2 { pub m11: N, pub m21: N, pub m12: N, pub m22: N @@ -211,8 +211,10 @@ mat_sub_scalar_impl!(Mat2, int, Mat2SubRhs, m11, m12, m21, m22) absolute_impl!(Mat2, m11, m12, m21, m22) -one_impl!(Mat2, One::one, Zero::zero, - Zero::zero, One::one) +zero_impl!(Mat2, m11, m12, + m21, m22) +one_impl!(Mat2, ::one, ::zero, + ::zero, ::one) iterable_impl!(Mat2, 2) iterable_mut_impl!(Mat2, 2) dim_impl!(Mat2, 2) @@ -236,7 +238,7 @@ outer_impl!(Vec2, Mat2) eigen_qr_impl!(Mat2, Vec2) /// Square matrix of dimension 3. -#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Zero, Show)] +#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Show)] pub struct Mat3 { pub m11: N, pub m21: N, pub m31: N, pub m12: N, pub m22: N, pub m32: N, @@ -328,9 +330,14 @@ absolute_impl!(Mat3, m21, m22, m23, m31, m32, m33 ) -one_impl!(Mat3, One::one , Zero::zero, Zero::zero, - Zero::zero, One::one , Zero::zero, - Zero::zero, Zero::zero, One::one) +zero_impl!(Mat3, + m11, m12, m13, + m21, m22, m23, + m31, m32, m33 +) +one_impl!(Mat3, ::one , ::zero, ::zero, + ::zero, ::one , ::zero, + ::zero, ::zero, ::one) iterable_impl!(Mat3, 3) iterable_mut_impl!(Mat3, 3) dim_impl!(Mat3, 3) @@ -354,7 +361,7 @@ outer_impl!(Vec3, Mat3) eigen_qr_impl!(Mat3, Vec3) /// Square matrix of dimension 4. -#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Zero, Show)] +#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Show)] pub struct Mat4 { pub m11: N, pub m21: N, pub m31: N, pub m41: N, pub m12: N, pub m22: N, pub m32: N, pub m42: N, @@ -497,10 +504,16 @@ absolute_impl!(Mat4, m31, m32, m33, m34, m41, m42, m43, m44 ) -one_impl!(Mat4, One::one , Zero::zero, Zero::zero, Zero::zero, - Zero::zero, One::one , Zero::zero, Zero::zero, - Zero::zero, Zero::zero, One::one , Zero::zero, - Zero::zero, Zero::zero, Zero::zero, One::one) +zero_impl!(Mat4, + m11, m12, m13, m14, + m21, m22, m23, m24, + m31, m32, m33, m34, + m41, m42, m43, m44 +) +one_impl!(Mat4, ::one , ::zero, ::zero, ::zero, + ::zero, ::one , ::zero, ::zero, + ::zero, ::zero, ::one , ::zero, + ::zero, ::zero, ::zero, ::one) iterable_impl!(Mat4, 4) iterable_mut_impl!(Mat4, 4) dim_impl!(Mat4, 4) @@ -508,8 +521,8 @@ indexable_impl!(Mat4, 4) index_impl!(Mat4, 4) at_fast_impl!(Mat4, 4) mat_mul_mat_impl!(Mat4, Mat4MulRhs, 4) -mat_mul_vec_impl!(Mat4, Vec4, Mat4MulRhs, 4, Zero::zero) -vec_mul_mat_impl!(Mat4, Vec4, Vec4MulRhs, 4, Zero::zero) +mat_mul_vec_impl!(Mat4, Vec4, Mat4MulRhs, 4, ::zero) +vec_mul_mat_impl!(Mat4, Vec4, Vec4MulRhs, 4, ::zero) mat_mul_pnt_impl!(Mat4, Pnt4, Mat4MulRhs, 4, Orig::orig) pnt_mul_mat_impl!(Mat4, Pnt4, Pnt4MulRhs, 4, Orig::orig) inv_impl!(Mat4, 4) @@ -526,7 +539,7 @@ outer_impl!(Vec4, Mat4) eigen_qr_impl!(Mat4, Vec4) /// Square matrix of dimension 5. -#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Zero, Show)] +#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Show)] pub struct Mat5 { pub m11: N, pub m21: N, pub m31: N, pub m41: N, pub m51: N, pub m12: N, pub m22: N, pub m32: N, pub m42: N, pub m52: N, @@ -568,12 +581,19 @@ absolute_impl!(Mat5, m41, m42, m43, m44, m45, m51, m52, m53, m54, m55 ) +zero_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 +) one_impl!(Mat5, - One::one , Zero::zero, Zero::zero, Zero::zero, Zero::zero, - Zero::zero, One::one , Zero::zero, Zero::zero, Zero::zero, - Zero::zero, Zero::zero, One::one , Zero::zero, Zero::zero, - Zero::zero, Zero::zero, Zero::zero, One::one , Zero::zero, - Zero::zero, Zero::zero, Zero::zero, Zero::zero, One::one + ::one , ::zero, ::zero, ::zero, ::zero, + ::zero, ::one , ::zero, ::zero, ::zero, + ::zero, ::zero, ::one , ::zero, ::zero, + ::zero, ::zero, ::zero, ::one , ::zero, + ::zero, ::zero, ::zero, ::zero, ::one ) add_impl!(Mat5, Mat5AddRhs, m11, m12, m13, m14, m15, @@ -696,8 +716,8 @@ indexable_impl!(Mat5, 5) index_impl!(Mat5, 5) at_fast_impl!(Mat5, 5) mat_mul_mat_impl!(Mat5, Mat5MulRhs, 5) -mat_mul_vec_impl!(Mat5, Vec5, Mat5MulRhs, 5, Zero::zero) -vec_mul_mat_impl!(Mat5, Vec5, Vec5MulRhs, 5, Zero::zero) +mat_mul_vec_impl!(Mat5, Vec5, Mat5MulRhs, 5, ::zero) +vec_mul_mat_impl!(Mat5, Vec5, Vec5MulRhs, 5, ::zero) mat_mul_pnt_impl!(Mat5, Pnt5, Mat5MulRhs, 5, Orig::orig) pnt_mul_mat_impl!(Mat5, Pnt5, Pnt5MulRhs, 5, Orig::orig) inv_impl!(Mat5, 5) @@ -714,7 +734,7 @@ outer_impl!(Vec5, Mat5) eigen_qr_impl!(Mat5, Vec5) /// Square matrix of dimension 6. -#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Zero, Show)] +#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Show)] pub struct Mat6 { pub m11: N, pub m21: N, pub m31: N, pub m41: N, pub m51: N, pub m61: N, pub m12: N, pub m22: N, pub m32: N, pub m42: N, pub m52: N, pub m62: N, @@ -921,13 +941,17 @@ absolute_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) +zero_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) + one_impl!(Mat6, - One::one , Zero::zero, Zero::zero, Zero::zero, Zero::zero, Zero::zero, - Zero::zero, One::one , Zero::zero, Zero::zero, Zero::zero, Zero::zero, - Zero::zero, Zero::zero, One::one , Zero::zero, Zero::zero, Zero::zero, - Zero::zero, Zero::zero, Zero::zero, One::one , Zero::zero, Zero::zero, - Zero::zero, Zero::zero, Zero::zero, Zero::zero, One::one , Zero::zero, - Zero::zero, Zero::zero, Zero::zero, Zero::zero, Zero::zero, One::one + ::one , ::zero, ::zero, ::zero, ::zero, ::zero, + ::zero, ::one , ::zero, ::zero, ::zero, ::zero, + ::zero, ::zero, ::one , ::zero, ::zero, ::zero, + ::zero, ::zero, ::zero, ::one , ::zero, ::zero, + ::zero, ::zero, ::zero, ::zero, ::one , ::zero, + ::zero, ::zero, ::zero, ::zero, ::zero, ::one ) iterable_impl!(Mat6, 6) iterable_mut_impl!(Mat6, 6) @@ -936,8 +960,8 @@ indexable_impl!(Mat6, 6) index_impl!(Mat6, 6) at_fast_impl!(Mat6, 6) mat_mul_mat_impl!(Mat6, Mat6MulRhs, 6) -mat_mul_vec_impl!(Mat6, Vec6, Mat6MulRhs, 6, Zero::zero) -vec_mul_mat_impl!(Mat6, Vec6, Vec6MulRhs, 6, Zero::zero) +mat_mul_vec_impl!(Mat6, Vec6, Mat6MulRhs, 6, ::zero) +vec_mul_mat_impl!(Mat6, Vec6, Vec6MulRhs, 6, ::zero) mat_mul_pnt_impl!(Mat6, Pnt6, Mat6MulRhs, 6, Orig::orig) pnt_mul_mat_impl!(Mat6, Pnt6, Pnt6MulRhs, 6, Orig::orig) inv_impl!(Mat6, 6) diff --git a/src/structs/mat_macros.rs b/src/structs/mat_macros.rs index e2d6afcf..960fdc2d 100644 --- a/src/structs/mat_macros.rs +++ b/src/structs/mat_macros.rs @@ -104,8 +104,8 @@ macro_rules! eye_impl( impl Eye for $t { fn new_identity(dim: uint) -> $t { assert!(dim == $ndim); - let mut eye: $t = Zero::zero(); - $(eye.$comp_diagN = One::one();)+ + let mut eye: $t = ::zero(); + $(eye.$comp_diagN = ::one();)+ eye } } @@ -162,7 +162,7 @@ macro_rules! iterable_mut_impl( macro_rules! one_impl( ($t: ident, $value0: expr $(, $valueN: expr)* ) => ( - impl One for $t { + impl One for $t { #[inline] fn one() -> $t { $t::new($value0() $(, $valueN() )*) @@ -171,6 +171,25 @@ macro_rules! one_impl( ) ) +macro_rules! zero_impl( + ($t: ident, $comp0: ident $(, $compN: ident)* ) => ( + impl Zero for $t { + #[inline] + fn zero() -> $t { + $t { + $comp0: ::zero() + $(, $compN: ::zero() )* + } + } + + #[inline] + fn is_zero(&self) -> bool { + ::is_zero(&self.$comp0) $(&& ::is_zero(&self.$compN) )* + } + } + ) +) + macro_rules! dim_impl( ($t: ident, $dim: expr) => ( impl Dim for $t { @@ -276,7 +295,7 @@ macro_rules! row_impl( #[inline] fn row(&self, row: uint) -> $tv { - let mut res: $tv = Zero::zero(); + let mut res: $tv = ::zero(); for (i, e) in res.iter_mut().enumerate() { *e = self.at((row, i)); @@ -317,7 +336,7 @@ macro_rules! col_impl( #[inline] fn col(&self, col: uint) -> $tv { - let mut res: $tv = Zero::zero(); + let mut res: $tv = ::zero(); for (i, e) in res.iter_mut().enumerate() { *e = self.at((i, col)); @@ -334,7 +353,7 @@ macro_rules! diag_impl( impl Diag<$tv> for $t { #[inline] fn from_diag(diag: &$tv) -> $t { - let mut res: $t = Zero::zero(); + let mut res: $t = ::zero(); res.set_diag(diag); @@ -350,7 +369,7 @@ macro_rules! diag_impl( #[inline] fn diag(&self) -> $tv { - let mut diag: $tv = Zero::zero(); + let mut diag: $tv = ::zero(); for i in range(0, $dim) { unsafe { diag.unsafe_set(i, self.unsafe_at((i, i))) } @@ -364,15 +383,15 @@ macro_rules! diag_impl( macro_rules! mat_mul_mat_impl( ($t: ident, $trhs: ident, $dim: expr) => ( - impl $trhs> for $t { + impl $trhs> for $t { #[inline] fn binop(left: &$t, right: &$t) -> $t { // careful! we need to comute other * self here (self is the rhs). - let mut res: $t = Zero::zero(); + let mut res: $t = ::zero(); for i in range(0u, $dim) { for j in range(0u, $dim) { - let mut acc: N = Zero::zero(); + let mut acc: N = ::zero(); unsafe { for k in range(0u, $dim) { @@ -392,7 +411,7 @@ macro_rules! mat_mul_mat_impl( macro_rules! vec_mul_mat_impl( ($t: ident, $v: ident, $trhs: ident, $dim: expr, $zero: expr) => ( - impl $trhs> for $t { + impl $trhs> for $t { #[inline] fn binop(left: &$v, right: &$t) -> $v { let mut res : $v = $zero(); @@ -414,7 +433,7 @@ macro_rules! vec_mul_mat_impl( macro_rules! mat_mul_vec_impl( ($t: ident, $v: ident, $trhs: ident, $dim: expr, $zero: expr) => ( - impl $trhs> for $v { + impl $trhs> for $v { #[inline] fn binop(left: &$t, right: &$v) -> $v { let mut res : $v = $zero(); @@ -448,7 +467,7 @@ macro_rules! mat_mul_pnt_impl( macro_rules! inv_impl( ($t: ident, $dim: expr) => ( - impl + impl Inv for $t { #[inline] fn inv_cpy(m: &$t) -> Option<$t> { @@ -463,7 +482,7 @@ macro_rules! inv_impl( } fn inv(&mut self) -> bool { - let mut res: $t = One::one(); + let mut res: $t = ::one(); // inversion using Gauss-Jordan elimination for k in range(0u, $dim) { @@ -474,7 +493,7 @@ macro_rules! inv_impl( let mut n0 = k; // index of a non-zero entry while n0 != $dim { - if self.at((n0, k)) != Zero::zero() { + if self.at((n0, k)) != ::zero() { break; } @@ -581,10 +600,10 @@ macro_rules! approx_eq_impl( macro_rules! to_homogeneous_impl( ($t: ident, $t2: ident, $dim: expr, $dim2: expr) => ( - impl ToHomogeneous<$t2> for $t { + impl ToHomogeneous<$t2> for $t { #[inline] fn to_homogeneous(m: &$t) -> $t2 { - let mut res: $t2 = One::one(); + let mut res: $t2 = ::one(); for i in range(0u, $dim) { for j in range(0u, $dim) { @@ -600,10 +619,10 @@ macro_rules! to_homogeneous_impl( macro_rules! from_homogeneous_impl( ($t: ident, $t2: ident, $dim: expr, $dim2: expr) => ( - impl FromHomogeneous<$t2> for $t { + impl FromHomogeneous<$t2> for $t { #[inline] fn from(m: &$t2) -> $t { - let mut res: $t = One::one(); + let mut res: $t = ::one(); for i in range(0u, $dim2) { for j in range(0u, $dim2) { @@ -625,7 +644,7 @@ macro_rules! outer_impl( impl + Zero> Outer<$m> for $t { #[inline] fn outer(a: &$t, b: &$t) -> $m { - let mut res: $m = Zero::zero(); + let mut res: $m = ::zero(); for i in range(0u, Dim::dim(None::<$t>)) { for j in range(0u, Dim::dim(None::<$t>)) { @@ -642,7 +661,7 @@ macro_rules! outer_impl( macro_rules! eigen_qr_impl( ($t: ident, $v: ident) => ( impl EigenQR> for $t - where N: Num + One + Zero + BaseFloat + ApproxEq + Clone { + where N: BaseNum + One + Zero + BaseFloat + ApproxEq + Clone { fn eigen_qr(m: &$t, eps: &N, niter: uint) -> ($t, $v) { linalg::eigen_qr(m, eps, niter) } diff --git a/src/structs/ortho.rs b/src/structs/ortho.rs index e92bee6a..01941ce4 100644 --- a/src/structs/ortho.rs +++ b/src/structs/ortho.rs @@ -1,4 +1,3 @@ -use std::num::{Zero, One }; use std::num; use traits::structure::BaseFloat; use structs::{Pnt3, Vec3, Mat4}; @@ -25,9 +24,9 @@ pub struct OrthoMat3 { impl Ortho3 { /// Creates a new 3D orthographic projection. pub fn new(width: N, height: N, znear: N, zfar: N) -> Ortho3 { - assert!(!(zfar - znear).is_zero()); - assert!(!width.is_zero()); - assert!(!height.is_zero()); + assert!(!::is_zero(&(zfar - znear))); + assert!(!::is_zero(&width)); + assert!(!::is_zero(&height)); Ortho3 { width: width, @@ -115,11 +114,11 @@ impl Ortho3 { impl OrthoMat3 { /// Creates a new orthographic projection matrix from the width, heihgt, znear and zfar planes of the view cuboid. pub fn new(width: N, height: N, znear: N, zfar: N) -> OrthoMat3 { - assert!(!(zfar - znear).is_zero()); - assert!(!width.is_zero()); - assert!(!height.is_zero()); + assert!(!::is_zero(&(zfar - znear))); + assert!(!::is_zero(&width)); + assert!(!::is_zero(&height)); - let mat: Mat4 = One::one(); + let mat: Mat4 = ::one(); let mut res = OrthoMat3 { mat: mat }; res.set_width(width); @@ -160,26 +159,26 @@ impl OrthoMat3 { /// The near plane offset of the view cuboid. #[inline] pub fn znear(&self) -> N { - (self.mat.m34 + One::one()) / self.mat.m33 + (self.mat.m34 + ::one()) / self.mat.m33 } /// The far plane offset of the view cuboid. #[inline] pub fn zfar(&self) -> N { - (self.mat.m34 - One::one()) / self.mat.m33 + (self.mat.m34 - ::one()) / self.mat.m33 } /// Sets the width of the view cuboid. #[inline] pub fn set_width(&mut self, width: N) { - assert!(!width.is_zero()); + assert!(!::is_zero(&width)); self.mat.m11 = num::cast::(2.0).unwrap() / width; } /// Sets the height of the view cuboid. #[inline] pub fn set_height(&mut self, height: N) { - assert!(!height.is_zero()); + assert!(!::is_zero(&height)); self.mat.m22 = num::cast::(2.0).unwrap() / height; } @@ -200,7 +199,7 @@ impl OrthoMat3 { /// Sets the near and far plane offsets of the view cuboid. #[inline] pub fn set_znear_and_zfar(&mut self, znear: N, zfar: N) { - assert!(!(zfar - znear).is_zero()); + assert!(!::is_zero(&(zfar - znear))); self.mat.m33 = -num::cast::(2.0).unwrap() / (zfar - znear); self.mat.m34 = -(zfar + znear) / (zfar - znear); } diff --git a/src/structs/persp.rs b/src/structs/persp.rs index df829577..0b420270 100644 --- a/src/structs/persp.rs +++ b/src/structs/persp.rs @@ -1,4 +1,3 @@ -use std::num::{Zero, One}; use traits::structure::BaseFloat; use structs::{Pnt3, Vec3, Mat4}; @@ -24,8 +23,8 @@ pub struct PerspMat3 { impl Persp3 { /// Creates a new 3D perspective projection. pub fn new(aspect: N, fov: N, znear: N, zfar: N) -> Persp3 { - assert!(!(zfar - znear).is_zero()); - assert!(!aspect.is_zero()); + assert!(!::is_zero(&(zfar - znear))); + assert!(!::is_zero(&aspect)); Persp3 { aspect: aspect, @@ -121,17 +120,17 @@ impl Persp3 { impl PerspMat3 { /// Creates a new persepctive matrix from the aspect ratio, field of view, and near/far planes. pub fn new(aspect: N, fov: N, znear: N, zfar: N) -> PerspMat3 { - assert!(!(znear - zfar).is_zero()); - assert!(!aspect.is_zero()); + assert!(!::is_zero(&(znear - zfar))); + assert!(!::is_zero(&aspect)); - let mat: Mat4 = One::one(); + let mat: Mat4 = ::one(); let mut res = PerspMat3 { mat: mat }; res.set_fov(fov); res.set_aspect(aspect); res.set_znear_and_zfar(znear, zfar); - res.mat.m44 = Zero::zero(); - res.mat.m43 = One::one(); + res.mat.m44 = ::zero(); + res.mat.m43 = ::one(); res } @@ -161,7 +160,7 @@ impl PerspMat3 { /// Gets the field of view of the view frustrum. #[inline] pub fn fov(&self) -> N { - let _1: N = One::one(); + let _1: N = ::one(); let _2 = _1 + _1; (_1 / self.mat.m22).atan() * _2 @@ -170,7 +169,7 @@ impl PerspMat3 { /// Gets the near plane offset of the view frustrum. #[inline] pub fn znear(&self) -> N { - let _1: N = One::one(); + let _1: N = ::one(); let _2 = _1 + _1; let ratio = (self.mat.m33 + _1) / (self.mat.m33 - _1); @@ -180,7 +179,7 @@ impl PerspMat3 { /// Gets the far plane offset of the view frustrum. #[inline] pub fn zfar(&self) -> N { - let _1: N = One::one(); + let _1: N = ::one(); let _2 = _1 + _1; let ratio = (self.mat.m33 + _1) / (self.mat.m33 - _1); @@ -193,14 +192,14 @@ impl PerspMat3 { /// frustrum. #[inline] pub fn set_aspect(&mut self, aspect: N) { - assert!(!aspect.is_zero()); + assert!(!::is_zero(&aspect)); self.mat.m11 = -self.mat.m22 / aspect; } /// Updates this projection with a new field of view of the view frustrum. #[inline] pub fn set_fov(&mut self, fov: N) { - let _1: N = One::one(); + let _1: N = ::one(); let _2 = _1 + _1; let old_m22 = self.mat.m22.clone(); @@ -225,7 +224,7 @@ impl PerspMat3 { /// Updates this projection matrix with new near and far plane offsets of the view frustrum. #[inline] pub fn set_znear_and_zfar(&mut self, znear: N, zfar: N) { - let _1: N = One::one(); + let _1: N = ::one(); let _2 = _1 + _1; self.mat.m33 = -(zfar + znear) / (znear - zfar); @@ -235,7 +234,7 @@ impl PerspMat3 { /// Projects a point. #[inline] pub fn project_pnt(&self, p: &Pnt3) -> Pnt3 { - let _1: N = One::one(); + let _1: N = ::one(); let inv_denom = _1 / p.z; Pnt3::new( self.mat.m11 * p.x * inv_denom, @@ -247,7 +246,7 @@ impl PerspMat3 { /// Projects a vector. #[inline] pub fn project_vec(&self, p: &Vec3) -> Vec3 { - let _1: N = One::one(); + let _1: N = ::one(); let inv_denom = _1 / p.z; Vec3::new( self.mat.m11 * p.x * inv_denom, diff --git a/src/structs/pnt.rs b/src/structs/pnt.rs index bc90eb83..51761d8b 100644 --- a/src/structs/pnt.rs +++ b/src/structs/pnt.rs @@ -3,14 +3,13 @@ #![allow(missing_docs)] // we allow missing to avoid having to document the point components. use std::mem; -use std::num::{Zero, One, Bounded, Num}; use std::slice::{Items, MutItems}; use std::iter::{Iterator, FromIterator}; use traits::operations::{ApproxEq, POrd, POrdering, PartialLess, PartialEqual, PartialGreater, NotComparable, Axpy, ScalarAdd, ScalarSub, ScalarMul, ScalarDiv}; use traits::structure::{Cast, Dim, Indexable, Iterable, IterableMut, PntAsVec, Shape, - NumPnt, FloatPnt, BaseFloat}; + NumPnt, FloatPnt, BaseFloat, BaseNum, Zero, One, Bounded}; use traits::geometry::{Orig, FromHomogeneous, ToHomogeneous}; use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6}; diff --git a/src/structs/pnt_macros.rs b/src/structs/pnt_macros.rs index d8ef262b..fc10fce3 100644 --- a/src/structs/pnt_macros.rs +++ b/src/structs/pnt_macros.rs @@ -6,8 +6,8 @@ macro_rules! orig_impl( #[inline] fn orig() -> $t { $t { - $comp0: Zero::zero() - $(, $compN: Zero::zero() )* + $comp0: ::zero() + $(, $compN: ::zero() )* } } @@ -106,7 +106,7 @@ macro_rules! pnt_to_homogeneous_impl( res.$comp0 = v.$comp0.clone(); $( res.$compN = v.$compN.clone(); )* - res.$extra = One::one(); + res.$extra = ::one(); res } @@ -132,11 +132,11 @@ macro_rules! pnt_from_homogeneous_impl( macro_rules! num_float_pnt_impl( ($t: ident, $tv: ident $(,$trhs: ident)*) => ( impl NumPnt> for $t - where N: Num $(+ $trhs>)* { + where N: BaseNum + Zero $(+ $trhs>)* { } impl FloatPnt> for $t - where N: Num + One + Zero + ApproxEq + BaseFloat $(+ $trhs>)* { + where N: BaseNum + One + Zero + ApproxEq + BaseFloat $(+ $trhs>)* { } ) ) diff --git a/src/structs/quat.rs b/src/structs/quat.rs index 5e1d03af..bdd4bd6d 100644 --- a/src/structs/quat.rs +++ b/src/structs/quat.rs @@ -3,7 +3,6 @@ #![allow(missing_docs)] // we allow missing to avoid having to document the dispatch trait. use std::mem; -use std::num::{Zero, One, Bounded, Num}; use std::num; use std::rand::{Rand, Rng}; use std::slice::{Items, MutItems}; @@ -11,11 +10,12 @@ use structs::{Vec3, Pnt3, Rot3, Mat3, Vec3MulRhs, Pnt3MulRhs}; use traits::operations::{ApproxEq, Inv, POrd, POrdering, NotComparable, PartialLess, PartialGreater, PartialEqual, Axpy, ScalarAdd, ScalarSub, ScalarMul, ScalarDiv}; -use traits::structure::{Cast, Indexable, Iterable, IterableMut, Dim, Shape, BaseFloat}; +use traits::structure::{Cast, Indexable, Iterable, IterableMut, Dim, Shape, BaseFloat, BaseNum, Zero, + One, Bounded}; use traits::geometry::{Norm, Cross, Rotation, Rotate, Transform}; /// A quaternion. -#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Zero, Show)] +#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Hash, Rand, Show)] pub struct Quat { /// The scalar component of the quaternion. pub w: N, @@ -82,7 +82,7 @@ impl + Clone> Inv for Quat { fn inv(&mut self) -> bool { let sqnorm = Norm::sqnorm(self); - if ApproxEq::approx_eq(&sqnorm, &Zero::zero()) { + if ApproxEq::approx_eq(&sqnorm, &::zero()) { false } else { @@ -152,8 +152,8 @@ impl UnitQuat { pub fn new(axisangle: Vec3) -> UnitQuat { let sqang = Norm::sqnorm(&axisangle); - if sqang.is_zero() { - One::one() + if ::is_zero(&sqang) { + ::one() } else { let ang = sqang.sqrt(); @@ -251,11 +251,11 @@ impl UnitQuat { } } -impl One for UnitQuat { +impl One for UnitQuat { #[inline] fn one() -> UnitQuat { unsafe { - UnitQuat::new_with_unit_quat(Quat::new(One::one(), Zero::zero(), Zero::zero(), Zero::zero())) + UnitQuat::new_with_unit_quat(Quat::new(::one(), ::zero(), ::zero(), ::zero())) } } } @@ -308,17 +308,17 @@ impl + Clone> Div, UnitQuat> for UnitQ } } -impl UnitQuatMulRhs> for UnitQuat { +impl UnitQuatMulRhs> for UnitQuat { #[inline] fn binop(left: &UnitQuat, right: &UnitQuat) -> UnitQuat { UnitQuat { q: left.q * right.q } } } -impl UnitQuatMulRhs> for Vec3 { +impl UnitQuatMulRhs> for Vec3 { #[inline] fn binop(left: &UnitQuat, right: &Vec3) -> Vec3 { - let _2: N = num::one::() + num::one(); + let _2: N = ::one::() + ::one(); let mut t = Cross::cross(left.q.vector(), right); t.x = t.x * _2; t.y = t.y * _2; @@ -330,14 +330,14 @@ impl UnitQuatMulRhs> for Vec3 { } } -impl UnitQuatMulRhs> for Pnt3 { +impl UnitQuatMulRhs> for Pnt3 { #[inline] fn binop(left: &UnitQuat, right: &Pnt3) -> Pnt3 { ::orig::>() + *left * *right.as_vec() } } -impl Vec3MulRhs> for UnitQuat { +impl Vec3MulRhs> for UnitQuat { #[inline] fn binop(left: &Vec3, right: &UnitQuat) -> Vec3 { let mut inv_quat = right.clone(); @@ -347,7 +347,7 @@ impl Vec3MulRhs> for UnitQuat { } } -impl Pnt3MulRhs> for UnitQuat { +impl Pnt3MulRhs> for UnitQuat { #[inline] fn binop(left: &Pnt3, right: &UnitQuat) -> Pnt3 { ::orig::>() + *left.as_vec() * *right @@ -357,12 +357,12 @@ impl Pnt3MulRhs> for UnitQuat { impl Rotation> for UnitQuat { #[inline] fn rotation(&self) -> Vec3 { - let _2 = num::one::() + num::one(); + let _2 = ::one::() + ::one(); let mut v = self.q.vector().clone(); let ang = _2 * v.normalize().atan2(self.q.w); - if ang.is_zero() { - num::zero() + if ::is_zero(&ang) { + ::zero() } else { Vec3::new(v.x * ang, v.y * ang, v.z * ang) @@ -400,7 +400,7 @@ impl Rotation> for UnitQuat { } } -impl Rotate> for UnitQuat { +impl Rotate> for UnitQuat { #[inline] fn rotate(&self, v: &Vec3) -> Vec3 { *self * *v @@ -412,7 +412,7 @@ impl Rotate> for UnitQuat { } } -impl Rotate> for UnitQuat { +impl Rotate> for UnitQuat { #[inline] fn rotate(&self, p: &Pnt3) -> Pnt3 { *self * *p @@ -424,7 +424,7 @@ impl Rotate> for UnitQuat { } } -impl Transform> for UnitQuat { +impl Transform> for UnitQuat { #[inline] fn transform(&self, v: &Vec3) -> Vec3 { *self * *v @@ -436,7 +436,7 @@ impl Transform> for UnitQuat { } } -impl Transform> for UnitQuat { +impl Transform> for UnitQuat { #[inline] fn transform(&self, p: &Pnt3) -> Pnt3 { *self * *p @@ -520,6 +520,7 @@ vec_sub_scalar_impl!(Quat, i16, QuatSubRhs, w, i, j, k) vec_sub_scalar_impl!(Quat, i8, QuatSubRhs, w, i, j, k) vec_sub_scalar_impl!(Quat, uint, QuatSubRhs, w, i, j, k) vec_sub_scalar_impl!(Quat, int, QuatSubRhs, w, i, j, k) +zero_one_impl!(Quat, w, i, j, k) approx_eq_impl!(Quat, w, i, j, k) from_iterator_impl!(Quat, iterator, iterator, iterator, iterator) bounded_impl!(Quat, w, i, j, k) diff --git a/src/structs/rot.rs b/src/structs/rot.rs index d1e63a98..a5a69b48 100644 --- a/src/structs/rot.rs +++ b/src/structs/rot.rs @@ -2,11 +2,10 @@ #![allow(missing_docs)] -use std::num::{Zero, One, Num}; use std::rand::{Rand, Rng}; use traits::geometry::{Rotate, Rotation, AbsoluteRotate, RotationMatrix, Transform, ToHomogeneous, Norm, Cross}; -use traits::structure::{Cast, Dim, Row, Col, BaseFloat}; +use traits::structure::{Cast, Dim, Row, Col, BaseFloat, BaseNum, Zero, One}; use traits::operations::{Absolute, Inv, Transpose, ApproxEq}; use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec2MulRhs, Vec3MulRhs, Vec4MulRhs}; use structs::pnt::{Pnt2, Pnt3, Pnt4, Pnt2MulRhs, Pnt3MulRhs, Pnt4MulRhs}; @@ -104,13 +103,13 @@ impl Rot3 { /// * `axisangle` - A vector representing the rotation. Its magnitude is the amount of rotation /// in radian. Its direction is the axis of rotation. pub fn new(axisangle: Vec3) -> Rot3 { - if Norm::sqnorm(&axisangle).is_zero() { - One::one() + if ::is_zero(&Norm::sqnorm(&axisangle)) { + ::one() } else { let mut axis = axisangle; let angle = axis.normalize(); - let _1: N = One::one(); + let _1: N = ::one(); let ux = axis.x.clone(); let uy = axis.y.clone(); let uz = axis.z.clone(); @@ -209,14 +208,14 @@ impl> Rotation> for Rot3 { #[inline] fn rotation(&self) -> Vec3 { - let angle = ((self.submat.m11 + self.submat.m22 + self.submat.m33 - One::one()) / Cast::from(2.0)).acos(); + let angle = ((self.submat.m11 + self.submat.m22 + self.submat.m33 - ::one()) / Cast::from(2.0)).acos(); if angle != angle { // FIXME: handle that correctly - Zero::zero() + ::zero() } - else if angle.is_zero() { - Zero::zero() + else if ::is_zero(&angle) { + ::zero() } else { let m32_m23 = self.submat.m32 - self.submat.m23; @@ -225,10 +224,10 @@ Rotation> for Rot3 { let denom = (m32_m23 * m32_m23 + m13_m31 * m13_m31 + m21_m12 * m21_m12).sqrt(); - if denom.is_zero() { + if ::is_zero(&denom) { // XXX: handle that properly // panic!("Internal error: singularity.") - Zero::zero() + ::zero() } else { let a_d = angle / denom; diff --git a/src/structs/rot_macros.rs b/src/structs/rot_macros.rs index ef1d06e4..82a105fd 100644 --- a/src/structs/rot_macros.rs +++ b/src/structs/rot_macros.rs @@ -34,7 +34,7 @@ macro_rules! rotate_impl( } } - impl $trhs for $tv { + impl $trhs for $tv { #[inline] fn rotate(t: &$t, v: &$tv) -> $tv { *t * *v @@ -46,7 +46,7 @@ macro_rules! rotate_impl( } } - impl $trhs for $tp { + impl $trhs for $tp { #[inline] fn rotate(t: &$t, p: &$tp) -> $tp { *t * *p @@ -83,7 +83,7 @@ macro_rules! transform_impl( } } - impl $trhs for $tv { + impl $trhs for $tv { #[inline] fn transform(t: &$t, v: &$tv) -> $tv { t.rotate(v) @@ -95,7 +95,7 @@ macro_rules! transform_impl( } } - impl $trhs for $tp { + impl $trhs for $tp { #[inline] fn transform(t: &$t, p: &$tp) -> $tp { t.rotate(p) @@ -122,7 +122,7 @@ macro_rules! dim_impl( macro_rules! rotation_matrix_impl( ($t: ident, $tlv: ident, $tav: ident) => ( - impl + BaseFloat> RotationMatrix, $tav, $t> for $t { + impl + BaseFloat> RotationMatrix, $tav, $t> for $t { #[inline] fn to_rot_mat(&self) -> $t { self.clone() @@ -133,10 +133,10 @@ macro_rules! rotation_matrix_impl( macro_rules! one_impl( ($t: ident) => ( - impl One for $t { + impl One for $t { #[inline] fn one() -> $t { - $t { submat: One::one() } + $t { submat: ::one() } } } ) @@ -144,7 +144,7 @@ macro_rules! one_impl( macro_rules! rot_mul_rot_impl( ($t: ident, $mulrhs: ident) => ( - impl $mulrhs> for $t { + impl $mulrhs> for $t { #[inline] fn binop(left: &$t, right: &$t) -> $t { $t { submat: left.submat * right.submat } @@ -155,7 +155,7 @@ macro_rules! rot_mul_rot_impl( macro_rules! rot_mul_vec_impl( ($t: ident, $tv: ident, $mulrhs: ident) => ( - impl $mulrhs> for $tv { + impl $mulrhs> for $tv { #[inline] fn binop(left: &$t, right: &$tv) -> $tv { left.submat * *right @@ -172,7 +172,7 @@ macro_rules! rot_mul_pnt_impl( macro_rules! vec_mul_rot_impl( ($t: ident, $tv: ident, $mulrhs: ident) => ( - impl $mulrhs> for $t { + impl $mulrhs> for $t { #[inline] fn binop(left: &$tv, right: &$t) -> $tv { *left * right.submat @@ -281,7 +281,7 @@ macro_rules! index_impl( macro_rules! to_homogeneous_impl( ($t: ident, $tm: ident) => ( - impl ToHomogeneous<$tm> for $t { + impl ToHomogeneous<$tm> for $t { #[inline] fn to_homogeneous(m: &$t) -> $tm { ToHomogeneous::to_homogeneous(&m.submat) diff --git a/src/structs/spec/complex.rs b/src/structs/spec/complex.rs index ec043e14..7a06d180 100644 --- a/src/structs/spec/complex.rs +++ b/src/structs/spec/complex.rs @@ -5,21 +5,21 @@ use extra::complex::Cmplx; use traits::operations::{Absolute, Inv}; use traits::structure::{Dim}; -impl Absolute> for Cmplx { +impl Absolute> for Cmplx { #[inline] fn absolute(&self) -> Cmplx { Cmplx::new(self.re.clone(), self.im.clone()) } } -impl Inv for Cmplx { +impl Inv for Cmplx { #[inline] fn inverse(&self) -> Option> { if self.is_zero() { None } else { - let _1: N = NumCast::from(1.0); + let _1: N = BaseNumCast::from(1.0); let divisor = _1 / (self.re * self.re - self.im * self.im); Some(Cmplx::new(self.re * divisor, -self.im * divisor)) @@ -32,7 +32,7 @@ impl Inv for Cmplx { false } else { - let _1: N = NumCast::from(1.0); + let _1: N = BaseNumCast::from(1.0); let divisor = _1 / (self.re * self.re - self.im * self.im); self.re = self.re * divisor; diff --git a/src/structs/spec/identity.rs b/src/structs/spec/identity.rs index b33d2f25..6b2687f2 100644 --- a/src/structs/spec/identity.rs +++ b/src/structs/spec/identity.rs @@ -1,7 +1,8 @@ -use std::num::{One, Zero}; use structs::mat; use traits::operations::{Inv, Transpose}; -use traits::geometry::{Translation, Translate, Rotation, Rotate, Transformation, Transform, AbsoluteRotate}; +use traits::structure::{Zero, One}; +use traits::geometry::{Translation, Translate, Rotation, Rotate, Transformation, Transform, + AbsoluteRotate}; impl One for mat::Identity { #[inline] @@ -41,12 +42,12 @@ impl Transpose for mat::Identity { impl Translation for mat::Identity { #[inline] fn translation(&self) -> V { - Zero::zero() + ::zero() } #[inline] fn inv_translation(&self) -> V { - Zero::zero() + ::zero() } #[inline] @@ -90,12 +91,12 @@ impl Translate for mat::Identity { impl Rotation for mat::Identity { #[inline] fn rotation(&self) -> V { - Zero::zero() + ::zero() } #[inline] fn inv_rotation(&self) -> V { - Zero::zero() + ::zero() } #[inline] @@ -146,12 +147,12 @@ impl AbsoluteRotate for mat::Identity { impl Transformation for mat::Identity { #[inline] fn transformation(&self) -> M { - One::one() + ::one() } #[inline] fn inv_transformation(&self) -> M { - One::one() + ::one() } #[inline] diff --git a/src/structs/spec/mat.rs b/src/structs/spec/mat.rs index 767caf34..c41b6f44 100644 --- a/src/structs/spec/mat.rs +++ b/src/structs/spec/mat.rs @@ -1,12 +1,11 @@ -use std::num::{Zero, One, Num}; use structs::vec::{Vec2, Vec3, Vec2MulRhs, Vec3MulRhs}; use structs::pnt::{Pnt2, Pnt3, Pnt2MulRhs, Pnt3MulRhs}; use structs::mat::{Mat1, Mat2, Mat3, Mat3MulRhs, Mat2MulRhs}; use traits::operations::{Inv, Det, ApproxEq}; -use traits::structure::{Row, Col, BaseFloat}; +use traits::structure::{Row, Col, BaseNum}; // some specializations: -impl + Clone> Inv for Mat1 { +impl + Clone> Inv for Mat1 { #[inline] fn inv_cpy(m: &Mat1) -> Option> { let mut res = m.clone(); @@ -21,11 +20,11 @@ impl + Clone> Inv for Mat1 { #[inline] fn inv(&mut self) -> bool { - if ApproxEq::approx_eq(&self.m11, &Zero::zero()) { + if ApproxEq::approx_eq(&self.m11, &::zero()) { false } else { - let _1: N = One::one(); + let _1: N = ::one(); self.m11 = _1 / Det::det(self); true @@ -33,7 +32,7 @@ impl + Clone> Inv for Mat1 { } } -impl + Clone> Inv for Mat2 { +impl + Clone> Inv for Mat2 { #[inline] fn inv_cpy(m: &Mat2) -> Option> { let mut res = m.clone(); @@ -50,7 +49,7 @@ impl + Clone> Inv for Mat2 { fn inv(&mut self) -> bool { let det = Det::det(self); - if ApproxEq::approx_eq(&det, &Zero::zero()) { + if ApproxEq::approx_eq(&det, &::zero()) { false } else { @@ -63,7 +62,7 @@ impl + Clone> Inv for Mat2 { } } -impl + Clone> Inv for Mat3 { +impl + Clone> Inv for Mat3 { #[inline] fn inv_cpy(m: &Mat3) -> Option> { let mut res = m.clone(); @@ -84,7 +83,7 @@ impl + Clone> Inv for Mat3 { let det = self.m11 * minor_m12_m23 - self.m12 * minor_m11_m23 + self.m13 * minor_m11_m22; - if ApproxEq::approx_eq(&det, &Zero::zero()) { + if ApproxEq::approx_eq(&det, &::zero()) { false } else { @@ -107,21 +106,21 @@ impl + Clone> Inv for Mat3 { } } -impl Det for Mat1 { +impl Det for Mat1 { #[inline] fn det(m: &Mat1) -> N { m.m11.clone() } } -impl Det for Mat2 { +impl Det for Mat2 { #[inline] fn det(m: &Mat2) -> N { m.m11 * m.m22 - m.m21 * m.m12 } } -impl Det for Mat3 { +impl Det for Mat3 { #[inline] fn det(m: &Mat3) -> N { let minor_m12_m23 = m.m22 * m.m33 - m.m32 * m.m23; diff --git a/src/structs/spec/vec.rs b/src/structs/spec/vec.rs index ebaf1b45..8f90b116 100644 --- a/src/structs/spec/vec.rs +++ b/src/structs/spec/vec.rs @@ -1,5 +1,4 @@ -use std::num::{Zero, One, Num}; -use traits::structure::{Cast, Row, Basis, BaseFloat}; +use traits::structure::{Cast, Row, Basis, BaseFloat, Zero, One}; use traits::geometry::{Norm, Cross, CrossMatrix, UniformSphereSample}; use structs::vec::{Vec1, Vec2, Vec3, Vec4}; use structs::mat::Mat3; @@ -34,9 +33,9 @@ impl + Zero + Clone> CrossMatrix> for Vec3 { #[inline] fn cross_matrix(v: &Vec3) -> Mat3 { Mat3::new( - Zero::zero(), -v.z , v.y.clone(), - v.z.clone() , Zero::zero(), -v.x, - -v.y , v.x.clone() , Zero::zero() + ::zero(), -v.z , v.y.clone(), + v.z.clone() , ::zero(), -v.x, + -v.y , v.x.clone() , ::zero() ) } } @@ -71,7 +70,7 @@ impl Row> for Vec2 { impl Basis for Vec1 { #[inline(always)] fn canonical_basis(f: |Vec1| -> bool) { - f(Vec1::new(One::one())); + f(Vec1::new(::one())); } #[inline(always)] @@ -80,7 +79,7 @@ impl Basis for Vec1 { #[inline] fn canonical_basis_element(i: uint) -> Option> { if i == 0 { - Some(Vec1::new(One::one())) + Some(Vec1::new(::one())) } else { None @@ -91,8 +90,8 @@ impl Basis for Vec1 { impl> Basis for Vec2 { #[inline(always)] fn canonical_basis(f: |Vec2| -> bool) { - if !f(Vec2::new(One::one(), Zero::zero())) { return }; - f(Vec2::new(Zero::zero(), One::one())); + if !f(Vec2::new(::one(), ::zero())) { return }; + f(Vec2::new(::zero(), ::one())); } #[inline] @@ -103,10 +102,10 @@ impl> Basis for Vec2 { #[inline] fn canonical_basis_element(i: uint) -> Option> { if i == 0 { - Some(Vec2::new(One::one(), Zero::zero())) + Some(Vec2::new(::one(), ::zero())) } else if i == 1 { - Some(Vec2::new(Zero::zero(), One::one())) + Some(Vec2::new(::zero(), ::one())) } else { None @@ -117,19 +116,19 @@ impl> Basis for Vec2 { impl Basis for Vec3 { #[inline(always)] fn canonical_basis(f: |Vec3| -> bool) { - if !f(Vec3::new(One::one(), Zero::zero(), Zero::zero())) { return }; - if !f(Vec3::new(Zero::zero(), One::one(), Zero::zero())) { return }; - f(Vec3::new(Zero::zero(), Zero::zero(), One::one())); + if !f(Vec3::new(::one(), ::zero(), ::zero())) { return }; + if !f(Vec3::new(::zero(), ::one(), ::zero())) { return }; + f(Vec3::new(::zero(), ::zero(), ::one())); } #[inline(always)] fn orthonormal_subspace_basis(n: &Vec3, f: |Vec3| -> bool) { let a = if n.x.clone().abs() > n.y.clone().abs() { - Norm::normalize_cpy(&Vec3::new(n.z.clone(), Zero::zero(), -n.x)) + Norm::normalize_cpy(&Vec3::new(n.z.clone(), ::zero(), -n.x)) } else { - Norm::normalize_cpy(&Vec3::new(Zero::zero(), -n.z, n.y.clone())) + Norm::normalize_cpy(&Vec3::new(::zero(), -n.z, n.y.clone())) }; if !f(Cross::cross(&a, n)) { return }; @@ -139,13 +138,13 @@ impl Basis for Vec3 { #[inline] fn canonical_basis_element(i: uint) -> Option> { if i == 0 { - Some(Vec3::new(One::one(), Zero::zero(), Zero::zero())) + Some(Vec3::new(::one(), ::zero(), ::zero())) } else if i == 1 { - Some(Vec3::new(Zero::zero(), One::one(), Zero::zero())) + Some(Vec3::new(::zero(), ::one(), ::zero())) } else if i == 2 { - Some(Vec3::new(Zero::zero(), Zero::zero(), One::one())) + Some(Vec3::new(::zero(), ::zero(), ::one())) } else { None @@ -227,7 +226,7 @@ static SAMPLES_3_F64: [Vec3, ..42] = [ impl UniformSphereSample for Vec1 { #[inline(always)] fn sample(f: |Vec1| -> ()) { - f(One::one()) + f(::one()) } } diff --git a/src/structs/spec/vec0.rs b/src/structs/spec/vec0.rs index ed575ceb..6b51fd46 100644 --- a/src/structs/spec/vec0.rs +++ b/src/structs/spec/vec0.rs @@ -1,12 +1,24 @@ use std::mem; -use std::num::{Zero, One, Bounded, Num}; use std::slice::{Items, MutItems}; use std::iter::{Iterator, FromIterator}; use traits::operations::ApproxEq; -use traits::structure::{Iterable, IterableMut, Indexable, Basis, Dim, Shape, BaseFloat}; +use traits::structure::{Iterable, IterableMut, Indexable, Basis, Dim, Shape, BaseFloat, BaseNum, + Zero, One, Bounded}; use traits::geometry::{Translation, Dot, Norm}; use structs::vec; +impl Zero for vec::Vec0 { + #[inline] + fn zero() -> vec::Vec0 { + vec::Vec0 + } + + #[inline] + fn is_zero(&self) -> bool { + true + } +} + impl Index for vec::Vec0 { #[inline] fn index(&self, _: &uint) -> &N { @@ -107,10 +119,10 @@ impl> Neg> for vec::Vec0 { } } -impl Dot for vec::Vec0 { +impl Dot for vec::Vec0 { #[inline] fn dot(_: &vec::Vec0, _: &vec::Vec0) -> N { - Zero::zero() + ::zero() } } @@ -167,22 +179,22 @@ impl + Neg> Translation> for vec::Vec0 { impl Norm for vec::Vec0 { #[inline] fn sqnorm(_: &vec::Vec0) -> N { - Zero::zero() + ::zero() } #[inline] fn norm(_: &vec::Vec0) -> N { - Zero::zero() + ::zero() } #[inline] fn normalize_cpy(_: &vec::Vec0) -> vec::Vec0 { - Zero::zero() + ::zero() } #[inline] fn normalize(&mut self) -> N { - Zero::zero() + ::zero() } } diff --git a/src/structs/vec.rs b/src/structs/vec.rs index f7d7d0e6..0cae3b8b 100644 --- a/src/structs/vec.rs +++ b/src/structs/vec.rs @@ -3,7 +3,6 @@ #![allow(missing_docs)] // we allow missing to avoid having to document the dispatch traits. use std::mem; -use std::num::{Zero, One, Bounded, Num}; use std::slice::{Items, MutItems}; use std::iter::{Iterator, FromIterator}; use traits::operations::{ApproxEq, POrd, POrdering, PartialLess, PartialEqual, @@ -12,7 +11,7 @@ use traits::operations::{ApproxEq, POrd, POrdering, PartialLess, PartialEqual, use traits::geometry::{Transform, Rotate, FromHomogeneous, ToHomogeneous, Dot, Norm, Translation, Translate}; use traits::structure::{Basis, Cast, Dim, Indexable, Iterable, IterableMut, VecAsPnt, Shape, - NumVec, FloatVec, BaseFloat}; + NumVec, FloatVec, BaseFloat, BaseNum, Zero, One, Bounded}; use structs::pnt::{Pnt1, Pnt2, Pnt3, Pnt4, Pnt5, Pnt6}; @@ -121,7 +120,7 @@ vec_sub_scalar_impl!(Vec1, int, Vec1SubRhs, x) translation_impl!(Vec1) norm_impl!(Vec1, x) approx_eq_impl!(Vec1, x) -one_impl!(Vec1, x) +zero_one_impl!(Vec1, x) from_iterator_impl!(Vec1, iterator) bounded_impl!(Vec1, x) axpy_impl!(Vec1, x) @@ -226,7 +225,7 @@ vec_sub_scalar_impl!(Vec2, int, Vec2SubRhs, x, y) translation_impl!(Vec2) norm_impl!(Vec2, x, y) approx_eq_impl!(Vec2, x, y) -one_impl!(Vec2, x, y) +zero_one_impl!(Vec2, x, y) from_iterator_impl!(Vec2, iterator, iterator) bounded_impl!(Vec2, x, y) axpy_impl!(Vec2, x, y) @@ -336,7 +335,7 @@ vec_sub_scalar_impl!(Vec3, int, Vec3SubRhs, x, y, z) translation_impl!(Vec3) norm_impl!(Vec3, x, y ,z) approx_eq_impl!(Vec3, x, y, z) -one_impl!(Vec3, x, y, z) +zero_one_impl!(Vec3, x, y, z) from_iterator_impl!(Vec3, iterator, iterator, iterator) bounded_impl!(Vec3, x, y, z) axpy_impl!(Vec3, x, y, z) @@ -446,7 +445,7 @@ vec_sub_scalar_impl!(Vec4, int, Vec4SubRhs, x, y, z, w) translation_impl!(Vec4) norm_impl!(Vec4, x, y, z, w) approx_eq_impl!(Vec4, x, y, z, w) -one_impl!(Vec4, x, y, z, w) +zero_one_impl!(Vec4, x, y, z, w) from_iterator_impl!(Vec4, iterator, iterator, iterator, iterator) bounded_impl!(Vec4, x, y, z, w) axpy_impl!(Vec4, x, y, z, w) @@ -557,7 +556,7 @@ vec_sub_scalar_impl!(Vec5, int, Vec5SubRhs, x, y, z, w, a) translation_impl!(Vec5) norm_impl!(Vec5, x, y, z, w, a) approx_eq_impl!(Vec5, x, y, z, w, a) -one_impl!(Vec5, x, y, z, w, a) +zero_one_impl!(Vec5, x, y, z, w, a) from_iterator_impl!(Vec5, iterator, iterator, iterator, iterator, iterator) bounded_impl!(Vec5, x, y, z, w, a) axpy_impl!(Vec5, x, y, z, w, a) @@ -670,7 +669,7 @@ vec_sub_scalar_impl!(Vec6, int, Vec6SubRhs, x, y, z, w, a, b) translation_impl!(Vec6) norm_impl!(Vec6, x, y, z, w, a, b) approx_eq_impl!(Vec6, x, y, z, w, a, b) -one_impl!(Vec6, x, y, z, w, a, b) +zero_one_impl!(Vec6, x, y, z, w, a, b) from_iterator_impl!(Vec6, iterator, iterator, iterator, iterator, iterator, iterator) bounded_impl!(Vec6, x, y, z, w, a, b) axpy_impl!(Vec6, x, y, z, w, a, b) diff --git a/src/structs/vec_macros.rs b/src/structs/vec_macros.rs index b8e502c2..7a4a771b 100644 --- a/src/structs/vec_macros.rs +++ b/src/structs/vec_macros.rs @@ -135,9 +135,9 @@ macro_rules! vec_axis_impl( /// Create a unit vector with its `$comp0` component equal to 1.0. #[inline] pub fn $comp0() -> $t { - let mut res: $t = Zero::zero(); + let mut res: $t = ::zero(); - res.$comp0 = One::one(); + res.$comp0 = ::one(); res } @@ -146,9 +146,9 @@ macro_rules! vec_axis_impl( /// Create a unit vector with its `$compN` component equal to 1.0. #[inline] pub fn $compN() -> $t { - let mut res: $t = Zero::zero(); + let mut res: $t = ::zero(); - res.$compN = One::one(); + res.$compN = ::one(); res } @@ -308,10 +308,10 @@ macro_rules! basis_impl( let mut basis: Vec<$t> = Vec::new(); for i in range(0u, $dim) { - let mut basis_element : $t = Zero::zero(); + let mut basis_element : $t = ::zero(); unsafe { - basis_element.set_fast(i, One::one()); + basis_element.set_fast(i, ::one()); } if basis.len() == $dim - 1 { @@ -326,7 +326,7 @@ macro_rules! basis_impl( elt = elt - *v * Dot::dot(&elt, v) }; - if !ApproxEq::approx_eq(&Norm::sqnorm(&elt), &Zero::zero()) { + if !ApproxEq::approx_eq(&Norm::sqnorm(&elt), &::zero()) { let new_element = Norm::normalize_cpy(&elt); if !f(new_element.clone()) { return }; @@ -339,10 +339,10 @@ macro_rules! basis_impl( #[inline] fn canonical_basis_element(i: uint) -> Option<$t> { if i < $dim { - let mut basis_element : $t = Zero::zero(); + let mut basis_element : $t = ::zero(); unsafe { - basis_element.set_fast(i, One::one()); + basis_element.set_fast(i, ::one()); } Some(basis_element) @@ -424,7 +424,7 @@ macro_rules! neg_impl( macro_rules! dot_impl( ($t: ident, $comp0: ident $(,$compN: ident)*) => ( - impl Dot for $t { + impl Dot for $t { #[inline] fn dot(a: &$t, b: &$t) -> N { a.$comp0 * b.$comp0 $(+ a.$compN * b.$compN )* @@ -608,17 +608,33 @@ macro_rules! approx_eq_impl( ) ) -macro_rules! one_impl( +macro_rules! zero_one_impl( ($t: ident, $comp0: ident $(,$compN: ident)*) => ( impl One for $t { #[inline] fn one() -> $t { $t { - $comp0: One::one() - $(, $compN: One::one() )* + $comp0: ::one() + $(, $compN: ::one() )* } } } + + impl Zero for $t { + #[inline] + fn zero() -> $t { + $t { + $comp0: ::zero() + $(, $compN: ::zero() )* + } + } + + #[inline] + fn is_zero(&self) -> bool { + self.$comp0.is_zero() + $(&& self.$compN.is_zero() )* + } + } ) ) @@ -659,7 +675,7 @@ macro_rules! vec_to_homogeneous_impl( ($t: ident, $t2: ident, $extra: ident, $comp0: ident $(,$compN: ident)*) => ( impl ToHomogeneous<$t2> for $t { fn to_homogeneous(v: &$t) -> $t2 { - let mut res: $t2 = Zero::zero(); + let mut res: $t2 = ::zero(); res.$comp0 = v.$comp0.clone(); $( res.$compN = v.$compN.clone(); )* @@ -674,7 +690,7 @@ macro_rules! vec_from_homogeneous_impl( ($t: ident, $t2: ident, $extra: ident, $comp0: ident $(,$compN: ident)*) => ( impl + One + Zero> FromHomogeneous<$t2> for $t { fn from(v: &$t2) -> $t { - let mut res: $t = Zero::zero(); + let mut res: $t = ::zero(); res.$comp0 = v.$comp0.clone(); $( res.$compN = v.$compN.clone(); )* @@ -765,11 +781,11 @@ macro_rules! vec_as_pnt_impl( macro_rules! num_float_vec_impl( ($t: ident $(,$trhs: ident)*) => ( impl NumVec for $t - where N: Num $(+ $trhs>)* { + where N: BaseNum + Zero $(+ $trhs>)* { } impl FloatVec for $t - where N: Num + Zero + One + ApproxEq + BaseFloat $(+ $trhs>)* { + where N: BaseNum + Zero + One + ApproxEq + BaseFloat $(+ $trhs>)* { } ) ) diff --git a/src/traits/mod.rs b/src/traits/mod.rs index 64a90352..7a54df3e 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, VecAsPnt, - ColSlice, RowSlice, Diag, Eye, Shape, BaseFloat}; + ColSlice, RowSlice, Diag, Eye, Shape, BaseFloat, BaseNum, Zero, One, + Bounded}; pub use traits::operations::{Absolute, ApproxEq, Axpy, Cov, Det, Inv, LMul, Mean, Outer, POrd, RMul, ScalarAdd, ScalarSub, ScalarMul, ScalarDiv, Transpose, EigenQR}; diff --git a/src/traits/operations.rs b/src/traits/operations.rs index 7333eff4..b47e6baa 100644 --- a/src/traits/operations.rs +++ b/src/traits/operations.rs @@ -257,27 +257,6 @@ pub trait EigenQR: SquareMat { fn eigen_qr(m: &Self, eps: &N, niter: uint) -> (Self, V); } - -// /// Cholesky decomposition. -// pub trait Chol { -// /// Performs the cholesky decomposition on `self`. The resulting upper-triangular matrix is -// /// returned. Returns `None` if the matrix is not symetric positive-definite. -// fn chol(self) -> Option; -// -// /// Performs the cholesky decomposition on `self`. The resulting upper-triangular matrix is -// /// written to a given parameter. If the decomposition fails `false` is returned; the state of -// /// the output parameter is undefined. -// fn chol_to(&self, out: &mut Self) -> bool { -// match self.chol() { -// None => false, -// Some(decomp) => { -// *out = decomp; -// true -// } -// } -// } -// } - // XXX: those two traits should not exist since there is generalized operator overloading of Add // and Sub. // However, using the same trait multiple time as a trait bound (ex: impl + Add) @@ -347,7 +326,11 @@ pub trait Axpy { } /* - * Some implementation for scalar types. + * + * + * Some implementations for scalar types. + * + * */ // FIXME: move this to another module ? macro_rules! impl_absolute( @@ -373,6 +356,7 @@ macro_rules! impl_absolute_id( impl_absolute!(f32) impl_absolute!(f64) +impl_absolute!(i8) impl_absolute!(i16) impl_absolute!(i32) impl_absolute!(i64) diff --git a/src/traits/structure.rs b/src/traits/structure.rs index e6dbbbfa..029d496f 100644 --- a/src/traits/structure.rs +++ b/src/traits/structure.rs @@ -1,13 +1,21 @@ //! Traits giving structural informations on linear algebra objects or the space they live in. -use std::num::{Zero, One, FloatMath, Num}; +use std::num::{Int, Float, FloatMath}; use std::slice::{Items, MutItems}; use traits::operations::{RMul, LMul, Axpy, Transpose, Inv, Absolute}; use traits::geometry::{Dot, Norm, Orig}; -pub trait BaseFloat: FloatMath + Zero + One + Num + Absolute { +/// Basic integral numeric trait. +pub trait BaseNum: Zero + One + Add + Sub + Mul + + Div + Rem + Neg + PartialEq + Absolute { } +/// Basic floating-point number numeric trait. +pub trait BaseFloat: FloatMath + BaseNum { +} + +impl BaseNum for f32 { } +impl BaseNum for f64 { } impl BaseFloat for f32 { } impl BaseFloat for f64 { } @@ -41,8 +49,29 @@ pub trait Eye { fn new_identity(dim: uint) -> Self; } -// XXX: we keep ScalarAdd and ScalarSub here to avoid trait impl conflict (overriding) between the -// different Add/Sub traits. This is _so_ unfortunate… +/// Additive identity. +pub trait Zero { + /// Returns the additive identity. + fn zero() -> Self; + /// Tests if `self` is exactly zero. + fn is_zero(&self) -> bool; +} + +/// Multiplicative identity. +pub trait One { + /// Returns the multiplicative identity. + fn one() -> Self; +} + +/// Types that have maximum and minimum value. +pub trait Bounded { + /// The minimum value. + #[inline] + fn min_value() -> Self; + /// The maximum value. + #[inline] + fn max_value() -> Self; +} // FIXME: return an iterator instead /// Traits of objects which can form a basis (typically vectors). @@ -223,3 +252,74 @@ pub trait FloatPnt>: NumPnt { Norm::norm(&(*a - *b)) } } + +/* + * + * + * Some implementations for builtin types. + * + * + */ +macro_rules! impl_zero_one( + ($n: ty, $zero: expr, $one: expr) => { + impl Zero for $n { + #[inline] + fn zero() -> $n { + $zero + } + + #[inline] + fn is_zero(&self) -> bool { + *self == $zero + } + } + + impl One for $n { + fn one() -> $n { + $one + } + } + } +) + +impl_zero_one!(f32, 0.0, 1.0) +impl_zero_one!(f64, 0.0, 1.0) +impl_zero_one!(i8, 0, 1) +impl_zero_one!(i16, 0, 1) +impl_zero_one!(i32, 0, 1) +impl_zero_one!(i64, 0, 1) +impl_zero_one!(int, 0, 1) +impl_zero_one!(u8, 0, 1) +impl_zero_one!(u16, 0, 1) +impl_zero_one!(u32, 0, 1) +impl_zero_one!(u64, 0, 1) +impl_zero_one!(uint, 0, 1) + +macro_rules! impl_bounded( + ($n: ty, $min: expr, $max: expr) => { + impl Bounded for $n { + #[inline] + fn min_value() -> $n { + $min + } + + #[inline] + fn max_value() -> $n { + $max + } + } + } +) + +impl_bounded!(f32, Float::min_value(), Float::max_value()) +impl_bounded!(f64, Float::min_value(), Float::max_value()) +impl_bounded!(i8, Int::min_value(), Int::max_value()) +impl_bounded!(i16, Int::min_value(), Int::max_value()) +impl_bounded!(i32, Int::min_value(), Int::max_value()) +impl_bounded!(i64, Int::min_value(), Int::max_value()) +impl_bounded!(int, Int::min_value(), Int::max_value()) +impl_bounded!(u8, Int::min_value(), Int::max_value()) +impl_bounded!(u16, Int::min_value(), Int::max_value()) +impl_bounded!(u32, Int::min_value(), Int::max_value()) +impl_bounded!(u64, Int::min_value(), Int::max_value()) +impl_bounded!(uint, Int::min_value(), Int::max_value())