Skip to content

Commit e5fa22c

Browse files
committed
Update indexing tutorials to latest API
Also moved all unit tests for indexing API into core/index module. Indexing tutorial page now includes the code from unit tests directly.
1 parent e91a5cf commit e5fa22c

File tree

3 files changed

+203
-97
lines changed

3 files changed

+203
-97
lines changed

src/core/index.rs

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,3 +630,167 @@ impl SeqInternal {
630630
}
631631
}
632632
}
633+
634+
#[cfg(test)]
635+
mod tests {
636+
use super::super::array::Array;
637+
use super::super::data::constant;
638+
use super::super::dim4::Dim4;
639+
use super::super::index::{assign_gen, assign_seq, col, index, index_gen, row, Indexer};
640+
use super::super::random::randu;
641+
use super::super::seq::Seq;
642+
643+
use crate::{dim4, seq, view};
644+
645+
#[test]
646+
fn non_macro_seq_index() {
647+
// ANCHOR: non_macro_seq_index
648+
let dims = Dim4::new(&[5, 5, 1, 1]);
649+
let a = randu::<f32>(dims);
650+
//af_print!("a", a);
651+
//a
652+
//[5 5 1 1]
653+
// 0.3990 0.5160 0.8831 0.9107 0.6688
654+
// 0.6720 0.3932 0.0621 0.9159 0.8434
655+
// 0.5339 0.2706 0.7089 0.0231 0.1328
656+
// 0.1386 0.9455 0.9434 0.2330 0.2657
657+
// 0.7353 0.1587 0.1227 0.2220 0.2299
658+
659+
// Index array using sequences
660+
let seqs = &[Seq::new(1u32, 3, 1), Seq::default()];
661+
let _sub = index(&a, seqs);
662+
//af_print!("a(seq(1,3,1), span)", sub);
663+
// [3 5 1 1]
664+
// 0.6720 0.3932 0.0621 0.9159 0.8434
665+
// 0.5339 0.2706 0.7089 0.0231 0.1328
666+
// 0.1386 0.9455 0.9434 0.2330 0.2657
667+
// ANCHOR_END: non_macro_seq_index
668+
}
669+
670+
#[test]
671+
fn seq_index() {
672+
// ANCHOR: seq_index
673+
let dims = dim4!(5, 5, 1, 1);
674+
let a = randu::<f32>(dims);
675+
let first3 = seq!(1:3:1);
676+
let allindim2 = seq!();
677+
let _sub = view!(a[first3, allindim2]);
678+
// ANCHOR_END: seq_index
679+
}
680+
681+
#[test]
682+
fn non_macro_seq_assign() {
683+
// ANCHOR: non_macro_seq_assign
684+
let mut a = constant(2.0 as f32, Dim4::new(&[5, 3, 1, 1]));
685+
//print(&a);
686+
// 2.0 2.0 2.0
687+
// 2.0 2.0 2.0
688+
// 2.0 2.0 2.0
689+
// 2.0 2.0 2.0
690+
// 2.0 2.0 2.0
691+
692+
let b = constant(1.0 as f32, Dim4::new(&[3, 3, 1, 1]));
693+
let seqs = &[Seq::new(1.0, 3.0, 1.0), Seq::default()];
694+
assign_seq(&mut a, seqs, &b);
695+
//print(&a);
696+
// 2.0 2.0 2.0
697+
// 1.0 1.0 1.0
698+
// 1.0 1.0 1.0
699+
// 1.0 1.0 1.0
700+
// 2.0 2.0 2.0
701+
// ANCHOR_END: non_macro_seq_assign
702+
}
703+
704+
#[test]
705+
fn non_macro_seq_array_index() {
706+
// ANCHOR: non_macro_seq_array_index
707+
let values: [f32; 3] = [1.0, 2.0, 3.0];
708+
let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
709+
let seq4gen = Seq::new(0.0, 2.0, 1.0);
710+
let a = randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
711+
// [5 3 1 1]
712+
// 0.0000 0.2190 0.3835
713+
// 0.1315 0.0470 0.5194
714+
// 0.7556 0.6789 0.8310
715+
// 0.4587 0.6793 0.0346
716+
// 0.5328 0.9347 0.0535
717+
718+
let mut idxrs = Indexer::default();
719+
idxrs.set_index(&indices, 0, None); // 2nd arg is indexing dimension
720+
idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd arg indicates batch operation
721+
722+
let _sub2 = index_gen(&a, idxrs);
723+
//println!("a(indices, seq(0, 2, 1))"); print(&sub2);
724+
// [3 3 1 1]
725+
// 0.1315 0.0470 0.5194
726+
// 0.7556 0.6789 0.8310
727+
// 0.4587 0.6793 0.0346
728+
// ANCHOR_END: non_macro_seq_array_index
729+
}
730+
731+
#[test]
732+
fn seq_array_index() {
733+
// ANCHOR: seq_array_index
734+
let values: [f32; 3] = [1.0, 2.0, 3.0];
735+
let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
736+
let seq4gen = seq!(0:2:1);
737+
let a = randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
738+
let _sub2 = view!(a[indices, seq4gen]);
739+
// ANCHOR_END: seq_array_index
740+
}
741+
742+
#[test]
743+
fn non_macro_seq_array_assign() {
744+
// ANCHOR: non_macro_seq_array_assign
745+
let values: [f32; 3] = [1.0, 2.0, 3.0];
746+
let indices = Array::new(&values, dim4!(3, 1, 1, 1));
747+
let seq4gen = seq!(0:2:1);
748+
let mut a = randu::<f32>(dim4!(5, 3, 1, 1));
749+
// [5 3 1 1]
750+
// 0.0000 0.2190 0.3835
751+
// 0.1315 0.0470 0.5194
752+
// 0.7556 0.6789 0.8310
753+
// 0.4587 0.6793 0.0346
754+
// 0.5328 0.9347 0.0535
755+
756+
let b = constant(2.0 as f32, dim4!(3, 3, 1, 1));
757+
758+
let mut idxrs = Indexer::default();
759+
idxrs.set_index(&indices, 0, None); // 2nd arg is indexing dimension
760+
idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd arg indicates batch operation
761+
762+
let _sub2 = assign_gen(&mut a, &idxrs, &b);
763+
//println!("a(indices, seq(0, 2, 1))"); print(&sub2);
764+
// [5 3 1 1]
765+
// 0.0000 0.2190 0.3835
766+
// 2.0000 2.0000 2.0000
767+
// 2.0000 2.0000 2.0000
768+
// 2.0000 2.0000 2.0000
769+
// 0.5328 0.9347 0.0535
770+
// ANCHOR_END: non_macro_seq_array_assign
771+
}
772+
773+
#[test]
774+
fn setrow() {
775+
// ANCHOR: setrow
776+
let a = randu::<f32>(dim4!(5, 5, 1, 1));
777+
//print(&a);
778+
// [5 5 1 1]
779+
// 0.6010 0.5497 0.1583 0.3636 0.6755
780+
// 0.0278 0.2864 0.3712 0.4165 0.6105
781+
// 0.9806 0.3410 0.3543 0.5814 0.5232
782+
// 0.2126 0.7509 0.6450 0.8962 0.5567
783+
// 0.0655 0.4105 0.9675 0.3712 0.7896
784+
let _r = row(&a, 4);
785+
// [1 5 1 1]
786+
// 0.0655 0.4105 0.9675 0.3712 0.7896
787+
let _c = col(&a, 4);
788+
// [5 1 1 1]
789+
// 0.6755
790+
// 0.6105
791+
// 0.5232
792+
// 0.5567
793+
// 0.7896
794+
// ANCHOR_END: setrow
795+
}
796+
}

src/core/macros.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,10 @@ macro_rules! seq {
184184
/// - A simple Array identifier.
185185
/// - An Array with slicing info for indexing.
186186
/// - An Array with slicing info and other arrays used for indexing.
187+
///
188+
/// Examples on how to use this macro are provided in the [tutorials book][1]
189+
///
190+
/// [1]: http://arrayfire.org/arrayfire-rust/book/indexing.html
187191
#[macro_export]
188192
macro_rules! view {
189193
(@af_max_dims) => {

tutorials-book/src/indexing.md

Lines changed: 35 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -8,128 +8,63 @@ to existing Arrays. Given below are few of such functions and their correspondin
88
[Indexer::new][2] to create an Indexer object and set either a `Seq` object or `Array` as indexing
99
object for a given dimension.
1010

11-
## Using Seq objects to index Array
11+
## Using Seq objects
1212

13-
Create a view of an existing Array using Sequences and the function [index][3].
13+
### Create a view of an existing Array
14+
15+
We will Sequences and the function [index][3] in this approach.
1416

1517
```rust,noplaypen
16-
let dims = Dim4::new(&[5, 5, 1, 1]);
17-
let a = randu::<f32>(dims);
18-
af_print!("a", a);
19-
//a
20-
//[5 5 1 1]
21-
// 0.3990 0.5160 0.8831 0.9107 0.6688
22-
// 0.6720 0.3932 0.0621 0.9159 0.8434
23-
// 0.5339 0.2706 0.7089 0.0231 0.1328
24-
// 0.1386 0.9455 0.9434 0.2330 0.2657
25-
// 0.7353 0.1587 0.1227 0.2220 0.2299
26-
27-
// Index array using sequences
28-
let seqs = &[Seq::new(1u32, 3, 1), Seq::default()];
29-
let sub = index(&a, seqs);
30-
af_print!("a(seq(1,3,1), span)", sub);
31-
// [3 5 1 1]
32-
// 0.6720 0.3932 0.0621 0.9159 0.8434
33-
// 0.5339 0.2706 0.7089 0.0231 0.1328
34-
// 0.1386 0.9455 0.9434 0.2330 0.2657
18+
{{#include ../../src/core/index.rs:non_macro_seq_index}}
19+
```
20+
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.
22+
```rust, noplaypen
23+
{{#include ../../src/core/index.rs:seq_index}}
3524
```
3625

37-
Set a sub-portion of an existing Array with a constant value using [assign\_seq][4].
26+
### Modify a sub region of an existing Array
27+
28+
Let us take a look at an example where a portion of an existing Array will be set to with another
29+
Array. We will an constant value Array and the function [assign\_seq][4] in the below example.
3830

3931
```rust,noplaypen
40-
let a = constant(2.0 as f32, Dim4::new(&[5, 3, 1, 1]));
41-
let b = constant(1.0 as f32, Dim4::new(&[3, 3, 1, 1]));
42-
let seqs = &[Seq::new(1.0, 3.0, 1.0), Seq::default()];
43-
let sub = assign_seq(&a, seqs, &b);
44-
print(&a);
45-
// 2.0 2.0 2.0
46-
// 2.0 2.0 2.0
47-
// 2.0 2.0 2.0
48-
// 2.0 2.0 2.0
49-
// 2.0 2.0 2.0
50-
51-
print(&sub);
52-
// 2.0 2.0 2.0
53-
// 1.0 1.0 1.0
54-
// 1.0 1.0 1.0
55-
// 1.0 1.0 1.0
56-
// 2.0 2.0 2.0
32+
{{#include ../../src/core/index.rs:non_macro_seq_assign}}
5733
```
5834

5935
> **NOTE** Normally you want to avoid accessing individual elements of the array like this for performance reasons.
6036
61-
## Using Array and Seq combination to index Array
37+
## Using Array and Seq combination
6238

63-
Create a view of an existing Array using another Array and Sequence.
39+
### Create a view of an existing Array
40+
41+
To use a combination of Array and Seq objects to index an existing Array, we will need a more
42+
generalized function [index\_gen][12].
6443

6544
```rust,noplaypen
66-
use arrayfire::{Array, Dim4, Seq, print, randu, index_gen, Indexer};
67-
let values: [f32; 3] = [1.0, 2.0, 3.0];
68-
let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
69-
let seq4gen = Seq::new(0.0, 2.0, 1.0);
70-
let a = randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
71-
// [5 3 1 1]
72-
// 0.0000 0.2190 0.3835
73-
// 0.1315 0.0470 0.5194
74-
// 0.7556 0.6789 0.8310
75-
// 0.4587 0.6793 0.0346
76-
// 0.5328 0.9347 0.0535
77-
78-
let mut idxrs = Indexer::new();
79-
idxrs.set_index(&indices, 0, None); // 2nd parameter is indexing dimension
80-
idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd parameter indicates batch operation
81-
82-
let sub2 = index_gen(&a, idxrs);
83-
println!("a(indices, seq(0, 2, 1))"); print(&sub2);
84-
// [3 3 1 1]
85-
// 0.1315 0.0470 0.5194
86-
// 0.7556 0.6789 0.8310
87-
// 0.4587 0.6793 0.0346
45+
{{#include ../../src/core/index.rs:non_macro_seq_array_index}}
46+
```
47+
Similar to how, [view][11] macro helped with abreviating the syntax when indexing with just
48+
sequences, it can also help when using a combination of Seq and Array.
49+
```rust, noplaypen
50+
{{#include ../../src/core/index.rs:seq_array_index}}
8851
```
8952

90-
Set a sub-portion of an existing Array with another Array using a combination
91-
of `Seq` and `Array`.
53+
### Modify a sub region of an existing Array
54+
55+
Set a portion of an existing Array with another Array using a combination of `Seq` and `Array`.
56+
We will use [assign\_gen][13] function to do it.
9257

9358
```rust,noplaypen
94-
use arrayfire::{Array, Dim4, Seq, print, randu, constant, Indexer, assign_gen};
95-
let values: [f32; 3] = [1.0, 2.0, 3.0];
96-
let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1]));
97-
let seq4gen = Seq::new(0.0, 2.0, 1.0);
98-
let a = randu::<f32>(Dim4::new(&[5, 3, 1, 1]));
99-
// [5 3 1 1]
100-
// 0.0000 0.2190 0.3835
101-
// 0.1315 0.0470 0.5194
102-
// 0.7556 0.6789 0.8310
103-
// 0.4587 0.6793 0.0346
104-
// 0.5328 0.9347 0.0535
105-
106-
let b = constant(2.0 as f32, Dim4::new(&[3, 3, 1, 1]));
107-
108-
let mut idxrs = Indexer::new();
109-
idxrs.set_index(&indices, 0, None); // 2nd parameter is indexing dimension
110-
idxrs.set_index(&seq4gen, 1, Some(false)); // 3rd parameter indicates batch operation
111-
112-
let sub2 = assign_gen(&a, &idxrs, &b);
113-
println!("a(indices, seq(0, 2, 1))"); print(&sub2);
114-
// [5 3 1 1]
115-
// 0.0000 0.2190 0.3835
116-
// 2.0000 2.0000 2.0000
117-
// 2.0000 2.0000 2.0000
118-
// 2.0000 2.0000 2.0000
119-
// 0.5328 0.9347 0.0535
59+
{{#include ../../src/core/index.rs:non_macro_seq_array_assign}}
12060
```
12161

12262
## Extract or Set rows/coloumns of an Array
12363

12464
Extract a specific set of rows/coloumns from an existing Array.
12565

12666
```rust,noplaypen
127-
let dims = Dim4::new(&[5, 5, 1, 1]);
128-
let a = randu::<f32>(dims);
129-
println!("Grab last row of the random matrix");
130-
print(&a);
131-
print(&row(&a, 4));
132-
print(&col(&a, 4));
67+
{{#include ../../src/core/index.rs:setrow}}
13368
```
13469

13570
You can also use [rows][5] & [cols][6] to retrieve a subset of rows or coloumns respectively.
@@ -148,3 +83,6 @@ for coloumns.
14883
[8]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.set_col.html
14984
[9]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.set_rows.html
15085
[10]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.set_cols.html
86+
[11]: http://arrayfire.org/arrayfire-rust/arrayfire/macro.view.html
87+
[12]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.index_gen.html
88+
[13]: http://arrayfire.org/arrayfire-rust/arrayfire/fn.assign_gen.html

0 commit comments

Comments
 (0)