Created
June 17, 2014 23:22
-
-
Save Thiez/df2072140f5483ff9105 to your computer and use it in GitHub Desktop.
Peano Matrix Madness
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![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