Skip to content

Instantly share code, notes, and snippets.

@Thiez
Created June 17, 2014 23:22
Show Gist options
  • Save Thiez/df2072140f5483ff9105 to your computer and use it in GitHub Desktop.
Save Thiez/df2072140f5483ff9105 to your computer and use it in GitHub Desktop.
Peano Matrix Madness
#![feature(asm, globs, macro_rules, phase, simd, struct_variant, quad_precision_float)]
extern crate collections;
extern crate native;
use std::num::{zero,Zero};
#[deriving(PartialEq,Eq)]
struct PeanoOne;
#[deriving(PartialEq,Eq)]
struct Succ<T>(T);
trait AsUint {
fn as_uint(_: Option<Self>) -> uint;
}
impl AsUint for PeanoOne {
fn as_uint(_: Option<PeanoOne>) -> uint { 1 }
}
impl<T: AsUint> AsUint for Succ<T> {
fn as_uint(_: Option<Succ<T>>) -> uint {
let opt: Option<T> = None;
1 + AsUint::as_uint(opt)
}
}
struct Matrix<T,R,C> {
data: Vec<T>,
}
fn dims<R:AsUint,C:AsUint>() -> (uint,uint) {
(AsUint::as_uint(None::<R>),AsUint::as_uint(None::<C>))
}
impl<T,R:AsUint,C:AsUint> Matrix<T,R,C> {
fn get<'a>(&'a self, row: uint, col: uint) -> &'a T {
let (mRow,mCol) = dims::<R,C>();
if row >= mRow || col >= mCol {
fail!("Index out of bounds.");
}
self.data.get( row + mRow * col )
}
fn get_mut<'a>(&'a mut self, row: uint, col: uint) -> &'a mut T {
let (mRow,mCol) = dims::<R,C>();
if row >= mRow || col >= mCol {
fail!("Index out of bounds.");
}
self.data.get_mut( row + mRow * col )
}
fn from_fn(op: |(uint,uint)| -> T) -> Matrix<T,R,C> {
let (mRow,mCol) = dims::<R,C>();
let f: |uint|->T = |n|op((n % mRow, n / mCol));
let v = Vec::from_fn(mRow * mCol, f);
Matrix{data: v}
}
}
impl<U,V,T:Add<U,V>,R:AsUint,C:AsUint> Add<Matrix<U,R,C>,Matrix<V,R,C>> for Matrix<T,R,C> {
fn add(&self, rhs: &Matrix<U,R,C>) -> Matrix<V,R,C> {
let res = self.data.iter().zip(rhs.data.iter()).map(|(a,b)|a.add(b)).collect();
Matrix{data:res}
}
}
impl<T:Zero,R:AsUint,C:AsUint> Matrix<T,R,C> {
fn zero() -> Matrix<T,R,C> {
Matrix::from_fn(|_|zero())
}
}
impl<U,V:Zero+Add<V,V>,T:Mul<U,V>,R1:AsUint,CR:AsUint,C2:AsUint> Mul<Matrix<U,CR,C2>,Matrix<V,R1,C2>> for Matrix<T,R1,CR> {
fn mul(&self, rhs: &Matrix<U,CR,C2>) -> Matrix<V,R1,C2> {
let (mCol,mRow) = dims::<R1,C2>();
let (share,_) = dims::<C2,C2>();
let mut res = Matrix::<V,R1,C2>::zero();
for i in range(0,mCol) {
for j in range(0,mRow) {
let pos = res.get_mut(i,j);
for k in range(0,share) {
*pos = pos.add(&(self.get(i,k).mul(rhs.get(k,j))));
}
}
}
res
}
}
fn main() {
let r = {
let m: Matrix<int,Succ<Succ<PeanoOne>>,Succ<PeanoOne>> = Matrix::zero();
let n: Matrix<int,Succ<PeanoOne>,PeanoOne> = Matrix::zero();
let _ = m * n;
*m.get(0,0)
};
println!("{}", r)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment