Skip to content

Commit 7d75e62

Browse files
committed
New macro, equation, to help modify Array using Seq and/or Array
This macro provides some syntactic sugar hiding the logic that involves creationg of Indexer object and then setting the indexing objects for interested axes for a given Array. Updated indexing tutorial in mdbook with examples using macros also.
1 parent e5fa22c commit 7d75e62

File tree

2 files changed

+156
-27
lines changed

2 files changed

+156
-27
lines changed

src/core/macros.rs

Lines changed: 139 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,6 @@ macro_rules! view {
204204
$(
205205
seq_vec.push($crate::seq!($start:$end:$step));
206206
)*
207-
for _span_place_holder in seq_vec.len()..AF_MAX_DIMS {
208-
seq_vec.push($crate::seq!());
209-
}
210207
$crate::index(&$array_ident, &seq_vec)
211208
}
212209
};
@@ -223,26 +220,76 @@ macro_rules! view {
223220
};
224221
($array_ident:ident [ $($_e:expr),+ ]) => {
225222
{
226-
#[allow(non_snake_case)]
227-
let AF_MAX_DIMS: u32 = view!(@af_max_dims);
228-
let span = $crate::seq!();
229223
let mut idxrs = $crate::Indexer::default();
230-
231224
view!(@set_indexer 0, idxrs, $($_e),*);
225+
$crate::index_gen(&$array_ident, idxrs)
226+
}
227+
};
228+
}
232229

233-
let mut dim_ix = idxrs.len() as u32;
234-
while dim_ix < AF_MAX_DIMS {
235-
idxrs.set_index(&span, dim_ix, None);
236-
dim_ix += 1;
230+
/// This macro is syntactic sugar for modifying portions of Array with another Array using a
231+
/// combination of [Sequences][1] and/or [Array][2] objects.
232+
///
233+
/// Examples on how to use this macro are provided in the [tutorials book][3]
234+
///
235+
/// [1]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Seq.html
236+
/// [2]: http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html
237+
/// [3]: http://arrayfire.org/arrayfire-rust/book/indexing.html
238+
#[macro_export]
239+
macro_rules! equation {
240+
( $l:ident [ $($lb:literal : $le:literal : $ls:literal),+ ] =
241+
$r:ident [ $($rb:literal : $re:literal : $rs:literal),+ ]) => {
242+
{
243+
#[allow(non_snake_case)]
244+
let AF_MAX_DIMS: usize = view!(@af_max_dims);
245+
let mut seq_vec = Vec::<$crate::Seq<i32>>::with_capacity(AF_MAX_DIMS);
246+
$(
247+
seq_vec.push($crate::seq!($lb:$le:$ls));
248+
)*
249+
let mut idxrs = $crate::Indexer::default();
250+
for i in 0..seq_vec.len() {
251+
idxrs.set_index(&seq_vec[i], i as u32, None);
237252
}
238-
$crate::index_gen(&$array_ident, idxrs)
253+
let eq_rterm = $crate::view!($r[ $($rb:$re:$rs),+ ]);
254+
$crate::assign_gen(&mut $l, &idxrs, &eq_rterm);
255+
}
256+
};
257+
( $l:ident [ $($lb:literal : $le:literal : $ls:literal),+ ] = $r:expr ) => {
258+
{
259+
#[allow(non_snake_case)]
260+
let AF_MAX_DIMS: usize = view!(@af_max_dims);
261+
let mut seq_vec = Vec::<$crate::Seq<i32>>::with_capacity(AF_MAX_DIMS);
262+
$(
263+
seq_vec.push($crate::seq!($lb:$le:$ls));
264+
)*
265+
let mut idxrs = $crate::Indexer::default();
266+
for i in 0..seq_vec.len() {
267+
idxrs.set_index(&seq_vec[i], i as u32, None);
268+
}
269+
$crate::assign_gen(&mut $l, &idxrs, &$r);
270+
}
271+
};
272+
($lhs:ident [ $($lhs_e:expr),+ ] = $rhs:ident [ $($rhs_e:expr),+ ]) => {
273+
{
274+
let eq_rterm = $crate::view!($rhs[ $($rhs_e),+ ]);
275+
let mut idxrs = $crate::Indexer::default();
276+
view!(@set_indexer 0, idxrs, $($lhs_e),*);
277+
$crate::assign_gen(&mut $lhs, &idxrs, &eq_rterm);
278+
}
279+
};
280+
($lhs:ident [ $($lhs_e:expr),+ ] = $rhs:expr) => {
281+
{
282+
let mut idxrs = $crate::Indexer::default();
283+
view!(@set_indexer 0, idxrs, $($lhs_e),*);
284+
$crate::assign_gen(&mut $lhs, &idxrs, &$rhs);
239285
}
240286
};
241287
}
242288

243289
#[cfg(test)]
244290
mod tests {
245291
use super::super::array::Array;
292+
use super::super::data::constant;
246293
use super::super::index::index;
247294
use super::super::random::randu;
248295

@@ -272,9 +319,15 @@ mod tests {
272319

273320
let a = randu::<f32>(dim4d);
274321
let seqs = &[seq!(1:3:1), seq!()];
275-
let sub = index(&a, seqs);
276-
af_print!("A", a);
277-
af_print!("Indexed A", sub);
322+
let _sub = index(&a, seqs);
323+
}
324+
325+
#[test]
326+
fn seq_view2() {
327+
// ANCHOR: seq_view2
328+
let a = randu::<f32>(dim4!(5, 5));
329+
let _sub = view!(a[1:3:1, 1:1:0]); // 1:1:0 means all elements along axis
330+
// ANCHOR_END: seq_view2
278331
}
279332

280333
#[test]
@@ -286,25 +339,86 @@ mod tests {
286339
let d = a.clone();
287340
let e = a.clone();
288341

289-
let v = view!(a);
290-
af_print!("v = a[None]", v);
342+
let _v = view!(a);
291343

292-
let m = view!(c[1:3:1, 1:3:2]);
293-
af_print!("m = c[:, :]", m);
344+
let _m = view!(c[1:3:1, 1:3:2]);
294345

295346
let x = seq!(1:3:1);
296347
let y = seq!(1:3:2);
297-
let u = view!(b[x, y]);
298-
af_print!("u = b[seq(), seq()]", u);
348+
let _u = view!(b[x, y]);
299349

300350
let values: [u32; 3] = [1, 2, 3];
301351
let indices = Array::new(&values, dim4!(3, 1, 1, 1));
302352
let indices2 = Array::new(&values, dim4!(3, 1, 1, 1));
303353

304-
let w = view!(d[indices, indices2]);
305-
af_print!("w = d[Array, Array]", w);
354+
let _w = view!(d[indices, indices2]);
355+
356+
let _z = view!(e[indices, y]);
357+
}
358+
359+
#[test]
360+
fn equation_macro1() {
361+
let dims = dim4!(5, 5);
362+
let mut a = randu::<f32>(dims);
363+
//print(&a);
364+
//[5 5 1 1]
365+
// 0.6010 0.5497 0.1583 0.3636 0.6755
366+
// 0.0278 0.2864 0.3712 0.4165 0.6105
367+
// 0.9806 0.3410 0.3543 0.5814 0.5232
368+
// 0.2126 0.7509 0.6450 0.8962 0.5567
369+
// 0.0655 0.4105 0.9675 0.3712 0.7896
370+
371+
let b = randu::<f32>(dims);
372+
//print(&b);
373+
//[5 5 1 1]
374+
// 0.8966 0.5143 0.0123 0.7917 0.2522
375+
// 0.0536 0.3670 0.3988 0.1654 0.9644
376+
// 0.5775 0.3336 0.9787 0.8657 0.4711
377+
// 0.2908 0.0363 0.2308 0.3766 0.3637
378+
// 0.9941 0.5349 0.6244 0.7331 0.9643
379+
380+
let d0 = seq!(1:2:1);
381+
let d1 = seq!(1:2:1);
382+
let s0 = seq!(1:2:1);
383+
let s1 = seq!(1:2:1);
384+
equation!(a[d0, d1] = b[s0, s1]);
385+
//print(&a);
386+
//[5 5 1 1]
387+
// 0.6010 0.5497 0.1583 0.3636 0.6755
388+
// 0.0278 0.3670 0.3988 0.4165 0.6105
389+
// 0.9806 0.3336 0.9787 0.5814 0.5232
390+
// 0.2126 0.7509 0.6450 0.8962 0.5567
391+
// 0.0655 0.4105 0.9675 0.3712 0.7896
392+
}
393+
394+
#[test]
395+
fn equation_macro2() {
396+
let dims = dim4!(5, 5);
397+
let mut a = randu::<f32>(dims);
398+
let b = randu::<f32>(dims);
399+
equation!(a[1:2:1, 1:2:1] = b[1:2:1, 1:2:1]);
400+
}
401+
402+
#[test]
403+
fn equation_macro3() {
404+
// ANCHOR: macro_seq_assign
405+
let mut a = randu::<f32>(dim4!(5, 5));
406+
let b = randu::<f32>(dim4!(2, 2));
407+
equation!(a[1:2:1, 1:2:1] = b);
408+
// ANCHOR_END: macro_seq_assign
409+
}
410+
411+
#[test]
412+
fn macro_seq_array_assign() {
413+
// ANCHOR: macro_seq_array_assign
414+
let values: [f32; 3] = [1.0, 2.0, 3.0];
415+
let indices = Array::new(&values, dim4!(3));
416+
let seq4gen = seq!(0:2:1);
417+
let mut a = randu::<f32>(dim4!(5, 3));
418+
419+
let b = constant(2.0 as f32, dim4!(3, 3));
306420

307-
let z = view!(e[indices, y]);
308-
af_print!("z = e[Array, Seq]", z);
421+
equation!(a[indices, seq4gen] = b);
422+
// ANCHOR_END: macro_seq_array_assign
309423
}
310424
}

tutorials-book/src/indexing.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,15 @@ We will Sequences and the function [index][3] in this approach.
1818
{{#include ../../src/core/index.rs:non_macro_seq_index}}
1919
```
2020
However, the same above code can be condensed into a much terse syntax with the help of [view][11]
21-
macro. Take a look at the above code modified to use view macro.
21+
macro. Take a look at the following two approaches using view macro.
2222
```rust, noplaypen
2323
{{#include ../../src/core/index.rs:seq_index}}
2424
```
25+
<div style="text-align: center"> OR </div>
26+
27+
```rust, noplaypen
28+
{{#include ../../src/core/macros.rs:seq_view2}}
29+
```
2530

2631
### Modify a sub region of an existing Array
2732

@@ -32,6 +37,11 @@ Array. We will an constant value Array and the function [assign\_seq][4] in the
3237
{{#include ../../src/core/index.rs:non_macro_seq_assign}}
3338
```
3439

40+
A much terser way of doing the same using macro is shown below
41+
```rust,noplaypen
42+
{{#include ../../src/core/macros.rs:macro_seq_assign}}
43+
```
44+
3545
> **NOTE** Normally you want to avoid accessing individual elements of the array like this for performance reasons.
3646
3747
## Using Array and Seq combination
@@ -44,7 +54,7 @@ generalized function [index\_gen][12].
4454
```rust,noplaypen
4555
{{#include ../../src/core/index.rs:non_macro_seq_array_index}}
4656
```
47-
Similar to how, [view][11] macro helped with abreviating the syntax when indexing with just
57+
Similar to how [view][11] macro helped with abreviating the syntax when indexing with just
4858
sequences, it can also help when using a combination of Seq and Array.
4959
```rust, noplaypen
5060
{{#include ../../src/core/index.rs:seq_array_index}}
@@ -58,6 +68,11 @@ We will use [assign\_gen][13] function to do it.
5868
```rust,noplaypen
5969
{{#include ../../src/core/index.rs:non_macro_seq_array_assign}}
6070
```
71+
<div style="text-align: center"> OR </div>
72+
73+
```rust,noplaypen
74+
{{#include ../../src/core/macros.rs:macro_seq_array_assign}}
75+
```
6176

6277
## Extract or Set rows/coloumns of an Array
6378

0 commit comments

Comments
 (0)