//! Traits giving structural informations on linear algebra objects or the space they live in. use std::num::{Zero, Bounded}; use std::vec::{Items, MutItems}; use traits::operations::{RMul, LMul, ScalarAdd, ScalarSub}; use traits::geometry::{Dot, Norm, UniformSphereSample}; /// Traits of objects which can be created from an object of type `T`. pub trait Cast { /// Converts an element of type `T` to an element of type `Self`. fn from(t: T) -> Self; } /// Trait of matrices. /// /// A matrix has rows and columns and are able to multiply them. pub trait Mat : Row + Col + RMul + LMul { } impl + Col + RMul + LMul, R, C> Mat for M { } // XXX: we keep ScalarAdd and ScalarSub here to avoid trait impl conflict (overriding) between the // different Add/Sub traits. This is _so_ unfortunateā€¦ /// Trait grouping most common operations on vectors. pub trait Vec: Dim + Sub + Add + Neg + Zero + Eq + Mul + Div + Dot { } /// Trait of vector with components implementing the `Real` trait. pub trait RealVec: Vec + Norm { } /// Trait grouping uncommon, low-level and borderline (from the mathematical point of view) /// operations on vectors. pub trait VecExt: Vec + Indexable + Iterable + UniformSphereSample + ScalarAdd + ScalarSub + Bounded + Orderable { } /// Trait grouping uncommon, low-level and borderline (from the mathematical point of view) /// operations on vectors. pub trait RealVecExt: RealVec + VecExt + Basis + Round { } impl + Add + Neg + Zero + Eq + Mul + Div + Dot> Vec for V { } impl + Norm> RealVec for V { } impl + Indexable + Iterable + UniformSphereSample + ScalarAdd + ScalarSub + Bounded + Orderable> VecExt for V { } impl + VecExt + Basis + Round> RealVecExt for V { } // FIXME: return an iterator instead /// Traits of objects which can form a basis (typically vectors). pub trait Basis { /// Iterates through the canonical basis of the space in which this object lives. fn canonical_basis(|Self| -> bool); /// Iterates through a basis of the subspace orthogonal to `self`. fn orthonormal_subspace_basis(&Self, |Self| -> bool); } /// Trait to access rows of a matrix or a vector. pub trait Row { /// The number of column of `self`. fn nrows(&self) -> uint; /// Reads the `i`-th row of `self`. fn row(&self, i: uint) -> R; /// Writes the `i`-th row of `self`. fn set_row(&mut self, i: uint, R); // FIXME: add iterators on rows: this could be a very good way to generalize _and_ optimize // a lot of operations. } /// Trait to access columns of a matrix or vector. pub trait Col { /// The number of column of this matrix or vector. fn ncols(&self) -> uint; /// Reads the `i`-th column of `self`. fn col(&self, i: uint) -> C; /// Writes the `i`-th column of `self`. fn set_col(&mut self, i: uint, C); // FIXME: add iterators on columns: this could be a very good way to generalize _and_ optimize // a lot of operations. } /// Trait of objects having a spacial dimension known at compile time. pub trait Dim { /// The dimension of the object. fn dim(unused_self: Option) -> uint; } // FIXME: this trait should not be on nalgebra. // however, it is needed because std::ops::Index is (strangely) to poor: it // does not have a function to set values. // Also, using Index with tuples crashes. /// This is a workaround of current Rust limitations. /// /// It exists because the `Index` trait cannot be used to express write access. /// Thus, this is the same as the `Index` trait but without the syntactic sugar and with a method /// to write to a specific index. pub trait Indexable { /// Reads the `i`-th element of `self`. fn at(&self, i: Index) -> Res; /// Writes to the `i`-th element of `self`. fn set(&mut self, i: Index, Res); /// Swaps the `i`-th element of `self` with its `j`-th element. fn swap(&mut self, i: Index, j: Index); /// Reads the `i`-th element of `self`. /// /// `i` is not checked. unsafe fn unsafe_at(&self, i: Index) -> Res; /// Writes to the `i`-th element of `self`. /// /// `i` is not checked. unsafe fn unsafe_set(&mut self, i: Index, Res); } /// This is a workaround of current Rust limitations. /// /// Traits of objects which can be iterated through like a vector. pub trait Iterable { /// Gets a vector-like read-only iterator. fn iter<'l>(&'l self) -> Items<'l, N>; } /// This is a workaround of current Rust limitations. /// /// Traits of mutable objects which can be iterated through like a vector. pub trait IterableMut { /// Gets a vector-like read-write iterator. fn mut_iter<'l>(&'l mut self) -> MutItems<'l, N>; }