Skip to content

Commit b40c7db

Browse files
committed
Merge pull request #57 from tedsta/devel
Make Seq generic
2 parents 86fc951 + 70fcd0f commit b40c7db

File tree

5 files changed

+106
-32
lines changed

5 files changed

+106
-32
lines changed

examples/helloworld.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ fn main() {
4242
println!("a + b"); print(&test);
4343

4444
// Index array using sequences
45-
let seqs = &[Seq::new(1.0, 3.0, 1.0), Seq::default()];
45+
let seqs = &[Seq::new(1u32, 3, 1), Seq::default()];
4646
let sub = index(&a, seqs).unwrap();
4747
println!("a(seq(1,3,1), span)"); print(&sub);
4848

4949
//Index array using array and sequence
50-
let seq4gen = Seq::new(0.0, 2.0, 1.0);
50+
let seq4gen = Seq::new(0u32, 2, 1);
5151

5252
let mut idxrs = match Indexer::new() {
5353
Ok(v) => v,

src/index.rs

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ extern crate libc;
33
use array::Array;
44
use defines::AfError;
55
use seq::Seq;
6-
use self::libc::{c_int, c_uint, c_longlong};
6+
use self::libc::{c_double, c_int, c_uint};
77

88
type MutAfIndex = *mut self::libc::c_longlong;
99
type MutAfArray = *mut self::libc::c_longlong;
@@ -15,12 +15,12 @@ type IndexT = self::libc::c_longlong;
1515
extern {
1616
fn af_create_indexers(indexers: MutAfIndex) -> c_int;
1717
fn af_set_array_indexer(indexer: MutAfIndex, idx: AfArray, dim: DimT) -> c_int;
18-
fn af_set_seq_indexer(indexer: MutAfIndex, idx: *const Seq, dim: DimT, is_batch: c_int) -> c_int;
18+
fn af_set_seq_indexer(indexer: MutAfIndex, idx: *const SeqInternal, dim: DimT, is_batch: c_int) -> c_int;
1919
fn af_release_indexers(indexers: MutAfIndex) -> c_int;
2020

21-
fn af_index(out: MutAfArray, input: AfArray, ndims: c_uint, index: *const Seq) -> c_int;
21+
fn af_index(out: MutAfArray, input: AfArray, ndims: c_uint, index: *const SeqInternal) -> c_int;
2222
fn af_lookup(out: MutAfArray, arr: AfArray, indices: AfArray, dim: c_uint) -> c_int;
23-
fn af_assign_seq(out: MutAfArray, lhs: AfArray, ndims: c_uint, indices: *const Seq, rhs: AfArray) -> c_int;
23+
fn af_assign_seq(out: MutAfArray, lhs: AfArray, ndims: c_uint, indices: *const SeqInternal, rhs: AfArray) -> c_int;
2424
fn af_index_gen(out: MutAfArray, input: AfArray, ndims: DimT, indices: *const IndexT) -> c_int;
2525
fn af_assign_gen(out: MutAfArray, lhs: AfArray, ndims: DimT, indices: *const IndexT, rhs: AfArray) -> c_int;
2626
}
@@ -62,11 +62,12 @@ impl Indexable for Array {
6262
///
6363
/// This is used in functions [index_gen](./fn.index_gen.html) and
6464
/// [assign_gen](./fn.assign_gen.html)
65-
impl Indexable for Seq {
65+
impl<T: Copy> Indexable for Seq<T> where c_double: From<T> {
6666
fn set(&self, idxr: &Indexer, dim: u32, is_batch: Option<bool>) -> Result<(), AfError> {
6767
unsafe {
68-
let err_val = af_set_seq_indexer(idxr.clone().get() as MutAfIndex, self as *const Seq,
69-
dim as DimT, is_batch.unwrap() as c_int);
68+
let err_val = af_set_seq_indexer(idxr.clone().get() as MutAfIndex,
69+
&SeqInternal::from_seq(self) as *const SeqInternal,
70+
dim as DimT, is_batch.unwrap() as c_int);
7071
match err_val {
7172
0 => Ok(()),
7273
_ => Err(AfError::from(err_val)),
@@ -130,12 +131,16 @@ impl Drop for Indexer {
130131
/// println!("a(seq(1, 3, 1), span)");
131132
/// print(&sub);
132133
/// ```
133-
pub fn index(input: &Array, seqs: &[Seq]) -> Result<Array, AfError> {
134+
pub fn index<T: Copy>(input: &Array, seqs: &[Seq<T>]) -> Result<Array, AfError>
135+
where c_double: From<T>
136+
{
134137
unsafe {
135138
let mut temp: i64 = 0;
139+
// TODO: allocating a whole new array on the heap just for this is BAD
140+
let seqs: Vec<SeqInternal> = seqs.iter().map(|s| SeqInternal::from_seq(s)).collect();
136141
let err_val = af_index(&mut temp as MutAfArray
137142
, input.get() as AfArray, seqs.len() as u32
138-
, seqs.as_ptr() as *const Seq);
143+
, seqs.as_ptr() as *const SeqInternal);
139144
match err_val {
140145
0 => Ok(Array::from(temp)),
141146
_ => Err(AfError::from(err_val)),
@@ -155,8 +160,8 @@ pub fn index(input: &Array, seqs: &[Seq]) -> Result<Array, AfError> {
155160
/// ```
156161
#[allow(dead_code)]
157162
pub fn row(input: &Array, row_num: u64) -> Result<Array, AfError> {
158-
index(input, &[Seq::new(row_num as f64, row_num as f64, 1.0)
159-
, Seq::default()])
163+
index(input, &[Seq::new(row_num as f64, row_num as f64, 1.0),
164+
Seq::default()])
160165
}
161166

162167
#[allow(dead_code)]
@@ -300,11 +305,15 @@ pub fn lookup(input: &Array, indices: &Array, seq_dim: i32) -> Result<Array, AfE
300305
/// // 1.0 1.0 1.0
301306
/// // 2.0 2.0 2.0
302307
/// ```
303-
pub fn assign_seq(lhs: &Array, seqs: &[Seq], rhs: &Array) -> Result<Array, AfError> {
308+
pub fn assign_seq<T: Copy>(lhs: &Array, seqs: &[Seq<T>], rhs: &Array) -> Result<Array, AfError>
309+
where c_double: From<T>
310+
{
304311
unsafe{
305312
let mut temp: i64 = 0;
313+
// TODO: allocating a whole new array on the heap just for this is BAD
314+
let seqs: Vec<SeqInternal> = seqs.iter().map(|s| SeqInternal::from_seq(s)).collect();
306315
let err_val = af_assign_seq(&mut temp as MutAfArray, lhs.get() as AfArray,
307-
seqs.len() as c_uint, seqs.as_ptr() as *const Seq,
316+
seqs.len() as c_uint, seqs.as_ptr() as *const SeqInternal,
308317
rhs.get() as AfArray);
309318
match err_val {
310319
0 => Ok(Array::from(temp)),
@@ -402,3 +411,20 @@ pub fn assign_gen(lhs: &Array, indices: &Indexer, rhs: &Array) -> Result<Array,
402411
}
403412
}
404413
}
414+
415+
#[repr(C)]
416+
struct SeqInternal {
417+
begin: c_double,
418+
end: c_double,
419+
step: c_double,
420+
}
421+
422+
impl SeqInternal {
423+
fn from_seq<T: Copy>(s: &Seq<T>) -> Self where c_double: From<T> {
424+
SeqInternal {
425+
begin: From::from(s.begin()),
426+
end: From::from(s.end()),
427+
step: From::from(s.step()),
428+
}
429+
}
430+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ mod image;
7171
pub use lapack::{svd, lu, qr, cholesky, solve, solve_lu, inverse, det, rank, norm};
7272
pub use lapack::{svd_inplace, lu_inplace, qr_inplace, cholesky_inplace};
7373
mod lapack;
74+
mod num;
7475

7576
pub use signal::{approx1, approx2};
7677
pub use signal::{fft, fft2, fft3, ifft, ifft2, ifft3};

src/num.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
pub trait Zero {
2+
fn zero() -> Self;
3+
}
4+
5+
pub trait One {
6+
fn one() -> Self;
7+
}
8+
9+
macro_rules! zero_impl {
10+
( $t:ident, $z:expr ) => (
11+
impl Zero for $t { fn zero() -> Self { $z } }
12+
)
13+
}
14+
15+
zero_impl!(u8, 0);
16+
zero_impl!(u16, 0);
17+
zero_impl!(u32, 0);
18+
zero_impl!(u64, 0);
19+
zero_impl!(usize, 0);
20+
zero_impl!(i8, 0);
21+
zero_impl!(i16, 0);
22+
zero_impl!(i32, 0);
23+
zero_impl!(i64, 0);
24+
zero_impl!(isize, 0);
25+
zero_impl!(f32, 0.0);
26+
zero_impl!(f64, 0.0);
27+
28+
29+
macro_rules! one_impl {
30+
( $t:ident, $o:expr ) => (
31+
impl One for $t { fn one() -> Self { $o } }
32+
)
33+
}
34+
35+
one_impl!(u8, 1);
36+
one_impl!(u16, 1);
37+
one_impl!(u32, 1);
38+
one_impl!(u64, 1);
39+
one_impl!(usize, 1);
40+
one_impl!(i8, 1);
41+
one_impl!(i16, 1);
42+
one_impl!(i32, 1);
43+
one_impl!(i64, 1);
44+
one_impl!(isize, 1);
45+
one_impl!(f32, 1.0);
46+
one_impl!(f64, 1.0);

src/seq.rs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,50 @@ extern crate libc;
22

33
use std::fmt;
44
use std::default::Default;
5-
use self::libc::{c_double};
5+
6+
use num::{One, Zero};
67

78
/// Sequences are used for indexing Arrays
89
#[derive(Copy, Clone)]
910
#[repr(C)]
10-
pub struct Seq {
11-
begin: c_double,
12-
end: c_double,
13-
step: c_double,
11+
pub struct Seq<T> {
12+
begin: T,
13+
end: T,
14+
step: T,
1415
}
1516

1617
/// Default `Seq` spans all the elements along a dimension
17-
impl Default for Seq {
18-
fn default() -> Seq {
19-
Seq { begin: 1.0, end: 1.0, step: 0.0, }
18+
impl<T: One+Zero> Default for Seq<T> {
19+
fn default() -> Self {
20+
Seq { begin: One::one(), end: One::one(), step: Zero::zero() }
2021
}
2122
}
2223

2324
/// Enables use of `Seq` with `{}` format in print statements
24-
impl fmt::Display for Seq {
25+
impl<T: fmt::Display> fmt::Display for Seq<T> {
2526
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2627
write!(f, "[begin: {}, end: {}, step: {}]", self.begin, self.end, self.step)
2728
}
2829
}
2930

30-
impl Seq {
31+
impl<T: Copy> Seq<T> {
3132
/// Create a `Seq` that goes from `begin` to `end` at a step size of `step`
32-
pub fn new(begin: f64, end: f64, step: f64) -> Seq {
33+
pub fn new(begin: T, end: T, step: T) -> Self {
3334
Seq { begin: begin, end: end, step: step, }
3435
}
3536

3637
/// Get begin index of Seq
37-
pub fn begin(&self) -> f64 {
38-
self.begin as f64
38+
pub fn begin(&self) -> T {
39+
self.begin
3940
}
4041

4142
/// Get begin index of Seq
42-
pub fn end(&self) -> f64 {
43-
self.end as f64
43+
pub fn end(&self) -> T {
44+
self.end
4445
}
4546

4647
/// Get step size of Seq
47-
pub fn step(&self) -> f64 {
48-
self.step as f64
48+
pub fn step(&self) -> T {
49+
self.step
4950
}
5051
}

0 commit comments

Comments
 (0)