diff --git a/examples/helloworld.rs b/examples/helloworld.rs index 6ed726019..356d3986c 100644 --- a/examples/helloworld.rs +++ b/examples/helloworld.rs @@ -42,12 +42,12 @@ fn main() { println!("a + b"); print(&test); // Index array using sequences - let seqs = &[Seq::new(1.0, 3.0, 1.0), Seq::default()]; + let seqs = &[Seq::new(1u32, 3, 1), Seq::default()]; let sub = index(&a, seqs).unwrap(); println!("a(seq(1,3,1), span)"); print(&sub); //Index array using array and sequence - let seq4gen = Seq::new(0.0, 2.0, 1.0); + let seq4gen = Seq::new(0u32, 2, 1); let mut idxrs = match Indexer::new() { Ok(v) => v, diff --git a/src/index.rs b/src/index.rs index c782b32a2..2aca11327 100644 --- a/src/index.rs +++ b/src/index.rs @@ -3,7 +3,7 @@ extern crate libc; use array::Array; use defines::AfError; use seq::Seq; -use self::libc::{c_int, c_uint, c_longlong}; +use self::libc::{c_double, c_int, c_uint}; type MutAfIndex = *mut self::libc::c_longlong; type MutAfArray = *mut self::libc::c_longlong; @@ -15,12 +15,12 @@ type IndexT = self::libc::c_longlong; extern { fn af_create_indexers(indexers: MutAfIndex) -> c_int; fn af_set_array_indexer(indexer: MutAfIndex, idx: AfArray, dim: DimT) -> c_int; - fn af_set_seq_indexer(indexer: MutAfIndex, idx: *const Seq, dim: DimT, is_batch: c_int) -> c_int; + fn af_set_seq_indexer(indexer: MutAfIndex, idx: *const SeqInternal, dim: DimT, is_batch: c_int) -> c_int; fn af_release_indexers(indexers: MutAfIndex) -> c_int; - fn af_index(out: MutAfArray, input: AfArray, ndims: c_uint, index: *const Seq) -> c_int; + fn af_index(out: MutAfArray, input: AfArray, ndims: c_uint, index: *const SeqInternal) -> c_int; fn af_lookup(out: MutAfArray, arr: AfArray, indices: AfArray, dim: c_uint) -> c_int; - fn af_assign_seq(out: MutAfArray, lhs: AfArray, ndims: c_uint, indices: *const Seq, rhs: AfArray) -> c_int; + fn af_assign_seq(out: MutAfArray, lhs: AfArray, ndims: c_uint, indices: *const SeqInternal, rhs: AfArray) -> c_int; fn af_index_gen(out: MutAfArray, input: AfArray, ndims: DimT, indices: *const IndexT) -> c_int; fn af_assign_gen(out: MutAfArray, lhs: AfArray, ndims: DimT, indices: *const IndexT, rhs: AfArray) -> c_int; } @@ -62,11 +62,12 @@ impl Indexable for Array { /// /// This is used in functions [index_gen](./fn.index_gen.html) and /// [assign_gen](./fn.assign_gen.html) -impl Indexable for Seq { +impl Indexable for Seq where c_double: From { fn set(&self, idxr: &Indexer, dim: u32, is_batch: Option) -> Result<(), AfError> { unsafe { - let err_val = af_set_seq_indexer(idxr.clone().get() as MutAfIndex, self as *const Seq, - dim as DimT, is_batch.unwrap() as c_int); + let err_val = af_set_seq_indexer(idxr.clone().get() as MutAfIndex, + &SeqInternal::from_seq(self) as *const SeqInternal, + dim as DimT, is_batch.unwrap() as c_int); match err_val { 0 => Ok(()), _ => Err(AfError::from(err_val)), @@ -130,12 +131,16 @@ impl Drop for Indexer { /// println!("a(seq(1, 3, 1), span)"); /// print(&sub); /// ``` -pub fn index(input: &Array, seqs: &[Seq]) -> Result { +pub fn index(input: &Array, seqs: &[Seq]) -> Result + where c_double: From +{ unsafe { let mut temp: i64 = 0; + // TODO: allocating a whole new array on the heap just for this is BAD + let seqs: Vec = seqs.iter().map(|s| SeqInternal::from_seq(s)).collect(); let err_val = af_index(&mut temp as MutAfArray , input.get() as AfArray, seqs.len() as u32 - , seqs.as_ptr() as *const Seq); + , seqs.as_ptr() as *const SeqInternal); match err_val { 0 => Ok(Array::from(temp)), _ => Err(AfError::from(err_val)), @@ -155,8 +160,8 @@ pub fn index(input: &Array, seqs: &[Seq]) -> Result { /// ``` #[allow(dead_code)] pub fn row(input: &Array, row_num: u64) -> Result { - index(input, &[Seq::new(row_num as f64, row_num as f64, 1.0) - , Seq::default()]) + index(input, &[Seq::new(row_num as f64, row_num as f64, 1.0), + Seq::default()]) } #[allow(dead_code)] @@ -300,11 +305,15 @@ pub fn lookup(input: &Array, indices: &Array, seq_dim: i32) -> Result Result { +pub fn assign_seq(lhs: &Array, seqs: &[Seq], rhs: &Array) -> Result + where c_double: From +{ unsafe{ let mut temp: i64 = 0; + // TODO: allocating a whole new array on the heap just for this is BAD + let seqs: Vec = seqs.iter().map(|s| SeqInternal::from_seq(s)).collect(); let err_val = af_assign_seq(&mut temp as MutAfArray, lhs.get() as AfArray, - seqs.len() as c_uint, seqs.as_ptr() as *const Seq, + seqs.len() as c_uint, seqs.as_ptr() as *const SeqInternal, rhs.get() as AfArray); match err_val { 0 => Ok(Array::from(temp)), @@ -402,3 +411,20 @@ pub fn assign_gen(lhs: &Array, indices: &Indexer, rhs: &Array) -> Result(s: &Seq) -> Self where c_double: From { + SeqInternal { + begin: From::from(s.begin()), + end: From::from(s.end()), + step: From::from(s.step()), + } + } +} diff --git a/src/lib.rs b/src/lib.rs index a09af0e1c..09d7a5b1e 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,6 +71,7 @@ mod image; pub use lapack::{svd, lu, qr, cholesky, solve, solve_lu, inverse, det, rank, norm}; pub use lapack::{svd_inplace, lu_inplace, qr_inplace, cholesky_inplace}; mod lapack; +mod num; pub use signal::{approx1, approx2}; pub use signal::{fft, fft2, fft3, ifft, ifft2, ifft3}; diff --git a/src/num.rs b/src/num.rs new file mode 100644 index 000000000..d5858d486 --- /dev/null +++ b/src/num.rs @@ -0,0 +1,46 @@ +pub trait Zero { + fn zero() -> Self; +} + +pub trait One { + fn one() -> Self; +} + +macro_rules! zero_impl { + ( $t:ident, $z:expr ) => ( + impl Zero for $t { fn zero() -> Self { $z } } + ) +} + +zero_impl!(u8, 0); +zero_impl!(u16, 0); +zero_impl!(u32, 0); +zero_impl!(u64, 0); +zero_impl!(usize, 0); +zero_impl!(i8, 0); +zero_impl!(i16, 0); +zero_impl!(i32, 0); +zero_impl!(i64, 0); +zero_impl!(isize, 0); +zero_impl!(f32, 0.0); +zero_impl!(f64, 0.0); + + +macro_rules! one_impl { + ( $t:ident, $o:expr ) => ( + impl One for $t { fn one() -> Self { $o } } + ) +} + +one_impl!(u8, 1); +one_impl!(u16, 1); +one_impl!(u32, 1); +one_impl!(u64, 1); +one_impl!(usize, 1); +one_impl!(i8, 1); +one_impl!(i16, 1); +one_impl!(i32, 1); +one_impl!(i64, 1); +one_impl!(isize, 1); +one_impl!(f32, 1.0); +one_impl!(f64, 1.0); diff --git a/src/seq.rs b/src/seq.rs index ae0a43b96..a56410362 100644 --- a/src/seq.rs +++ b/src/seq.rs @@ -2,49 +2,50 @@ extern crate libc; use std::fmt; use std::default::Default; -use self::libc::{c_double}; + +use num::{One, Zero}; /// Sequences are used for indexing Arrays #[derive(Copy, Clone)] #[repr(C)] -pub struct Seq { - begin: c_double, - end: c_double, - step: c_double, +pub struct Seq { + begin: T, + end: T, + step: T, } /// Default `Seq` spans all the elements along a dimension -impl Default for Seq { - fn default() -> Seq { - Seq { begin: 1.0, end: 1.0, step: 0.0, } +impl Default for Seq { + fn default() -> Self { + Seq { begin: One::one(), end: One::one(), step: Zero::zero() } } } /// Enables use of `Seq` with `{}` format in print statements -impl fmt::Display for Seq { +impl fmt::Display for Seq { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "[begin: {}, end: {}, step: {}]", self.begin, self.end, self.step) } } -impl Seq { +impl Seq { /// Create a `Seq` that goes from `begin` to `end` at a step size of `step` - pub fn new(begin: f64, end: f64, step: f64) -> Seq { + pub fn new(begin: T, end: T, step: T) -> Self { Seq { begin: begin, end: end, step: step, } } /// Get begin index of Seq - pub fn begin(&self) -> f64 { - self.begin as f64 + pub fn begin(&self) -> T { + self.begin } /// Get begin index of Seq - pub fn end(&self) -> f64 { - self.end as f64 + pub fn end(&self) -> T { + self.end } /// Get step size of Seq - pub fn step(&self) -> f64 { - self.step as f64 + pub fn step(&self) -> T { + self.step } }