gorgonia.org/tensor@v0.9.24/native/example_test.go (about) 1 package native 2 3 import ( 4 "fmt" 5 6 . "gorgonia.org/tensor" 7 ) 8 9 // There are times where it is more effective to use native Go slice semantics to do work (for example, when performing batch work over kernels). 10 // Iterators are useful for this purpose. This package provides iterators for the standard types 11 // However, custom types are also available. See Vector, Matrix and Tensor3 examples. 12 func Example_iterator() { 13 var T *Dense 14 T = New(WithShape(2, 3), WithBacking(Range(Float64, 0, 6))) 15 x, err := MatrixF64(T) 16 if err != nil { 17 fmt.Printf("ERR: %v", err) 18 } 19 20 for _, row := range x { 21 fmt.Printf("%v\n", row) 22 } 23 24 // Output: 25 // [0 1 2] 26 // [3 4 5] 27 } 28 29 // The NativeSelect function squashes the dimensions, and returns an iterator in native Go slice semantics. 30 func Example_select() { 31 // Selection is a bit of an interesting use case. Sometimes you don't want to iterate through the layers. 32 // 33 // For example, in a number of use cases where you have a 4-Tensor, you'd typically reshape it to some 34 // 2D matrix which can then be plugged into BLAS algorithms directly. Sometimes you wouldn't need to reshape. 35 // All you have to do is squash the dimensions inwards. This function does that. 36 // 37 // The best way to explain the Select functions is through concrete examples. 38 // Imagine a tensor with (2,3,4,5) shape. Arbitrarily, we call them (NCHW) - Batch Size, Channel Count, Height, Width. 39 // If we want to select all the channels, across all batches, then `NativeSelectX(T, 1)` would yield all channels. The resulting matrix will be (6, 20) 40 // If we want to select all the heights, across all channels and batches, then `NativeSelectX(T, 2) will yield all heights. The resulting matrix will be (24, 5) 41 // 42 // If for some reason the format was in NHWC, then you would need to reshape. This wouldn't be useful. 43 44 var T *Dense 45 T = New(WithShape(2, 3, 4, 5), WithBacking(Range(Float64, 0, 2*3*4*5))) 46 x, err := SelectF64(T, 1) 47 if err != nil { 48 fmt.Printf("ERR %v", err) 49 } 50 for _, row := range x { 51 fmt.Printf("%3.0f\n", row) 52 } 53 54 // Output: 55 // [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19] 56 // [ 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39] 57 // [ 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59] 58 // [ 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79] 59 // [ 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99] 60 // [100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119] 61 } 62 63 // The iterators are iteratos in the truest sense. The data isn't copied, as this example shows 64 func Example_clobber() { 65 var T *Dense 66 T = New(WithShape(2, 3), WithBacking(Range(Float64, 0, 6))) 67 fmt.Printf("Before :\n%v", T) 68 69 xx, _ := MatrixF64(T) 70 xx[1][1] = 10000 71 fmt.Printf("After :\n%v", T) 72 73 // Output: 74 // Before : 75 // ⎡0 1 2⎤ 76 // ⎣3 4 5⎦ 77 // After : 78 // ⎡ 0 1 2⎤ 79 // ⎣ 3 10000 5⎦ 80 81 }