parent
74fd3e1a04
commit
9e739676a7
|
@ -5,9 +5,9 @@ nalgebra
|
||||||
|
|
||||||
**nalgebra** is a low-dimensional linear algebra library written for Rust targeting:
|
**nalgebra** is a low-dimensional linear algebra library written for Rust targeting:
|
||||||
|
|
||||||
* general-purpose linear algebra (still lacks a lot of features…).
|
* General-purpose linear algebra (still lacks a lot of features…)
|
||||||
* real time computer graphics.
|
* Real time computer graphics.
|
||||||
* real time computer physics.
|
* Real time computer physics.
|
||||||
|
|
||||||
An on-line version of this documentation is available [here](http://nalgebra.org/doc/nalgebra).
|
An on-line version of this documentation is available [here](http://nalgebra.org/doc/nalgebra).
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::iter::repeat;
|
use std::iter::repeat;
|
||||||
use std::ops::{Add, Sub, Mul, Div, Index, IndexMut};
|
use std::ops::{Add, Sub, Mul, Div, AddAssign, SubAssign, MulAssign, Index, IndexMut};
|
||||||
use std::fmt::{Debug, Formatter, Result};
|
use std::fmt::{Debug, Formatter, Result};
|
||||||
use rand::{self, Rand};
|
use rand::{self, Rand};
|
||||||
use num::{Zero, One};
|
use num::{Zero, One};
|
||||||
|
|
|
@ -165,7 +165,13 @@ macro_rules! dmat_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N> + Zero> Mul<$dmat<N>> for $dmat<N> {
|
/*
|
||||||
|
*
|
||||||
|
* Multiplications matrix/matrix.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
impl<N> Mul<$dmat<N>> for $dmat<N>
|
||||||
|
where N: Copy + Mul<N, Output = N> + Add<N, Output = N> + Zero {
|
||||||
type Output = $dmat<N>;
|
type Output = $dmat<N>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -174,7 +180,8 @@ macro_rules! dmat_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, N: Copy + Mul<N, Output = N> + Add<N, Output = N> + Zero> Mul<&'a $dmat<N>> for $dmat<N> {
|
impl<'a, N> Mul<&'a $dmat<N>> for $dmat<N>
|
||||||
|
where N: Copy + Mul<N, Output = N> + Add<N, Output = N> + Zero {
|
||||||
type Output = $dmat<N>;
|
type Output = $dmat<N>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -183,7 +190,8 @@ macro_rules! dmat_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, N: Copy + Mul<N, Output = N> + Add<N, Output = N> + Zero> Mul<$dmat<N>> for &'a $dmat<N> {
|
impl<'a, N> Mul<$dmat<N>> for &'a $dmat<N>
|
||||||
|
where N: Copy + Mul<N, Output = N> + Add<N, Output = N> + Zero {
|
||||||
type Output = $dmat<N>;
|
type Output = $dmat<N>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -192,7 +200,8 @@ macro_rules! dmat_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, N: Copy + Mul<N, Output = N> + Add<N, Output = N> + Zero> Mul<&'b $dmat<N>> for &'a $dmat<N> {
|
impl<'a, 'b, N> Mul<&'b $dmat<N>> for &'a $dmat<N>
|
||||||
|
where N: Copy + Mul<N, Output = N> + Add<N, Output = N> + Zero {
|
||||||
type Output = $dmat<N>;
|
type Output = $dmat<N>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -201,14 +210,13 @@ macro_rules! dmat_impl(
|
||||||
|
|
||||||
let mut res = unsafe { $dmat::new_uninitialized(self.nrows, right.ncols) };
|
let mut res = unsafe { $dmat::new_uninitialized(self.nrows, right.ncols) };
|
||||||
|
|
||||||
for i in 0..self.nrows {
|
for i in 0 .. self.nrows {
|
||||||
for j in 0..right.ncols {
|
for j in 0 .. right.ncols {
|
||||||
let mut acc: N = ::zero();
|
let mut acc: N = ::zero();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
for k in 0..self.ncols {
|
for k in 0 .. self.ncols {
|
||||||
acc = acc
|
acc = acc + self.unsafe_at((i, k)) * right.unsafe_at((k, j));
|
||||||
+ self.unsafe_at((i, k)) * right.unsafe_at((k, j));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res.unsafe_set((i, j), acc);
|
res.unsafe_set((i, j), acc);
|
||||||
|
@ -220,10 +228,64 @@ macro_rules! dmat_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Copy + Add<N, Output = N> + Mul<N, Output = N> + Zero> Mul<$dvec<N>> for $dmat<N> {
|
impl<N> MulAssign<$dmat<N>> for $dmat<N>
|
||||||
|
where N: Copy + Mul<N, Output = N> + Add<N, Output = N> + Zero {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: $dmat<N>) {
|
||||||
|
self.mul_assign(&right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, N> MulAssign<&'a $dmat<N>> for $dmat<N>
|
||||||
|
where N: Copy + Mul<N, Output = N> + Add<N, Output = N> + Zero {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: &'a $dmat<N>) {
|
||||||
|
assert!(self.ncols == right.nrows);
|
||||||
|
|
||||||
|
// FIXME: optimize when both matrices have the same layout.
|
||||||
|
let res = &*self * right;
|
||||||
|
*self = res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Multiplication matrix/vector.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
impl<N> Mul<$dvec<N>> for $dmat<N>
|
||||||
|
where N: Copy + Add<N, Output = N> + Mul<N, Output = N> + Zero {
|
||||||
type Output = $dvec<N>;
|
type Output = $dvec<N>;
|
||||||
|
|
||||||
fn mul(self, right: $dvec<N>) -> $dvec<N> {
|
fn mul(self, right: $dvec<N>) -> $dvec<N> {
|
||||||
|
(&self) * (&right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, N> Mul<$dvec<N>> for &'a $dmat<N>
|
||||||
|
where N: Copy + Add<N, Output = N> + Mul<N, Output = N> + Zero {
|
||||||
|
type Output = $dvec<N>;
|
||||||
|
|
||||||
|
fn mul(self, right: $dvec<N>) -> $dvec<N> {
|
||||||
|
self * (&right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, N> Mul<&'a $dvec<N>> for $dmat<N>
|
||||||
|
where N: Copy + Add<N, Output = N> + Mul<N, Output = N> + Zero {
|
||||||
|
type Output = $dvec<N>;
|
||||||
|
|
||||||
|
fn mul(self, right: &'a $dvec<N>) -> $dvec<N> {
|
||||||
|
(&self) * right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'b, N> Mul<&'b $dvec<N>> for &'a $dmat<N>
|
||||||
|
where N: Copy + Add<N, Output = N> + Mul<N, Output = N> + Zero {
|
||||||
|
type Output = $dvec<N>;
|
||||||
|
|
||||||
|
fn mul(self, right: &'b $dvec<N>) -> $dvec<N> {
|
||||||
assert!(self.ncols == right.len());
|
assert!(self.ncols == right.len());
|
||||||
|
|
||||||
let mut res : $dvec<N> = unsafe { $dvec::new_uninitialized(self.nrows) };
|
let mut res : $dvec<N> = unsafe { $dvec::new_uninitialized(self.nrows) };
|
||||||
|
@ -246,11 +308,39 @@ macro_rules! dmat_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N> Mul<$dmat<N>> for $dvec<N>
|
||||||
impl<N: Copy + Add<N, Output = N> + Mul<N, Output = N> + Zero> Mul<$dmat<N>> for $dvec<N> {
|
where N: Copy + Add<N, Output = N> + Mul<N, Output = N> + Zero {
|
||||||
type Output = $dvec<N>;
|
type Output = $dvec<N>;
|
||||||
|
|
||||||
fn mul(self, right: $dmat<N>) -> $dvec<N> {
|
fn mul(self, right: $dmat<N>) -> $dvec<N> {
|
||||||
|
(&self) * (&right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, N> Mul<$dmat<N>> for &'a $dvec<N>
|
||||||
|
where N: Copy + Add<N, Output = N> + Mul<N, Output = N> + Zero {
|
||||||
|
type Output = $dvec<N>;
|
||||||
|
|
||||||
|
fn mul(self, right: $dmat<N>) -> $dvec<N> {
|
||||||
|
self * (&right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, N> Mul<&'a $dmat<N>> for $dvec<N>
|
||||||
|
where N: Copy + Add<N, Output = N> + Mul<N, Output = N> + Zero {
|
||||||
|
type Output = $dvec<N>;
|
||||||
|
|
||||||
|
fn mul(self, right: &'a $dmat<N>) -> $dvec<N> {
|
||||||
|
(&self) * right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<'a, 'b, N> Mul<&'b $dmat<N>> for &'a $dvec<N>
|
||||||
|
where N: Copy + Add<N, Output = N> + Mul<N, Output = N> + Zero {
|
||||||
|
type Output = $dvec<N>;
|
||||||
|
|
||||||
|
fn mul(self, right: &'b $dmat<N>) -> $dvec<N> {
|
||||||
assert!(right.nrows == self.len());
|
assert!(right.nrows == self.len());
|
||||||
|
|
||||||
let mut res : $dvec<N> = unsafe { $dvec::new_uninitialized(right.ncols) };
|
let mut res : $dvec<N> = unsafe { $dvec::new_uninitialized(right.ncols) };
|
||||||
|
@ -273,6 +363,206 @@ macro_rules! dmat_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N> MulAssign<$dmat<N>> for $dvec<N>
|
||||||
|
where N: Copy + Mul<N, Output = N> + Add<N, Output = N> + Zero {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: $dmat<N>) {
|
||||||
|
self.mul_assign(&right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, N> MulAssign<&'a $dmat<N>> for $dvec<N>
|
||||||
|
where N: Copy + Mul<N, Output = N> + Add<N, Output = N> + Zero {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: &'a $dmat<N>) {
|
||||||
|
assert!(right.nrows == self.len());
|
||||||
|
|
||||||
|
let res = &*self * right;
|
||||||
|
*self = res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Addition matrix/matrix.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
impl<N: Copy + Add<N, Output = N>> Add<$dmat<N>> for $dmat<N> {
|
||||||
|
type Output = $dmat<N>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn add(self, right: $dmat<N>) -> $dmat<N> {
|
||||||
|
self + (&right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, N: Copy + Add<N, Output = N>> Add<$dmat<N>> for &'a $dmat<N> {
|
||||||
|
type Output = $dmat<N>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn add(self, right: $dmat<N>) -> $dmat<N> {
|
||||||
|
right + self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, N: Copy + Add<N, Output = N>> Add<&'a $dmat<N>> for $dmat<N> {
|
||||||
|
type Output = $dmat<N>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn add(self, right: &'a $dmat<N>) -> $dmat<N> {
|
||||||
|
let mut res = self;
|
||||||
|
|
||||||
|
for (mij, right_ij) in res.mij.iter_mut().zip(right.mij.iter()) {
|
||||||
|
*mij = *mij + *right_ij;
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Copy + AddAssign<N>> AddAssign<$dmat<N>> for $dmat<N> {
|
||||||
|
#[inline]
|
||||||
|
fn add_assign(&mut self, right: $dmat<N>) {
|
||||||
|
self.add_assign(&right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, N: Copy + AddAssign<N>> AddAssign<&'a $dmat<N>> for $dmat<N> {
|
||||||
|
#[inline]
|
||||||
|
fn add_assign(&mut self, right: &'a $dmat<N>) {
|
||||||
|
assert!(self.nrows == right.nrows && self.ncols == right.ncols,
|
||||||
|
"Unable to add matrices with different dimensions.");
|
||||||
|
|
||||||
|
for (mij, right_ij) in self.mij.iter_mut().zip(right.mij.iter()) {
|
||||||
|
*mij += *right_ij;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Subtraction matrix/scalar.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
impl<N: Copy + Sub<N, Output = N>> Sub<N> for $dmat<N> {
|
||||||
|
type Output = $dmat<N>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, right: N) -> $dmat<N> {
|
||||||
|
let mut res = self;
|
||||||
|
|
||||||
|
for mij in res.mij.iter_mut() {
|
||||||
|
*mij = *mij - right;
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, N: Copy + SubAssign<N>> SubAssign<N> for $dmat<N> {
|
||||||
|
#[inline]
|
||||||
|
fn sub_assign(&mut self, right: N) {
|
||||||
|
for mij in self.mij.iter_mut() {
|
||||||
|
*mij -= right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sub<$dmat<f32>> for f32 {
|
||||||
|
type Output = $dmat<f32>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, right: $dmat<f32>) -> $dmat<f32> {
|
||||||
|
let mut res = right;
|
||||||
|
|
||||||
|
for mij in res.mij.iter_mut() {
|
||||||
|
*mij = self - *mij;
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sub<$dmat<f64>> for f64 {
|
||||||
|
type Output = $dmat<f64>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, right: $dmat<f64>) -> $dmat<f64> {
|
||||||
|
let mut res = right;
|
||||||
|
|
||||||
|
for mij in res.mij.iter_mut() {
|
||||||
|
*mij = self - *mij;
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Subtraction matrix/matrix.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
impl<N: Copy + Sub<N, Output = N>> Sub<$dmat<N>> for $dmat<N> {
|
||||||
|
type Output = $dmat<N>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, right: $dmat<N>) -> $dmat<N> {
|
||||||
|
self - (&right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, N: Copy + Sub<N, Output = N>> Sub<$dmat<N>> for &'a $dmat<N> {
|
||||||
|
type Output = $dmat<N>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, right: $dmat<N>) -> $dmat<N> {
|
||||||
|
right - self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, N: Copy + Sub<N, Output = N>> Sub<&'a $dmat<N>> for $dmat<N> {
|
||||||
|
type Output = $dmat<N>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, right: &'a $dmat<N>) -> $dmat<N> {
|
||||||
|
assert!(self.nrows == right.nrows && self.ncols == right.ncols,
|
||||||
|
"Unable to subtract matrices with different dimensions.");
|
||||||
|
|
||||||
|
let mut res = self;
|
||||||
|
|
||||||
|
for (mij, right_ij) in res.mij.iter_mut().zip(right.mij.iter()) {
|
||||||
|
*mij = *mij - *right_ij;
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Copy + SubAssign<N>> SubAssign<$dmat<N>> for $dmat<N> {
|
||||||
|
#[inline]
|
||||||
|
fn sub_assign(&mut self, right: $dmat<N>) {
|
||||||
|
self.sub_assign(&right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, N: Copy + SubAssign<N>> SubAssign<&'a $dmat<N>> for $dmat<N> {
|
||||||
|
#[inline]
|
||||||
|
fn sub_assign(&mut self, right: &'a $dmat<N>) {
|
||||||
|
assert!(self.nrows == right.nrows && self.ncols == right.ncols,
|
||||||
|
"Unable to subtract matrices with different dimensions.");
|
||||||
|
|
||||||
|
for (mij, right_ij) in self.mij.iter_mut().zip(right.mij.iter()) {
|
||||||
|
*mij -= *right_ij;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Inversion.
|
||||||
|
*
|
||||||
|
*/
|
||||||
impl<N: BaseNum + Clone> Inv for $dmat<N> {
|
impl<N: BaseNum + Clone> Inv for $dmat<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inv(&self) -> Option<$dmat<N>> {
|
fn inv(&self) -> Option<$dmat<N>> {
|
||||||
|
@ -619,6 +909,11 @@ macro_rules! dmat_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Multpilication matrix/scalar.
|
||||||
|
*
|
||||||
|
*/
|
||||||
impl<N: Copy + Mul<N, Output = N>> Mul<N> for $dmat<N> {
|
impl<N: Copy + Mul<N, Output = N>> Mul<N> for $dmat<N> {
|
||||||
type Output = $dmat<N>;
|
type Output = $dmat<N>;
|
||||||
|
|
||||||
|
@ -664,6 +959,11 @@ macro_rules! dmat_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Division matrix/scalar.
|
||||||
|
*
|
||||||
|
*/
|
||||||
impl<N: Copy + Div<N, Output = N>> Div<N> for $dmat<N> {
|
impl<N: Copy + Div<N, Output = N>> Div<N> for $dmat<N> {
|
||||||
type Output = $dmat<N>;
|
type Output = $dmat<N>;
|
||||||
|
|
||||||
|
@ -679,6 +979,12 @@ macro_rules! dmat_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Addition matrix/scalar.
|
||||||
|
*
|
||||||
|
*/
|
||||||
impl<N: Copy + Add<N, Output = N>> Add<N> for $dmat<N> {
|
impl<N: Copy + Add<N, Output = N>> Add<N> for $dmat<N> {
|
||||||
type Output = $dmat<N>;
|
type Output = $dmat<N>;
|
||||||
|
|
||||||
|
@ -724,123 +1030,6 @@ macro_rules! dmat_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Copy + Add<N, Output = N>> Add<$dmat<N>> for $dmat<N> {
|
|
||||||
type Output = $dmat<N>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn add(self, right: $dmat<N>) -> $dmat<N> {
|
|
||||||
self + (&right)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, N: Copy + Add<N, Output = N>> Add<$dmat<N>> for &'a $dmat<N> {
|
|
||||||
type Output = $dmat<N>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn add(self, right: $dmat<N>) -> $dmat<N> {
|
|
||||||
right + self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, N: Copy + Add<N, Output = N>> Add<&'a $dmat<N>> for $dmat<N> {
|
|
||||||
type Output = $dmat<N>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn add(self, right: &'a $dmat<N>) -> $dmat<N> {
|
|
||||||
assert!(self.nrows == right.nrows && self.ncols == right.ncols,
|
|
||||||
"Unable to add matrices with different dimensions.");
|
|
||||||
|
|
||||||
let mut res = self;
|
|
||||||
|
|
||||||
for (mij, right_ij) in res.mij.iter_mut().zip(right.mij.iter()) {
|
|
||||||
*mij = *mij + *right_ij;
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N: Copy + Sub<N, Output = N>> Sub<N> for $dmat<N> {
|
|
||||||
type Output = $dmat<N>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn sub(self, right: N) -> $dmat<N> {
|
|
||||||
let mut res = self;
|
|
||||||
|
|
||||||
for mij in res.mij.iter_mut() {
|
|
||||||
*mij = *mij - right;
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Sub<$dmat<f32>> for f32 {
|
|
||||||
type Output = $dmat<f32>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn sub(self, right: $dmat<f32>) -> $dmat<f32> {
|
|
||||||
let mut res = right;
|
|
||||||
|
|
||||||
for mij in res.mij.iter_mut() {
|
|
||||||
*mij = self - *mij;
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Sub<$dmat<f64>> for f64 {
|
|
||||||
type Output = $dmat<f64>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn sub(self, right: $dmat<f64>) -> $dmat<f64> {
|
|
||||||
let mut res = right;
|
|
||||||
|
|
||||||
for mij in res.mij.iter_mut() {
|
|
||||||
*mij = self - *mij;
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N: Copy + Sub<N, Output = N>> Sub<$dmat<N>> for $dmat<N> {
|
|
||||||
type Output = $dmat<N>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn sub(self, right: $dmat<N>) -> $dmat<N> {
|
|
||||||
self - (&right)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, N: Copy + Sub<N, Output = N>> Sub<$dmat<N>> for &'a $dmat<N> {
|
|
||||||
type Output = $dmat<N>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn sub(self, right: $dmat<N>) -> $dmat<N> {
|
|
||||||
right - self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, N: Copy + Sub<N, Output = N>> Sub<&'a $dmat<N>> for $dmat<N> {
|
|
||||||
type Output = $dmat<N>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn sub(self, right: &'a $dmat<N>) -> $dmat<N> {
|
|
||||||
assert!(self.nrows == right.nrows && self.ncols == right.ncols,
|
|
||||||
"Unable to subtract matrices with different dimensions.");
|
|
||||||
|
|
||||||
let mut res = self;
|
|
||||||
|
|
||||||
for (mij, right_ij) in res.mij.iter_mut().zip(right.mij.iter()) {
|
|
||||||
*mij = *mij - *right_ij;
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature="arbitrary")]
|
#[cfg(feature="arbitrary")]
|
||||||
impl<N: Copy + Zero + Arbitrary> Arbitrary for $dmat<N> {
|
impl<N: Copy + Zero + Arbitrary> Arbitrary for $dmat<N> {
|
||||||
fn arbitrary<G: Gen>(g: &mut G) -> $dmat<N> {
|
fn arbitrary<G: Gen>(g: &mut G) -> $dmat<N> {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use std::slice::{Iter, IterMut};
|
use std::slice::{Iter, IterMut};
|
||||||
use std::iter::{FromIterator, IntoIterator};
|
use std::iter::{FromIterator, IntoIterator};
|
||||||
use std::iter::repeat;
|
use std::iter::repeat;
|
||||||
use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut};
|
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use rand::{self, Rand};
|
use rand::{self, Rand};
|
||||||
use num::{Zero, One};
|
use num::{Zero, One};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::{Add, Sub, Mul, Neg};
|
use std::ops::{Add, Sub, Mul, Neg, MulAssign};
|
||||||
|
|
||||||
use rand::{Rand, Rng};
|
use rand::{Rand, Rng};
|
||||||
use num::One;
|
use num::One;
|
||||||
|
|
|
@ -73,21 +73,29 @@ macro_rules! iso_mul_iso_impl(
|
||||||
self.rotation * right.rotation)
|
self.rotation * right.rotation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: BaseFloat> MulAssign<$t<N>> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: $t<N>) {
|
||||||
|
self.translation += self.rotation * right.translation;
|
||||||
|
self.rotation *= right.rotation;
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
macro_rules! iso_mul_rot_impl(
|
macro_rules! iso_mul_rot_impl(
|
||||||
($t: ident, $tr: ident) => (
|
($t: ident, $rot: ident) => (
|
||||||
impl<N: BaseFloat> Mul<$tr<N>> for $t<N> {
|
impl<N: BaseFloat> Mul<$rot<N>> for $t<N> {
|
||||||
type Output = $t<N>;
|
type Output = $t<N>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul(self, right: $tr<N>) -> $t<N> {
|
fn mul(self, right: $rot<N>) -> $t<N> {
|
||||||
$t::new_with_rotmat(self.translation, self.rotation * right)
|
$t::new_with_rotmat(self.translation, self.rotation * right)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: BaseFloat> Mul<$t<N>> for $tr<N> {
|
impl<N: BaseFloat> Mul<$t<N>> for $rot<N> {
|
||||||
type Output = $t<N>;
|
type Output = $t<N>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -97,6 +105,13 @@ macro_rules! iso_mul_rot_impl(
|
||||||
self * right.rotation)
|
self * right.rotation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: BaseFloat> MulAssign<$rot<N>> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: $rot<N>) {
|
||||||
|
self.rotation *= right
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -110,9 +125,6 @@ macro_rules! iso_mul_pnt_impl(
|
||||||
self.rotation * right + self.translation
|
self.rotation * right + self.translation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: there is no viable pre-multiplication definition because of the translation
|
|
||||||
// component.
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#![allow(missing_docs)] // we allow missing to avoid having to document the mij components.
|
#![allow(missing_docs)] // we allow missing to avoid having to document the mij components.
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::{Add, Sub, Mul, Div, Index, IndexMut};
|
use std::ops::{Add, Sub, Mul, Div, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::slice::{Iter, IterMut};
|
use std::slice::{Iter, IterMut};
|
||||||
use rand::{Rand, Rng};
|
use rand::{Rand, Rng};
|
||||||
|
|
|
@ -92,6 +92,13 @@ macro_rules! add_impl(
|
||||||
$t::new($(self.$compN + right.$compN),+)
|
$t::new($(self.$compN + right.$compN),+)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: AddAssign<N>> AddAssign<$t<N>> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn add_assign(&mut self, right: $t<N>) {
|
||||||
|
$( self.$compN += right.$compN; )+
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -105,6 +112,14 @@ macro_rules! sub_impl(
|
||||||
$t::new($(self.$compN - right.$compN),+)
|
$t::new($(self.$compN - right.$compN),+)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<N: SubAssign<N>> SubAssign<$t<N>> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn sub_assign(&mut self, right: $t<N>) {
|
||||||
|
$( self.$compN -= right.$compN; )+
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -119,6 +134,13 @@ macro_rules! mat_mul_scalar_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: MulAssign<N>> MulAssign<N> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: N) {
|
||||||
|
$( self.$compN *= *right; )+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Mul<$t<f32>> for f32 {
|
impl Mul<$t<f32>> for f32 {
|
||||||
type Output = $t<f32>;
|
type Output = $t<f32>;
|
||||||
|
|
||||||
|
@ -149,6 +171,13 @@ macro_rules! mat_div_scalar_impl(
|
||||||
$t::new($(self.$compN / *right),+)
|
$t::new($(self.$compN / *right),+)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: DivAssign<N>> DivAssign<N> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn div_assign(&mut self, right: N) {
|
||||||
|
$( self.$compN /= *right; )+
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -163,6 +192,13 @@ macro_rules! mat_add_scalar_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: AddAssign<N>> AddAssign<N> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn add_assign(&mut self, right: N) {
|
||||||
|
$( self.$compN += *right; )+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Add<$t<f32>> for f32 {
|
impl Add<$t<f32>> for f32 {
|
||||||
type Output = $t<f32>;
|
type Output = $t<f32>;
|
||||||
|
|
||||||
|
@ -183,6 +219,44 @@ macro_rules! mat_add_scalar_impl(
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
macro_rules! mat_sub_scalar_impl(
|
||||||
|
($t: ident, $($compN: ident),+) => (
|
||||||
|
impl<N: Sub<N, Output = N>> Sub<N> for $t<N> {
|
||||||
|
type Output = $t<N>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, right: &N) -> $t<N> {
|
||||||
|
$t::new($(self.$compN - *right),+)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: SubAssign<N>> SubAssign<N> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn sub_assign(&mut self, right: N) {
|
||||||
|
$( self.$compN -= *right; )+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sub<f32> for $t<f32> {
|
||||||
|
type Output = $t<f32>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, right: $t<f32>) -> $t<f32> {
|
||||||
|
$t::new($(self - right.$compN),+)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sub<f64> for $t<f64> {
|
||||||
|
type Output = $t<f64>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, right: $t<f64>) -> $t<f64> {
|
||||||
|
$t::new($(self - right.$compN),+)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
macro_rules! eye_impl(
|
macro_rules! eye_impl(
|
||||||
($t: ident, $dim: expr, $($comp_diagN: ident),+) => (
|
($t: ident, $dim: expr, $($comp_diagN: ident),+) => (
|
||||||
|
@ -209,37 +283,6 @@ macro_rules! repeat_impl(
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
macro_rules! mat_sub_scalar_impl(
|
|
||||||
($t: ident, $($compN: ident),+) => (
|
|
||||||
impl<N: Sub<N, Output = N>> Sub<N> for $t<N> {
|
|
||||||
type Output = $t<N>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn sub(self, right: &N) -> $t<N> {
|
|
||||||
$t::new($(self.$compN - *right),+)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Sub<f32> for $t<f32> {
|
|
||||||
type Output = $t<f32>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn sub(self, right: $t<f32>) -> $t<f32> {
|
|
||||||
$t::new($(self - right.$compN),+)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Sub<f64> for $t<f64> {
|
|
||||||
type Output = $t<f64>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn sub(self, right: $t<f64>) -> $t<f64> {
|
|
||||||
$t::new($(self - right.$compN),+)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
macro_rules! absolute_impl(
|
macro_rules! absolute_impl(
|
||||||
($t: ident, $($compN: ident),+) => (
|
($t: ident, $($compN: ident),+) => (
|
||||||
impl<N: Absolute<N>> Absolute<$t<N>> for $t<N> {
|
impl<N: Absolute<N>> Absolute<$t<N>> for $t<N> {
|
||||||
|
@ -468,7 +511,7 @@ macro_rules! diag_impl(
|
||||||
fn diag(&self) -> $tv<N> {
|
fn diag(&self) -> $tv<N> {
|
||||||
let mut diag: $tv<N> = ::zero();
|
let mut diag: $tv<N> = ::zero();
|
||||||
|
|
||||||
for i in 0..$dim {
|
for i in 0 .. $dim {
|
||||||
unsafe { diag.unsafe_set(i, self.unsafe_at((i, i))) }
|
unsafe { diag.unsafe_set(i, self.unsafe_at((i, i))) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,7 +522,7 @@ macro_rules! diag_impl(
|
||||||
impl<N: Copy + Zero> DiagMut<$tv<N>> for $t<N> {
|
impl<N: Copy + Zero> DiagMut<$tv<N>> for $t<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn set_diag(&mut self, diag: &$tv<N>) {
|
fn set_diag(&mut self, diag: &$tv<N>) {
|
||||||
for i in 0..$dim {
|
for i in 0 .. $dim {
|
||||||
unsafe { self.unsafe_set((i, i), diag.unsafe_at(i)) }
|
unsafe { self.unsafe_set((i, i), diag.unsafe_at(i)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -493,15 +536,14 @@ macro_rules! mat_mul_mat_impl(
|
||||||
type Output = $t<N>;
|
type Output = $t<N>;
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul(self, right: $t<N>) -> $t<N> {
|
fn mul(self, right: $t<N>) -> $t<N> {
|
||||||
// careful! we need to comute other * self here (self is the rhs).
|
|
||||||
let mut res: $t<N> = ::zero();
|
let mut res: $t<N> = ::zero();
|
||||||
|
|
||||||
for i in 0..$dim {
|
for i in 0 .. $dim {
|
||||||
for j in 0..$dim {
|
for j in 0 .. $dim {
|
||||||
let mut acc: N = ::zero();
|
let mut acc: N = ::zero();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
for k in 0..$dim {
|
for k in 0 .. $dim {
|
||||||
acc = acc + self.at_fast((i, k)) * right.at_fast((k, j));
|
acc = acc + self.at_fast((i, k)) * right.at_fast((k, j));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,6 +555,15 @@ macro_rules! mat_mul_mat_impl(
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: Copy + BaseNum> MulAssign<$t<N>> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: $t<N>) {
|
||||||
|
// NOTE: there is probably not any useful optimization to perform here compaired to the
|
||||||
|
// version without assignment..
|
||||||
|
*self = *self * right
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -537,6 +588,15 @@ macro_rules! vec_mul_mat_impl(
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: Copy + BaseNum> MulAssign<$t<N>> for $v<N> {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: $t<N>) {
|
||||||
|
// NOTE: there is probably not any useful optimization to perform here compaired to the
|
||||||
|
// version without assignment..
|
||||||
|
*self = *self * right
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -549,8 +609,8 @@ macro_rules! mat_mul_vec_impl(
|
||||||
fn mul(self, right: $v<N>) -> $v<N> {
|
fn mul(self, right: $v<N>) -> $v<N> {
|
||||||
let mut res : $v<N> = $zero();
|
let mut res : $v<N> = $zero();
|
||||||
|
|
||||||
for i in 0..$dim {
|
for i in 0 .. $dim {
|
||||||
for j in 0..$dim {
|
for j in 0 .. $dim {
|
||||||
unsafe {
|
unsafe {
|
||||||
let val = res.at_fast(i) + self.at_fast((i, j)) * right.at_fast(j);
|
let val = res.at_fast(i) + self.at_fast((i, j)) * right.at_fast(j);
|
||||||
res.set_fast(i, val)
|
res.set_fast(i, val)
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::mem;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::slice::{Iter, IterMut};
|
use std::slice::{Iter, IterMut};
|
||||||
use std::iter::{Iterator, FromIterator, IntoIterator};
|
use std::iter::{Iterator, FromIterator, IntoIterator};
|
||||||
use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut};
|
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
|
||||||
use rand::{Rand, Rng};
|
use rand::{Rand, Rng};
|
||||||
use num::{Zero, One};
|
use num::{Zero, One};
|
||||||
use traits::operations::{ApproxEq, POrd, POrdering, Axpy};
|
use traits::operations::{ApproxEq, POrd, POrdering, Axpy};
|
||||||
|
|
|
@ -41,6 +41,13 @@ macro_rules! pnt_add_vec_impl(
|
||||||
$t::new($(self.$compN + right.$compN),+)
|
$t::new($(self.$compN + right.$compN),+)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: Copy + AddAssign<N>> AddAssign<$tv<N>> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn add_assign(&mut self, right: $tv<N>) {
|
||||||
|
$( self.$compN += right.$compN; )+
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -54,6 +61,13 @@ macro_rules! pnt_sub_vec_impl(
|
||||||
$t::new($(self.$compN - right.$compN),+)
|
$t::new($(self.$compN - right.$compN),+)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: Copy + SubAssign<N>> SubAssign<$tv<N>> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn sub_assign(&mut self, right: $tv<N>) {
|
||||||
|
$( self.$compN -= right.$compN; )+
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::slice::{Iter, IterMut};
|
use std::slice::{Iter, IterMut};
|
||||||
use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut};
|
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
|
||||||
use std::iter::{FromIterator, IntoIterator};
|
use std::iter::{FromIterator, IntoIterator};
|
||||||
use rand::{Rand, Rng};
|
use rand::{Rand, Rng};
|
||||||
use num::{Zero, One};
|
use num::{Zero, One};
|
||||||
|
@ -146,6 +146,14 @@ impl<N> Mul<Quat<N>> for Quat<N>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N> MulAssign<Quat<N>> for Quat<N>
|
||||||
|
where N: Copy + Mul<N, Output = N> + Sub<N, Output = N> + Add<N, Output = N> {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: Quat<N>) {
|
||||||
|
*self = *self * right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<N: ApproxEq<N> + BaseFloat> Div<Quat<N>> for Quat<N> {
|
impl<N: ApproxEq<N> + BaseFloat> Div<Quat<N>> for Quat<N> {
|
||||||
type Output = Quat<N>;
|
type Output = Quat<N>;
|
||||||
|
|
||||||
|
@ -155,6 +163,13 @@ impl<N: ApproxEq<N> + BaseFloat> Div<Quat<N>> for Quat<N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: ApproxEq<N> + BaseFloat> DivAssign<Quat<N>> for Quat<N> {
|
||||||
|
#[inline]
|
||||||
|
fn div_assign(&mut self, right: Quat<N>) {
|
||||||
|
*self *= right.inv().expect("Unable to invert the denominator.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<N: fmt::Display> fmt::Display for Quat<N> {
|
impl<N: fmt::Display> fmt::Display for Quat<N> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "Quaternion {} − ({}, {}, {})", self.w, self.i, self.j, self.k)
|
write!(f, "Quaternion {} − ({}, {}, {})", self.w, self.i, self.j, self.k)
|
||||||
|
@ -336,6 +351,13 @@ impl<N: BaseFloat + ApproxEq<N>> Div<UnitQuat<N>> for UnitQuat<N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: BaseFloat + ApproxEq<N>> DivAssign<UnitQuat<N>> for UnitQuat<N> {
|
||||||
|
#[inline]
|
||||||
|
fn div_assign(&mut self, other: UnitQuat<N>) {
|
||||||
|
self.q /= other.q
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<N: BaseNum> Mul<UnitQuat<N>> for UnitQuat<N> {
|
impl<N: BaseNum> Mul<UnitQuat<N>> for UnitQuat<N> {
|
||||||
type Output = UnitQuat<N>;
|
type Output = UnitQuat<N>;
|
||||||
|
|
||||||
|
@ -345,6 +367,13 @@ impl<N: BaseNum> Mul<UnitQuat<N>> for UnitQuat<N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: BaseNum> MulAssign<UnitQuat<N>> for UnitQuat<N> {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: UnitQuat<N>) {
|
||||||
|
self.q *= right.q
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<N: BaseNum> Mul<Vec3<N>> for UnitQuat<N> {
|
impl<N: BaseNum> Mul<Vec3<N>> for UnitQuat<N> {
|
||||||
type Output = Vec3<N>;
|
type Output = Vec3<N>;
|
||||||
|
|
||||||
|
@ -391,6 +420,20 @@ impl<N: BaseNum + Neg<Output = N>> Mul<UnitQuat<N>> for Pnt3<N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: BaseNum + Neg<Output = N>> MulAssign<UnitQuat<N>> for Vec3<N> {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: UnitQuat<N>) {
|
||||||
|
*self = *self * right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: BaseNum + Neg<Output = N>> MulAssign<UnitQuat<N>> for Pnt3<N> {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: UnitQuat<N>) {
|
||||||
|
*self = *self * right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<N: BaseFloat> Rotation<Vec3<N>> for UnitQuat<N> {
|
impl<N: BaseFloat> Rotation<Vec3<N>> for UnitQuat<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotation(&self) -> Vec3<N> {
|
fn rotation(&self) -> Vec3<N> {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! Rotations matrices.
|
//! Rotations matrices.
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::{Mul, Neg, Index};
|
use std::ops::{Mul, Neg, MulAssign, Index};
|
||||||
use rand::{Rand, Rng};
|
use rand::{Rand, Rng};
|
||||||
use num::{Zero, One};
|
use num::{Zero, One};
|
||||||
use traits::geometry::{Rotate, Rotation, AbsoluteRotate, RotationMatrix, RotationTo, Transform,
|
use traits::geometry::{Rotate, Rotation, AbsoluteRotate, RotationMatrix, RotationTo, Transform,
|
||||||
|
|
|
@ -145,6 +145,13 @@ macro_rules! rot_mul_rot_impl(
|
||||||
$t { submat: self.submat * right.submat }
|
$t { submat: self.submat * right.submat }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: Copy + BaseNum> MulAssign<$t<N>> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: $t<N>) {
|
||||||
|
self.submat *= right.submat
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -177,6 +184,13 @@ macro_rules! vec_mul_rot_impl(
|
||||||
self * right.submat
|
self * right.submat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: Copy + BaseNum> MulAssign<$t<N>> for $tv<N> {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: $t<N>) {
|
||||||
|
*self *= right.submat
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::{Mul, Neg};
|
use std::ops::{Mul, Neg, MulAssign};
|
||||||
|
|
||||||
use rand::{Rand, Rng};
|
use rand::{Rand, Rng};
|
||||||
use num::One;
|
use num::One;
|
||||||
|
|
|
@ -123,6 +123,15 @@ macro_rules! sim_mul_sim_impl(
|
||||||
self.scale * right.scale)
|
self.scale * right.scale)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: BaseFloat> MulAssign<$t<N>> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: $t<N>) {
|
||||||
|
self.isometry.translation += self.isometry.rotation * (right.isometry.translation * self.scale);
|
||||||
|
self.isometry.rotation *= right.isometry.rotation;
|
||||||
|
self.scale *= right.scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -140,6 +149,14 @@ macro_rules! sim_mul_iso_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: BaseFloat> MulAssign<$ti<N>> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: $ti<N>) {
|
||||||
|
self.isometry.translation += self.isometry.rotation * (right.translation * self.scale);
|
||||||
|
self.isometry.rotation *= right.rotation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<N: BaseFloat> Mul<$t<N>> for $ti<N> {
|
impl<N: BaseFloat> Mul<$t<N>> for $ti<N> {
|
||||||
type Output = $t<N>;
|
type Output = $t<N>;
|
||||||
|
|
||||||
|
@ -168,6 +185,13 @@ macro_rules! sim_mul_rot_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: BaseFloat> MulAssign<$tr<N>> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: $tr<N>) {
|
||||||
|
self.isometry.rotation *= right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<N: BaseFloat> Mul<$t<N>> for $tr<N> {
|
impl<N: BaseFloat> Mul<$t<N>> for $tr<N> {
|
||||||
type Output = $t<N>;
|
type Output = $t<N>;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::ops::{Add, Mul, Neg};
|
use std::ops::{Add, Mul, Neg, MulAssign};
|
||||||
use structs::vec::{Vec2, Vec3};
|
use structs::vec::{Vec2, Vec3};
|
||||||
use structs::pnt::{Pnt2, Pnt3};
|
use structs::pnt::{Pnt2, Pnt3};
|
||||||
use structs::mat::{Mat1, Mat2, Mat3};
|
use structs::mat::{Mat1, Mat2, Mat3};
|
||||||
|
@ -345,3 +345,25 @@ impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> Mul<Pnt2<N>> for Mat2<N>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
macro_rules! impl_mul_assign_from_mul(
|
||||||
|
($tleft: ident, $tright: ident) => (
|
||||||
|
impl<N: Copy + Mul<N, Output = N> + Add<N, Output = N>> MulAssign<$tright<N>> for $tleft<N> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn mul_assign(&mut self, right: $tright<N>) {
|
||||||
|
// NOTE: there is probably no interesting optimization compared to the not-inplace
|
||||||
|
// operation.
|
||||||
|
*self = *self * right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
impl_mul_assign_from_mul!(Mat3, Mat3);
|
||||||
|
impl_mul_assign_from_mul!(Mat2, Mat2);
|
||||||
|
|
||||||
|
impl_mul_assign_from_mul!(Vec3, Mat3);
|
||||||
|
impl_mul_assign_from_mul!(Vec2, Mat2);
|
||||||
|
impl_mul_assign_from_mul!(Pnt3, Mat3);
|
||||||
|
impl_mul_assign_from_mul!(Pnt2, Mat2);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! Vectors with dimension known at compile-time.
|
//! Vectors with dimension known at compile-time.
|
||||||
|
|
||||||
use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut};
|
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::slice::{Iter, IterMut};
|
use std::slice::{Iter, IterMut};
|
||||||
use std::iter::{Iterator, FromIterator, IntoIterator};
|
use std::iter::{Iterator, FromIterator, IntoIterator};
|
||||||
|
|
|
@ -372,6 +372,13 @@ macro_rules! add_impl(
|
||||||
$t::new($(self.$compN + right.$compN),+)
|
$t::new($(self.$compN + right.$compN),+)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: AddAssign<N>> AddAssign<$t<N>> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn add_assign(&mut self, right: $t<N>) {
|
||||||
|
$( self.$compN += right.$compN; )+
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -387,6 +394,13 @@ macro_rules! scalar_add_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: Copy + AddAssign<N>> AddAssign<N> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn add_assign(&mut self, right: N) {
|
||||||
|
$( self.$compN += right; )+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Add<$t<f32>> for f32 {
|
impl Add<$t<f32>> for f32 {
|
||||||
type Output = $t<f32>;
|
type Output = $t<f32>;
|
||||||
|
|
||||||
|
@ -417,6 +431,13 @@ macro_rules! sub_impl(
|
||||||
$t::new($(self.$compN - right.$compN),+)
|
$t::new($(self.$compN - right.$compN),+)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: SubAssign<N>> SubAssign<$t<N>> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn sub_assign(&mut self, right: $t<N>) {
|
||||||
|
$( self.$compN -= right.$compN; )+
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -431,6 +452,13 @@ macro_rules! scalar_sub_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: Copy + SubAssign<N>> SubAssign<N> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn sub_assign(&mut self, right: N) {
|
||||||
|
$( self.$compN -= right; )+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Sub<$t<f32>> for f32 {
|
impl Sub<$t<f32>> for f32 {
|
||||||
type Output = $t<f32>;
|
type Output = $t<f32>;
|
||||||
|
|
||||||
|
@ -460,6 +488,13 @@ macro_rules! mul_impl(
|
||||||
$t::new($(self.$compN * right.$compN),+)
|
$t::new($(self.$compN * right.$compN),+)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: MulAssign<N>> MulAssign<$t<N>> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: $t<N>) {
|
||||||
|
$( self.$compN *= right.$compN; )+
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -474,6 +509,13 @@ macro_rules! scalar_mul_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: Copy + MulAssign<N>> MulAssign<N> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: N) {
|
||||||
|
$( self.$compN *= right; )+
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Mul<$t<f32>> for f32 {
|
impl Mul<$t<f32>> for f32 {
|
||||||
type Output = $t<f32>;
|
type Output = $t<f32>;
|
||||||
|
|
||||||
|
@ -504,6 +546,13 @@ macro_rules! div_impl(
|
||||||
$t::new($(self.$compN / right.$compN),+)
|
$t::new($(self.$compN / right.$compN),+)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: DivAssign<N>> DivAssign<$t<N>> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn div_assign(&mut self, right: $t<N>) {
|
||||||
|
$( self.$compN /= right.$compN; )+
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -517,6 +566,13 @@ macro_rules! scalar_div_impl(
|
||||||
$t::new($(self.$compN / right),+)
|
$t::new($(self.$compN / right),+)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: Copy + DivAssign<N>> DivAssign<N> for $t<N> {
|
||||||
|
#[inline]
|
||||||
|
fn div_assign(&mut self, right: N) {
|
||||||
|
$( self.$compN /= right; )+
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::slice::{Iter, IterMut};
|
use std::slice::{Iter, IterMut};
|
||||||
use std::iter::{FromIterator, IntoIterator};
|
use std::iter::{FromIterator, IntoIterator};
|
||||||
use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut};
|
use std::ops::{Add, Sub, Mul, Div, Neg, AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use rand::{Rand, Rng};
|
use rand::{Rand, Rng};
|
||||||
use num::{Zero, One};
|
use num::{Zero, One};
|
||||||
|
|
|
@ -2,6 +2,11 @@
|
||||||
|
|
||||||
macro_rules! vecn_dvec_common_impl(
|
macro_rules! vecn_dvec_common_impl(
|
||||||
($vecn: ident $(, $param: ident)*) => (
|
($vecn: ident $(, $param: ident)*) => (
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Zero.
|
||||||
|
*
|
||||||
|
*/
|
||||||
impl<N: Zero + Copy + Clone $(, $param: ArrayLength<N>)*> $vecn<N $(, $param)*> {
|
impl<N: Zero + Copy + Clone $(, $param: ArrayLength<N>)*> $vecn<N $(, $param)*> {
|
||||||
/// Tests if all components of the vector are zeroes.
|
/// Tests if all components of the vector are zeroes.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -10,6 +15,11 @@ macro_rules! vecn_dvec_common_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* AsRef/AsMut
|
||||||
|
*
|
||||||
|
*/
|
||||||
impl<N $(, $param: ArrayLength<N>)*> AsRef<[N]> for $vecn<N $(, $param)*> {
|
impl<N $(, $param: ArrayLength<N>)*> AsRef<[N]> for $vecn<N $(, $param)*> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_ref(&self) -> &[N] {
|
fn as_ref(&self) -> &[N] {
|
||||||
|
@ -25,6 +35,11 @@ macro_rules! vecn_dvec_common_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Shape.
|
||||||
|
*
|
||||||
|
*/
|
||||||
impl<N $(, $param: ArrayLength<N>)*> Shape<usize> for $vecn<N $(, $param)*> {
|
impl<N $(, $param: ArrayLength<N>)*> Shape<usize> for $vecn<N $(, $param)*> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn shape(&self) -> usize {
|
fn shape(&self) -> usize {
|
||||||
|
@ -32,6 +47,11 @@ macro_rules! vecn_dvec_common_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Index et. al.
|
||||||
|
*
|
||||||
|
*/
|
||||||
impl<N: Copy $(, $param : ArrayLength<N>)*> Indexable<usize, N> for $vecn<N $(, $param)*> {
|
impl<N: Copy $(, $param : ArrayLength<N>)*> Indexable<usize, N> for $vecn<N $(, $param)*> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn swap(&mut self, i: usize, j: usize) {
|
fn swap(&mut self, i: usize, j: usize) {
|
||||||
|
@ -66,6 +86,11 @@ macro_rules! vecn_dvec_common_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Iterable et al.
|
||||||
|
*
|
||||||
|
*/
|
||||||
impl<N $(, $param : ArrayLength<N>)*> Iterable<N> for $vecn<N $(, $param)*> {
|
impl<N $(, $param : ArrayLength<N>)*> Iterable<N> for $vecn<N $(, $param)*> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn iter<'l>(&'l self) -> Iter<'l, N> {
|
fn iter<'l>(&'l self) -> Iter<'l, N> {
|
||||||
|
@ -80,6 +105,11 @@ macro_rules! vecn_dvec_common_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Axpy
|
||||||
|
*
|
||||||
|
*/
|
||||||
impl<N: Copy + Add<N, Output = N> + Mul<N, Output = N> $(, $param : ArrayLength<N>)*>
|
impl<N: Copy + Add<N, Output = N> + Mul<N, Output = N> $(, $param : ArrayLength<N>)*>
|
||||||
Axpy<N> for $vecn<N $(, $param)*> {
|
Axpy<N> for $vecn<N $(, $param)*> {
|
||||||
fn axpy(&mut self, a: &N, x: &$vecn<N $(, $param)*>) {
|
fn axpy(&mut self, a: &N, x: &$vecn<N $(, $param)*>) {
|
||||||
|
@ -94,6 +124,11 @@ macro_rules! vecn_dvec_common_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Mul
|
||||||
|
*
|
||||||
|
*/
|
||||||
impl<N: Copy + Mul<N, Output = N> + Zero $(, $param : ArrayLength<N>)*>
|
impl<N: Copy + Mul<N, Output = N> + Zero $(, $param : ArrayLength<N>)*>
|
||||||
Mul<$vecn<N $(, $param)*>> for $vecn<N $(, $param)*> {
|
Mul<$vecn<N $(, $param)*>> for $vecn<N $(, $param)*> {
|
||||||
type Output = $vecn<N $(, $param)*>;
|
type Output = $vecn<N $(, $param)*>;
|
||||||
|
@ -112,142 +147,6 @@ macro_rules! vecn_dvec_common_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Copy + Div<N, Output = N> + Zero $(, $param : ArrayLength<N>)*>
|
|
||||||
Div<$vecn<N $(, $param)*>> for $vecn<N $(, $param)*> {
|
|
||||||
type Output = $vecn<N $(, $param)*>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn div(self, right: $vecn<N $(, $param)*>) -> $vecn<N $(, $param)*> {
|
|
||||||
assert!(self.len() == right.len());
|
|
||||||
|
|
||||||
let mut res = self;
|
|
||||||
|
|
||||||
for (left, right) in res.as_mut().iter_mut().zip(right.as_ref().iter()) {
|
|
||||||
*left = *left / *right
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N: Copy + Add<N, Output = N> + Zero $(, $param : ArrayLength<N>)*>
|
|
||||||
Add<$vecn<N $(, $param)*>> for $vecn<N $(, $param)*> {
|
|
||||||
type Output = $vecn<N $(, $param)*>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn add(self, right: $vecn<N $(, $param)*>) -> $vecn<N $(, $param)*> {
|
|
||||||
assert!(self.len() == right.len());
|
|
||||||
|
|
||||||
let mut res = self;
|
|
||||||
|
|
||||||
for (left, right) in res.as_mut().iter_mut().zip(right.as_ref().iter()) {
|
|
||||||
*left = *left + *right
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N: Copy + Sub<N, Output = N> + Zero $(, $param : ArrayLength<N>)*>
|
|
||||||
Sub<$vecn<N $(, $param)*>> for $vecn<N $(, $param)*> {
|
|
||||||
type Output = $vecn<N $(, $param)*>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn sub(self, right: $vecn<N $(, $param)*>) -> $vecn<N $(, $param)*> {
|
|
||||||
assert!(self.len() == right.len());
|
|
||||||
|
|
||||||
let mut res = self;
|
|
||||||
|
|
||||||
for (left, right) in res.as_mut().iter_mut().zip(right.as_ref().iter()) {
|
|
||||||
*left = *left - *right
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N: Neg<Output = N> + Zero + Copy $(, $param : ArrayLength<N>)*> Neg for $vecn<N $(, $param)*> {
|
|
||||||
type Output = $vecn<N $(, $param)*>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn neg(mut self) -> $vecn<N $(, $param)*> {
|
|
||||||
for e in self.as_mut().iter_mut() {
|
|
||||||
*e = -*e;
|
|
||||||
}
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N: BaseNum $(, $param : ArrayLength<N>)*> Dot<N> for $vecn<N $(, $param)*> {
|
|
||||||
#[inline]
|
|
||||||
fn dot(&self, other: &$vecn<N $(, $param)*>) -> N {
|
|
||||||
assert!(self.len() == other.len());
|
|
||||||
let mut res: N = ::zero();
|
|
||||||
for i in 0 .. self.len() {
|
|
||||||
res = res + unsafe { self.unsafe_at(i) * other.unsafe_at(i) };
|
|
||||||
}
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N: BaseFloat $(, $param : ArrayLength<N>)*> Norm<N> for $vecn<N $(, $param)*> {
|
|
||||||
#[inline]
|
|
||||||
fn sqnorm(&self) -> N {
|
|
||||||
Dot::dot(self, self)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn normalize(&self) -> $vecn<N $(, $param)*> {
|
|
||||||
let mut res : $vecn<N $(, $param)*> = self.clone();
|
|
||||||
let _ = res.normalize_mut();
|
|
||||||
res
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn normalize_mut(&mut self) -> N {
|
|
||||||
let l = Norm::norm(self);
|
|
||||||
|
|
||||||
for n in self.as_mut().iter_mut() {
|
|
||||||
*n = *n / l;
|
|
||||||
}
|
|
||||||
|
|
||||||
l
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N: BaseFloat + Cast<f64> $(, $param : ArrayLength<N>)*> Mean<N> for $vecn<N $(, $param)*> {
|
|
||||||
#[inline]
|
|
||||||
fn mean(&self) -> N {
|
|
||||||
let normalizer = ::cast(1.0f64 / self.len() as f64);
|
|
||||||
self.iter().fold(::zero(), |acc, x| acc + *x * normalizer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N: ApproxEq<N> $(, $param : ArrayLength<N>)*> ApproxEq<N> for $vecn<N $(, $param)*> {
|
|
||||||
#[inline]
|
|
||||||
fn approx_epsilon(_: Option<$vecn<N $(, $param)*>>) -> N {
|
|
||||||
ApproxEq::approx_epsilon(None::<N>)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_ulps(_: Option<$vecn<N $(, $param)*>>) -> u32 {
|
|
||||||
ApproxEq::approx_ulps(None::<N>)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_eq_eps(&self, other: &$vecn<N $(, $param)*>, epsilon: &N) -> bool {
|
|
||||||
let mut zip = self.as_ref().iter().zip(other.as_ref().iter());
|
|
||||||
zip.all(|(a, b)| ApproxEq::approx_eq_eps(a, b, epsilon))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn approx_eq_ulps(&self, other: &$vecn<N $(, $param)*>, ulps: u32) -> bool {
|
|
||||||
let mut zip = self.as_ref().iter().zip(other.as_ref().iter());
|
|
||||||
zip.all(|(a, b)| ApproxEq::approx_eq_ulps(a, b, ulps))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N: Copy + Mul<N, Output = N> + Zero $(, $param : ArrayLength<N>)*>
|
impl<N: Copy + Mul<N, Output = N> + Zero $(, $param : ArrayLength<N>)*>
|
||||||
Mul<N> for $vecn<N $(, $param)*> {
|
Mul<N> for $vecn<N $(, $param)*> {
|
||||||
type Output = $vecn<N $(, $param)*>;
|
type Output = $vecn<N $(, $param)*>;
|
||||||
|
@ -264,6 +163,28 @@ macro_rules! vecn_dvec_common_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N> MulAssign<$vecn<N $(, $param)*>> for $vecn<N $(, $param)*>
|
||||||
|
where N: Copy + MulAssign<N> + Zero $(, $param : ArrayLength<N>)* {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: $vecn<N $(, $param)*>) {
|
||||||
|
assert!(self.len() == right.len());
|
||||||
|
|
||||||
|
for (left, right) in self.as_mut().iter_mut().zip(right.as_ref().iter()) {
|
||||||
|
*left *= *right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N> MulAssign<N> for $vecn<N $(, $param)*>
|
||||||
|
where N: Copy + MulAssign<N> + Zero $(, $param : ArrayLength<N>)* {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, right: N) {
|
||||||
|
for e in self.as_mut().iter_mut() {
|
||||||
|
*e *= right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<$($param : ArrayLength<N>),*> Mul<$vecn<f32 $(, $param)*>> for f32 {
|
impl<$($param : ArrayLength<N>),*> Mul<$vecn<f32 $(, $param)*>> for f32 {
|
||||||
type Output = $vecn<f32 $(, $param)*>;
|
type Output = $vecn<f32 $(, $param)*>;
|
||||||
|
|
||||||
|
@ -294,6 +215,29 @@ macro_rules! vecn_dvec_common_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Div.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
impl<N: Copy + Div<N, Output = N> + Zero $(, $param : ArrayLength<N>)*>
|
||||||
|
Div<$vecn<N $(, $param)*>> for $vecn<N $(, $param)*> {
|
||||||
|
type Output = $vecn<N $(, $param)*>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn div(self, right: $vecn<N $(, $param)*>) -> $vecn<N $(, $param)*> {
|
||||||
|
assert!(self.len() == right.len());
|
||||||
|
|
||||||
|
let mut res = self;
|
||||||
|
|
||||||
|
for (left, right) in res.as_mut().iter_mut().zip(right.as_ref().iter()) {
|
||||||
|
*left = *left / *right
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<N: Copy + Div<N, Output = N> + Zero $(, $param : ArrayLength<N>)*> Div<N> for $vecn<N $(, $param)*> {
|
impl<N: Copy + Div<N, Output = N> + Zero $(, $param : ArrayLength<N>)*> Div<N> for $vecn<N $(, $param)*> {
|
||||||
type Output = $vecn<N $(, $param)*>;
|
type Output = $vecn<N $(, $param)*>;
|
||||||
|
|
||||||
|
@ -309,6 +253,51 @@ macro_rules! vecn_dvec_common_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N> DivAssign<$vecn<N $(, $param)*>> for $vecn<N $(, $param)*>
|
||||||
|
where N: Copy + DivAssign<N> + Zero $(, $param : ArrayLength<N>)* {
|
||||||
|
#[inline]
|
||||||
|
fn div_assign(&mut self, right: $vecn<N $(, $param)*>) {
|
||||||
|
assert!(self.len() == right.len());
|
||||||
|
|
||||||
|
for (left, right) in self.as_mut().iter_mut().zip(right.as_ref().iter()) {
|
||||||
|
*left /= *right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N> DivAssign<N> for $vecn<N $(, $param)*>
|
||||||
|
where N: Copy + DivAssign<N> + Zero $(, $param : ArrayLength<N>)* {
|
||||||
|
#[inline]
|
||||||
|
fn div_assign(&mut self, right: N) {
|
||||||
|
for e in self.as_mut().iter_mut() {
|
||||||
|
*e /= right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Add.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
impl<N: Copy + Add<N, Output = N> + Zero $(, $param : ArrayLength<N>)*>
|
||||||
|
Add<$vecn<N $(, $param)*>> for $vecn<N $(, $param)*> {
|
||||||
|
type Output = $vecn<N $(, $param)*>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn add(self, right: $vecn<N $(, $param)*>) -> $vecn<N $(, $param)*> {
|
||||||
|
assert!(self.len() == right.len());
|
||||||
|
|
||||||
|
let mut res = self;
|
||||||
|
|
||||||
|
for (left, right) in res.as_mut().iter_mut().zip(right.as_ref().iter()) {
|
||||||
|
*left = *left + *right
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<N: Copy + Add<N, Output = N> + Zero $(, $param : ArrayLength<N>)*> Add<N> for $vecn<N $(, $param)*> {
|
impl<N: Copy + Add<N, Output = N> + Zero $(, $param : ArrayLength<N>)*> Add<N> for $vecn<N $(, $param)*> {
|
||||||
type Output = $vecn<N $(, $param)*>;
|
type Output = $vecn<N $(, $param)*>;
|
||||||
|
|
||||||
|
@ -324,6 +313,28 @@ macro_rules! vecn_dvec_common_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N> AddAssign<$vecn<N $(, $param)*>> for $vecn<N $(, $param)*>
|
||||||
|
where N: Copy + AddAssign<N> + Zero $(, $param : ArrayLength<N>)* {
|
||||||
|
#[inline]
|
||||||
|
fn add_assign(&mut self, right: $vecn<N $(, $param)*>) {
|
||||||
|
assert!(self.len() == right.len());
|
||||||
|
|
||||||
|
for (left, right) in self.as_mut().iter_mut().zip(right.as_ref().iter()) {
|
||||||
|
*left += *right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N> AddAssign<N> for $vecn<N $(, $param)*>
|
||||||
|
where N: Copy + AddAssign<N> + Zero $(, $param : ArrayLength<N>)* {
|
||||||
|
#[inline]
|
||||||
|
fn add_assign(&mut self, right: N) {
|
||||||
|
for e in self.as_mut().iter_mut() {
|
||||||
|
*e += right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<$($param : ArrayLength<f32>),*> Add<$vecn<f32 $(, $param)*>> for f32 {
|
impl<$($param : ArrayLength<f32>),*> Add<$vecn<f32 $(, $param)*>> for f32 {
|
||||||
type Output = $vecn<f32 $(, $param)*>;
|
type Output = $vecn<f32 $(, $param)*>;
|
||||||
|
|
||||||
|
@ -354,6 +365,29 @@ macro_rules! vecn_dvec_common_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Sub.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
impl<N: Copy + Sub<N, Output = N> + Zero $(, $param : ArrayLength<N>)*>
|
||||||
|
Sub<$vecn<N $(, $param)*>> for $vecn<N $(, $param)*> {
|
||||||
|
type Output = $vecn<N $(, $param)*>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, right: $vecn<N $(, $param)*>) -> $vecn<N $(, $param)*> {
|
||||||
|
assert!(self.len() == right.len());
|
||||||
|
|
||||||
|
let mut res = self;
|
||||||
|
|
||||||
|
for (left, right) in res.as_mut().iter_mut().zip(right.as_ref().iter()) {
|
||||||
|
*left = *left - *right
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<N: Copy + Sub<N, Output = N> + Zero $(, $param : ArrayLength<N>)*> Sub<N> for $vecn<N $(, $param)*> {
|
impl<N: Copy + Sub<N, Output = N> + Zero $(, $param : ArrayLength<N>)*> Sub<N> for $vecn<N $(, $param)*> {
|
||||||
type Output = $vecn<N $(, $param)*>;
|
type Output = $vecn<N $(, $param)*>;
|
||||||
|
|
||||||
|
@ -369,6 +403,28 @@ macro_rules! vecn_dvec_common_impl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N> SubAssign<$vecn<N $(, $param)*>> for $vecn<N $(, $param)*>
|
||||||
|
where N: Copy + SubAssign<N> + Zero $(, $param : ArrayLength<N>)* {
|
||||||
|
#[inline]
|
||||||
|
fn sub_assign(&mut self, right: $vecn<N $(, $param)*>) {
|
||||||
|
assert!(self.len() == right.len());
|
||||||
|
|
||||||
|
for (left, right) in self.as_mut().iter_mut().zip(right.as_ref().iter()) {
|
||||||
|
*left -= *right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N> SubAssign<N> for $vecn<N $(, $param)*>
|
||||||
|
where N: Copy + SubAssign<N> + Zero $(, $param : ArrayLength<N>)* {
|
||||||
|
#[inline]
|
||||||
|
fn sub_assign(&mut self, right: N) {
|
||||||
|
for e in self.as_mut().iter_mut() {
|
||||||
|
*e -= right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<$($param : ArrayLength<f32>),*> Sub<$vecn<f32 $(, $param)*>> for f32 {
|
impl<$($param : ArrayLength<f32>),*> Sub<$vecn<f32 $(, $param)*>> for f32 {
|
||||||
type Output = $vecn<f32 $(, $param)*>;
|
type Output = $vecn<f32 $(, $param)*>;
|
||||||
|
|
||||||
|
@ -398,5 +454,112 @@ macro_rules! vecn_dvec_common_impl(
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Neg.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
impl<N: Neg<Output = N> + Zero + Copy $(, $param : ArrayLength<N>)*> Neg for $vecn<N $(, $param)*> {
|
||||||
|
type Output = $vecn<N $(, $param)*>;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn neg(mut self) -> $vecn<N $(, $param)*> {
|
||||||
|
for e in self.as_mut().iter_mut() {
|
||||||
|
*e = -*e;
|
||||||
|
}
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Dot.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
impl<N: BaseNum $(, $param : ArrayLength<N>)*> Dot<N> for $vecn<N $(, $param)*> {
|
||||||
|
#[inline]
|
||||||
|
fn dot(&self, other: &$vecn<N $(, $param)*>) -> N {
|
||||||
|
assert!(self.len() == other.len());
|
||||||
|
let mut res: N = ::zero();
|
||||||
|
for i in 0 .. self.len() {
|
||||||
|
res = res + unsafe { self.unsafe_at(i) * other.unsafe_at(i) };
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Norm.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
impl<N: BaseFloat $(, $param : ArrayLength<N>)*> Norm<N> for $vecn<N $(, $param)*> {
|
||||||
|
#[inline]
|
||||||
|
fn sqnorm(&self) -> N {
|
||||||
|
Dot::dot(self, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn normalize(&self) -> $vecn<N $(, $param)*> {
|
||||||
|
let mut res : $vecn<N $(, $param)*> = self.clone();
|
||||||
|
let _ = res.normalize_mut();
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn normalize_mut(&mut self) -> N {
|
||||||
|
let l = Norm::norm(self);
|
||||||
|
|
||||||
|
for n in self.as_mut().iter_mut() {
|
||||||
|
*n = *n / l;
|
||||||
|
}
|
||||||
|
|
||||||
|
l
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Mean.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
impl<N: BaseFloat + Cast<f64> $(, $param : ArrayLength<N>)*> Mean<N> for $vecn<N $(, $param)*> {
|
||||||
|
#[inline]
|
||||||
|
fn mean(&self) -> N {
|
||||||
|
let normalizer = ::cast(1.0f64 / self.len() as f64);
|
||||||
|
self.iter().fold(::zero(), |acc, x| acc + *x * normalizer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* ApproxEq
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
impl<N: ApproxEq<N> $(, $param : ArrayLength<N>)*> ApproxEq<N> for $vecn<N $(, $param)*> {
|
||||||
|
#[inline]
|
||||||
|
fn approx_epsilon(_: Option<$vecn<N $(, $param)*>>) -> N {
|
||||||
|
ApproxEq::approx_epsilon(None::<N>)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn approx_ulps(_: Option<$vecn<N $(, $param)*>>) -> u32 {
|
||||||
|
ApproxEq::approx_ulps(None::<N>)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn approx_eq_eps(&self, other: &$vecn<N $(, $param)*>, epsilon: &N) -> bool {
|
||||||
|
let mut zip = self.as_ref().iter().zip(other.as_ref().iter());
|
||||||
|
zip.all(|(a, b)| ApproxEq::approx_eq_eps(a, b, epsilon))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn approx_eq_ulps(&self, other: &$vecn<N $(, $param)*>, ulps: u32) -> bool {
|
||||||
|
let mut zip = self.as_ref().iter().zip(other.as_ref().iter());
|
||||||
|
zip.all(|(a, b)| ApproxEq::approx_eq_ulps(a, b, ulps))
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
use std::{f32, f64, i8, i16, i32, i64, u8, u16, u32, u64, isize, usize};
|
use std::{f32, f64, i8, i16, i32, i64, u8, u16, u32, u64, isize, usize};
|
||||||
use std::slice::{Iter, IterMut};
|
use std::slice::{Iter, IterMut};
|
||||||
use std::ops::{Add, Sub, Mul, Div, Rem, Index, IndexMut, Neg};
|
use std::ops::{Add, Sub, Mul, Div, Rem,
|
||||||
|
AddAssign, SubAssign, MulAssign, DivAssign, RemAssign,
|
||||||
|
Index, IndexMut, Neg};
|
||||||
use num::{Float, Zero, One};
|
use num::{Float, Zero, One};
|
||||||
use traits::operations::{Axpy, Transpose, Inv, Absolute};
|
use traits::operations::{Axpy, Transpose, Inv, Absolute};
|
||||||
use traits::geometry::{Dot, Norm, Orig};
|
use traits::geometry::{Dot, Norm, Orig};
|
||||||
|
@ -11,8 +13,11 @@ use traits::geometry::{Dot, Norm, Orig};
|
||||||
pub trait BaseNum: Copy + Zero + One +
|
pub trait BaseNum: Copy + Zero + One +
|
||||||
Add<Self, Output = Self> + Sub<Self, Output = Self> +
|
Add<Self, Output = Self> + Sub<Self, Output = Self> +
|
||||||
Mul<Self, Output = Self> + Div<Self, Output = Self> +
|
Mul<Self, Output = Self> + Div<Self, Output = Self> +
|
||||||
Rem<Self, Output = Self> + PartialEq +
|
Rem<Self, Output = Self> +
|
||||||
Absolute<Self> + Axpy<Self> {
|
AddAssign<Self> + SubAssign<Self> +
|
||||||
|
MulAssign<Self> + DivAssign<Self> +
|
||||||
|
RemAssign<Self> +
|
||||||
|
PartialEq + Absolute<Self> + Axpy<Self> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Basic floating-point number numeric trait.
|
/// Basic floating-point number numeric trait.
|
||||||
|
@ -221,10 +226,19 @@ pub trait IterableMut<N> {
|
||||||
* Vec related traits.
|
* Vec related traits.
|
||||||
*/
|
*/
|
||||||
/// Trait grouping most common operations on vectors.
|
/// Trait grouping most common operations on vectors.
|
||||||
pub trait NumVec<N>: Dim +
|
pub trait NumVec<N>: Add<Self, Output = Self> + Sub<Self, Output = Self> +
|
||||||
Sub<Self, Output = Self> + Add<Self, Output = Self> +
|
Mul<Self, Output = Self> + Div<Self, Output = Self> +
|
||||||
|
|
||||||
|
Add<N, Output = Self> + Sub<N, Output = Self> +
|
||||||
Mul<N, Output = Self> + Div<N, Output = Self> +
|
Mul<N, Output = Self> + Div<N, Output = Self> +
|
||||||
Index<usize, Output = N> +
|
|
||||||
|
AddAssign<Self> + SubAssign<Self> +
|
||||||
|
MulAssign<Self> + DivAssign<Self> +
|
||||||
|
|
||||||
|
AddAssign<N> + SubAssign<N> +
|
||||||
|
MulAssign<N> + DivAssign<N> +
|
||||||
|
|
||||||
|
Dim + Index<usize, Output = N> +
|
||||||
Zero + PartialEq + Dot<N> + Axpy<N> {
|
Zero + PartialEq + Dot<N> + Axpy<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,9 +277,13 @@ pub trait NumPnt<N>:
|
||||||
PartialEq +
|
PartialEq +
|
||||||
Axpy<N> +
|
Axpy<N> +
|
||||||
Sub<Self, Output = <Self as PntAsVec>::Vec> +
|
Sub<Self, Output = <Self as PntAsVec>::Vec> +
|
||||||
Mul<N, Output = Self> +
|
|
||||||
Div<N, Output = Self> +
|
Mul<N, Output = Self> + Div<N, Output = Self> +
|
||||||
Add<<Self as PntAsVec>::Vec, Output = Self> +
|
Add<<Self as PntAsVec>::Vec, Output = Self> +
|
||||||
|
|
||||||
|
MulAssign<N> + DivAssign<N> +
|
||||||
|
AddAssign<<Self as PntAsVec>::Vec> +
|
||||||
|
|
||||||
Index<usize, Output = N> { // FIXME: + Sub<V, Self>
|
Index<usize, Output = N> { // FIXME: + Sub<V, Self>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
extern crate nalgebra as na;
|
||||||
|
extern crate rand;
|
||||||
|
|
||||||
|
use std::ops::{Mul, Div, Add, Sub, MulAssign, DivAssign, AddAssign, SubAssign};
|
||||||
|
use rand::random;
|
||||||
|
use na::{Pnt3, Vec3, Mat3, Rot3, Iso3, Sim3, Quat, UnitQuat};
|
||||||
|
|
||||||
|
// NOTE: we test only the 3D version because the others share the same code anyway.
|
||||||
|
|
||||||
|
macro_rules! test_op_vs_op_assign(
|
||||||
|
($name: ident, $t1: ty, $t2: ty, $op: ident, $op_assign: ident) => (
|
||||||
|
#[test]
|
||||||
|
fn $name() {
|
||||||
|
for _ in 0usize .. 10000 {
|
||||||
|
let rand1 = random::<$t1>();
|
||||||
|
let rand2 = random::<$t2>();
|
||||||
|
let mut res = rand1;
|
||||||
|
|
||||||
|
res.$op_assign(rand2);
|
||||||
|
|
||||||
|
assert_eq!(rand1.$op(rand2), res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Multiplication.
|
||||||
|
test_op_vs_op_assign!(test_vec3_f32_mul_assign, Vec3<f32>, f32, mul, mul_assign);
|
||||||
|
test_op_vs_op_assign!(test_mat3_f32_mul_assign, Mat3<f32>, f32, mul, mul_assign);
|
||||||
|
test_op_vs_op_assign!(test_quat_f32_mul_assign, Quat<f32>, f32, mul, mul_assign);
|
||||||
|
|
||||||
|
test_op_vs_op_assign!(test_vec3_vec3_mul_assign, Vec3<f32>, Vec3<f32>, mul, mul_assign);
|
||||||
|
test_op_vs_op_assign!(test_quat_quat_mul_assign, Quat<f32>, Quat<f32>, mul, mul_assign);
|
||||||
|
test_op_vs_op_assign!(test_unit_quat_unit_quat_mul_assign, UnitQuat<f32>, UnitQuat<f32>, mul, mul_assign);
|
||||||
|
|
||||||
|
test_op_vs_op_assign!(test_vec3_unit_quat_mul_assign, Vec3<f32>, UnitQuat<f32>, mul, mul_assign);
|
||||||
|
test_op_vs_op_assign!(test_pnt3_unit_quat_mul_assign, Pnt3<f32>, UnitQuat<f32>, mul, mul_assign);
|
||||||
|
|
||||||
|
test_op_vs_op_assign!(test_mat3_mat3_mul_assign, Mat3<f32>, Mat3<f32>, mul, mul_assign);
|
||||||
|
test_op_vs_op_assign!(test_vec3_mat3_mul_assign, Vec3<f32>, Mat3<f32>, mul, mul_assign);
|
||||||
|
test_op_vs_op_assign!(test_pnt3_mat3_mul_assign, Pnt3<f32>, Mat3<f32>, mul, mul_assign);
|
||||||
|
|
||||||
|
test_op_vs_op_assign!(test_rot3_rot3_mul_assign, Rot3<f32>, Rot3<f32>, mul, mul_assign);
|
||||||
|
test_op_vs_op_assign!(test_vec3_rot3_mul_assign, Vec3<f32>, Rot3<f32>, mul, mul_assign);
|
||||||
|
test_op_vs_op_assign!(test_pnt3_rot3_mul_assign, Pnt3<f32>, Rot3<f32>, mul, mul_assign);
|
||||||
|
|
||||||
|
test_op_vs_op_assign!(test_iso3_iso3_mul_assign, Iso3<f32>, Iso3<f32>, mul, mul_assign);
|
||||||
|
test_op_vs_op_assign!(test_iso3_rot3_mul_assign, Iso3<f32>, Rot3<f32>, mul, mul_assign);
|
||||||
|
|
||||||
|
test_op_vs_op_assign!(test_sim3_sim3_mul_assign, Sim3<f32>, Sim3<f32>, mul, mul_assign);
|
||||||
|
test_op_vs_op_assign!(test_sim3_iso3_mul_assign, Sim3<f32>, Iso3<f32>, mul, mul_assign);
|
||||||
|
test_op_vs_op_assign!(test_sim3_rot3_mul_assign, Sim3<f32>, Rot3<f32>, mul, mul_assign);
|
||||||
|
|
||||||
|
// Division.
|
||||||
|
test_op_vs_op_assign!(test_vec3_vec3_div_assign, Vec3<f32>, Vec3<f32>, div, div_assign);
|
||||||
|
test_op_vs_op_assign!(test_quat_quat_div_assign, Quat<f32>, Quat<f32>, div, div_assign);
|
||||||
|
test_op_vs_op_assign!(test_unit_quat_unit_quat_div_assign, UnitQuat<f32>, UnitQuat<f32>, div, div_assign);
|
||||||
|
|
||||||
|
test_op_vs_op_assign!(test_vec3_f32_div_assign, Vec3<f32>, f32, div, div_assign);
|
||||||
|
test_op_vs_op_assign!(test_mat3_f32_div_assign, Mat3<f32>, f32, div, div_assign);
|
||||||
|
|
||||||
|
// Addition.
|
||||||
|
test_op_vs_op_assign!(test_vec3_vec3_add_assign, Vec3<f32>, Vec3<f32>, add, add_assign);
|
||||||
|
test_op_vs_op_assign!(test_mat3_mat3_add_assign, Mat3<f32>, Mat3<f32>, add, add_assign);
|
||||||
|
test_op_vs_op_assign!(test_quat_quat_add_assign, Quat<f32>, Quat<f32>, add, add_assign);
|
||||||
|
|
||||||
|
test_op_vs_op_assign!(test_vec3_f32_add_assign, Vec3<f32>, f32, add, add_assign);
|
||||||
|
test_op_vs_op_assign!(test_mat3_f32_add_assign, Mat3<f32>, f32, add, add_assign);
|
||||||
|
|
||||||
|
// Subtraction.
|
||||||
|
test_op_vs_op_assign!(test_vec3_vec3_sub_assign, Vec3<f32>, Vec3<f32>, sub, sub_assign);
|
||||||
|
test_op_vs_op_assign!(test_mat3_mat3_sub_assign, Mat3<f32>, Mat3<f32>, sub, sub_assign);
|
||||||
|
test_op_vs_op_assign!(test_quat_quat_sub_assign, Quat<f32>, Quat<f32>, sub, sub_assign);
|
||||||
|
|
||||||
|
test_op_vs_op_assign!(test_vec3_f32_sub_assign, Vec3<f32>, f32, sub, sub_assign);
|
||||||
|
test_op_vs_op_assign!(test_mat3_f32_sub_assign, Mat3<f32>, f32, sub, sub_assign);
|
Loading…
Reference in New Issue