Make most out-of-place methods static.

This is to make people prefer the functional style.
Things like `a.dot(b)` dont make sense per se (there is no reason for `a` to have a different
status than `b`). Using static methods avoid this.

In-place methods are left unchanged.
This commit is contained in:
Sébastien Crozet 2013-10-16 21:44:33 +02:00
parent dcd1e7719b
commit 90e40aaec0
14 changed files with 130 additions and 126 deletions

View File

@ -113,7 +113,7 @@ Feel free to add your project to this list if you happen to use **nalgebra**!
#[deny(non_camel_case_types)]; #[deny(non_camel_case_types)];
#[deny(non_uppercase_statics)]; #[deny(non_uppercase_statics)];
#[deny(unnecessary_qualification)]; #[deny(unnecessary_qualification)];
#[deny(missing_doc)]; #[warn(missing_doc)];
#[feature(macro_rules)]; #[feature(macro_rules)];
extern mod std; extern mod std;

View File

@ -300,11 +300,11 @@ pub fn append_rotation_wrt_point<LV: Neg<LV>,
/// Rotates a copy of `m` by `amount` using `m.translation()` as the pivot point. /// Rotates a copy of `m` by `amount` using `m.translation()` as the pivot point.
#[inline(always)] #[inline(always)]
pub fn rotate_wrt_center<LV: Neg<LV>, pub fn append_rotation_wrt_center<LV: Neg<LV>,
AV, AV,
M: RotationWithTranslation<LV, AV>>( M: RotationWithTranslation<LV, AV>>(
m: &M, m: &M,
amount: &AV) -> M { amount: &AV) -> M {
RotationWithTranslation::append_rotation_wrt_center_cpy(m, amount) RotationWithTranslation::append_rotation_wrt_center_cpy(m, amount)
} }
@ -373,13 +373,13 @@ pub fn inv_transform<V, M: Transform<V>>(m: &M, v: &V) -> V {
/// Computes the dot product of two vectors. /// Computes the dot product of two vectors.
#[inline(always)] #[inline(always)]
pub fn dot<V: Dot<N>, N>(a: &V, b: &V) -> N { pub fn dot<V: Dot<N>, N>(a: &V, b: &V) -> N {
a.dot(b) Dot::dot(a, b)
} }
/// Computes a subtraction followed by a dot product. /// Computes a subtraction followed by a dot product.
#[inline(always)] #[inline(always)]
pub fn sub_dot<V: Dot<N>, N>(a: &V, b: &V, c: &V) -> N { pub fn sub_dot<V: Dot<N>, N>(a: &V, b: &V, c: &V) -> N {
a.sub_dot(b, c) Dot::sub_dot(a, b, c)
} }
/* /*
@ -389,13 +389,13 @@ pub fn sub_dot<V: Dot<N>, N>(a: &V, b: &V, c: &V) -> N {
/// Computes the L2 norm of a vector. /// Computes the L2 norm of a vector.
#[inline(always)] #[inline(always)]
pub fn norm<V: Norm<N>, N: Algebraic>(v: &V) -> N { pub fn norm<V: Norm<N>, N: Algebraic>(v: &V) -> N {
v.norm() Norm::norm(v)
} }
/// Computes the squared L2 norm of a vector. /// Computes the squared L2 norm of a vector.
#[inline(always)] #[inline(always)]
pub fn sqnorm<V: Norm<N>, N: Algebraic>(v: &V) -> N { pub fn sqnorm<V: Norm<N>, N: Algebraic>(v: &V) -> N {
v.sqnorm() Norm::sqnorm(v)
} }
/// Gets the normalized version of a vector. /// Gets the normalized version of a vector.
@ -411,7 +411,7 @@ pub fn normalize<V: Norm<N>, N: Algebraic>(v: &V) -> V {
/// Computes the cross product of two vectors. /// Computes the cross product of two vectors.
#[inline(always)] #[inline(always)]
pub fn cross<LV: Cross<AV>, AV>(a: &LV, b: &LV) -> AV { pub fn cross<LV: Cross<AV>, AV>(a: &LV, b: &LV) -> AV {
a.cross(b) Cross::cross(a, b)
} }
/* /*
@ -422,7 +422,7 @@ pub fn cross<LV: Cross<AV>, AV>(a: &LV, b: &LV) -> AV {
/// product. /// product.
#[inline(always)] #[inline(always)]
pub fn cross_matrix<V: CrossMatrix<M>, M>(v: &V) -> M { pub fn cross_matrix<V: CrossMatrix<M>, M>(v: &V) -> M {
v.cross_matrix() CrossMatrix::cross_matrix(v)
} }
/* /*
@ -432,7 +432,7 @@ pub fn cross_matrix<V: CrossMatrix<M>, M>(v: &V) -> M {
/// Converts a matrix or vector to homogoneous coordinates. /// Converts a matrix or vector to homogoneous coordinates.
#[inline(always)] #[inline(always)]
pub fn to_homogeneous<M: ToHomogeneous<Res>, Res>(m: &M) -> Res { pub fn to_homogeneous<M: ToHomogeneous<Res>, Res>(m: &M) -> Res {
m.to_homogeneous() ToHomogeneous::to_homogeneous(m)
} }
/* /*
@ -472,8 +472,8 @@ pub fn sample_sphere<V: UniformSphereSample>(f: &fn(V)) {
/// Computes a component-wise absolute value. /// Computes a component-wise absolute value.
#[inline(always)] #[inline(always)]
pub fn absolute<M: Absolute<Res>, Res>(m: &M) -> Res { pub fn abs<M: Absolute<Res>, Res>(m: &M) -> Res {
m.absolute() Absolute::abs(m)
} }
/* /*
@ -503,7 +503,7 @@ pub fn transpose<M: Transpose>(m: &M) -> M {
/// Computes the outer product of two vectors. /// Computes the outer product of two vectors.
#[inline(always)] #[inline(always)]
pub fn outer<V: Outer<M>, M>(a: &V, b: &V) -> M { pub fn outer<V: Outer<M>, M>(a: &V, b: &V) -> M {
a.outer(b) Outer::outer(a, b)
} }
/* /*
@ -513,7 +513,7 @@ pub fn outer<V: Outer<M>, M>(a: &V, b: &V) -> M {
/// Computes the covariance of a set of observations. /// Computes the covariance of a set of observations.
#[inline(always)] #[inline(always)]
pub fn cov<M: Cov<Res>, Res>(observations: &M) -> Res { pub fn cov<M: Cov<Res>, Res>(observations: &M) -> Res {
observations.cov() Cov::cov(observations)
} }
/* /*
@ -523,7 +523,7 @@ pub fn cov<M: Cov<Res>, Res>(observations: &M) -> Res {
/// Computes the mean of a set of observations. /// Computes the mean of a set of observations.
#[inline(always)] #[inline(always)]
pub fn mean<N, M: Mean<N>>(observations: &M) -> N { pub fn mean<N, M: Mean<N>>(observations: &M) -> N {
observations.mean() Mean::mean(observations)
} }
// //
@ -545,7 +545,7 @@ pub fn canonical_basis<V: Basis>(f: &fn(V) -> bool) {
/// Computes the basis of the orthonormal subspace of a given vector. /// Computes the basis of the orthonormal subspace of a given vector.
#[inline(always)] #[inline(always)]
pub fn orthonormal_subspace_basis<V: Basis>(v: &V, f: &fn(V) -> bool) { pub fn orthonormal_subspace_basis<V: Basis>(v: &V, f: &fn(V) -> bool) {
v.orthonormal_subspace_basis(f) Basis::orthonormal_subspace_basis(v, f)
} }
/* /*

View File

@ -65,6 +65,7 @@ impl<N: Zero + Clone> DMat<N> {
self.mij.iter().all(|e| e.is_zero()) self.mij.iter().all(|e| e.is_zero())
} }
#[inline]
pub fn reset(&mut self) { pub fn reset(&mut self) {
for mij in self.mij.mut_iter() { for mij in self.mij.mut_iter() {
*mij = Zero::zero(); *mij = Zero::zero();
@ -416,14 +417,14 @@ impl<N: Clone> Transpose for DMat<N> {
} }
impl<N: Num + Cast<f32> + Clone> Mean<DVec<N>> for DMat<N> { impl<N: Num + Cast<f32> + Clone> Mean<DVec<N>> for DMat<N> {
fn mean(&self) -> DVec<N> { fn mean(m: &DMat<N>) -> DVec<N> {
let mut res: DVec<N> = DVec::new_zeros(self.ncols); let mut res: DVec<N> = DVec::new_zeros(m.ncols);
let normalizer: N = Cast::from(1.0f32 / Cast::from(self.nrows)); let normalizer: N = Cast::from(1.0f32 / Cast::from(m.nrows));
for i in range(0u, self.nrows) { for i in range(0u, m.nrows) {
for j in range(0u, self.ncols) { for j in range(0u, m.ncols) {
unsafe { unsafe {
let acc = res.at_fast(j) + self.at_fast(i, j) * normalizer; let acc = res.at_fast(j) + m.at_fast(i, j) * normalizer;
res.set_fast(j, acc); res.set_fast(j, acc);
} }
} }
@ -435,23 +436,23 @@ impl<N: Num + Cast<f32> + Clone> Mean<DVec<N>> for DMat<N> {
impl<N: Clone + Num + Cast<f32> + DMatDivRhs<N, DMat<N>> + ToStr > Cov<DMat<N>> for DMat<N> { impl<N: Clone + Num + Cast<f32> + DMatDivRhs<N, DMat<N>> + ToStr > Cov<DMat<N>> for DMat<N> {
// FIXME: this could be heavily optimized, removing all temporaries by merging loops. // FIXME: this could be heavily optimized, removing all temporaries by merging loops.
fn cov(&self) -> DMat<N> { fn cov(m: &DMat<N>) -> DMat<N> {
assert!(self.nrows > 1); assert!(m.nrows > 1);
let mut centered = unsafe { DMat::new_uninitialized(self.nrows, self.ncols) }; let mut centered = unsafe { DMat::new_uninitialized(m.nrows, m.ncols) };
let mean = self.mean(); let mean = Mean::mean(m);
// FIXME: use the rows iterator when available // FIXME: use the rows iterator when available
for i in range(0u, self.nrows) { for i in range(0u, m.nrows) {
for j in range(0u, self.ncols) { for j in range(0u, m.ncols) {
unsafe { unsafe {
centered.set_fast(i, j, self.at_fast(i, j) - mean.at_fast(j)); centered.set_fast(i, j, m.at_fast(i, j) - mean.at_fast(j));
} }
} }
} }
// FIXME: return a triangular matrix? // FIXME: return a triangular matrix?
let fnormalizer: f32 = Cast::from(self.nrows() - 1); let fnormalizer: f32 = Cast::from(m.nrows() - 1);
let normalizer: N = Cast::from(fnormalizer); let normalizer: N = Cast::from(fnormalizer);
// FIXME: this will do 2 allocations for temporaries! // FIXME: this will do 2 allocations for temporaries!
(Transpose::transpose_cpy(&centered) * centered) / normalizer (Transpose::transpose_cpy(&centered) * centered) / normalizer

View File

@ -92,6 +92,7 @@ impl<N> DVec<N> {
*self.at.unsafe_mut_ref(i) = val *self.at.unsafe_mut_ref(i) = val
} }
/// Gets a reference to of this vector datas.
#[inline] #[inline]
pub fn as_vec<'r>(&'r self) -> &'r [N] { pub fn as_vec<'r>(&'r self) -> &'r [N] {
let data: &'r [N] = self.at; let data: &'r [N] = self.at;
@ -99,6 +100,7 @@ impl<N> DVec<N> {
data data
} }
/// Gets a mutable reference to of this vector datas.
#[inline] #[inline]
pub fn as_mut_vec<'r>(&'r mut self) -> &'r mut [N] { pub fn as_mut_vec<'r>(&'r mut self) -> &'r mut [N] {
let data: &'r mut [N] = self.at; let data: &'r mut [N] = self.at;
@ -106,6 +108,7 @@ impl<N> DVec<N> {
data data
} }
/// Extracts this vector datas.
#[inline] #[inline]
pub fn to_vec(self) -> ~[N] { pub fn to_vec(self) -> ~[N] {
self.at self.at
@ -211,13 +214,13 @@ impl<N: Clone + Num + Algebraic + ApproxEq<N> + DVecMulRhs<N, DVec<N>>> DVec<N>
let mut elt = basis_element.clone(); let mut elt = basis_element.clone();
elt = elt - self * basis_element.dot(self); elt = elt - self * Dot::dot(&basis_element, self);
for v in res.iter() { for v in res.iter() {
elt = elt - v * elt.dot(v) elt = elt - v * Dot::dot(&elt, v)
}; };
if !elt.sqnorm().approx_eq(&Zero::zero()) { if !Norm::sqnorm(&elt).approx_eq(&Zero::zero()) {
res.push(Norm::normalize_cpy(&elt)); res.push(Norm::normalize_cpy(&elt));
} }
} }
@ -257,24 +260,24 @@ impl<N: Neg<N>> Neg<DVec<N>> for DVec<N> {
impl<N: Num + Clone> Dot<N> for DVec<N> { impl<N: Num + Clone> Dot<N> for DVec<N> {
#[inline] #[inline]
fn dot(&self, other: &DVec<N>) -> N { fn dot(a: &DVec<N>, b: &DVec<N>) -> N {
assert!(self.at.len() == other.at.len()); assert!(a.at.len() == b.at.len());
let mut res: N = Zero::zero(); let mut res: N = Zero::zero();
for i in range(0u, self.at.len()) { for i in range(0u, a.at.len()) {
res = res + unsafe { self.at_fast(i) * other.at_fast(i) }; res = res + unsafe { a.at_fast(i) * b.at_fast(i) };
} }
res res
} }
#[inline] #[inline]
fn sub_dot(&self, a: &DVec<N>, b: &DVec<N>) -> N { fn sub_dot(a: &DVec<N>, b: &DVec<N>, c: &DVec<N>) -> N {
let mut res: N = Zero::zero(); let mut res: N = Zero::zero();
for i in range(0u, self.at.len()) { for i in range(0u, a.at.len()) {
res = res + unsafe { (self.at_fast(i) - a.at_fast(i)) * b.at_fast(i) }; res = res + unsafe { (a.at_fast(i) - b.at_fast(i)) * c.at_fast(i) };
} }
res res
@ -283,13 +286,13 @@ impl<N: Num + Clone> Dot<N> for DVec<N> {
impl<N: Num + Algebraic + Clone> Norm<N> for DVec<N> { impl<N: Num + Algebraic + Clone> Norm<N> for DVec<N> {
#[inline] #[inline]
fn sqnorm(&self) -> N { fn sqnorm(v: &DVec<N>) -> N {
self.dot(self) Dot::dot(v, v)
} }
#[inline] #[inline]
fn norm(&self) -> N { fn norm(v: &DVec<N>) -> N {
self.sqnorm().sqrt() Norm::sqnorm(v).sqrt()
} }
#[inline] #[inline]
@ -303,7 +306,7 @@ impl<N: Num + Algebraic + Clone> Norm<N> for DVec<N> {
#[inline] #[inline]
fn normalize(&mut self) -> N { fn normalize(&mut self) -> N {
let l = self.norm(); let l = Norm::norm(self);
for i in range(0u, self.at.len()) { for i in range(0u, self.at.len()) {
self.at[i] = self.at[i] / l; self.at[i] = self.at[i] / l;

View File

@ -297,13 +297,13 @@ macro_rules! inv_impl(
macro_rules! to_homogeneous_impl( macro_rules! to_homogeneous_impl(
($t: ident, $th: ident) => ( ($t: ident, $th: ident) => (
impl<N: One + Zero + Clone> ToHomogeneous<$th<N>> for $t<N> { impl<N: One + Zero + Clone> ToHomogeneous<$th<N>> for $t<N> {
fn to_homogeneous(&self) -> $th<N> { fn to_homogeneous(m: &$t<N>) -> $th<N> {
let mut res = self.rotation.to_homogeneous(); let mut res = ToHomogeneous::to_homogeneous(&m.rotation);
// copy the translation // copy the translation
let dim = Dim::dim(None::<$th<N>>); let dim = Dim::dim(None::<$th<N>>);
res.set_col(dim - 1, self.translation.to_homogeneous()); res.set_col(dim - 1, ToHomogeneous::to_homogeneous(&m.translation));
res res
} }

View File

@ -113,8 +113,8 @@ macro_rules! absolute_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Signed> Absolute<$t<N>> for $t<N> { impl<N: Signed> Absolute<$t<N>> for $t<N> {
#[inline] #[inline]
fn absolute(&self) -> $t<N> { fn abs(m: &$t<N>) -> $t<N> {
$t::new(self.$comp0.abs() $(, self.$compN.abs() )*) $t::new(m.$comp0.abs() $(, m.$compN.abs() )*)
} }
} }
) )
@ -469,12 +469,12 @@ macro_rules! to_homogeneous_impl(
($t: ident, $t2: ident, $dim: expr, $dim2: expr) => ( ($t: ident, $t2: ident, $dim: expr, $dim2: expr) => (
impl<N: One + Zero + Clone> ToHomogeneous<$t2<N>> for $t<N> { impl<N: One + Zero + Clone> ToHomogeneous<$t2<N>> for $t<N> {
#[inline] #[inline]
fn to_homogeneous(&self) -> $t2<N> { fn to_homogeneous(m: &$t<N>) -> $t2<N> {
let mut res: $t2<N> = One::one(); let mut res: $t2<N> = One::one();
for i in range(0u, $dim) { for i in range(0u, $dim) {
for j in range(0u, $dim) { for j in range(0u, $dim) {
res.set((i, j), self.at((i, j))) res.set((i, j), m.at((i, j)))
} }
} }
@ -510,12 +510,12 @@ macro_rules! outer_impl(
($t: ident, $m: ident) => ( ($t: ident, $m: ident) => (
impl<N: Mul<N, N> + Zero + Clone> Outer<$m<N>> for $t<N> { impl<N: Mul<N, N> + Zero + Clone> Outer<$m<N>> for $t<N> {
#[inline] #[inline]
fn outer(&self, other: &$t<N>) -> $m<N> { fn outer(a: &$t<N>, b: &$t<N>) -> $m<N> {
let mut res: $m<N> = Zero::zero(); let mut res: $m<N> = Zero::zero();
for i in range(0u, Dim::dim(None::<$t<N>>)) { for i in range(0u, Dim::dim(None::<$t<N>>)) {
for j in range(0u, Dim::dim(None::<$t<N>>)) { for j in range(0u, Dim::dim(None::<$t<N>>)) {
res.set((i, j), self.at(i) * other.at(j)) res.set((i, j), a.at(i) * b.at(j))
} }
} }

View File

@ -106,7 +106,7 @@ impl<N: Clone + Trigonometric + Num + Algebraic> Rot3<N> {
/// * `axisangle` - A vector representing the rotation. Its magnitude is the amount of rotation /// * `axisangle` - A vector representing the rotation. Its magnitude is the amount of rotation
/// in radian. Its direction is the axis of rotation. /// in radian. Its direction is the axis of rotation.
pub fn new(axisangle: Vec3<N>) -> Rot3<N> { pub fn new(axisangle: Vec3<N>) -> Rot3<N> {
if axisangle.sqnorm().is_zero() { if Norm::sqnorm(&axisangle).is_zero() {
One::one() One::one()
} }
else { else {
@ -152,8 +152,8 @@ impl<N: Clone + Num + Algebraic> Rot3<N> {
/// with `at`. Non-colinearity is not checked. /// with `at`. Non-colinearity is not checked.
pub fn look_at(&mut self, at: &Vec3<N>, up: &Vec3<N>) { pub fn look_at(&mut self, at: &Vec3<N>, up: &Vec3<N>) {
let xaxis = Norm::normalize_cpy(at); let xaxis = Norm::normalize_cpy(at);
let zaxis = Norm::normalize_cpy(&up.cross(&xaxis)); let zaxis = Norm::normalize_cpy(&Cross::cross(up, &xaxis));
let yaxis = zaxis.cross(&xaxis); let yaxis = Cross::cross(&zaxis, &xaxis);
self.submat = Mat3::new( self.submat = Mat3::new(
xaxis.x.clone(), yaxis.x.clone(), zaxis.x.clone(), xaxis.x.clone(), yaxis.x.clone(), zaxis.x.clone(),
@ -170,8 +170,8 @@ impl<N: Clone + Num + Algebraic> Rot3<N> {
/// with `at`. Non-colinearity is not checked. /// with `at`. Non-colinearity is not checked.
pub fn look_at_z(&mut self, at: &Vec3<N>, up: &Vec3<N>) { pub fn look_at_z(&mut self, at: &Vec3<N>, up: &Vec3<N>) {
let zaxis = Norm::normalize_cpy(at); let zaxis = Norm::normalize_cpy(at);
let xaxis = Norm::normalize_cpy(&up.cross(&zaxis)); let xaxis = Norm::normalize_cpy(&Cross::cross(up, &zaxis));
let yaxis = zaxis.cross(&xaxis); let yaxis = Cross::cross(&zaxis, &xaxis);
self.submat = Mat3::new( self.submat = Mat3::new(
xaxis.x.clone(), yaxis.x.clone(), zaxis.x.clone(), xaxis.x.clone(), yaxis.x.clone(), zaxis.x.clone(),

View File

@ -190,8 +190,8 @@ macro_rules! to_homogeneous_impl(
($t: ident, $tm: ident) => ( ($t: ident, $tm: ident) => (
impl<N: One + Zero + Clone> ToHomogeneous<$tm<N>> for $t<N> { impl<N: One + Zero + Clone> ToHomogeneous<$tm<N>> for $t<N> {
#[inline] #[inline]
fn to_homogeneous(&self) -> $tm<N> { fn to_homogeneous(m: &$t<N>) -> $tm<N> {
self.submat.to_homogeneous() ToHomogeneous::to_homogeneous(&m.submat)
} }
} }
) )
@ -223,8 +223,8 @@ macro_rules! absolute_impl(
($t: ident, $tm: ident) => ( ($t: ident, $tm: ident) => (
impl<N: Signed> Absolute<$tm<N>> for $t<N> { impl<N: Signed> Absolute<$tm<N>> for $t<N> {
#[inline] #[inline]
fn absolute(&self) -> $tm<N> { fn abs(m: &$t<N>) -> $tm<N> {
self.submat.absolute() Absolute::abs(&m.submat)
} }
} }
) )

View File

@ -6,37 +6,37 @@ use structs::mat::Mat3;
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec1<N>> for Vec2<N> { impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec1<N>> for Vec2<N> {
#[inline] #[inline]
fn cross(&self, other : &Vec2<N>) -> Vec1<N> { fn cross(a: &Vec2<N>, b: &Vec2<N>) -> Vec1<N> {
Vec1::new(self.x * other.y - self.y * other.x) Vec1::new(a.x * b.y - a.y * b.x)
} }
} }
// FIXME: instead of returning a Vec2, define a Mat2x1 matrix? // FIXME: instead of returning a Vec2, define a Mat2x1 matrix?
impl<N: Neg<N> + Clone> CrossMatrix<Vec2<N>> for Vec2<N> { impl<N: Neg<N> + Clone> CrossMatrix<Vec2<N>> for Vec2<N> {
#[inline] #[inline]
fn cross_matrix(&self) -> Vec2<N> { fn cross_matrix(v: &Vec2<N>) -> Vec2<N> {
Vec2::new(-self.y, self.x.clone()) Vec2::new(-v.y, v.x.clone())
} }
} }
impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec3<N>> for Vec3<N> { impl<N: Mul<N, N> + Sub<N, N>> Cross<Vec3<N>> for Vec3<N> {
#[inline] #[inline]
fn cross(&self, other : &Vec3<N>) -> Vec3<N> { fn cross(a: &Vec3<N>, b: &Vec3<N>) -> Vec3<N> {
Vec3::new( Vec3::new(
self.y * other.z - self.z * other.y, a.y * b.z - a.z * b.y,
self.z * other.x - self.x * other.z, a.z * b.x - a.x * b.z,
self.x * other.y - self.y * other.x a.x * b.y - a.y * b.x
) )
} }
} }
impl<N: Neg<N> + Zero + Clone> CrossMatrix<Mat3<N>> for Vec3<N> { impl<N: Neg<N> + Zero + Clone> CrossMatrix<Mat3<N>> for Vec3<N> {
#[inline] #[inline]
fn cross_matrix(&self) -> Mat3<N> { fn cross_matrix(v: &Vec3<N>) -> Mat3<N> {
Mat3::new( Mat3::new(
Zero::zero() , -self.z, self.y.clone(), Zero::zero(), -v.z , v.y.clone(),
self.z.clone(), Zero::zero(), -self.x, v.z.clone() , Zero::zero(), -v.x,
-self.y , self.x.clone(), Zero::zero() -v.y , v.x.clone() , Zero::zero()
) )
} }
} }
@ -75,7 +75,7 @@ impl<N: One> Basis for Vec1<N> {
} }
#[inline(always)] #[inline(always)]
fn orthonormal_subspace_basis(&self, _: &fn(Vec1<N>) -> bool ) { } fn orthonormal_subspace_basis(_: &Vec1<N>, _: &fn(Vec1<N>) -> bool ) { }
} }
impl<N: Clone + One + Zero + Neg<N>> Basis for Vec2<N> { impl<N: Clone + One + Zero + Neg<N>> Basis for Vec2<N> {
@ -86,8 +86,8 @@ impl<N: Clone + One + Zero + Neg<N>> Basis for Vec2<N> {
} }
#[inline] #[inline]
fn orthonormal_subspace_basis(&self, f: &fn(Vec2<N>) -> bool) { fn orthonormal_subspace_basis(n: &Vec2<N>, f: &fn(Vec2<N>) -> bool) {
f(Vec2::new(-self.y, self.x.clone())); f(Vec2::new(-n.y, n.x.clone()));
} }
} }
@ -100,16 +100,16 @@ impl<N: Clone + Ord + Algebraic + Signed> Basis for Vec3<N> {
} }
#[inline(always)] #[inline(always)]
fn orthonormal_subspace_basis(&self, f: &fn(Vec3<N>) -> bool) { fn orthonormal_subspace_basis(n: &Vec3<N>, f: &fn(Vec3<N>) -> bool) {
let a = let a =
if self.x.clone().abs() > self.y.clone().abs() { if n.x.clone().abs() > n.y.clone().abs() {
Norm::normalize_cpy(&Vec3::new(self.z.clone(), Zero::zero(), -self.x)) Norm::normalize_cpy(&Vec3::new(n.z.clone(), Zero::zero(), -n.x))
} }
else { else {
Norm::normalize_cpy(&Vec3::new(Zero::zero(), -self.z, self.y.clone())) Norm::normalize_cpy(&Vec3::new(Zero::zero(), -n.z, n.y.clone()))
}; };
if !f(a.cross(self)) { return }; if !f(Cross::cross(&a, n)) { return };
f(a); f(a);
} }
} }

View File

@ -66,7 +66,7 @@ impl<N> Basis for vec::Vec0<N> {
fn canonical_basis(_: &fn(vec::Vec0<N>) -> bool) { } fn canonical_basis(_: &fn(vec::Vec0<N>) -> bool) { }
#[inline(always)] #[inline(always)]
fn orthonormal_subspace_basis(&self, _: &fn(vec::Vec0<N>) -> bool) { } fn orthonormal_subspace_basis(_: &vec::Vec0<N>, _: &fn(vec::Vec0<N>) -> bool) { }
} }
impl<N, T> Add<T, vec::Vec0<N>> for vec::Vec0<N> { impl<N, T> Add<T, vec::Vec0<N>> for vec::Vec0<N> {
@ -92,12 +92,12 @@ impl<N: Neg<N>> Neg<vec::Vec0<N>> for vec::Vec0<N> {
impl<N: Num + Clone> Dot<N> for vec::Vec0<N> { impl<N: Num + Clone> Dot<N> for vec::Vec0<N> {
#[inline] #[inline]
fn dot(&self, _: &vec::Vec0<N>) -> N { fn dot(_: &vec::Vec0<N>, _: &vec::Vec0<N>) -> N {
Zero::zero() Zero::zero()
} }
#[inline] #[inline]
fn sub_dot(&self, _: &vec::Vec0<N>, _: &vec::Vec0<N>) -> N { fn sub_dot(_: &vec::Vec0<N>, _: &vec::Vec0<N>, _: &vec::Vec0<N>) -> N {
Zero::zero() Zero::zero()
} }
} }
@ -154,18 +154,18 @@ impl<N: Clone + Add<N, N> + Neg<N>> Translation<vec::Vec0<N>> for vec::Vec0<N> {
impl<N: Clone + Num + Algebraic> Norm<N> for vec::Vec0<N> { impl<N: Clone + Num + Algebraic> Norm<N> for vec::Vec0<N> {
#[inline] #[inline]
fn sqnorm(&self) -> N { fn sqnorm(_: &vec::Vec0<N>) -> N {
self.dot(self) Zero::zero()
} }
#[inline] #[inline]
fn norm(&self) -> N { fn norm(_: &vec::Vec0<N>) -> N {
self.sqnorm().sqrt() Zero::zero()
} }
#[inline] #[inline]
fn normalize_cpy(v: &vec::Vec0<N>) -> vec::Vec0<N> { fn normalize_cpy(_: &vec::Vec0<N>) -> vec::Vec0<N> {
v.clone() Zero::zero()
} }
#[inline] #[inline]

View File

@ -228,7 +228,7 @@ macro_rules! basis_impl(
} }
#[inline] #[inline]
fn orthonormal_subspace_basis(&self, f: &fn($t<N>) -> bool) { fn orthonormal_subspace_basis(n: &$t<N>, f: &fn($t<N>) -> bool) {
// compute the basis of the orthogonal subspace using Gram-Schmidt // compute the basis of the orthogonal subspace using Gram-Schmidt
// orthogonalization algorithm // orthogonalization algorithm
let mut basis: ~[$t<N>] = ~[]; let mut basis: ~[$t<N>] = ~[];
@ -246,13 +246,13 @@ macro_rules! basis_impl(
let mut elt = basis_element.clone(); let mut elt = basis_element.clone();
elt = elt - *self * basis_element.dot(self); elt = elt - *n * Dot::dot(&basis_element, n);
for v in basis.iter() { for v in basis.iter() {
elt = elt - v * elt.dot(v) elt = elt - v * Dot::dot(&elt, v)
}; };
if !elt.sqnorm().approx_eq(&Zero::zero()) { if !Norm::sqnorm(&elt).approx_eq(&Zero::zero()) {
let new_element = Norm::normalize_cpy(&elt); let new_element = Norm::normalize_cpy(&elt);
if !f(new_element.clone()) { return }; if !f(new_element.clone()) { return };
@ -324,13 +324,13 @@ macro_rules! dot_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Num + Clone> Dot<N> for $t<N> { impl<N: Num + Clone> Dot<N> for $t<N> {
#[inline] #[inline]
fn dot(&self, other: &$t<N>) -> N { fn dot(a: &$t<N>, b: &$t<N>) -> N {
self.$comp0 * other.$comp0 $(+ self.$compN * other.$compN )* a.$comp0 * b.$comp0 $(+ a.$compN * b.$compN )*
} }
#[inline] #[inline]
fn sub_dot(&self, a: &$t<N>, b: &$t<N>) -> N { fn sub_dot(a: &$t<N>, b: &$t<N>, c: &$t<N>) -> N {
(self.$comp0 - a.$comp0) * b.$comp0 $(+ (self.$compN - a.$compN) * b.$compN )* (a.$comp0 - b.$comp0) * c.$comp0 $(+ (a.$compN - b.$compN) * c.$compN )*
} }
} }
) )
@ -425,13 +425,13 @@ macro_rules! norm_impl(
($t: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Clone + Num + Algebraic> Norm<N> for $t<N> { impl<N: Clone + Num + Algebraic> Norm<N> for $t<N> {
#[inline] #[inline]
fn sqnorm(&self) -> N { fn sqnorm(v: &$t<N>) -> N {
self.dot(self) Dot::dot(v, v)
} }
#[inline] #[inline]
fn norm(&self) -> N { fn norm(v: &$t<N>) -> N {
self.sqnorm().sqrt() Norm::sqnorm(v).sqrt()
} }
#[inline] #[inline]
@ -445,7 +445,7 @@ macro_rules! norm_impl(
#[inline] #[inline]
fn normalize(&mut self) -> N { fn normalize(&mut self) -> N {
let l = self.norm(); let l = Norm::norm(self);
self.$comp0 = self.$comp0 / l; self.$comp0 = self.$comp0 / l;
$(self.$compN = self.$compN / l;)* $(self.$compN = self.$compN / l;)*
@ -545,11 +545,11 @@ macro_rules! bounded_impl(
macro_rules! to_homogeneous_impl( macro_rules! to_homogeneous_impl(
($t: ident, $t2: ident, $extra: ident, $comp0: ident $(,$compN: ident)*) => ( ($t: ident, $t2: ident, $extra: ident, $comp0: ident $(,$compN: ident)*) => (
impl<N: Clone + One + Zero> ToHomogeneous<$t2<N>> for $t<N> { impl<N: Clone + One + Zero> ToHomogeneous<$t2<N>> for $t<N> {
fn to_homogeneous(&self) -> $t2<N> { fn to_homogeneous(v: &$t<N>) -> $t2<N> {
let mut res: $t2<N> = One::one(); let mut res: $t2<N> = One::one();
res.$comp0 = self.$comp0.clone(); res.$comp0 = v.$comp0.clone();
$( res.$compN = self.$compN.clone(); )* $( res.$compN = v.$compN.clone(); )*
res res
} }

View File

@ -201,7 +201,7 @@ pub trait Transform<V> {
pub trait Dot<N> { pub trait Dot<N> {
/// Computes the dot (inner) product of two vectors. /// Computes the dot (inner) product of two vectors.
#[inline] #[inline]
fn dot(&self, &Self) -> N; fn dot(&Self, &Self) -> N;
/** /**
* Short-cut to compute the projection of a point on a vector, but without * Short-cut to compute the projection of a point on a vector, but without
@ -214,22 +214,22 @@ pub trait Dot<N> {
* *
*/ */
#[inline] #[inline]
fn sub_dot(&self, b: &Self, c: &Self) -> N; fn sub_dot(a: &Self, b: &Self, c: &Self) -> N;
} }
/// Traits of objects having an euclidian norm. /// Traits of objects having an euclidian norm.
pub trait Norm<N: Algebraic> { pub trait Norm<N: Algebraic> {
/// Computes the norm of `self`. /// Computes the norm of `self`.
#[inline] #[inline]
fn norm(&self) -> N { fn norm(v: &Self) -> N {
self.sqnorm().sqrt() Norm::sqnorm(v).sqrt()
} }
/// Computes the squared norm of `self`. /// Computes the squared norm of `self`.
/// ///
/// This is usually faster than computing the norm itself. /// This is usually faster than computing the norm itself.
#[inline] #[inline]
fn sqnorm(&self) -> N; fn sqnorm(&Self) -> N;
/// Gets the normalized version of a copy of `v`. /// Gets the normalized version of a copy of `v`.
#[inline] #[inline]
@ -245,7 +245,7 @@ pub trait Norm<N: Algebraic> {
*/ */
pub trait Cross<V> { pub trait Cross<V> {
/// Computes the cross product between two elements (usually vectors). /// Computes the cross product between two elements (usually vectors).
fn cross(&self, other: &Self) -> V; fn cross(&Self, other: &Self) -> V;
} }
/** /**
@ -254,13 +254,13 @@ pub trait Cross<V> {
pub trait CrossMatrix<M> { pub trait CrossMatrix<M> {
/// The matrix associated to any cross product with this vector. I.e. `v.cross(anything)` = /// The matrix associated to any cross product with this vector. I.e. `v.cross(anything)` =
/// `v.cross_matrix().rmul(anything)`. /// `v.cross_matrix().rmul(anything)`.
fn cross_matrix(&self) -> M; fn cross_matrix(&Self) -> M;
} }
/// Traits of objects which can be put in homogeneous coordinates form. /// Traits of objects which can be put in homogeneous coordinates form.
pub trait ToHomogeneous<U> { pub trait ToHomogeneous<U> {
/// Gets the homogeneous coordinates form of this object. /// Gets the homogeneous coordinates form of this object.
fn to_homogeneous(&self) -> U; fn to_homogeneous(&Self) -> U;
} }
/// Traits of objects which can be build from an homogeneous coordinate form. /// Traits of objects which can be build from an homogeneous coordinate form.

View File

@ -6,7 +6,7 @@
pub trait Absolute<A> { pub trait Absolute<A> {
/// Computes some absolute value of this object. /// Computes some absolute value of this object.
/// Typically, this will make all component of a matrix or vector positive. /// Typically, this will make all component of a matrix or vector positive.
fn absolute(&self) -> A; fn abs(&Self) -> A;
} }
/// Trait of objects having an inverse. Typically used to implement matrix inverse. /// Trait of objects having an inverse. Typically used to implement matrix inverse.
@ -30,7 +30,7 @@ pub trait Transpose {
/// Traits of objects having an outer product. /// Traits of objects having an outer product.
pub trait Outer<M> { pub trait Outer<M> {
/// Computes the outer product: `self * other` /// Computes the outer product: `self * other`
fn outer(&self, other: &Self) -> M; fn outer(a: &Self, b: &Self) -> M;
} }
/// Trait for computing the covariance of a set of data. /// Trait for computing the covariance of a set of data.
@ -39,14 +39,14 @@ pub trait Cov<M> {
/// ///
/// * For matrices, observations are stored in its rows. /// * For matrices, observations are stored in its rows.
/// * For vectors, observations are stored in its components (thus are 1-dimensional). /// * For vectors, observations are stored in its components (thus are 1-dimensional).
fn cov(&self) -> M; fn cov(&Self) -> M;
/// Computes the covariance of the obsevations stored by `self`: /// Computes the covariance of the obsevations stored by `self`:
/// ///
/// * For matrices, observations are stored in its rows. /// * For matrices, observations are stored in its rows.
/// * For vectors, observations are stored in its components (thus are 1-dimensional). /// * For vectors, observations are stored in its components (thus are 1-dimensional).
fn cov_to(&self, out: &mut M) { fn cov_to(m: &Self, out: &mut M) {
*out = self.cov() *out = Cov::cov(m)
} }
} }
@ -56,7 +56,7 @@ pub trait Mean<N> {
/// ///
/// * For matrices, observations are stored in its rows. /// * For matrices, observations are stored in its rows.
/// * For vectors, observations are stored in its components (thus are 1-dimensional). /// * For vectors, observations are stored in its components (thus are 1-dimensional).
fn mean(&self) -> N; fn mean(&Self) -> N;
} }
// /// Cholesky decomposition. // /// Cholesky decomposition.

View File

@ -60,7 +60,7 @@ pub trait Basis {
fn canonical_basis(&fn(Self) -> bool); fn canonical_basis(&fn(Self) -> bool);
/// Iterates through a basis of the subspace orthogonal to `self`. /// Iterates through a basis of the subspace orthogonal to `self`.
fn orthonormal_subspace_basis(&self, &fn(Self) -> bool); fn orthonormal_subspace_basis(&Self, &fn(Self) -> bool);
} }
/// Trait to access rows of a matrix or a vector. /// Trait to access rows of a matrix or a vector.