Add flatten trait.
This commit is contained in:
parent
c02edb9d09
commit
4c65f793e8
@ -4,6 +4,7 @@ use std::cmp::ApproxEq;
|
||||
use traits::dim::Dim;
|
||||
use traits::inv::Inv;
|
||||
use traits::transpose::Transpose;
|
||||
use traits::flatten::Flatten;
|
||||
use traits::workarounds::rlmul::{RMul, LMul};
|
||||
use dim1::vec1::Vec1;
|
||||
|
||||
@ -105,3 +106,18 @@ impl<N:Rand + Copy> Rand for Mat1<N>
|
||||
fn rand<R: Rng>(rng: &mut R) -> Mat1<N>
|
||||
{ Mat1::new(rng.gen()) }
|
||||
}
|
||||
|
||||
impl<N: Copy> Flatten<N> for Mat1<N>
|
||||
{
|
||||
fn flat_size() -> uint
|
||||
{ 1 }
|
||||
|
||||
fn from_flattened(l: &[N], off: uint) -> Mat1<N>
|
||||
{ Mat1::new(l[off]) }
|
||||
|
||||
fn to_flattened(&self) -> ~[N]
|
||||
{ ~[ self.m11 ] }
|
||||
|
||||
fn to_flattened_inplace(&self, l: &mut [N], off: uint)
|
||||
{ l[off] = self.m11 }
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ use traits::dot::Dot;
|
||||
use traits::norm::Norm;
|
||||
use traits::translation::Translation;
|
||||
use traits::sub_dot::SubDot;
|
||||
use traits::flatten::Flatten;
|
||||
use traits::workarounds::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
||||
|
||||
#[deriving(Eq, ToStr)]
|
||||
@ -169,3 +170,18 @@ impl<N:Rand + Copy> Rand for Vec1<N>
|
||||
fn rand<R: Rng>(rng: &mut R) -> Vec1<N>
|
||||
{ Vec1::new(rng.gen()) }
|
||||
}
|
||||
|
||||
impl<N: Copy> Flatten<N> for Vec1<N>
|
||||
{
|
||||
fn flat_size() -> uint
|
||||
{ 1 }
|
||||
|
||||
fn from_flattened(l: &[N], off: uint) -> Vec1<N>
|
||||
{ Vec1::new(l[off]) }
|
||||
|
||||
fn to_flattened(&self) -> ~[N]
|
||||
{ ~[ self.x ] }
|
||||
|
||||
fn to_flattened_inplace(&self, l: &mut [N], off: uint)
|
||||
{ l[off] = self.x }
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ use std::util::swap;
|
||||
use traits::dim::Dim;
|
||||
use traits::inv::Inv;
|
||||
use traits::transpose::Transpose;
|
||||
use traits::flatten::Flatten;
|
||||
use traits::workarounds::rlmul::{RMul, LMul};
|
||||
use dim2::vec2::Vec2;
|
||||
|
||||
@ -158,3 +159,23 @@ impl<N:Rand + Copy> Rand for Mat2<N>
|
||||
fn rand<R: Rng>(rng: &mut R) -> Mat2<N>
|
||||
{ Mat2::new(rng.gen(), rng.gen(), rng.gen(), rng.gen()) }
|
||||
}
|
||||
|
||||
impl<N: Copy> Flatten<N> for Mat2<N>
|
||||
{
|
||||
fn flat_size() -> uint
|
||||
{ 4 }
|
||||
|
||||
fn from_flattened(l: &[N], off: uint) -> Mat2<N>
|
||||
{ Mat2::new(l[off], l[off + 1], l[off + 2], l[off + 3]) }
|
||||
|
||||
fn to_flattened(&self) -> ~[N]
|
||||
{ ~[ self.m11, self.m12, self.m21, self.m22 ] }
|
||||
|
||||
fn to_flattened_inplace(&self, l: &mut [N], off: uint)
|
||||
{
|
||||
l[off] = self.m11;
|
||||
l[off + 1] = self.m12;
|
||||
l[off + 2] = self.m21;
|
||||
l[off + 3] = self.m22;
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ use traits::dim::Dim;
|
||||
use traits::dot::Dot;
|
||||
use traits::sub_dot::SubDot;
|
||||
use traits::norm::Norm;
|
||||
use traits::flatten::Flatten;
|
||||
use traits::translation::Translation;
|
||||
use traits::workarounds::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
||||
|
||||
@ -203,3 +204,21 @@ impl<N:Rand + Copy> Rand for Vec2<N>
|
||||
fn rand<R: Rng>(rng: &mut R) -> Vec2<N>
|
||||
{ Vec2::new(rng.gen(), rng.gen()) }
|
||||
}
|
||||
|
||||
impl<N: Copy> Flatten<N> for Vec2<N>
|
||||
{
|
||||
fn flat_size() -> uint
|
||||
{ 2 }
|
||||
|
||||
fn from_flattened(l: &[N], off: uint) -> Vec2<N>
|
||||
{ Vec2::new(l[off], l[off + 1]) }
|
||||
|
||||
fn to_flattened(&self) -> ~[N]
|
||||
{ ~[ self.x, self.y ] }
|
||||
|
||||
fn to_flattened_inplace(&self, l: &mut [N], off: uint)
|
||||
{
|
||||
l[off] = self.x;
|
||||
l[off + 1] = self.y;
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ use std::util::swap;
|
||||
use traits::dim::Dim;
|
||||
use traits::inv::Inv;
|
||||
use traits::transpose::Transpose;
|
||||
use traits::flatten::Flatten;
|
||||
use traits::workarounds::rlmul::{RMul, LMul};
|
||||
use dim3::vec3::Vec3;
|
||||
|
||||
@ -212,3 +213,36 @@ impl<N:Rand + Copy> Rand for Mat3<N>
|
||||
rng.gen(), rng.gen(), rng.gen())
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy> Flatten<N> for Mat3<N>
|
||||
{
|
||||
fn flat_size() -> uint
|
||||
{ 9 }
|
||||
|
||||
fn from_flattened(l: &[N], off: uint) -> Mat3<N>
|
||||
{ Mat3::new(l[off + 0], l[off + 1], l[off + 2],
|
||||
l[off + 3], l[off + 4], l[off + 5],
|
||||
l[off + 6], l[off + 7], l[off + 8]) }
|
||||
|
||||
fn to_flattened(&self) -> ~[N]
|
||||
{
|
||||
~[
|
||||
self.m11, self.m12, self.m13,
|
||||
self.m21, self.m22, self.m23,
|
||||
self.m31, self.m32, self.m33
|
||||
]
|
||||
}
|
||||
|
||||
fn to_flattened_inplace(&self, l: &mut [N], off: uint)
|
||||
{
|
||||
l[off + 0] = self.m11;
|
||||
l[off + 1] = self.m12;
|
||||
l[off + 2] = self.m13;
|
||||
l[off + 3] = self.m21;
|
||||
l[off + 4] = self.m22;
|
||||
l[off + 5] = self.m23;
|
||||
l[off + 6] = self.m31;
|
||||
l[off + 7] = self.m32;
|
||||
l[off + 8] = self.m33;
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ use traits::dim::Dim;
|
||||
use traits::dot::Dot;
|
||||
use traits::sub_dot::SubDot;
|
||||
use traits::norm::Norm;
|
||||
use traits::flatten::Flatten;
|
||||
use traits::translation::Translation;
|
||||
use traits::workarounds::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
||||
|
||||
@ -232,3 +233,22 @@ impl<N:Copy + Rand> Rand for Vec3<N>
|
||||
fn rand<R: Rng>(rng: &mut R) -> Vec3<N>
|
||||
{ Vec3::new(rng.gen(), rng.gen(), rng.gen()) }
|
||||
}
|
||||
|
||||
impl<N: Copy> Flatten<N> for Vec3<N>
|
||||
{
|
||||
fn flat_size() -> uint
|
||||
{ 3 }
|
||||
|
||||
fn from_flattened(l: &[N], off: uint) -> Vec3<N>
|
||||
{ Vec3::new(l[off], l[off + 1], l[off + 2]) }
|
||||
|
||||
fn to_flattened(&self) -> ~[N]
|
||||
{ ~[ self.x, self.y, self.z ] }
|
||||
|
||||
fn to_flattened_inplace(&self, l: &mut [N], off: uint)
|
||||
{
|
||||
l[off] = self.x;
|
||||
l[off + 1] = self.y;
|
||||
l[off + 2] = self.z;
|
||||
}
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ pub mod traits
|
||||
pub mod ring;
|
||||
pub mod division_ring;
|
||||
pub mod sub_dot;
|
||||
pub mod flatten;
|
||||
|
||||
/// This package contains everything done because the current compiler either
|
||||
/// crashes or miss features.
|
||||
|
@ -6,6 +6,7 @@ use traits::dim::Dim;
|
||||
use traits::inv::Inv;
|
||||
use traits::division_ring::DivisionRing;
|
||||
use traits::transpose::Transpose;
|
||||
use traits::flatten::Flatten;
|
||||
use traits::workarounds::rlmul::{RMul, LMul};
|
||||
use ndim::dmat::{DMat, one_mat_with_dim, zero_mat_with_dim, is_zero_mat};
|
||||
use ndim::nvec::NVec;
|
||||
@ -168,3 +169,39 @@ impl<D: Dim, N: Rand + Zero + Copy> Rand for NMat<D, N>
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Dim, N: Zero + Copy> Flatten<N> for NMat<D, N>
|
||||
{
|
||||
fn flat_size() -> uint
|
||||
{ Dim::dim::<D>() * Dim::dim::<D>() }
|
||||
|
||||
fn from_flattened(l: &[N], off: uint) -> NMat<D, N>
|
||||
{
|
||||
let dim = Dim::dim::<D>();
|
||||
let mut res = Zero::zero::<NMat<D, N>>();
|
||||
|
||||
for iterate(0u, dim * dim) |i|
|
||||
{ res.mij.mij[i] = l[off + i] }
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
fn to_flattened(&self) -> ~[N]
|
||||
{
|
||||
let dim = Dim::dim::<D>();
|
||||
let mut res = ~[];
|
||||
|
||||
for iterate(0u, dim * dim) |i|
|
||||
{ res.push(self.mij.mij[i]) }
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
fn to_flattened_inplace(&self, l: &mut [N], off: uint)
|
||||
{
|
||||
let dim = Dim::dim::<D>();
|
||||
|
||||
for iterate(0u, dim * dim) |i|
|
||||
{ l[off + i] = self.mij.mij[i] }
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ use traits::dot::Dot;
|
||||
use traits::sub_dot::SubDot;
|
||||
use traits::norm::Norm;
|
||||
use traits::translation::Translation;
|
||||
use traits::flatten::Flatten;
|
||||
use traits::workarounds::scalar_op::{ScalarMul, ScalarDiv, ScalarAdd, ScalarSub};
|
||||
|
||||
// D is a phantom parameter, used only as a dimensional token.
|
||||
@ -196,3 +197,39 @@ impl<D: Dim, N: Rand + Zero + Copy> Rand for NVec<D, N>
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Dim, N: Zero + Copy> Flatten<N> for NVec<D, N>
|
||||
{
|
||||
fn flat_size() -> uint
|
||||
{ Dim::dim::<D>() }
|
||||
|
||||
fn from_flattened(l: &[N], off: uint) -> NVec<D, N>
|
||||
{
|
||||
let dim = Dim::dim::<D>();
|
||||
let mut res = Zero::zero::<NVec<D, N>>();
|
||||
|
||||
for iterate(0u, dim) |i|
|
||||
{ res.at.at[i] = l[off + i] }
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
fn to_flattened(&self) -> ~[N]
|
||||
{
|
||||
let dim = Dim::dim::<D>();
|
||||
let mut res = ~[];
|
||||
|
||||
for iterate(0u, dim) |i|
|
||||
{ res.push(self.at.at[i]) }
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
fn to_flattened_inplace(&self, l: &mut [N], off: uint)
|
||||
{
|
||||
let dim = Dim::dim::<D>();
|
||||
|
||||
for iterate(0u, dim) |i|
|
||||
{ l[off + i] = self.at.at[i] }
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
#[test]
|
||||
use std::num::{Real, One, abs};
|
||||
use std::vec;
|
||||
#[test]
|
||||
use std::num::{Real, Zero, One, abs};
|
||||
#[test]
|
||||
use std::rand::{random};
|
||||
#[test]
|
||||
@ -8,8 +10,8 @@ use std::cmp::ApproxEq;
|
||||
use traits::inv::Inv;
|
||||
#[test]
|
||||
use traits::rotation::Rotation;
|
||||
// #[test]
|
||||
// use traits::dim::d7;
|
||||
#[test]
|
||||
use traits::dim::d7;
|
||||
#[test]
|
||||
use dim1::vec1::Vec1;
|
||||
#[test]
|
||||
@ -18,10 +20,12 @@ use dim1::mat1::Mat1;
|
||||
use dim2::mat2::Mat2;
|
||||
#[test]
|
||||
use dim3::mat3::Mat3;
|
||||
// #[test]
|
||||
// use ndim::nmat::NMat;
|
||||
#[test]
|
||||
use ndim::nmat::NMat;
|
||||
#[test]
|
||||
use adaptors::rotmat::Rotmat;
|
||||
#[test]
|
||||
use traits::flatten::Flatten;
|
||||
|
||||
macro_rules! test_inv_mat_impl(
|
||||
($t: ty) => (
|
||||
@ -34,6 +38,21 @@ macro_rules! test_inv_mat_impl(
|
||||
);
|
||||
)
|
||||
|
||||
macro_rules! test_flatten_impl(
|
||||
($t: ty, $n: ty) => (
|
||||
for 10000.times
|
||||
{
|
||||
let v: $t = random();
|
||||
let mut l: ~[$n] = vec::from_elem(42 + Flatten::flat_size::<$n, $t>(), Zero::zero::<$n>());
|
||||
|
||||
v.to_flattened_inplace(l, 42);
|
||||
|
||||
assert!(Flatten::from_flattened::<$n, $t>(v.to_flattened(), 0) == v);
|
||||
assert!(Flatten::from_flattened::<$n, $t>(l, 42) == v);
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
#[test]
|
||||
fn test_inv_mat1()
|
||||
{ test_inv_mat_impl!(Mat1<f64>); }
|
||||
@ -51,6 +70,22 @@ fn test_inv_mat3()
|
||||
// fn test_inv_nmat()
|
||||
// { test_inv_mat_impl!(NMat<d7, f64>); }
|
||||
|
||||
#[test]
|
||||
fn test_flatten_mat1()
|
||||
{ test_flatten_impl!(Mat1<f64>, f64); }
|
||||
|
||||
#[test]
|
||||
fn test_flatten_mat2()
|
||||
{ test_flatten_impl!(Mat2<f64>, f64); }
|
||||
|
||||
#[test]
|
||||
fn test_flatten_mat3()
|
||||
{ test_flatten_impl!(Mat3<f64>, f64); }
|
||||
|
||||
#[test]
|
||||
fn test_flatten_nmat()
|
||||
{ test_flatten_impl!(NMat<d7, f64>, f64); }
|
||||
|
||||
#[test]
|
||||
fn test_rotation2()
|
||||
{
|
||||
|
@ -1,4 +1,6 @@
|
||||
#[test]
|
||||
use std::vec;
|
||||
#[test]
|
||||
use std::iterator::IteratorUtil;
|
||||
#[test]
|
||||
use std::num::{Zero, One};
|
||||
@ -24,6 +26,8 @@ use traits::cross::Cross;
|
||||
use traits::dot::Dot;
|
||||
#[test]
|
||||
use traits::norm::Norm;
|
||||
#[test]
|
||||
use traits::flatten::Flatten;
|
||||
|
||||
macro_rules! test_commut_dot_impl(
|
||||
($t: ty) => (
|
||||
@ -75,6 +79,21 @@ macro_rules! test_subspace_basis_impl(
|
||||
);
|
||||
)
|
||||
|
||||
macro_rules! test_flatten_impl(
|
||||
($t: ty, $n: ty) => (
|
||||
for 10000.times
|
||||
{
|
||||
let v: $t = random();
|
||||
let mut l: ~[$n] = vec::from_elem(42 + Flatten::flat_size::<$n, $t>(), Zero::zero::<$n>());
|
||||
|
||||
v.to_flattened_inplace(l, 42);
|
||||
|
||||
assert!(Flatten::from_flattened::<$n, $t>(v.to_flattened(), 0) == v);
|
||||
assert!(Flatten::from_flattened::<$n, $t>(l, 42) == v);
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
#[test]
|
||||
fn test_cross_vec3()
|
||||
{
|
||||
@ -136,3 +155,19 @@ fn test_subspace_basis_vec3()
|
||||
#[test]
|
||||
fn test_subspace_basis_nvec()
|
||||
{ test_subspace_basis_impl!(NVec<d7, f64>); }
|
||||
|
||||
#[test]
|
||||
fn test_flatten_vec1()
|
||||
{ test_flatten_impl!(Vec1<f64>, f64); }
|
||||
|
||||
#[test]
|
||||
fn test_flatten_vec2()
|
||||
{ test_flatten_impl!(Vec2<f64>, f64); }
|
||||
|
||||
#[test]
|
||||
fn test_flatten_vec3()
|
||||
{ test_flatten_impl!(Vec3<f64>, f64); }
|
||||
|
||||
#[test]
|
||||
fn test_flatten_nvec()
|
||||
{ test_flatten_impl!(NVec<d7, f64>, f64); }
|
||||
|
34
src/traits/flatten.rs
Normal file
34
src/traits/flatten.rs
Normal file
@ -0,0 +1,34 @@
|
||||
/// Trait of objects which can be written as a list of values, and read from
|
||||
/// that list.
|
||||
pub trait Flatten<N>
|
||||
{
|
||||
/// The number of elements needed to flatten this object.
|
||||
fn flat_size() -> uint;
|
||||
|
||||
/**
|
||||
* Creates a new object from its flattened version. Its flattened version is
|
||||
* a continuous list of values. It is assumet that `flat_size` elements will
|
||||
* be read.
|
||||
*
|
||||
* - `l`: list from which the flat version must be read.
|
||||
* - `off`: index from which (included) the flat version read must begin.
|
||||
* It is assumed that the caller gives a valid input.
|
||||
*/
|
||||
fn from_flattened(l: &[N], off: uint) -> Self; // FIXME: keep (vector + index) or use an iterator?
|
||||
|
||||
/**
|
||||
* Creates a flattened version of `self`. The result vector must be of size
|
||||
* `flat_size`.
|
||||
*/
|
||||
fn to_flattened(&self) -> ~[N];
|
||||
|
||||
/**
|
||||
* Creates a flattened version of `self` on a vector. It is assumed that
|
||||
* `flat_size` elements will be written contiguously.
|
||||
*
|
||||
* - `l`: list to which the flat version must be written.
|
||||
* - `off`: index from which (included) the flat version write must begin.
|
||||
* It is assumed that the caller allocated a long enough list.
|
||||
*/
|
||||
fn to_flattened_inplace(&self, l: &mut [N], off: uint); // FIXME: keep (vector + index) or use an iterator (to a mutable value…)?
|
||||
}
|
Loading…
Reference in New Issue
Block a user