github.com/wzzhu/tensor@v0.9.24/example_dense_arith_test.go (about) 1 package tensor 2 3 import "fmt" 4 5 // By default, arithmetic operations are safe 6 func ExampleDense_Add_basic() { 7 var T1, T2, T3, V *Dense 8 var sliced Tensor 9 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 10 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 11 T3, _ = T1.Add(T2) 12 fmt.Printf("Default operation is safe\n==========================\nT3 = T1 + T2\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 13 14 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 15 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 16 V = sliced.(*Dense) 17 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 18 T3, _ = V.Add(T2) 19 fmt.Printf("Default operation is safe (sliced operations)\n=============================================\nT3 = T1[0:2, 0:2] + T2\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 20 21 // Output: 22 // Default operation is safe 23 // ========================== 24 // T3 = T1 + T2 25 // T3: 26 // ⎡10 12 14⎤ 27 // ⎢16 18 20⎥ 28 // ⎣22 24 26⎦ 29 // 30 // T1 is unchanged: 31 // ⎡0 1 2⎤ 32 // ⎢3 4 5⎥ 33 // ⎣6 7 8⎦ 34 // 35 // Default operation is safe (sliced operations) 36 // ============================================= 37 // T3 = T1[0:2, 0:2] + T2 38 // T3: 39 // ⎡10 12⎤ 40 // ⎣15 17⎦ 41 // 42 // T1 is unchanged: 43 // ⎡0 1 2⎤ 44 // ⎢3 4 5⎥ 45 // ⎣6 7 8⎦ 46 } 47 48 // To perform unsafe operations, use the `UseUnsafe` function option 49 func ExampleDense_Add_unsafe() { 50 var T1, T2, T3, V *Dense 51 var sliced Tensor 52 53 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 54 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 55 T3, _ = T1.Add(T2, UseUnsafe()) 56 fmt.Printf("Unsafe Operation\n================\nT3 = T1 + T2\nT1 == T3: %t\nT1:\n%v", T1 == T3, T1) 57 58 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 59 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 60 V = sliced.(*Dense) 61 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 62 63 V.Add(T2, UseUnsafe()) // unsafe overwrites the data in T1 64 fmt.Printf("Unsafe Operation on sliced Tensors\n==================================\nV = T1[0:2, 0:2] + T2\nV:\n%v\n", V) 65 fmt.Printf("Naturally, T1 is mutated too:\n%v", T1) 66 67 // Output: 68 // Unsafe Operation 69 // ================ 70 // T3 = T1 + T2 71 // T1 == T3: true 72 // T1: 73 // ⎡10 12 14⎤ 74 // ⎢16 18 20⎥ 75 // ⎣22 24 26⎦ 76 // Unsafe Operation on sliced Tensors 77 // ================================== 78 // V = T1[0:2, 0:2] + T2 79 // V: 80 // ⎡10 12⎤ 81 // ⎣15 17⎦ 82 // 83 // Naturally, T1 is mutated too: 84 // ⎡10 12 2⎤ 85 // ⎢15 17 5⎥ 86 // ⎣ 6 7 8⎦ 87 } 88 89 // An optional reuse tensor can also be specified with the WithReuse function option 90 func ExampleDense_Add_reuse() { 91 var T1, V, T2, Reuse, T3 *Dense 92 var sliced Tensor 93 94 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 95 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 96 Reuse = New(WithBacking(Range(Float64, 100, 109)), WithShape(3, 3)) 97 T3, _ = T1.Add(T2, WithReuse(Reuse)) 98 fmt.Printf("Reuse tensor passed in\n======================\nT3 == Reuse: %t\nT3:\n%v\n", T3 == Reuse, T3) 99 100 // You can also use it on operations on sliced tensors - note your reuse tensor has to be the same shape as the result 101 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 102 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 103 V = sliced.(*Dense) 104 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 105 Reuse = New(WithBacking(Range(Float64, 100, 104)), WithShape(2, 2)) // same shape as result 106 T3, _ = V.Add(T2, WithReuse(Reuse)) 107 fmt.Printf("Reuse tensor passed in (sliced tensor)\n======================================\nT3 == Reuse: %t\nT3:\n%v", T3 == Reuse, T3) 108 109 // Output: 110 // Reuse tensor passed in 111 // ====================== 112 // T3 == Reuse: true 113 // T3: 114 // ⎡10 12 14⎤ 115 // ⎢16 18 20⎥ 116 // ⎣22 24 26⎦ 117 // 118 // Reuse tensor passed in (sliced tensor) 119 // ====================================== 120 // T3 == Reuse: true 121 // T3: 122 // ⎡10 12⎤ 123 // ⎣15 17⎦ 124 125 } 126 127 // An optional reuse tensor can also be specified with the WithReuse function option. Passing in an operand would not cause a problem. 128 func ExampleDense_Add_reuse_operand() { 129 var T1, T2, T3 *Dense 130 131 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 132 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 133 T3, _ = T1.Add(T2, WithReuse(T1)) 134 fmt.Printf("Reuse tensor passed in\n======================\nT3 == T1: %t\nT3:\n%v\n", T3 == T1, T3) 135 136 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 137 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 138 T3, _ = T1.Add(T2, WithReuse(T2)) 139 fmt.Printf("Reuse tensor passed in\n======================\nT3 == T2: %t\nT3:\n%v\n", T3 == T2, T3) 140 141 // Output: 142 // Reuse tensor passed in 143 // ====================== 144 // T3 == T1: true 145 // T3: 146 // ⎡10 12 14⎤ 147 // ⎢16 18 20⎥ 148 // ⎣22 24 26⎦ 149 // 150 // Reuse tensor passed in 151 // ====================== 152 // T3 == T2: true 153 // T3: 154 // ⎡10 12 14⎤ 155 // ⎢16 18 20⎥ 156 // ⎣22 24 26⎦ 157 158 } 159 160 // Incrementing a tensor is also a function option provided by the package 161 func ExampleDense_Add_incr() { 162 var T1, T2, T3, Incr, V *Dense 163 var sliced Tensor 164 165 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 166 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 167 Incr = New(WithBacking([]float64{100, 100, 100, 100, 100, 100, 100, 100, 100}), WithShape(3, 3)) 168 T3, _ = T1.Add(T2, WithIncr(Incr)) 169 fmt.Printf("Incr tensor passed in\n======================\nIncr += T1 + T2\nIncr == T3: %t\nT3:\n%v\n", Incr == T3, T3) 170 171 // Operations on sliced tensor is also allowed. Note that your Incr tensor has to be the same shape as the result 172 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 173 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 174 V = sliced.(*Dense) 175 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 176 Incr = New(WithBacking([]float64{100, 100, 100, 100}), WithShape(2, 2)) 177 T3, _ = V.Add(T2, WithIncr(Incr)) 178 fmt.Printf("Incr tensor passed in (sliced tensor)\n======================================\nIncr += T1 + T2\nIncr == T3: %t\nT3:\n%v\n", Incr == T3, T3) 179 180 // Output: 181 // Incr tensor passed in 182 // ====================== 183 // Incr += T1 + T2 184 // Incr == T3: true 185 // T3: 186 // ⎡110 112 114⎤ 187 // ⎢116 118 120⎥ 188 // ⎣122 124 126⎦ 189 // 190 // Incr tensor passed in (sliced tensor) 191 // ====================================== 192 // Incr += T1 + T2 193 // Incr == T3: true 194 // T3: 195 // ⎡110 112⎤ 196 // ⎣115 117⎦ 197 } 198 199 /* SUB */ 200 201 // By default, arithmetic operations are safe 202 func ExampleDense_Sub_basic() { 203 var T1, T2, T3, V *Dense 204 var sliced Tensor 205 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 206 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 207 T3, _ = T1.Sub(T2) 208 fmt.Printf("Default operation is safe\n==========================\nT3 = T1 - T2\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 209 210 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 211 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 212 V = sliced.(*Dense) 213 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 214 T3, _ = V.Sub(T2) 215 fmt.Printf("Default operation is safe (sliced operations)\n=============================================\nT3 = T1[0:2, 0:2] + T2\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 216 217 // Output: 218 // Default operation is safe 219 // ========================== 220 // T3 = T1 - T2 221 // T3: 222 // ⎡-10 -10 -10⎤ 223 // ⎢-10 -10 -10⎥ 224 // ⎣-10 -10 -10⎦ 225 // 226 // T1 is unchanged: 227 // ⎡0 1 2⎤ 228 // ⎢3 4 5⎥ 229 // ⎣6 7 8⎦ 230 // 231 // Default operation is safe (sliced operations) 232 // ============================================= 233 // T3 = T1[0:2, 0:2] + T2 234 // T3: 235 // ⎡-10 -10⎤ 236 // ⎣ -9 -9⎦ 237 // 238 // T1 is unchanged: 239 // ⎡0 1 2⎤ 240 // ⎢3 4 5⎥ 241 // ⎣6 7 8⎦ 242 } 243 244 // To perform unsafe operations, use the `UseUnsafe` function option 245 func ExampleDense_Sub_unsafe() { 246 var T1, T2, T3, V *Dense 247 var sliced Tensor 248 249 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 250 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 251 T3, _ = T1.Sub(T2, UseUnsafe()) 252 fmt.Printf("Unsafe Operation\n================\nT3 = T1 - T2\nT1 == T3: %t\nT1:\n%v", T1 == T3, T1) 253 254 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 255 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 256 V = sliced.(*Dense) 257 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 258 259 V.Sub(T2, UseUnsafe()) // unsafe overwrites the data in T1 260 fmt.Printf("Unsafe Operation on sliced Tensors\n==================================\nV = T1[0:2, 0:2] + T2\nV:\n%v\n", V) 261 fmt.Printf("Naturally, T1 is mutated too:\n%v", T1) 262 263 // Output: 264 // Unsafe Operation 265 // ================ 266 // T3 = T1 - T2 267 // T1 == T3: true 268 // T1: 269 // ⎡-10 -10 -10⎤ 270 // ⎢-10 -10 -10⎥ 271 // ⎣-10 -10 -10⎦ 272 // Unsafe Operation on sliced Tensors 273 // ================================== 274 // V = T1[0:2, 0:2] + T2 275 // V: 276 // ⎡-10 -10⎤ 277 // ⎣ -9 -9⎦ 278 // 279 // Naturally, T1 is mutated too: 280 // ⎡-10 -10 2⎤ 281 // ⎢ -9 -9 5⎥ 282 // ⎣ 6 7 8⎦ 283 } 284 285 // An optional reuse tensor can also be specified with the WithReuse function option 286 func ExampleDense_Sub_reuse() { 287 var T1, V, T2, Reuse, T3 *Dense 288 var sliced Tensor 289 290 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 291 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 292 Reuse = New(WithBacking(Range(Float64, 100, 109)), WithShape(3, 3)) 293 T3, _ = T1.Sub(T2, WithReuse(Reuse)) 294 fmt.Printf("Reuse tensor passed in\n======================\nT3 == Reuse: %t\nT3:\n%v\n", T3 == Reuse, T3) 295 296 // You can also use it on operations on sliced tensors - note your reuse tensor has to be the same shape as the result 297 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 298 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 299 V = sliced.(*Dense) 300 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 301 Reuse = New(WithBacking(Range(Float64, 100, 104)), WithShape(2, 2)) // same shape as result 302 T3, _ = V.Sub(T2, WithReuse(Reuse)) 303 fmt.Printf("Reuse tensor passed in (sliced tensor)\n======================================\nT3 == Reuse: %t\nT3:\n%v", T3 == Reuse, T3) 304 305 // Output: 306 // Reuse tensor passed in 307 // ====================== 308 // T3 == Reuse: true 309 // T3: 310 // ⎡-10 -10 -10⎤ 311 // ⎢-10 -10 -10⎥ 312 // ⎣-10 -10 -10⎦ 313 // 314 // Reuse tensor passed in (sliced tensor) 315 // ====================================== 316 // T3 == Reuse: true 317 // T3: 318 // ⎡-10 -10⎤ 319 // ⎣ -9 -9⎦ 320 } 321 322 // An optional reuse tensor can also be specified with the WithReuse function option. Passing in an operand would not cause a problem. 323 func ExampleDense_Sub_reuse_operand() { 324 var T1, T2, T3 *Dense 325 326 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 327 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 328 T3, _ = T1.Sub(T2, WithReuse(T1)) 329 fmt.Printf("Reuse tensor passed in\n======================\nT3 == T1: %t\nT3:\n%v\n", T3 == T1, T3) 330 331 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 332 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 333 T3, _ = T1.Sub(T2, WithReuse(T2)) 334 fmt.Printf("Reuse tensor passed in\n======================\nT3 == T2: %t\nT3:\n%v\n", T3 == T2, T3) 335 336 // Output: 337 // Reuse tensor passed in 338 // ====================== 339 // T3 == T1: true 340 // T3: 341 // ⎡-10 -10 -10⎤ 342 // ⎢-10 -10 -10⎥ 343 // ⎣-10 -10 -10⎦ 344 // 345 // Reuse tensor passed in 346 // ====================== 347 // T3 == T2: true 348 // T3: 349 // ⎡-10 -10 -10⎤ 350 // ⎢-10 -10 -10⎥ 351 // ⎣-10 -10 -10⎦ 352 } 353 354 // Incrementing a tensor is also a function option provided by the package 355 func ExampleDense_Sub_incr() { 356 var T1, T2, T3, Incr, V *Dense 357 var sliced Tensor 358 359 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 360 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 361 Incr = New(WithBacking([]float64{100, 100, 100, 100, 100, 100, 100, 100, 100}), WithShape(3, 3)) 362 T3, _ = T1.Sub(T2, WithIncr(Incr)) 363 fmt.Printf("Incr tensor passed in\n======================\nIncr += T1 - T2\nIncr == T3: %t\nT3:\n%v\n", Incr == T3, T3) 364 365 // Operations on sliced tensor is also allowed. Note that your Incr tensor has to be the same shape as the result 366 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 367 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 368 V = sliced.(*Dense) 369 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 370 Incr = New(WithBacking([]float64{100, 100, 100, 100}), WithShape(2, 2)) 371 T3, _ = V.Sub(T2, WithIncr(Incr)) 372 fmt.Printf("Incr tensor passed in (sliced tensor)\n======================================\nIncr += T1 + T2\nIncr == T3: %t\nT3:\n%v\n", Incr == T3, T3) 373 374 // Output: 375 // Incr tensor passed in 376 // ====================== 377 // Incr += T1 - T2 378 // Incr == T3: true 379 // T3: 380 // ⎡90 90 90⎤ 381 // ⎢90 90 90⎥ 382 // ⎣90 90 90⎦ 383 // 384 // Incr tensor passed in (sliced tensor) 385 // ====================================== 386 // Incr += T1 + T2 387 // Incr == T3: true 388 // T3: 389 // ⎡90 90⎤ 390 // ⎣91 91⎦ 391 } 392 393 /* MUL */ 394 395 // By default, arithmetic operations are safe 396 func ExampleDense_Mul_basic() { 397 var T1, T2, T3, V *Dense 398 var sliced Tensor 399 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 400 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 401 T3, _ = T1.Mul(T2) 402 fmt.Printf("Default operation is safe\n==========================\nT3 = T1 × T2\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 403 404 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 405 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 406 V = sliced.(*Dense) 407 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 408 T3, _ = V.Mul(T2) 409 fmt.Printf("Default operation is safe (sliced operations)\n=============================================\nT3 = T1[0:2, 0:2] × T2\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 410 411 // Output: 412 // Default operation is safe 413 // ========================== 414 // T3 = T1 × T2 415 // T3: 416 // ⎡ 0 11 24⎤ 417 // ⎢ 39 56 75⎥ 418 // ⎣ 96 119 144⎦ 419 // 420 // T1 is unchanged: 421 // ⎡0 1 2⎤ 422 // ⎢3 4 5⎥ 423 // ⎣6 7 8⎦ 424 // 425 // Default operation is safe (sliced operations) 426 // ============================================= 427 // T3 = T1[0:2, 0:2] × T2 428 // T3: 429 // ⎡ 0 11⎤ 430 // ⎣36 52⎦ 431 // 432 // T1 is unchanged: 433 // ⎡0 1 2⎤ 434 // ⎢3 4 5⎥ 435 // ⎣6 7 8⎦ 436 } 437 438 // To perform unsafe operations, use the `UseUnsafe` function option 439 func ExampleDense_Mul_unsafe() { 440 var T1, T2, T3, V *Dense 441 var sliced Tensor 442 443 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 444 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 445 T3, _ = T1.Mul(T2, UseUnsafe()) 446 fmt.Printf("Unsafe Operation\n================\nT3 = T1 × T2\nT1 == T3: %t\nT1:\n%v", T1 == T3, T1) 447 448 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 449 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 450 V = sliced.(*Dense) 451 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 452 453 V.Mul(T2, UseUnsafe()) // unsafe overwrites the data in T1 454 fmt.Printf("Unsafe Operation on sliced Tensors\n==================================\nV = T1[0:2, 0:2] × T2\nV:\n%v\n", V) 455 fmt.Printf("Naturally, T1 is mutated too:\n%v", T1) 456 457 // Output: 458 // Unsafe Operation 459 // ================ 460 // T3 = T1 × T2 461 // T1 == T3: true 462 // T1: 463 // ⎡ 0 11 24⎤ 464 // ⎢ 39 56 75⎥ 465 // ⎣ 96 119 144⎦ 466 // Unsafe Operation on sliced Tensors 467 // ================================== 468 // V = T1[0:2, 0:2] × T2 469 // V: 470 // ⎡ 0 11⎤ 471 // ⎣36 52⎦ 472 // 473 // Naturally, T1 is mutated too: 474 // ⎡ 0 11 2⎤ 475 // ⎢36 52 5⎥ 476 // ⎣ 6 7 8⎦ 477 } 478 479 // An optional reuse tensor can also be specified with the WithReuse function option 480 func ExampleDense_Mul_reuse() { 481 var T1, V, T2, Reuse, T3 *Dense 482 var sliced Tensor 483 484 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 485 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 486 Reuse = New(WithBacking(Range(Float64, 100, 109)), WithShape(3, 3)) 487 T3, _ = T1.Mul(T2, WithReuse(Reuse)) 488 fmt.Printf("Reuse tensor passed in\n======================\nT3 == Reuse: %t\nT3:\n%v\n", T3 == Reuse, T3) 489 490 // You can also use it on operations on sliced tensors - note your reuse tensor has to be the same shape as the result 491 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 492 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 493 V = sliced.(*Dense) 494 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 495 Reuse = New(WithBacking(Range(Float64, 100, 104)), WithShape(2, 2)) // same shape as result 496 T3, _ = V.Mul(T2, WithReuse(Reuse)) 497 fmt.Printf("Reuse tensor passed in (sliced tensor)\n======================================\nT3 == Reuse: %t\nT3:\n%v", T3 == Reuse, T3) 498 499 // Output: 500 // Reuse tensor passed in 501 // ====================== 502 // T3 == Reuse: true 503 // T3: 504 // ⎡ 0 11 24⎤ 505 // ⎢ 39 56 75⎥ 506 // ⎣ 96 119 144⎦ 507 // 508 // Reuse tensor passed in (sliced tensor) 509 // ====================================== 510 // T3 == Reuse: true 511 // T3: 512 // ⎡ 0 11⎤ 513 // ⎣36 52⎦ 514 } 515 516 // An optional reuse tensor can also be specified with the WithReuse function option. Passing in an operand would not cause a problem. 517 func ExampleDense_Mul_reuse_operand() { 518 var T1, T2, T3 *Dense 519 520 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 521 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 522 T3, _ = T1.Mul(T2, WithReuse(T1)) 523 fmt.Printf("Reuse tensor passed in\n======================\nT3 == T1: %t\nT3:\n%v\n", T3 == T1, T3) 524 525 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 526 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 527 T3, _ = T1.Mul(T2, WithReuse(T2)) 528 fmt.Printf("Reuse tensor passed in\n======================\nT3 == T2: %t\nT3:\n%v\n", T3 == T2, T3) 529 530 // Output: 531 // Reuse tensor passed in 532 // ====================== 533 // T3 == T1: true 534 // T3: 535 // ⎡ 0 11 24⎤ 536 // ⎢ 39 56 75⎥ 537 // ⎣ 96 119 144⎦ 538 // 539 // Reuse tensor passed in 540 // ====================== 541 // T3 == T2: true 542 // T3: 543 // ⎡ 0 11 24⎤ 544 // ⎢ 39 56 75⎥ 545 // ⎣ 96 119 144⎦ 546 547 } 548 549 // Incrementing a tensor is also a function option provided by the package 550 func ExampleDense_Mul_incr() { 551 var T1, T2, T3, Incr, V *Dense 552 var sliced Tensor 553 554 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 555 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 556 Incr = New(WithBacking([]float64{100, 100, 100, 100, 100, 100, 100, 100, 100}), WithShape(3, 3)) 557 T3, _ = T1.Mul(T2, WithIncr(Incr)) 558 fmt.Printf("Incr tensor passed in\n======================\nIncr += T1 × T2\nIncr == T3: %t\nT3:\n%v\n", Incr == T3, T3) 559 560 // Operations on sliced tensor is also allowed. Note that your Incr tensor has to be the same shape as the result 561 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 562 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 563 V = sliced.(*Dense) 564 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 565 Incr = New(WithBacking([]float64{100, 100, 100, 100}), WithShape(2, 2)) 566 T3, _ = V.Mul(T2, WithIncr(Incr)) 567 fmt.Printf("Incr tensor passed in (sliced tensor)\n======================================\nIncr += T1 × T2\nIncr == T3: %t\nT3:\n%v\n", Incr == T3, T3) 568 569 // Output: 570 // Incr tensor passed in 571 // ====================== 572 // Incr += T1 × T2 573 // Incr == T3: true 574 // T3: 575 // ⎡100 111 124⎤ 576 // ⎢139 156 175⎥ 577 // ⎣196 219 244⎦ 578 // 579 // Incr tensor passed in (sliced tensor) 580 // ====================================== 581 // Incr += T1 × T2 582 // Incr == T3: true 583 // T3: 584 // ⎡100 111⎤ 585 // ⎣136 152⎦ 586 } 587 588 /* DIV */ 589 590 // By default, arithmetic operations are safe 591 func ExampleDense_Div_basic() { 592 var T1, T2, T3, V *Dense 593 var sliced Tensor 594 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 595 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 596 T3, _ = T1.Div(T2) 597 fmt.Printf("Default operation is safe\n==========================\nT3 = T1 ÷ T2\nT3:\n%1.1v\nT1 is unchanged:\n%1.1v\n", T3, T1) 598 599 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 600 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 601 V = sliced.(*Dense) 602 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 603 T3, _ = V.Div(T2) 604 fmt.Printf("Default operation is safe (sliced operations)\n=============================================\nT3 = T1[0:2, 0:2] ÷ T2\nT3:\n%1.1v\nT1 is unchanged:\n%1.1v\n", T3, T1) 605 606 // Output: 607 // Default operation is safe 608 // ========================== 609 // T3 = T1 ÷ T2 610 // T3: 611 // ⎡ 0 0.09 0.2⎤ 612 // ⎢ 0.2 0.3 0.3⎥ 613 // ⎣ 0.4 0.4 0.4⎦ 614 // 615 // T1 is unchanged: 616 // ⎡0 1 2⎤ 617 // ⎢3 4 5⎥ 618 // ⎣6 7 8⎦ 619 // 620 // Default operation is safe (sliced operations) 621 // ============================================= 622 // T3 = T1[0:2, 0:2] ÷ T2 623 // T3: 624 // ⎡ 0 0.09⎤ 625 // ⎣ 0.2 0.3⎦ 626 // 627 // T1 is unchanged: 628 // ⎡0 1 2⎤ 629 // ⎢3 4 5⎥ 630 // ⎣6 7 8⎦ 631 } 632 633 // To perform unsafe operations, use the `UseUnsafe` function option 634 func ExampleDense_Div_unsafe() { 635 var T1, T2, T3, V *Dense 636 var sliced Tensor 637 638 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 639 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 640 T3, _ = T1.Div(T2, UseUnsafe()) 641 fmt.Printf("Unsafe Operation\n================\nT3 = T1 ÷ T2\nT1 == T3: %t\nT1:\n%1.1v", T1 == T3, T1) 642 643 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 644 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 645 V = sliced.(*Dense) 646 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 647 648 V.Div(T2, UseUnsafe()) // unsafe overwrites the data in T1 649 fmt.Printf("Unsafe Operation on sliced Tensors\n==================================\nV = T1[0:2, 0:2] ÷ T2\nV:\n%1.1v\n", V) 650 fmt.Printf("Naturally, T1 is mutated too:\n%1.1v", T1) 651 652 // Output: 653 // Unsafe Operation 654 // ================ 655 // T3 = T1 ÷ T2 656 // T1 == T3: true 657 // T1: 658 // ⎡ 0 0.09 0.2⎤ 659 // ⎢ 0.2 0.3 0.3⎥ 660 // ⎣ 0.4 0.4 0.4⎦ 661 // Unsafe Operation on sliced Tensors 662 // ================================== 663 // V = T1[0:2, 0:2] ÷ T2 664 // V: 665 // ⎡ 0 0.09⎤ 666 // ⎣ 0.2 0.3⎦ 667 // 668 // Naturally, T1 is mutated too: 669 // ⎡ 0 0.09 2⎤ 670 // ⎢ 0.2 0.3 5⎥ 671 // ⎣ 6 7 8⎦ 672 } 673 674 // An optional reuse tensor can also be specified with the WithReuse function option 675 func ExampleDense_Div_reuse() { 676 var T1, V, T2, Reuse, T3 *Dense 677 var sliced Tensor 678 679 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 680 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 681 Reuse = New(WithBacking(Range(Float64, 100, 109)), WithShape(3, 3)) 682 T3, _ = T1.Div(T2, WithReuse(Reuse)) 683 fmt.Printf("Reuse tensor passed in\n======================\nT3 == Reuse: %t\nT3:\n%1.1v\n", T3 == Reuse, T3) 684 685 // You can also use it on operations on sliced tensors - note your reuse tensor has to be the same shape as the result 686 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 687 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 688 V = sliced.(*Dense) 689 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 690 Reuse = New(WithBacking(Range(Float64, 100, 104)), WithShape(2, 2)) // same shape as result 691 T3, _ = V.Div(T2, WithReuse(Reuse)) 692 fmt.Printf("Reuse tensor passed in (sliced tensor)\n======================================\nT3 == Reuse: %t\nT3:\n%1.1v", T3 == Reuse, T3) 693 694 // Output: 695 // Reuse tensor passed in 696 // ====================== 697 // T3 == Reuse: true 698 // T3: 699 // ⎡ 0 0.09 0.2⎤ 700 // ⎢ 0.2 0.3 0.3⎥ 701 // ⎣ 0.4 0.4 0.4⎦ 702 // 703 // Reuse tensor passed in (sliced tensor) 704 // ====================================== 705 // T3 == Reuse: true 706 // T3: 707 // ⎡ 0 0.09⎤ 708 // ⎣ 0.2 0.3⎦ 709 } 710 711 // An optional reuse tensor can also be specified with the WithReuse function option. Passing in an operand would not cause a problem. 712 func ExampleDense_Div_reuse_operand() { 713 var T1, T2, T3 *Dense 714 715 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 716 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 717 T3, _ = T1.Div(T2, WithReuse(T1)) 718 fmt.Printf("Reuse tensor passed in\n======================\nT3 == T1: %t\nT3:\n%1.1v\n", T3 == T1, T3) 719 720 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 721 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 722 T3, _ = T1.Div(T2, WithReuse(T2)) 723 fmt.Printf("Reuse tensor passed in\n======================\nT3 == T2: %t\nT3:\n%1.1v\n", T3 == T2, T3) 724 725 // Output: 726 // Reuse tensor passed in 727 // ====================== 728 // T3 == T1: true 729 // T3: 730 // ⎡ 0 0.09 0.2⎤ 731 // ⎢ 0.2 0.3 0.3⎥ 732 // ⎣ 0.4 0.4 0.4⎦ 733 // 734 // Reuse tensor passed in 735 // ====================== 736 // T3 == T2: true 737 // T3: 738 // ⎡ 0 0.09 0.2⎤ 739 // ⎢ 0.2 0.3 0.3⎥ 740 // ⎣ 0.4 0.4 0.4⎦ 741 } 742 743 // Incrementing a tensor is also a function option provided by the package 744 func ExampleDense_Div_incr() { 745 var T1, T2, T3, Incr, V *Dense 746 var sliced Tensor 747 748 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 749 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 750 Incr = New(WithBacking([]float64{100, 100, 100, 100, 100, 100, 100, 100, 100}), WithShape(3, 3)) 751 T3, _ = T1.Div(T2, WithIncr(Incr)) 752 fmt.Printf("Incr tensor passed in\n======================\nIncr += T1 ÷ T2\nIncr == T3: %t\nT3:\n%1.5v\n", Incr == T3, T3) 753 754 // Operations on sliced tensor is also allowed. Note that your Incr tensor has to be the same shape as the result 755 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 756 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 757 V = sliced.(*Dense) 758 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 759 Incr = New(WithBacking([]float64{100, 100, 100, 100}), WithShape(2, 2)) 760 T3, _ = V.Div(T2, WithIncr(Incr)) 761 fmt.Printf("Incr tensor passed in (sliced tensor)\n======================================\nIncr += T1 ÷ T2\nIncr == T3: %t\nT3:\n%1.5v\n", Incr == T3, T3) 762 763 // Output: 764 // Incr tensor passed in 765 // ====================== 766 // Incr += T1 ÷ T2 767 // Incr == T3: true 768 // T3: 769 // ⎡ 100 100.09 100.17⎤ 770 // ⎢100.23 100.29 100.33⎥ 771 // ⎣100.38 100.41 100.44⎦ 772 // 773 // Incr tensor passed in (sliced tensor) 774 // ====================================== 775 // Incr += T1 ÷ T2 776 // Incr == T3: true 777 // T3: 778 // ⎡ 100 100.09⎤ 779 // ⎣100.25 100.31⎦ 780 } 781 782 /* POW */ 783 784 // By default, arithmetic operations are safe 785 func ExampleDense_Pow_basic() { 786 var T1, T2, T3, V *Dense 787 var sliced Tensor 788 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 789 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 790 T3, _ = T1.Pow(T2) 791 fmt.Printf("Default operation is safe\n==========================\nT3 = T1 ^ T2\nT3:\n%1.1v\nT1 is unchanged:\n%v\n", T3, T1) 792 793 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 794 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 795 V = sliced.(*Dense) 796 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 797 T3, _ = V.Pow(T2) 798 fmt.Printf("Default operation is safe (sliced operations)\n=============================================\nT3 = T1[0:2, 0:2] ^ T2\nT3:\n%1.1v\nT1 is unchanged:\n%v\n", T3, T1) 799 800 // Output: 801 // Default operation is safe 802 // ========================== 803 // T3 = T1 ^ T2 804 // T3: 805 // ⎡ 0 1 4e+03⎤ 806 // ⎢2e+06 3e+08 3e+10⎥ 807 // ⎣3e+12 2e+14 2e+16⎦ 808 // 809 // T1 is unchanged: 810 // ⎡0 1 2⎤ 811 // ⎢3 4 5⎥ 812 // ⎣6 7 8⎦ 813 // 814 // Default operation is safe (sliced operations) 815 // ============================================= 816 // T3 = T1[0:2, 0:2] ^ T2 817 // T3: 818 // ⎡ 0 1⎤ 819 // ⎣5e+05 7e+07⎦ 820 // 821 // T1 is unchanged: 822 // ⎡0 1 2⎤ 823 // ⎢3 4 5⎥ 824 // ⎣6 7 8⎦ 825 } 826 827 // To perform unsafe operations, use the `UseUnsafe` function option 828 func ExampleDense_Pow_unsafe() { 829 var T1, T2, T3, V *Dense 830 var sliced Tensor 831 832 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 833 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 834 T3, _ = T1.Pow(T2, UseUnsafe()) 835 fmt.Printf("Unsafe Operation\n================\nT3 = T1 ^ T2\nT1 == T3: %t\nT1:\n%1.1v\n", T1 == T3, T1) 836 837 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 838 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 839 V = sliced.(*Dense) 840 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 841 842 V.Pow(T2, UseUnsafe()) // unsafe overwrites the data in T1 843 fmt.Printf("Unsafe Operation on sliced Tensors\n==================================\nV = T1[0:2, 0:2] ^ T2\nV:\n%1.1v\n", V) 844 fmt.Printf("Naturally, T1 is mutated too:\n%1.1v", T1) 845 846 // Output: 847 // Unsafe Operation 848 // ================ 849 // T3 = T1 ^ T2 850 // T1 == T3: true 851 // T1: 852 // ⎡ 0 1 4e+03⎤ 853 // ⎢2e+06 3e+08 3e+10⎥ 854 // ⎣3e+12 2e+14 2e+16⎦ 855 // 856 // Unsafe Operation on sliced Tensors 857 // ================================== 858 // V = T1[0:2, 0:2] ^ T2 859 // V: 860 // ⎡ 0 1⎤ 861 // ⎣5e+05 7e+07⎦ 862 // 863 // Naturally, T1 is mutated too: 864 // ⎡ 0 1 2⎤ 865 // ⎢5e+05 7e+07 5⎥ 866 // ⎣ 6 7 8⎦ 867 } 868 869 // An optional reuse tensor can also be specified with the WithReuse function option 870 func ExampleDense_Pow_reuse() { 871 var T1, V, T2, Reuse, T3 *Dense 872 var sliced Tensor 873 874 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 875 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 876 Reuse = New(WithBacking(Range(Float64, 100, 109)), WithShape(3, 3)) 877 T3, _ = T1.Pow(T2, WithReuse(Reuse)) 878 fmt.Printf("Reuse tensor passed in\n======================\nT3 == Reuse: %t\nT3:\n%1.1v\n", T3 == Reuse, T3) 879 880 // You can also use it on operations on sliced tensors - note your reuse tensor has to be the same shape as the result 881 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 882 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 883 V = sliced.(*Dense) 884 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 885 Reuse = New(WithBacking(Range(Float64, 100, 104)), WithShape(2, 2)) // same shape as result 886 T3, _ = V.Pow(T2, WithReuse(Reuse)) 887 fmt.Printf("Reuse tensor passed in (sliced tensor)\n======================================\nT3 == Reuse: %t\nT3:\n%1.v", T3 == Reuse, T3) 888 889 // Output: 890 // Reuse tensor passed in 891 // ====================== 892 // T3 == Reuse: true 893 // T3: 894 // ⎡ 0 1 4e+03⎤ 895 // ⎢2e+06 3e+08 3e+10⎥ 896 // ⎣3e+12 2e+14 2e+16⎦ 897 // 898 // Reuse tensor passed in (sliced tensor) 899 // ====================================== 900 // T3 == Reuse: true 901 // T3: 902 // ⎡ 0 1⎤ 903 // ⎣5e+05 7e+07⎦ 904 } 905 906 // Incrementing a tensor is also a function option provided by the package 907 func ExampleDense_Pow_incr() { 908 var T1, T2, T3, Incr, V *Dense 909 var sliced Tensor 910 911 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 912 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 913 Incr = New(WithBacking([]float64{100, 100, 100, 100, 100, 100, 100, 100, 100}), WithShape(3, 3)) 914 T3, _ = T1.Pow(T2, WithIncr(Incr)) 915 fmt.Printf("Incr tensor passed in\n======================\nIncr += T1 ^ T2\nIncr == T3: %t\nT3:\n%1.5v\n", Incr == T3, T3) 916 917 // Operations on sliced tensor is also allowed. Note that your Incr tensor has to be the same shape as the result 918 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 919 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 920 V = sliced.(*Dense) 921 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 922 Incr = New(WithBacking([]float64{100, 100, 100, 100}), WithShape(2, 2)) 923 T3, _ = V.Pow(T2, WithIncr(Incr)) 924 fmt.Printf("Incr tensor passed in (sliced tensor)\n======================================\nIncr += T1 ^ T2\nIncr == T3: %t\nT3:\n%1.5v\n", Incr == T3, T3) 925 926 // Output: 927 // Incr tensor passed in 928 // ====================== 929 // Incr += T1 ^ T2 930 // Incr == T3: true 931 // T3: 932 // ⎡ 100 101 4196⎤ 933 // ⎢1.5944e+06 2.6844e+08 3.0518e+10⎥ 934 // ⎣2.8211e+12 2.3263e+14 1.8014e+16⎦ 935 // 936 // Incr tensor passed in (sliced tensor) 937 // ====================================== 938 // Incr += T1 ^ T2 939 // Incr == T3: true 940 // T3: 941 // ⎡ 100 101⎤ 942 // ⎣5.3154e+05 6.7109e+07⎦ 943 } 944 945 /* MOD */ 946 947 // By default, arithmetic operations are safe 948 func ExampleDense_Mod_basic() { 949 var T1, T2, T3, V *Dense 950 var sliced Tensor 951 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 952 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 953 T3, _ = T1.Mod(T2) 954 fmt.Printf("Default operation is safe\n==========================\nT3 = T1 %% T2\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 955 956 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 957 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 958 V = sliced.(*Dense) 959 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 960 T3, _ = V.Mod(T2) 961 fmt.Printf("Default operation is safe (sliced operations)\n=============================================\nT3 = T1[0:2, 0:2] %% T2\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 962 963 // Output: 964 // Default operation is safe 965 // ========================== 966 // T3 = T1 % T2 967 // T3: 968 // ⎡0 1 2⎤ 969 // ⎢3 4 5⎥ 970 // ⎣6 7 8⎦ 971 // 972 // T1 is unchanged: 973 // ⎡0 1 2⎤ 974 // ⎢3 4 5⎥ 975 // ⎣6 7 8⎦ 976 // 977 // Default operation is safe (sliced operations) 978 // ============================================= 979 // T3 = T1[0:2, 0:2] % T2 980 // T3: 981 // ⎡0 1⎤ 982 // ⎣3 4⎦ 983 // 984 // T1 is unchanged: 985 // ⎡0 1 2⎤ 986 // ⎢3 4 5⎥ 987 // ⎣6 7 8⎦ 988 } 989 990 // To perform unsafe operations, use the `UseUnsafe` function option 991 func ExampleDense_Mod_unsafe() { 992 var T1, T2, T3, V *Dense 993 var sliced Tensor 994 995 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 996 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 997 T3, _ = T1.Mod(T2, UseUnsafe()) 998 fmt.Printf("Unsafe Operation\n================\nT3 = T1 %% T2\nT1 == T3: %t\nT1:\n%v\n", T1 == T3, T1) 999 1000 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 1001 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 1002 V = sliced.(*Dense) 1003 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 1004 1005 V.Mod(T2, UseUnsafe()) // unsafe overwrites the data in T1 1006 fmt.Printf("Unsafe Operation on sliced Tensors\n==================================\nV = T1[0:2, 0:2] %% T2\nV:\n%v\n", V) 1007 fmt.Printf("Naturally, T1 is mutated too:\n%v", T1) 1008 1009 // Output: 1010 // Unsafe Operation 1011 // ================ 1012 // T3 = T1 % T2 1013 // T1 == T3: true 1014 // T1: 1015 // ⎡0 1 2⎤ 1016 // ⎢3 4 5⎥ 1017 // ⎣6 7 8⎦ 1018 // 1019 // Unsafe Operation on sliced Tensors 1020 // ================================== 1021 // V = T1[0:2, 0:2] % T2 1022 // V: 1023 // ⎡0 1⎤ 1024 // ⎣3 4⎦ 1025 // 1026 // Naturally, T1 is mutated too: 1027 // ⎡0 1 2⎤ 1028 // ⎢3 4 5⎥ 1029 // ⎣6 7 8⎦ 1030 } 1031 1032 // An optional reuse tensor can also be specified with the WithReuse function option 1033 func ExampleDense_Mod_reuse() { 1034 var T1, V, T2, Reuse, T3 *Dense 1035 var sliced Tensor 1036 1037 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 1038 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 1039 Reuse = New(WithBacking(Range(Float64, 100, 109)), WithShape(3, 3)) 1040 T3, _ = T1.Mod(T2, WithReuse(Reuse)) 1041 fmt.Printf("Reuse tensor passed in\n======================\nT3 == Reuse: %t\nT3:\n%v\n", T3 == Reuse, T3) 1042 1043 // You can also use it on operations on sliced tensors - note your reuse tensor has to be the same shape as the result 1044 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 1045 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 1046 V = sliced.(*Dense) 1047 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 1048 Reuse = New(WithBacking(Range(Float64, 100, 104)), WithShape(2, 2)) // same shape as result 1049 T3, _ = V.Mod(T2, WithReuse(Reuse)) 1050 fmt.Printf("Reuse tensor passed in (sliced tensor)\n======================================\nT3 == Reuse: %t\nT3:\n%v", T3 == Reuse, T3) 1051 1052 // Output: 1053 // Reuse tensor passed in 1054 // ====================== 1055 // T3 == Reuse: true 1056 // T3: 1057 // ⎡0 1 2⎤ 1058 // ⎢3 4 5⎥ 1059 // ⎣6 7 8⎦ 1060 // 1061 // Reuse tensor passed in (sliced tensor) 1062 // ====================================== 1063 // T3 == Reuse: true 1064 // T3: 1065 // ⎡0 1⎤ 1066 // ⎣3 4⎦ 1067 } 1068 1069 // Incrementing a tensor is also a function option provided by the package 1070 func ExampleDense_Mod_incr() { 1071 var T1, T2, T3, Incr, V *Dense 1072 var sliced Tensor 1073 1074 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 1075 T2 = New(WithBacking(Range(Float64, 10, 19)), WithShape(3, 3)) 1076 Incr = New(WithBacking([]float64{100, 100, 100, 100, 100, 100, 100, 100, 100}), WithShape(3, 3)) 1077 T3, _ = T1.Mod(T2, WithIncr(Incr)) 1078 fmt.Printf("Incr tensor passed in\n======================\nIncr += T1 %% T2\nIncr == T3: %t\nT3:\n%v\n", Incr == T3, T3) 1079 1080 // Operations on sliced tensor is also allowed. Note that your Incr tensor has to be the same shape as the result 1081 T1 = New(WithBacking(Range(Float64, 0, 9)), WithShape(3, 3)) 1082 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 1083 V = sliced.(*Dense) 1084 T2 = New(WithBacking(Range(Float64, 10, 14)), WithShape(2, 2)) 1085 Incr = New(WithBacking([]float64{100, 100, 100, 100}), WithShape(2, 2)) 1086 T3, _ = V.Mod(T2, WithIncr(Incr)) 1087 fmt.Printf("Incr tensor passed in (sliced tensor)\n======================================\nIncr += T1 %% T2\nIncr == T3: %t\nT3:\n%v\n", Incr == T3, T3) 1088 1089 // Output: 1090 // Incr tensor passed in 1091 // ====================== 1092 // Incr += T1 % T2 1093 // Incr == T3: true 1094 // T3: 1095 // ⎡100 101 102⎤ 1096 // ⎢103 104 105⎥ 1097 // ⎣106 107 108⎦ 1098 // 1099 // Incr tensor passed in (sliced tensor) 1100 // ====================================== 1101 // Incr += T1 % T2 1102 // Incr == T3: true 1103 // T3: 1104 // ⎡100 101⎤ 1105 // ⎣103 104⎦ 1106 } 1107 1108 /* TENSOR-SCALAR AND VICE VERSA OPERATIONS */ 1109 1110 /* ADD */ 1111 1112 // By default, arithmetic operations are safe 1113 func ExampleDense_AddScalar_basic() { 1114 var T1, T3, V *Dense 1115 var sliced Tensor 1116 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1117 T3, _ = T1.AddScalar(float32(5), true) 1118 fmt.Printf("Default operation is safe (tensor is left operand)\n==========================\nT3 = T1 + 5\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 1119 1120 T3, _ = T1.AddScalar(float32(5), false) 1121 fmt.Printf("Default operation is safe (tensor is right operand)\n==========================\nT3 = 5 + T1\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 1122 1123 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1124 sliced, _ = T1.Slice(nil, makeRS(1, 3)) 1125 V = sliced.(*Dense) 1126 T3, _ = V.AddScalar(float32(5), true) 1127 fmt.Printf("Default operation is safe (sliced operations - tensor is left operand)\n=============================================\nT3 = T1[:, 1:3] + 5\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 1128 1129 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1130 sliced, _ = T1.Slice(nil, makeRS(1, 3)) 1131 V = sliced.(*Dense) 1132 T3, _ = V.AddScalar(float32(5), false) 1133 fmt.Printf("Default operation is safe (sliced operations - tensor is right operand)\n=============================================\nT3 = 5 + T1[:, 1:3]\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 1134 1135 // Output: 1136 // Default operation is safe (tensor is left operand) 1137 // ========================== 1138 // T3 = T1 + 5 1139 // T3: 1140 // ⎡ 5 6 7⎤ 1141 // ⎢ 8 9 10⎥ 1142 // ⎣11 12 13⎦ 1143 // 1144 // T1 is unchanged: 1145 // ⎡0 1 2⎤ 1146 // ⎢3 4 5⎥ 1147 // ⎣6 7 8⎦ 1148 // 1149 // Default operation is safe (tensor is right operand) 1150 // ========================== 1151 // T3 = 5 + T1 1152 // T3: 1153 // ⎡ 5 6 7⎤ 1154 // ⎢ 8 9 10⎥ 1155 // ⎣11 12 13⎦ 1156 // 1157 // T1 is unchanged: 1158 // ⎡0 1 2⎤ 1159 // ⎢3 4 5⎥ 1160 // ⎣6 7 8⎦ 1161 // 1162 // Default operation is safe (sliced operations - tensor is left operand) 1163 // ============================================= 1164 // T3 = T1[:, 1:3] + 5 1165 // T3: 1166 // ⎡ 6 7⎤ 1167 // ⎢ 9 10⎥ 1168 // ⎣12 13⎦ 1169 // 1170 // T1 is unchanged: 1171 // ⎡0 1 2⎤ 1172 // ⎢3 4 5⎥ 1173 // ⎣6 7 8⎦ 1174 // 1175 // Default operation is safe (sliced operations - tensor is right operand) 1176 // ============================================= 1177 // T3 = 5 + T1[:, 1:3] 1178 // T3: 1179 // ⎡ 6 7⎤ 1180 // ⎢ 9 10⎥ 1181 // ⎣12 13⎦ 1182 // 1183 // T1 is unchanged: 1184 // ⎡0 1 2⎤ 1185 // ⎢3 4 5⎥ 1186 // ⎣6 7 8⎦ 1187 } 1188 1189 func ExampleDense_AddScalar_unsafe() { 1190 var T1, T3, V *Dense 1191 var sliced Tensor 1192 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1193 T3, _ = T1.AddScalar(float32(5), true, UseUnsafe()) 1194 fmt.Printf("Operation is unsafe (tensor is left operand)\n==========================\nT3 = T1 + 5\nT3:\n%v\nT3 == T1: %t\nT1 is changed:\n%v\n", T3, T3 == T1, T1) 1195 1196 T3, _ = T1.AddScalar(float32(5), false, UseUnsafe()) 1197 fmt.Printf("Operation is unsafe (tensor is right operand)\n==========================\nT3 = 5 + T1\nT3:\n%v\nT3 == T1: %t\nT1 is changed:\n%v\n", T3, T3 == T1, T1) 1198 1199 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1200 sliced, _ = T1.Slice(nil, makeRS(0, 2)) 1201 V = sliced.(*Dense) 1202 T3, _ = V.AddScalar(float32(5), true, UseUnsafe()) 1203 fmt.Printf("Operation is unsafe (sliced operations - tensor is left operand)\n=============================================\nT3 = T1[:, 0:2] + 5\nT3:\n%v\nsliced == T3: %t\nT1 is changed:\n%v\n", T3, sliced == T3, T1) 1204 1205 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1206 sliced, _ = T1.Slice(nil, makeRS(0, 2)) 1207 V = sliced.(*Dense) 1208 T3, _ = V.AddScalar(float32(5), false, UseUnsafe()) 1209 fmt.Printf("Operation is unsafe (sliced operations - tensor is right operand)\n=============================================\nT3 = 5 + T1[:, 0:2]\nT3:\n%v\nsliced == T3: %t\nT1 is changed:\n%v\n", T3, sliced == T3, T1) 1210 1211 // Output: 1212 // Operation is unsafe (tensor is left operand) 1213 // ========================== 1214 // T3 = T1 + 5 1215 // T3: 1216 // ⎡ 5 6 7⎤ 1217 // ⎢ 8 9 10⎥ 1218 // ⎣11 12 13⎦ 1219 // 1220 // T3 == T1: true 1221 // T1 is changed: 1222 // ⎡ 5 6 7⎤ 1223 // ⎢ 8 9 10⎥ 1224 // ⎣11 12 13⎦ 1225 // 1226 // Operation is unsafe (tensor is right operand) 1227 // ========================== 1228 // T3 = 5 + T1 1229 // T3: 1230 // ⎡10 11 12⎤ 1231 // ⎢13 14 15⎥ 1232 // ⎣16 17 18⎦ 1233 // 1234 // T3 == T1: true 1235 // T1 is changed: 1236 // ⎡10 11 12⎤ 1237 // ⎢13 14 15⎥ 1238 // ⎣16 17 18⎦ 1239 // 1240 // Operation is unsafe (sliced operations - tensor is left operand) 1241 // ============================================= 1242 // T3 = T1[:, 0:2] + 5 1243 // T3: 1244 // ⎡ 5 6⎤ 1245 // ⎢ 8 9⎥ 1246 // ⎣11 12⎦ 1247 // 1248 // sliced == T3: true 1249 // T1 is changed: 1250 // ⎡ 5 6 2⎤ 1251 // ⎢ 8 9 5⎥ 1252 // ⎣11 12 8⎦ 1253 // 1254 // Operation is unsafe (sliced operations - tensor is right operand) 1255 // ============================================= 1256 // T3 = 5 + T1[:, 0:2] 1257 // T3: 1258 // ⎡ 5 6⎤ 1259 // ⎢ 8 9⎥ 1260 // ⎣11 12⎦ 1261 // 1262 // sliced == T3: true 1263 // T1 is changed: 1264 // ⎡ 5 6 2⎤ 1265 // ⎢ 8 9 5⎥ 1266 // ⎣11 12 8⎦ 1267 } 1268 1269 // Reuse tensors may be used, with the WithReuse() function option. 1270 func ExampleDense_AddScalar_reuse() { 1271 var T1, V, Reuse, T3 *Dense 1272 var sliced Tensor 1273 1274 // Tensor is left operand 1275 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1276 Reuse = New(WithBacking(Range(Float32, 100, 109)), WithShape(3, 3)) 1277 T3, _ = T1.AddScalar(float32(5), true, WithReuse(Reuse)) 1278 fmt.Printf("Reuse tensor passed in (Tensor is left operand)\n======================\nT3 == Reuse: %t\nT3:\n%v\n", T3 == Reuse, T3) 1279 1280 // Tensor is right operand 1281 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1282 Reuse = New(WithBacking(Range(Float32, 100, 109)), WithShape(3, 3)) 1283 T3, _ = T1.AddScalar(float32(5), false, WithReuse(Reuse)) 1284 fmt.Printf("Reuse tensor passed in (Tensor is right operand)\n======================\nT3 == Reuse: %t\nT3:\n%v\n", T3 == Reuse, T3) 1285 1286 // Tensor is left operand 1287 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1288 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 1289 V = sliced.(*Dense) 1290 Reuse = New(WithBacking(Range(Float32, 100, 104)), WithShape(2, 2)) // same shape as result 1291 T3, _ = V.AddScalar(float32(5), true, WithReuse(Reuse)) 1292 fmt.Printf("Reuse tensor passed in (sliced tensor - Tensor is left operand)\n======================================\nT3 == Reuse: %t\nT3:\n%v\n", T3 == Reuse, T3) 1293 1294 // Tensor is left operand 1295 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1296 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 1297 V = sliced.(*Dense) 1298 Reuse = New(WithBacking(Range(Float32, 100, 104)), WithShape(2, 2)) // same shape as result 1299 T3, _ = V.AddScalar(float32(5), false, WithReuse(Reuse)) 1300 fmt.Printf("Reuse tensor passed in (sliced tensor - Tensor is left operand)\n======================================\nT3 == Reuse: %t\nT3:\n%v", T3 == Reuse, T3) 1301 1302 // Output: 1303 // Reuse tensor passed in (Tensor is left operand) 1304 // ====================== 1305 // T3 == Reuse: true 1306 // T3: 1307 // ⎡ 5 6 7⎤ 1308 // ⎢ 8 9 10⎥ 1309 // ⎣11 12 13⎦ 1310 // 1311 // Reuse tensor passed in (Tensor is right operand) 1312 // ====================== 1313 // T3 == Reuse: true 1314 // T3: 1315 // ⎡ 5 6 7⎤ 1316 // ⎢ 8 9 10⎥ 1317 // ⎣11 12 13⎦ 1318 // 1319 // Reuse tensor passed in (sliced tensor - Tensor is left operand) 1320 // ====================================== 1321 // T3 == Reuse: true 1322 // T3: 1323 // ⎡5 6⎤ 1324 // ⎣8 9⎦ 1325 // 1326 // Reuse tensor passed in (sliced tensor - Tensor is left operand) 1327 // ====================================== 1328 // T3 == Reuse: true 1329 // T3: 1330 // ⎡5 6⎤ 1331 // ⎣8 9⎦ 1332 } 1333 1334 // Incrementing a tensor is also a function option provided by the package 1335 func ExampleDense_AddScalar_incr() { 1336 var T1, T3, Incr, V *Dense 1337 var sliced Tensor 1338 1339 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1340 Incr = New(WithBacking([]float32{100, 100, 100, 100, 100, 100, 100, 100, 100}), WithShape(3, 3)) 1341 T3, _ = T1.AddScalar(float32(5), true, WithIncr(Incr)) 1342 fmt.Printf("Incr tensor passed in\n======================\nIncr += T1 + T2\nIncr == T3: %t\nT3:\n%v\n", Incr == T3, T3) 1343 1344 // Operations on sliced tensor is also allowed. Note that your Incr tensor has to be the same shape as the result 1345 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1346 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 1347 V = sliced.(*Dense) 1348 Incr = New(WithBacking([]float32{100, 100, 100, 100}), WithShape(2, 2)) 1349 T3, _ = V.AddScalar(float32(5), true, WithIncr(Incr)) 1350 fmt.Printf("Incr tensor passed in (sliced tensor)\n======================================\nIncr += T1 + T2\nIncr == T3: %t\nT3:\n%v\n", Incr == T3, T3) 1351 1352 // Output: 1353 // Incr tensor passed in 1354 // ====================== 1355 // Incr += T1 + T2 1356 // Incr == T3: true 1357 // T3: 1358 // ⎡105 106 107⎤ 1359 // ⎢108 109 110⎥ 1360 // ⎣111 112 113⎦ 1361 // 1362 // Incr tensor passed in (sliced tensor) 1363 // ====================================== 1364 // Incr += T1 + T2 1365 // Incr == T3: true 1366 // T3: 1367 // ⎡105 106⎤ 1368 // ⎣108 109⎦ 1369 } 1370 1371 // By default, arithmetic operations are safe 1372 func ExampleDense_SubScalar_basic() { 1373 var T1, T3, V *Dense 1374 var sliced Tensor 1375 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1376 T3, _ = T1.SubScalar(float32(5), true) 1377 fmt.Printf("Default operation is safe (tensor is left operand)\n==========================\nT3 = T1 - 5\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 1378 1379 T3, _ = T1.SubScalar(float32(5), false) 1380 fmt.Printf("Default operation is safe (tensor is right operand)\n==========================\nT3 = 5 - T1\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 1381 1382 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1383 sliced, _ = T1.Slice(nil, makeRS(1, 3)) 1384 V = sliced.(*Dense) 1385 T3, _ = V.SubScalar(float32(5), true) 1386 fmt.Printf("Default operation is safe (sliced operations - tensor is left operand)\n=============================================\nT3 = T1[:, 1:3] + 5\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 1387 1388 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1389 sliced, _ = T1.Slice(nil, makeRS(1, 3)) 1390 V = sliced.(*Dense) 1391 T3, _ = V.SubScalar(float32(5), false) 1392 fmt.Printf("Default operation is safe (sliced operations - tensor is right operand)\n=============================================\nT3 = 5 - T1[:, 1:3]\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 1393 1394 // Output: 1395 // Default operation is safe (tensor is left operand) 1396 // ========================== 1397 // T3 = T1 - 5 1398 // T3: 1399 // ⎡-5 -4 -3⎤ 1400 // ⎢-2 -1 0⎥ 1401 // ⎣ 1 2 3⎦ 1402 // 1403 // T1 is unchanged: 1404 // ⎡0 1 2⎤ 1405 // ⎢3 4 5⎥ 1406 // ⎣6 7 8⎦ 1407 // 1408 // Default operation is safe (tensor is right operand) 1409 // ========================== 1410 // T3 = 5 - T1 1411 // T3: 1412 // ⎡ 5 4 3⎤ 1413 // ⎢ 2 1 0⎥ 1414 // ⎣-1 -2 -3⎦ 1415 // 1416 // T1 is unchanged: 1417 // ⎡0 1 2⎤ 1418 // ⎢3 4 5⎥ 1419 // ⎣6 7 8⎦ 1420 // 1421 // Default operation is safe (sliced operations - tensor is left operand) 1422 // ============================================= 1423 // T3 = T1[:, 1:3] + 5 1424 // T3: 1425 // ⎡-4 -3⎤ 1426 // ⎢-1 0⎥ 1427 // ⎣ 2 3⎦ 1428 // 1429 // T1 is unchanged: 1430 // ⎡0 1 2⎤ 1431 // ⎢3 4 5⎥ 1432 // ⎣6 7 8⎦ 1433 // 1434 // Default operation is safe (sliced operations - tensor is right operand) 1435 // ============================================= 1436 // T3 = 5 - T1[:, 1:3] 1437 // T3: 1438 // ⎡ 4 3⎤ 1439 // ⎢ 1 0⎥ 1440 // ⎣-2 -3⎦ 1441 // 1442 // T1 is unchanged: 1443 // ⎡0 1 2⎤ 1444 // ⎢3 4 5⎥ 1445 // ⎣6 7 8⎦ 1446 1447 } 1448 1449 func ExampleDense_SubScalar_unsafe() { 1450 var T1, T3, V *Dense 1451 var sliced Tensor 1452 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1453 T3, _ = T1.SubScalar(float32(5), true, UseUnsafe()) 1454 fmt.Printf("Operation is unsafe (tensor is left operand)\n==========================\nT3 = T1 - 5\nT3:\n%v\nT3 == T1: %t\nT1 is changed:\n%v\n", T3, T3 == T1, T1) 1455 1456 T3, _ = T1.SubScalar(float32(5), false, UseUnsafe()) 1457 fmt.Printf("Operation is unsafe (tensor is right operand)\n==========================\nT3 = 5 - T1\nT3:\n%v\nT3 == T1: %t\nT1 is changed:\n%v\n", T3, T3 == T1, T1) 1458 1459 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1460 sliced, _ = T1.Slice(nil, makeRS(0, 2)) 1461 V = sliced.(*Dense) 1462 T3, _ = V.SubScalar(float32(5), true, UseUnsafe()) 1463 fmt.Printf("Operation is unsafe (sliced operations - tensor is left operand)\n=============================================\nT3 = T1[:, 0:2] + 5\nT3:\n%v\nsliced == T3: %t\nT1 is changed:\n%v\n", T3, sliced == T3, T1) 1464 1465 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1466 sliced, _ = T1.Slice(nil, makeRS(0, 2)) 1467 V = sliced.(*Dense) 1468 T3, _ = V.SubScalar(float32(5), false, UseUnsafe()) 1469 fmt.Printf("Operation is unsafe (sliced operations - tensor is right operand)\n=============================================\nT3 = 5 - T1[:, 0:2]\nT3:\n%v\nsliced == T3: %t\nT1 is changed:\n%v\n", T3, sliced == T3, T1) 1470 1471 // Output: 1472 // Operation is unsafe (tensor is left operand) 1473 // ========================== 1474 // T3 = T1 - 5 1475 // T3: 1476 // ⎡-5 -4 -3⎤ 1477 // ⎢-2 -1 0⎥ 1478 // ⎣ 1 2 3⎦ 1479 // 1480 // T3 == T1: true 1481 // T1 is changed: 1482 // ⎡-5 -4 -3⎤ 1483 // ⎢-2 -1 0⎥ 1484 // ⎣ 1 2 3⎦ 1485 // 1486 // Operation is unsafe (tensor is right operand) 1487 // ========================== 1488 // T3 = 5 - T1 1489 // T3: 1490 // ⎡10 9 8⎤ 1491 // ⎢ 7 6 5⎥ 1492 // ⎣ 4 3 2⎦ 1493 // 1494 // T3 == T1: true 1495 // T1 is changed: 1496 // ⎡10 9 8⎤ 1497 // ⎢ 7 6 5⎥ 1498 // ⎣ 4 3 2⎦ 1499 // 1500 // Operation is unsafe (sliced operations - tensor is left operand) 1501 // ============================================= 1502 // T3 = T1[:, 0:2] + 5 1503 // T3: 1504 // ⎡-5 -4⎤ 1505 // ⎢-2 -1⎥ 1506 // ⎣ 1 2⎦ 1507 // 1508 // sliced == T3: true 1509 // T1 is changed: 1510 // ⎡-5 -4 2⎤ 1511 // ⎢-2 -1 5⎥ 1512 // ⎣ 1 2 8⎦ 1513 // 1514 // Operation is unsafe (sliced operations - tensor is right operand) 1515 // ============================================= 1516 // T3 = 5 - T1[:, 0:2] 1517 // T3: 1518 // ⎡ 5 4⎤ 1519 // ⎢ 2 1⎥ 1520 // ⎣-1 -2⎦ 1521 // 1522 // sliced == T3: true 1523 // T1 is changed: 1524 // ⎡ 5 4 2⎤ 1525 // ⎢ 2 1 5⎥ 1526 // ⎣-1 -2 8⎦ 1527 } 1528 1529 // Reuse tensors may be used, with the WithReuse() function option. 1530 func ExampleDense_SubScalar_reuse() { 1531 var T1, V, Reuse, T3 *Dense 1532 var sliced Tensor 1533 1534 // Tensor is left operand 1535 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1536 Reuse = New(WithBacking(Range(Float32, 100, 109)), WithShape(3, 3)) 1537 T3, _ = T1.SubScalar(float32(5), true, WithReuse(Reuse)) 1538 fmt.Printf("Reuse tensor passed in (Tensor is left operand)\n======================\nT3 == Reuse: %t\nT3:\n%v\n", T3 == Reuse, T3) 1539 1540 // Tensor is right operand 1541 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1542 Reuse = New(WithBacking(Range(Float32, 100, 109)), WithShape(3, 3)) 1543 T3, _ = T1.SubScalar(float32(5), false, WithReuse(Reuse)) 1544 fmt.Printf("Reuse tensor passed in (Tensor is right operand)\n======================\nT3 == Reuse: %t\nT3:\n%v\n", T3 == Reuse, T3) 1545 1546 // Tensor is left operand 1547 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1548 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 1549 V = sliced.(*Dense) 1550 Reuse = New(WithBacking(Range(Float32, 100, 104)), WithShape(2, 2)) // same shape as result 1551 T3, _ = V.SubScalar(float32(5), true, WithReuse(Reuse)) 1552 fmt.Printf("Reuse tensor passed in (sliced tensor - Tensor is left operand)\n======================================\nT3 == Reuse: %t\nT3:\n%v\n", T3 == Reuse, T3) 1553 1554 // Tensor is left operand 1555 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1556 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 1557 V = sliced.(*Dense) 1558 Reuse = New(WithBacking(Range(Float32, 100, 104)), WithShape(2, 2)) // same shape as result 1559 T3, _ = V.SubScalar(float32(5), false, WithReuse(Reuse)) 1560 fmt.Printf("Reuse tensor passed in (sliced tensor - Tensor is left operand)\n======================================\nT3 == Reuse: %t\nT3:\n%v", T3 == Reuse, T3) 1561 1562 // Output: 1563 // Reuse tensor passed in (Tensor is left operand) 1564 // ====================== 1565 // T3 == Reuse: true 1566 // T3: 1567 // ⎡-5 -4 -3⎤ 1568 // ⎢-2 -1 0⎥ 1569 // ⎣ 1 2 3⎦ 1570 // 1571 // Reuse tensor passed in (Tensor is right operand) 1572 // ====================== 1573 // T3 == Reuse: true 1574 // T3: 1575 // ⎡ 5 4 3⎤ 1576 // ⎢ 2 1 0⎥ 1577 // ⎣-1 -2 -3⎦ 1578 // 1579 // Reuse tensor passed in (sliced tensor - Tensor is left operand) 1580 // ====================================== 1581 // T3 == Reuse: true 1582 // T3: 1583 // ⎡-5 -4⎤ 1584 // ⎣-2 -1⎦ 1585 // 1586 // Reuse tensor passed in (sliced tensor - Tensor is left operand) 1587 // ====================================== 1588 // T3 == Reuse: true 1589 // T3: 1590 // ⎡5 4⎤ 1591 // ⎣2 1⎦ 1592 } 1593 1594 // Incrementing a tensor is also a function option provided by the package 1595 func ExampleDense_SubScalar_incr() { 1596 var T1, T3, Incr, V *Dense 1597 var sliced Tensor 1598 1599 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1600 Incr = New(WithBacking([]float32{100, 100, 100, 100, 100, 100, 100, 100, 100}), WithShape(3, 3)) 1601 T3, _ = T1.SubScalar(float32(5), true, WithIncr(Incr)) 1602 fmt.Printf("Incr tensor passed in\n======================\nIncr += T1 - T2\nIncr == T3: %t\nT3:\n%v\n", Incr == T3, T3) 1603 1604 // Operations on sliced tensor is also allowed. Note that your Incr tensor has to be the same shape as the result 1605 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1606 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 1607 V = sliced.(*Dense) 1608 Incr = New(WithBacking([]float32{100, 100, 100, 100}), WithShape(2, 2)) 1609 T3, _ = V.SubScalar(float32(5), true, WithIncr(Incr)) 1610 fmt.Printf("Incr tensor passed in (sliced tensor)\n======================================\nIncr += T1 - T2\nIncr == T3: %t\nT3:\n%v\n", Incr == T3, T3) 1611 1612 // Output: 1613 // Incr tensor passed in 1614 // ====================== 1615 // Incr += T1 - T2 1616 // Incr == T3: true 1617 // T3: 1618 // ⎡ 95 96 97⎤ 1619 // ⎢ 98 99 100⎥ 1620 // ⎣101 102 103⎦ 1621 // 1622 // Incr tensor passed in (sliced tensor) 1623 // ====================================== 1624 // Incr += T1 - T2 1625 // Incr == T3: true 1626 // T3: 1627 // ⎡95 96⎤ 1628 // ⎣98 99⎦ 1629 } 1630 1631 /* MUL */ 1632 1633 // By default, arithmetic operations are safe 1634 func ExampleDense_MulScalar_basic() { 1635 var T1, T3, V *Dense 1636 var sliced Tensor 1637 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1638 T3, _ = T1.MulScalar(float32(5), true) 1639 fmt.Printf("Default operation is safe (tensor is left operand)\n==========================\nT3 = T1 * 5\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 1640 1641 T3, _ = T1.MulScalar(float32(5), false) 1642 fmt.Printf("Default operation is safe (tensor is right operand)\n==========================\nT3 = 5 * T1\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 1643 1644 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1645 sliced, _ = T1.Slice(nil, makeRS(1, 3)) 1646 V = sliced.(*Dense) 1647 T3, _ = V.MulScalar(float32(5), true) 1648 fmt.Printf("Default operation is safe (sliced operations - tensor is left operand)\n=============================================\nT3 = T1[:, 1:3] + 5\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 1649 1650 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1651 sliced, _ = T1.Slice(nil, makeRS(1, 3)) 1652 V = sliced.(*Dense) 1653 T3, _ = V.MulScalar(float32(5), false) 1654 fmt.Printf("Default operation is safe (sliced operations - tensor is right operand)\n=============================================\nT3 = 5 * T1[:, 1:3]\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 1655 1656 // Output: 1657 // Default operation is safe (tensor is left operand) 1658 // ========================== 1659 // T3 = T1 * 5 1660 // T3: 1661 // ⎡ 0 5 10⎤ 1662 // ⎢15 20 25⎥ 1663 // ⎣30 35 40⎦ 1664 // 1665 // T1 is unchanged: 1666 // ⎡0 1 2⎤ 1667 // ⎢3 4 5⎥ 1668 // ⎣6 7 8⎦ 1669 // 1670 // Default operation is safe (tensor is right operand) 1671 // ========================== 1672 // T3 = 5 * T1 1673 // T3: 1674 // ⎡ 0 5 10⎤ 1675 // ⎢15 20 25⎥ 1676 // ⎣30 35 40⎦ 1677 // 1678 // T1 is unchanged: 1679 // ⎡0 1 2⎤ 1680 // ⎢3 4 5⎥ 1681 // ⎣6 7 8⎦ 1682 // 1683 // Default operation is safe (sliced operations - tensor is left operand) 1684 // ============================================= 1685 // T3 = T1[:, 1:3] + 5 1686 // T3: 1687 // ⎡ 5 10⎤ 1688 // ⎢20 25⎥ 1689 // ⎣35 40⎦ 1690 // 1691 // T1 is unchanged: 1692 // ⎡0 1 2⎤ 1693 // ⎢3 4 5⎥ 1694 // ⎣6 7 8⎦ 1695 // 1696 // Default operation is safe (sliced operations - tensor is right operand) 1697 // ============================================= 1698 // T3 = 5 * T1[:, 1:3] 1699 // T3: 1700 // ⎡ 5 10⎤ 1701 // ⎢20 25⎥ 1702 // ⎣35 40⎦ 1703 // 1704 // T1 is unchanged: 1705 // ⎡0 1 2⎤ 1706 // ⎢3 4 5⎥ 1707 // ⎣6 7 8⎦ 1708 } 1709 1710 func ExampleDense_MulScalar_unsafe() { 1711 var T1, T3, V *Dense 1712 var sliced Tensor 1713 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1714 T3, _ = T1.MulScalar(float32(5), true, UseUnsafe()) 1715 fmt.Printf("Operation is unsafe (tensor is left operand)\n==========================\nT3 = T1 * 5\nT3:\n%v\nT3 == T1: %t\nT1 is changed:\n%v\n", T3, T3 == T1, T1) 1716 1717 T3, _ = T1.MulScalar(float32(5), false, UseUnsafe()) 1718 fmt.Printf("Operation is unsafe (tensor is right operand)\n==========================\nT3 = 5 * T1\nT3:\n%v\nT3 == T1: %t\nT1 is changed:\n%v\n", T3, T3 == T1, T1) 1719 1720 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1721 sliced, _ = T1.Slice(nil, makeRS(0, 2)) 1722 V = sliced.(*Dense) 1723 T3, _ = V.MulScalar(float32(5), true, UseUnsafe()) 1724 fmt.Printf("Operation is unsafe (sliced operations - tensor is left operand)\n=============================================\nT3 = T1[:, 0:2] + 5\nT3:\n%v\nsliced == T3: %t\nT1 is changed:\n%v\n", T3, sliced == T3, T1) 1725 1726 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1727 sliced, _ = T1.Slice(nil, makeRS(0, 2)) 1728 V = sliced.(*Dense) 1729 T3, _ = V.MulScalar(float32(5), false, UseUnsafe()) 1730 fmt.Printf("Operation is unsafe (sliced operations - tensor is right operand)\n=============================================\nT3 = 5 * T1[:, 0:2]\nT3:\n%v\nsliced == T3: %t\nT1 is changed:\n%v\n", T3, sliced == T3, T1) 1731 1732 // Output: 1733 // Operation is unsafe (tensor is left operand) 1734 // ========================== 1735 // T3 = T1 * 5 1736 // T3: 1737 // ⎡ 0 5 10⎤ 1738 // ⎢15 20 25⎥ 1739 // ⎣30 35 40⎦ 1740 // 1741 // T3 == T1: true 1742 // T1 is changed: 1743 // ⎡ 0 5 10⎤ 1744 // ⎢15 20 25⎥ 1745 // ⎣30 35 40⎦ 1746 // 1747 // Operation is unsafe (tensor is right operand) 1748 // ========================== 1749 // T3 = 5 * T1 1750 // T3: 1751 // ⎡ 0 25 50⎤ 1752 // ⎢ 75 100 125⎥ 1753 // ⎣150 175 200⎦ 1754 // 1755 // T3 == T1: true 1756 // T1 is changed: 1757 // ⎡ 0 25 50⎤ 1758 // ⎢ 75 100 125⎥ 1759 // ⎣150 175 200⎦ 1760 // 1761 // Operation is unsafe (sliced operations - tensor is left operand) 1762 // ============================================= 1763 // T3 = T1[:, 0:2] + 5 1764 // T3: 1765 // ⎡ 0 5⎤ 1766 // ⎢15 20⎥ 1767 // ⎣30 35⎦ 1768 // 1769 // sliced == T3: true 1770 // T1 is changed: 1771 // ⎡ 0 5 2⎤ 1772 // ⎢15 20 5⎥ 1773 // ⎣30 35 8⎦ 1774 // 1775 // Operation is unsafe (sliced operations - tensor is right operand) 1776 // ============================================= 1777 // T3 = 5 * T1[:, 0:2] 1778 // T3: 1779 // ⎡ 0 5⎤ 1780 // ⎢15 20⎥ 1781 // ⎣30 35⎦ 1782 // 1783 // sliced == T3: true 1784 // T1 is changed: 1785 // ⎡ 0 5 2⎤ 1786 // ⎢15 20 5⎥ 1787 // ⎣30 35 8⎦ 1788 } 1789 1790 // Reuse tensors may be used, with the WithReuse() function option. 1791 func ExampleDense_MulScalar_reuse() { 1792 var T1, V, Reuse, T3 *Dense 1793 var sliced Tensor 1794 1795 // Tensor is left operand 1796 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1797 Reuse = New(WithBacking(Range(Float32, 100, 109)), WithShape(3, 3)) 1798 T3, _ = T1.MulScalar(float32(5), true, WithReuse(Reuse)) 1799 fmt.Printf("Reuse tensor passed in (Tensor is left operand)\n======================\nT3 == Reuse: %t\nT3:\n%v\n", T3 == Reuse, T3) 1800 1801 // Tensor is right operand 1802 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1803 Reuse = New(WithBacking(Range(Float32, 100, 109)), WithShape(3, 3)) 1804 T3, _ = T1.MulScalar(float32(5), false, WithReuse(Reuse)) 1805 fmt.Printf("Reuse tensor passed in (Tensor is right operand)\n======================\nT3 == Reuse: %t\nT3:\n%v\n", T3 == Reuse, T3) 1806 1807 // Tensor is left operand 1808 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1809 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 1810 V = sliced.(*Dense) 1811 Reuse = New(WithBacking(Range(Float32, 100, 104)), WithShape(2, 2)) // same shape as result 1812 T3, _ = V.MulScalar(float32(5), true, WithReuse(Reuse)) 1813 fmt.Printf("Reuse tensor passed in (sliced tensor - Tensor is left operand)\n======================================\nT3 == Reuse: %t\nT3:\n%v\n", T3 == Reuse, T3) 1814 1815 // Tensor is left operand 1816 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1817 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 1818 V = sliced.(*Dense) 1819 Reuse = New(WithBacking(Range(Float32, 100, 104)), WithShape(2, 2)) // same shape as result 1820 T3, _ = V.MulScalar(float32(5), false, WithReuse(Reuse)) 1821 fmt.Printf("Reuse tensor passed in (sliced tensor - Tensor is left operand)\n======================================\nT3 == Reuse: %t\nT3:\n%v", T3 == Reuse, T3) 1822 1823 // Output: 1824 // Reuse tensor passed in (Tensor is left operand) 1825 // ====================== 1826 // T3 == Reuse: true 1827 // T3: 1828 // ⎡ 0 5 10⎤ 1829 // ⎢15 20 25⎥ 1830 // ⎣30 35 40⎦ 1831 // 1832 // Reuse tensor passed in (Tensor is right operand) 1833 // ====================== 1834 // T3 == Reuse: true 1835 // T3: 1836 // ⎡ 0 5 10⎤ 1837 // ⎢15 20 25⎥ 1838 // ⎣30 35 40⎦ 1839 // 1840 // Reuse tensor passed in (sliced tensor - Tensor is left operand) 1841 // ====================================== 1842 // T3 == Reuse: true 1843 // T3: 1844 // ⎡ 0 5⎤ 1845 // ⎣15 20⎦ 1846 // 1847 // Reuse tensor passed in (sliced tensor - Tensor is left operand) 1848 // ====================================== 1849 // T3 == Reuse: true 1850 // T3: 1851 // ⎡ 0 5⎤ 1852 // ⎣15 20⎦ 1853 } 1854 1855 // Incrementing a tensor is also a function option provided by the package 1856 func ExampleDense_MulScalar_incr() { 1857 var T1, T3, Incr, V *Dense 1858 var sliced Tensor 1859 1860 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1861 Incr = New(WithBacking([]float32{100, 100, 100, 100, 100, 100, 100, 100, 100}), WithShape(3, 3)) 1862 T3, _ = T1.MulScalar(float32(5), true, WithIncr(Incr)) 1863 fmt.Printf("Incr tensor passed in\n======================\nIncr += T1 * T2\nIncr == T3: %t\nT3:\n%v\n", Incr == T3, T3) 1864 1865 // Operations on sliced tensor is also allowed. Note that your Incr tensor has to be the same shape as the result 1866 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1867 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 1868 V = sliced.(*Dense) 1869 Incr = New(WithBacking([]float32{100, 100, 100, 100}), WithShape(2, 2)) 1870 T3, _ = V.MulScalar(float32(5), true, WithIncr(Incr)) 1871 fmt.Printf("Incr tensor passed in (sliced tensor)\n======================================\nIncr += T1 * T2\nIncr == T3: %t\nT3:\n%v\n", Incr == T3, T3) 1872 1873 // Output: 1874 // Incr tensor passed in 1875 // ====================== 1876 // Incr += T1 * T2 1877 // Incr == T3: true 1878 // T3: 1879 // ⎡100 105 110⎤ 1880 // ⎢115 120 125⎥ 1881 // ⎣130 135 140⎦ 1882 // 1883 // Incr tensor passed in (sliced tensor) 1884 // ====================================== 1885 // Incr += T1 * T2 1886 // Incr == T3: true 1887 // T3: 1888 // ⎡100 105⎤ 1889 // ⎣115 120⎦ 1890 } 1891 1892 // By default, arithmetic operations are safe 1893 func ExampleDense_DivScalar_basic() { 1894 var T1, T3, V *Dense 1895 var sliced Tensor 1896 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1897 T3, _ = T1.DivScalar(float32(5), true) 1898 fmt.Printf("Default operation is safe (tensor is left operand)\n==========================\nT3 = T1 / 5\nT3:\n%1.1v\nT1 is unchanged:\n%1.1v\n", T3, T1) 1899 1900 T3, _ = T1.DivScalar(float32(5), false) 1901 fmt.Printf("Default operation is safe (tensor is right operand)\n==========================\nT3 = 5 / T1\nT3:\n%1.1v\nT1 is unchanged:\n%1.1v\n", T3, T1) 1902 1903 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1904 sliced, _ = T1.Slice(nil, makeRS(1, 3)) 1905 V = sliced.(*Dense) 1906 T3, _ = V.DivScalar(float32(5), true) 1907 fmt.Printf("Default operation is safe (sliced operations - tensor is left operand)\n=============================================\nT3 = T1[:, 1:3] + 5\nT3:\n%1.1v\nT1 is unchanged:\n%1.1v\n", T3, T1) 1908 1909 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1910 sliced, _ = T1.Slice(nil, makeRS(1, 3)) 1911 V = sliced.(*Dense) 1912 T3, _ = V.DivScalar(float32(5), false) 1913 fmt.Printf("Default operation is safe (sliced operations - tensor is right operand)\n=============================================\nT3 = 5 / T1[:, 1:3]\nT3:\n%1.1v\nT1 is unchanged:\n%1.1v\n", T3, T1) 1914 1915 // Output: 1916 // Default operation is safe (tensor is left operand) 1917 // ========================== 1918 // T3 = T1 / 5 1919 // T3: 1920 // ⎡ 0 0.2 0.4⎤ 1921 // ⎢0.6 0.8 1⎥ 1922 // ⎣ 1 1 2⎦ 1923 // 1924 // T1 is unchanged: 1925 // ⎡0 1 2⎤ 1926 // ⎢3 4 5⎥ 1927 // ⎣6 7 8⎦ 1928 // 1929 // Default operation is safe (tensor is right operand) 1930 // ========================== 1931 // T3 = 5 / T1 1932 // T3: 1933 // ⎡+Inf 5 2⎤ 1934 // ⎢ 2 1 1⎥ 1935 // ⎣ 0.8 0.7 0.6⎦ 1936 // 1937 // T1 is unchanged: 1938 // ⎡0 1 2⎤ 1939 // ⎢3 4 5⎥ 1940 // ⎣6 7 8⎦ 1941 // 1942 // Default operation is safe (sliced operations - tensor is left operand) 1943 // ============================================= 1944 // T3 = T1[:, 1:3] + 5 1945 // T3: 1946 // ⎡0.2 0.4⎤ 1947 // ⎢0.8 1⎥ 1948 // ⎣ 1 2⎦ 1949 // 1950 // T1 is unchanged: 1951 // ⎡0 1 2⎤ 1952 // ⎢3 4 5⎥ 1953 // ⎣6 7 8⎦ 1954 // 1955 // Default operation is safe (sliced operations - tensor is right operand) 1956 // ============================================= 1957 // T3 = 5 / T1[:, 1:3] 1958 // T3: 1959 // ⎡ 5 2⎤ 1960 // ⎢ 1 1⎥ 1961 // ⎣0.7 0.6⎦ 1962 // 1963 // T1 is unchanged: 1964 // ⎡0 1 2⎤ 1965 // ⎢3 4 5⎥ 1966 // ⎣6 7 8⎦ 1967 } 1968 1969 func ExampleDense_DivScalar_unsafe() { 1970 var T1, T3, V *Dense 1971 var sliced Tensor 1972 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1973 T3, _ = T1.DivScalar(float32(5), true, UseUnsafe()) 1974 fmt.Printf("Operation is unsafe (tensor is left operand)\n==========================\nT3 = T1 / 5\nT3:\n%1.1v\nT3 == T1: %t\nT1 is changed:\n%1.1v\n", T3, T3 == T1, T1) 1975 1976 T3, _ = T1.DivScalar(float32(5), false, UseUnsafe()) 1977 fmt.Printf("Operation is unsafe (tensor is right operand)\n==========================\nT3 = 5 / T1\nT3:\n%1.1v\nT3 == T1: %t\nT1 is changed:\n%1.1v\n", T3, T3 == T1, T1) 1978 1979 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1980 sliced, _ = T1.Slice(nil, makeRS(0, 2)) 1981 V = sliced.(*Dense) 1982 T3, _ = V.DivScalar(float32(5), true, UseUnsafe()) 1983 fmt.Printf("Operation is unsafe (sliced operations - tensor is left operand)\n=============================================\nT3 = T1[:, 0:2] + 5\nT3:\n%1.1v\nsliced == T3: %t\nT1 is changed:\n%1.1v\n", T3, sliced == T3, T1) 1984 1985 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 1986 sliced, _ = T1.Slice(nil, makeRS(0, 2)) 1987 V = sliced.(*Dense) 1988 T3, _ = V.DivScalar(float32(5), false, UseUnsafe()) 1989 fmt.Printf("Operation is unsafe (sliced operations - tensor is right operand)\n=============================================\nT3 = 5 / T1[:, 0:2]\nT3:\n%1.1v\nsliced == T3: %t\nT1 is changed:\n%1.1v\n", T3, sliced == T3, T1) 1990 1991 // Output: 1992 // Operation is unsafe (tensor is left operand) 1993 // ========================== 1994 // T3 = T1 / 5 1995 // T3: 1996 // ⎡ 0 0.2 0.4⎤ 1997 // ⎢0.6 0.8 1⎥ 1998 // ⎣ 1 1 2⎦ 1999 // 2000 // T3 == T1: true 2001 // T1 is changed: 2002 // ⎡ 0 0.2 0.4⎤ 2003 // ⎢0.6 0.8 1⎥ 2004 // ⎣ 1 1 2⎦ 2005 // 2006 // Operation is unsafe (tensor is right operand) 2007 // ========================== 2008 // T3 = 5 / T1 2009 // T3: 2010 // ⎡ +Inf 2e+01 1e+01⎤ 2011 // ⎢ 8 6 5⎥ 2012 // ⎣ 4 4 3⎦ 2013 // 2014 // T3 == T1: true 2015 // T1 is changed: 2016 // ⎡ +Inf 2e+01 1e+01⎤ 2017 // ⎢ 8 6 5⎥ 2018 // ⎣ 4 4 3⎦ 2019 // 2020 // Operation is unsafe (sliced operations - tensor is left operand) 2021 // ============================================= 2022 // T3 = T1[:, 0:2] + 5 2023 // T3: 2024 // ⎡ 0 0.2⎤ 2025 // ⎢0.6 0.8⎥ 2026 // ⎣ 1 1⎦ 2027 // 2028 // sliced == T3: true 2029 // T1 is changed: 2030 // ⎡ 0 0.2 2⎤ 2031 // ⎢0.6 0.8 5⎥ 2032 // ⎣ 1 1 8⎦ 2033 // 2034 // Operation is unsafe (sliced operations - tensor is right operand) 2035 // ============================================= 2036 // T3 = 5 / T1[:, 0:2] 2037 // T3: 2038 // ⎡+Inf 5⎤ 2039 // ⎢ 2 1⎥ 2040 // ⎣ 0.8 0.7⎦ 2041 // 2042 // sliced == T3: true 2043 // T1 is changed: 2044 // ⎡+Inf 5 2⎤ 2045 // ⎢ 2 1 5⎥ 2046 // ⎣ 0.8 0.7 8⎦ 2047 } 2048 2049 // Reuse tensors may be used, with the WithReuse() function option. 2050 func ExampleDense_DivScalar_reuse() { 2051 var T1, V, Reuse, T3 *Dense 2052 var sliced Tensor 2053 2054 // Tensor is left operand 2055 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 2056 Reuse = New(WithBacking(Range(Float32, 100, 109)), WithShape(3, 3)) 2057 T3, _ = T1.DivScalar(float32(5), true, WithReuse(Reuse)) 2058 fmt.Printf("Reuse tensor passed in (Tensor is left operand)\n======================\nT3 == Reuse: %t\nT3:\n%1.1v\n", T3 == Reuse, T3) 2059 2060 // Tensor is right operand 2061 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 2062 Reuse = New(WithBacking(Range(Float32, 100, 109)), WithShape(3, 3)) 2063 T3, _ = T1.DivScalar(float32(5), false, WithReuse(Reuse)) 2064 fmt.Printf("Reuse tensor passed in (Tensor is right operand)\n======================\nT3 == Reuse: %t\nT3:\n%1.1v\n", T3 == Reuse, T3) 2065 2066 // Tensor is left operand 2067 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 2068 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 2069 V = sliced.(*Dense) 2070 Reuse = New(WithBacking(Range(Float32, 100, 104)), WithShape(2, 2)) // same shape as result 2071 T3, _ = V.DivScalar(float32(5), true, WithReuse(Reuse)) 2072 fmt.Printf("Reuse tensor passed in (sliced tensor - Tensor is left operand)\n======================================\nT3 == Reuse: %t\nT3:\n%1.1v\n", T3 == Reuse, T3) 2073 2074 // Tensor is left operand 2075 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 2076 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 2077 V = sliced.(*Dense) 2078 Reuse = New(WithBacking(Range(Float32, 100, 104)), WithShape(2, 2)) // same shape as result 2079 T3, _ = V.DivScalar(float32(5), false, WithReuse(Reuse)) 2080 fmt.Printf("Reuse tensor passed in (sliced tensor - Tensor is left operand)\n======================================\nT3 == Reuse: %t\nT3:\n%1.1v", T3 == Reuse, T3) 2081 2082 // Output: 2083 // Reuse tensor passed in (Tensor is left operand) 2084 // ====================== 2085 // T3 == Reuse: true 2086 // T3: 2087 // ⎡ 0 0.2 0.4⎤ 2088 // ⎢0.6 0.8 1⎥ 2089 // ⎣ 1 1 2⎦ 2090 // 2091 // Reuse tensor passed in (Tensor is right operand) 2092 // ====================== 2093 // T3 == Reuse: true 2094 // T3: 2095 // ⎡+Inf 5 2⎤ 2096 // ⎢ 2 1 1⎥ 2097 // ⎣ 0.8 0.7 0.6⎦ 2098 // 2099 // Reuse tensor passed in (sliced tensor - Tensor is left operand) 2100 // ====================================== 2101 // T3 == Reuse: true 2102 // T3: 2103 // ⎡ 0 0.2⎤ 2104 // ⎣0.6 0.8⎦ 2105 // 2106 // Reuse tensor passed in (sliced tensor - Tensor is left operand) 2107 // ====================================== 2108 // T3 == Reuse: true 2109 // T3: 2110 // ⎡+Inf 5⎤ 2111 // ⎣ 2 1⎦ 2112 } 2113 2114 // Incrementing a tensor is also a function option provided by the package 2115 func ExampleDense_DivScalar_incr() { 2116 var T1, T3, Incr, V *Dense 2117 var sliced Tensor 2118 2119 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 2120 Incr = New(WithBacking([]float32{100, 100, 100, 100, 100, 100, 100, 100, 100}), WithShape(3, 3)) 2121 T3, _ = T1.DivScalar(float32(5), true, WithIncr(Incr)) 2122 fmt.Printf("Incr tensor passed in\n======================\nIncr += T1 / T2\nIncr == T3: %t\nT3:\n%3.1v\n", Incr == T3, T3) 2123 2124 // Operations on sliced tensor is also allowed. Note that your Incr tensor has to be the same shape as the result 2125 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 2126 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 2127 V = sliced.(*Dense) 2128 Incr = New(WithBacking([]float32{100, 100, 100, 100}), WithShape(2, 2)) 2129 T3, _ = V.DivScalar(float32(5), true, WithIncr(Incr)) 2130 fmt.Printf("Incr tensor passed in (sliced tensor)\n======================================\nIncr += T1 / T2\nIncr == T3: %t\nT3:\n%3.1v\n", Incr == T3, T3) 2131 2132 // Output: 2133 // Incr tensor passed in 2134 // ====================== 2135 // Incr += T1 / T2 2136 // Incr == T3: true 2137 // T3: 2138 // ⎡1e+02 1e+02 1e+02⎤ 2139 // ⎢1e+02 1e+02 1e+02⎥ 2140 // ⎣1e+02 1e+02 1e+02⎦ 2141 // 2142 // Incr tensor passed in (sliced tensor) 2143 // ====================================== 2144 // Incr += T1 / T2 2145 // Incr == T3: true 2146 // T3: 2147 // ⎡1e+02 1e+02⎤ 2148 // ⎣1e+02 1e+02⎦ 2149 } 2150 2151 // By default, arithmetic operations are safe 2152 func ExampleDense_PowScalar_basic() { 2153 var T1, T3, V *Dense 2154 var sliced Tensor 2155 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 2156 T3, _ = T1.PowScalar(float32(5), true) 2157 fmt.Printf("Default operation is safe (tensor is left operand)\n==========================\nT3 = T1 ^ 5\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 2158 2159 T3, _ = T1.PowScalar(float32(5), false) 2160 fmt.Printf("Default operation is safe (tensor is right operand)\n==========================\nT3 = 5 ^ T1\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 2161 2162 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 2163 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 2164 V = sliced.(*Dense) 2165 T3, _ = V.PowScalar(float32(5), true) 2166 fmt.Printf("Default operation is safe (sliced operations - tensor is left operand)\n=============================================\nT3 = T1[0:2, 0:2] ^ 5\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 2167 2168 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 2169 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 2170 V = sliced.(*Dense) 2171 T3, _ = V.PowScalar(float32(5), false) 2172 fmt.Printf("Default operation is safe (sliced operations - tensor is right operand)\n=============================================\nT3 = 5 ^ T1[0:2, 0:2]\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 2173 2174 // Output: 2175 // Default operation is safe (tensor is left operand) 2176 // ========================== 2177 // T3 = T1 ^ 5 2178 // T3: 2179 // ⎡ 0 1 32⎤ 2180 // ⎢ 243 1024 3125⎥ 2181 // ⎣ 7776 16807 32768⎦ 2182 // 2183 // T1 is unchanged: 2184 // ⎡0 1 2⎤ 2185 // ⎢3 4 5⎥ 2186 // ⎣6 7 8⎦ 2187 // 2188 // Default operation is safe (tensor is right operand) 2189 // ========================== 2190 // T3 = 5 ^ T1 2191 // T3: 2192 // ⎡ 1 5 25⎤ 2193 // ⎢ 125 625 3125⎥ 2194 // ⎣ 15625 78125 390625⎦ 2195 2196 // T1 is unchanged: 2197 // ⎡0 1 2⎤ 2198 // ⎢3 4 5⎥ 2199 // ⎣6 7 8⎦ 2200 // 2201 // Default operation is safe (sliced operations - tensor is left operand) 2202 // ============================================= 2203 // T3 = T1[0:2, 0:2] ^ 5 2204 // T3: 2205 // ⎡ 0 1⎤ 2206 // ⎣ 243 1024⎦ 2207 2208 // T1 is unchanged: 2209 // ⎡0 1 2⎤ 2210 // ⎢3 4 5⎥ 2211 // ⎣6 7 8⎦ 2212 // 2213 // Default operation is safe (sliced operations - tensor is right operand) 2214 // ============================================= 2215 // T3 = 5 ^ T1[0:2, 0:2] 2216 // T3: 2217 // ⎡ 1 5⎤ 2218 // ⎣125 625⎦ 2219 // 2220 // T1 is unchanged: 2221 // ⎡0 1 2⎤ 2222 // ⎢3 4 5⎥ 2223 // ⎣6 7 8⎦ 2224 } 2225 2226 // By default, arithmetic operations are safe 2227 func ExampleDense_ModScalar_basic() { 2228 var T1, T3, V *Dense 2229 var sliced Tensor 2230 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 2231 T3, _ = T1.ModScalar(float32(5), true) 2232 fmt.Printf("Default operation is safe (tensor is left operand)\n==========================\nT3 = T1 %% 5\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 2233 2234 T3, _ = T1.ModScalar(float32(5), false) 2235 fmt.Printf("Default operation is safe (tensor is right operand)\n==========================\nT3 = 5 %% T1\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 2236 2237 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 2238 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 2239 V = sliced.(*Dense) 2240 T3, _ = V.ModScalar(float32(5), true) 2241 fmt.Printf("Default operation is safe (sliced operations - tensor is left operand)\n=============================================\nT3 = T1[0:2, 0:2] %% 5\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 2242 2243 T1 = New(WithBacking(Range(Float32, 0, 9)), WithShape(3, 3)) 2244 sliced, _ = T1.Slice(makeRS(0, 2), makeRS(0, 2)) 2245 V = sliced.(*Dense) 2246 T3, _ = V.ModScalar(float32(5), false) 2247 fmt.Printf("Default operation is safe (sliced operations - tensor is right operand)\n=============================================\nT3 = 5 %% T1[0:2, 0:2]\nT3:\n%v\nT1 is unchanged:\n%v\n", T3, T1) 2248 2249 // Output: 2250 // Default operation is safe (tensor is left operand) 2251 // ========================== 2252 // T3 = T1 % 5 2253 // T3: 2254 // ⎡0 1 2⎤ 2255 // ⎢3 4 0⎥ 2256 // ⎣1 2 3⎦ 2257 // 2258 // T1 is unchanged: 2259 // ⎡0 1 2⎤ 2260 // ⎢3 4 5⎥ 2261 // ⎣6 7 8⎦ 2262 // 2263 // Default operation is safe (tensor is right operand) 2264 // ========================== 2265 // T3 = 5 % T1 2266 // T3: 2267 // ⎡NaN 0 1⎤ 2268 // ⎢ 2 1 0⎥ 2269 // ⎣ 5 5 5⎦ 2270 // 2271 // T1 is unchanged: 2272 // ⎡0 1 2⎤ 2273 // ⎢3 4 5⎥ 2274 // ⎣6 7 8⎦ 2275 // 2276 // Default operation is safe (sliced operations - tensor is left operand) 2277 // ============================================= 2278 // T3 = T1[0:2, 0:2] % 5 2279 // T3: 2280 // ⎡0 1⎤ 2281 // ⎣3 4⎦ 2282 // 2283 // T1 is unchanged: 2284 // ⎡0 1 2⎤ 2285 // ⎢3 4 5⎥ 2286 // ⎣6 7 8⎦ 2287 // 2288 // Default operation is safe (sliced operations - tensor is right operand) 2289 // ============================================= 2290 // T3 = 5 % T1[0:2, 0:2] 2291 // T3: 2292 // ⎡NaN 0⎤ 2293 // ⎣ 2 1⎦ 2294 // 2295 // T1 is unchanged: 2296 // ⎡0 1 2⎤ 2297 // ⎢3 4 5⎥ 2298 // ⎣6 7 8⎦ 2299 }