Add basic operations.

This commit is contained in:
Sébastien Crozet 2013-05-14 11:35:01 +00:00
parent 8ecd37ebc8
commit 8b18310c3c
9 changed files with 375 additions and 0 deletions

7
Makefile Normal file
View File

@ -0,0 +1,7 @@
all:
rustpkg install
doc:
rust doc src/nalgebra.rc --output-dir doc
.PHONY:doc

3
pkg.rs Normal file
View File

@ -0,0 +1,3 @@
#[pkg(id = "re.crozet.nalgebra", vers = "0.0.0")];
#[pkg_crate(file = "src/nalgebra.rc")];

99
src/dim2/mat2.rs Normal file
View File

@ -0,0 +1,99 @@
use core::num::{One, Zero};
use traits::inv::Inv;
use dim2::vec2::Vec2;
pub struct Mat2<T>
{
m11: T, m12: T,
m21: T, m22: T
}
pub fn Mat2<T:Copy>(m11: T, m12: T, m21: T, m22: T) -> Mat2<T>
{
Mat2
{
m11: m11, m12: m12,
m21: m21, m22: m22,
}
}
impl<T:Copy + One + Zero> One for Mat2<T>
{
fn one() -> Mat2<T>
{
let (_0, _1) = (Zero::zero(), One::one());
return Mat2(_1, _0,
_0, _1)
}
}
impl<T:Copy + Zero> Zero for Mat2<T>
{
fn zero() -> Mat2<T>
{
let _0 = Zero::zero();
return Mat2(_0, _0,
_0, _0)
}
// fn is_zero(&self) -> bool
// {
// self.m11.is_zero() && self.m11.is_zero() && self.m12.is_zero()
// && self.m21.is_zero() && self.m21.is_zero() && self.m22.is_zero()
// }
}
impl<T:Copy + Mul<T, T> + Add<T, T>> Mul<Mat2<T>, Mat2<T>> for Mat2<T>
{
fn mul(&self, other : &Mat2<T>) -> Mat2<T>
{
Mat2
(self.m11 * other.m11 + self.m12 * other.m21,
self.m11 * other.m12 + self.m12 * other.m22,
self.m21 * other.m11 + self.m22 * other.m21,
self.m21 * other.m22 + self.m22 * other.m22)
}
}
// FIXME: implementation of multiple classes for the same struct fails
// with "internal compiler error: Asked to compute kind of a type variable".
//
// impl<T:Copy + Mul<T, T> + Add<T, T>> Mul<Vec2<T>, Vec2<T>> for Mat2<T>
// {
// fn mul(&self, v : &Vec2<T>) -> Vec2<T>
// { Vec2(self.m11 * v.x + self.m12 * v.y, self.m21 * v.x + self.m22 * v.y) }
// }
impl<T:Copy + Mul<T, T> + Add<T, T>> Mul<Mat2<T>, Vec2<T>> for Vec2<T>
{
fn mul(&self, m : &Mat2<T>) -> Vec2<T>
{ Vec2(self.x * m.m11 + self.y * m.m21, self.x * m.m12 + self.y * m.m22) }
}
impl<T:Copy + Mul<T, T> + Div<T, T> + Sub<T, T> + Neg<T> + Eq + Zero>
Inv<T> for Mat2<T>
{
fn inv(&self) -> Mat2<T>
{
let det = self.m11 * self.m22 - self.m21 * self.m12;
assert!(det != Zero::zero());
Mat2(self.m22 / det , -self.m12 / det,
-self.m21 / det, self.m11 / det)
}
}
impl<T:ToStr> ToStr for Mat2<T>
{
fn to_str(&self) -> ~str
{
~"Mat2 {"
+ " m11: " + self.m11.to_str()
+ " m12: " + self.m12.to_str()
+ " m21: " + self.m21.to_str()
+ " m22: " + self.m22.to_str()
+ " }"
}
}

43
src/dim2/vec2.rs Normal file
View File

@ -0,0 +1,43 @@
use traits::dot::Dot;
use traits::sqrt::Sqrt;
#[deriving(Eq)]
pub struct Vec2<T>
{
x : T,
y : T
}
pub fn Vec2<T:Copy>(x: T, y: T) -> Vec2<T>
{ Vec2 {x: x, y: y} }
impl<T:Copy + Add<T,T>> Add<Vec2<T>, Vec2<T>> for Vec2<T>
{
fn add(&self, other: &Vec2<T>) -> Vec2<T>
{ Vec2(self.x + other.x, self.y + other.y) }
}
impl<T:Copy + Sub<T,T>> Sub<Vec2<T>, Vec2<T>> for Vec2<T>
{
fn sub(&self, other: &Vec2<T>) -> Vec2<T>
{ Vec2(self.x - other.x, self.y - other.y) }
}
impl<T:Copy + Mul<T, T> + Add<T, T> + Sqrt> Dot<T> for Vec2<T>
{
fn dot(&self, other : &Vec2<T>) -> T
{ self.x * other.x + self.y * other.y }
fn sqnorm(&self) -> T
{ self.dot(self) }
fn norm(&self) -> T
{ self.sqnorm().sqrt() }
}
impl<T:ToStr> ToStr for Vec2<T>
{
fn to_str(&self) -> ~str
{ ~"Vec2 { x : " + self.x.to_str() + ", y : " + self.y.to_str() + " }" }
}

146
src/dim3/mat3.rs Normal file
View File

@ -0,0 +1,146 @@
use core::num::{One, Zero};
use traits::inv::Inv;
use dim3::vec3::Vec3;
pub struct Mat3<T>
{
m11: T, m12: T, m13: T,
m21: T, m22: T, m23: T,
m31: T, m32: T, m33: T
}
pub fn Mat3<T:Copy>(m11: T, m12: T, m13: T,
m21: T, m22: T, m23: T,
m31: T, m32: T, m33: T) -> Mat3<T>
{
Mat3
{
m11: m11, m12: m12, m13: m13,
m21: m21, m22: m22, m23: m23,
m31: m31, m32: m32, m33: m33
}
}
impl<T:Copy + One + Zero> One for Mat3<T>
{
fn one() -> Mat3<T>
{
let (_0, _1) = (Zero::zero(), One::one());
return Mat3(_1, _0, _0,
_0, _1, _0,
_0, _0, _1)
}
}
impl<T:Copy + Zero> Zero for Mat3<T>
{
fn zero() -> Mat3<T>
{
let _0 = Zero::zero();
return Mat3(_0, _0, _0,
_0, _0, _0,
_0, _0, _0)
}
// fn is_zero(&self) -> bool
// {
// self.m11.is_zero() && self.m12.is_zero() && self.m13.is_zero()
// && self.m21.is_zero() && self.m22.is_zero() && self.m23.is_zero()
// && self.m31.is_zero() && self.m32.is_zero() && self.m33.is_zero()
// }
}
impl<T:Copy + Mul<T, T> + Add<T, T>> Mul<Mat3<T>, Mat3<T>> for Mat3<T>
{
fn mul(&self, other : &Mat3<T>) -> Mat3<T>
{
Mat3(
self.m11 * other.m11 + self.m12 * other.m21 + self.m13 * other.m31,
self.m11 * other.m12 + self.m12 * other.m22 + self.m13 * other.m32,
self.m11 * other.m13 + self.m12 * other.m23 + self.m13 * other.m33,
self.m21 * other.m11 + self.m22 * other.m21 + self.m23 * other.m31,
self.m21 * other.m12 + self.m22 * other.m22 + self.m23 * other.m32,
self.m21 * other.m13 + self.m22 * other.m23 + self.m23 * other.m33,
self.m31 * other.m11 + self.m32 * other.m21 + self.m33 * other.m31,
self.m31 * other.m12 + self.m32 * other.m22 + self.m33 * other.m32,
self.m31 * other.m13 + self.m32 * other.m23 + self.m33 * other.m33
)
}
}
// FIXME: implementation of multiple classes for the same struct fails
// with "internal compiler error: Asked to compute kind of a type variable".
//
// impl<T:Copy + Mul<T, T> + Add<T, T>> Mul<Vec3<T>, Vec3<T>> for Mat3<T>
// {
// fn mul(&self, m : &Mat3<T>) -> Vec3<T>
// {
// Vec3(self.x * m.m11 + self.y * m.m21 + self.z * m.m31,
// self.x * m.m12 + self.y * m.m22 + self.z * m.m32,
// self.x * m.m13 + self.y * m.m23 + self.z * m.m33)
// }
// }
impl<T:Copy + Mul<T, T> + Add<T, T>> Mul<Mat3<T>, Vec3<T>> for Vec3<T>
{
fn mul(&self, m : &Mat3<T>) -> Vec3<T>
{
Vec3(self.x * m.m11 + self.y * m.m21 + self.z * m.m31,
self.x * m.m12 + self.y * m.m22 + self.z * m.m32,
self.x * m.m13 + self.y * m.m23 + self.z * m.m33)
}
}
impl<T:Copy + Mul<T, T> + Div<T, T> + Sub<T, T> + Add<T, T> + Neg<T>
+ Eq + Zero>
Inv<T> for Mat3<T>
{
fn inv(&self) -> Mat3<T>
{
let minor_m22_m33 = self.m22 * self.m33 - self.m32 * self.m23;
let minor_m21_m33 = self.m21 * self.m33 - self.m31 * self.m23;
let minor_m21_m32 = self.m21 * self.m32 - self.m31 * self.m22;
let det = self.m11 * minor_m22_m33
- self.m12 * minor_m21_m33
+ self.m13 * minor_m21_m32;
assert!(det != Zero::zero());
Mat3(
(minor_m22_m33 / det),
((self.m13 * self.m32 - self.m33 * self.m12) / det),
((self.m12 * self.m23 - self.m22 * self.m13) / det),
(-minor_m21_m33 / det),
((self.m11 * self.m33 - self.m31 * self.m13) / det),
((self.m13 * self.m21 - self.m23 * self.m11) / det),
(minor_m21_m32 / det),
((self.m12 * self.m31 - self.m31 * self.m11) / det),
((self.m11 * self.m22 - self.m21 * self.m12) / det)
)
}
}
impl<T:ToStr> ToStr for Mat3<T>
{
fn to_str(&self) -> ~str
{
~"Mat3 {"
+ " m11: " + self.m11.to_str()
+ " m12: " + self.m12.to_str()
+ " m13: " + self.m13.to_str()
+ " m21: " + self.m21.to_str()
+ " m22: " + self.m22.to_str()
+ " m23: " + self.m23.to_str()
+ " m31: " + self.m31.to_str()
+ " m32: " + self.m32.to_str()
+ " m33: " + self.m33.to_str()
+ " }"
}
}

50
src/dim3/vec3.rs Normal file
View File

@ -0,0 +1,50 @@
use traits::dot::Dot;
use traits::sqrt::Sqrt;
#[deriving(Eq)]
pub struct Vec3<T>
{
x : T,
y : T,
z : T
}
pub fn Vec3<T:Copy>(x: T, y: T, z: T) -> Vec3<T>
{ Vec3 {x: x, y: y, z: z} }
impl<T:Copy + Add<T,T>> Add<Vec3<T>, Vec3<T>> for Vec3<T>
{
fn add(&self, other: &Vec3<T>) -> Vec3<T>
{ Vec3(self.x + other.x, self.y + other.y, self.z + other.z) }
}
impl<T:Copy + Sub<T,T>> Sub<Vec3<T>, Vec3<T>> for Vec3<T>
{
fn sub(&self, other: &Vec3<T>) -> Vec3<T>
{ Vec3(self.x - other.x, self.y - other.y, self.z - other.z) }
}
impl<T:ToStr> ToStr for Vec3<T>
{
fn to_str(&self) -> ~str
{
~"Vec3 "
+ "{ x : " + self.x.to_str()
+ ", y : " + self.y.to_str()
+ ", z : " + self.z.to_str()
+ " }"
}
}
impl<T:Copy + Mul<T, T> + Add<T, T> + Sqrt> Dot<T> for Vec3<T>
{
fn dot(&self, other : &Vec3<T>) -> T
{ self.x * other.x + self.y * other.y + self.z * other.z }
fn sqnorm(&self) -> T
{ self.dot(self) }
fn norm(&self) -> T
{ self.sqnorm().sqrt() }
}

6
src/traits/dot.rs Normal file
View File

@ -0,0 +1,6 @@
pub trait Dot<T>
{
fn dot(&self, &Self) -> T;
fn norm(&self) -> T;
fn sqnorm(&self) -> T; // { self.dot(self); }
}

4
src/traits/inv.rs Normal file
View File

@ -0,0 +1,4 @@
pub trait Inv<T>
{
fn inv(&self) -> Self;
}

17
src/traits/sqrt.rs Normal file
View File

@ -0,0 +1,17 @@
// FIXME: this does not seem to exist already
// but it will surely be added someday.
pub trait Sqrt
{
fn sqrt(&self) -> Self;
}
impl Sqrt for f64
{
fn sqrt(&self) -> f64 { f64::sqrt(*self) }
}
impl Sqrt for f32
{
fn sqrt(&self) -> f32 { f32::sqrt(*self) }
}