//! Traits giving structural informations on linear algebra objects or the space they live in. use std::num::{Zero, Bounded}; use std::slice::{Items, MutItems}; use traits::operations::{RMul, LMul, ScalarAdd, ScalarSub, Axpy}; use traits::geometry::{Dot, Norm, UniformSphereSample, Orig}; /// 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 { } /// Trait for constructing the identity matrix pub trait Eye { /// Return the identity matrix of specified dimension 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ā€¦ // 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 to access part of a column of a matrix pub trait ColSlice { /// Returns a view to a slice of a column of a matrix. fn col_slice(&self, col_id: uint, row_start: uint, row_end: uint) -> C; } /// Trait to access part of a row of a matrix pub trait RowSlice { /// Returns a view to a slice of a row of a matrix. fn row_slice(&self, row_id: uint, col_start: uint, col_end: uint) -> R; } /// 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; } /// Trait to get the diagonal of square matrices. pub trait Diag { /// Creates a new matrix with the given diagonal. fn from_diag(diag: &V) -> Self; /// Sets the diagonal of this matrix. fn set_diag(&mut self, diag: &V); /// The diagonal of this matrix. fn diag(&self) -> V; } // 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); /// Returns the shape of the iterable range. fn shape(&self) -> 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>; } /* * Vec related traits. */ /// Trait that relates a point of an affine space to a vector of the associated vector space. #[deprecated = "This will be removed in the future. Use point + vector operations instead."] pub trait VecAsPnt

{ /// Converts this point to its associated vector. fn to_pnt(self) -> P; /// Converts a reference to this point to a reference to its associated vector. fn as_pnt<'a>(&'a self) -> &'a P; } /// Trait grouping most common operations on vectors. pub trait AnyVec: Dim + Sub + Add + Neg + Zero + PartialEq + Mul + Div + Dot + Axpy { } /// Trait of vector with components implementing the `Float` trait. pub trait FloatVec: AnyVec + Norm { } /// Trait grouping uncommon, low-level and borderline (from the mathematical point of view) /// operations on vectors. pub trait VecExt: AnyVec + Indexable + Iterable + UniformSphereSample + ScalarAdd + ScalarSub + Bounded { } /// Trait grouping uncommon, low-level and borderline (from the mathematical point of view) /// operations on vectors. pub trait FloatVecExt: FloatVec + VecExt + Basis { } impl + Add + Neg + Zero + PartialEq + Mul + Div + Dot + Axpy> AnyVec for V { } impl + Norm> FloatVec for V { } impl + Indexable + Iterable + UniformSphereSample + ScalarAdd + ScalarSub + Bounded> VecExt for V { } impl + VecExt + Basis> FloatVecExt for V { } /* * Pnt related traits. */ /// Trait that relates a point of an affine space to a vector of the associated vector space. pub trait PntAsVec { /// Converts this point to its associated vector. fn to_vec(self) -> V; /// Converts a reference to this point to a reference to its associated vector. fn as_vec<'a>(&'a self) -> &'a V; // NOTE: this is used in some places to overcome some limitations untill the trait reform is // done on rustc. /// Sets the coordinates of this point to match those of a given vector. fn set_coords(&mut self, coords: V); } /// Trait grouping most common operations on points. // XXX: the vector space element `V` should be an associated type. Though this would prevent V from // having bounds (they are not supported yet). So, for now, we will just use a type parameter. pub trait AnyPnt: PntAsVec + Dim + Sub + Orig + Neg + PartialEq + Mul + Div + Add { // FIXME: + Sub } /// Trait of points with components implementing the `Float` trait. pub trait FloatPnt>: AnyPnt { /// Computes the square distance between two points. #[inline] fn sqdist(a: &Self, b: &Self) -> N { Norm::sqnorm(&(*a - *b)) } /// Computes the distance between two points. #[inline] fn dist(a: &Self, b: &Self) -> N { Norm::norm(&(*a - *b)) } } /// Trait grouping uncommon, low-level and borderline (from the mathematical point of view) /// operations on points. pub trait PntExt: AnyPnt + Indexable + Iterable + ScalarAdd + ScalarSub + Bounded + Axpy { } /// Trait grouping uncommon, low-level and borderline (from the mathematical point of view) /// operations on points. pub trait FloatPntExt> : FloatPnt + PntExt { } impl + Dim + Sub + Add + Orig + Neg

+ PartialEq + Mul + Div> AnyPnt for P { } impl, P: AnyPnt> FloatPnt for P { } impl + Indexable + Iterable + ScalarAdd + ScalarSub + Bounded + Axpy> PntExt for P { } impl, P: FloatPnt + PntExt> FloatPntExt for P { }