 #### <DEEP C EXPLORATION>

``Part of you is always traveling faster, always traveling ahead. Even when you are moving, it is never fast enough to satisfy that part of you...''

##### WHAT IS TRIOT?

Template-Recursive Iteration Over Tensors (TRIOT) is a design pattern in C++11 that allows elegant vectorizing over multiple tensors with different shapes. It runs as fast as hand-edited Fortran and C code, but unlike those methods, it can be used when the dimensionality is unknown at runtime.

Heyl & Serang, 2017 (PROGRAMMING)

You can download a TRIOT multidimensional array (Creative Commons license) library here.

##### HOW FAST IS IT?

TRIOT is more flexible than other methods, including allowing you to use the current tuple index within vectorized operations; however, its design makes its performance competitive with the fastest methods.  ##### HOW DO YOU USE IT?
```	  ```// Copy tensor in C:
for (unsigned long i=0; i<x.data_shape(); ++i)
for (unsigned long j=0; i<x.data_shape(); ++j) {
unsigned long x_bias = (i*x.data_shape() + j)*x.data_shape();
unsigned long y_bias = (i*y.data_shape() + j)*y.data_shape();
for (unsigned long k=0; i<x.data_shape(); ++k)
x[x_bias + k] = y[y_bias +k];
}

// Copy tensor with TRIOT:
apply_tensors([](double & xV, double yV) {
xV = yV;
},
x.data_shape(),
x, y);
```
```
```	  ```// Inner product with TRIOT:
double tot=0.0;
for_each_tensors([&tot](double xV, double yV) {
tot += xV * yV;
},
x.data_shape(),
x, y);
```
```
```	  ```// 3-way inner product with TRIOT:
double tot=0.0;
for_each_tensors([&tot](double xV, double yV, double zV) {
tot += xV * yV * zV;
},
x.data_shape(),
x, y, z);
```
```
```	  ```// Expected value with TRIOT:
Vector result(x.dimension()); // filled with 0.0 by default
enumerate_for_each_tensors(
[&result](const_tup_t counter, const unsigned int dim, double xV) {
for (unsigned int k=0; k<dim; ++k)
result[k] += counter[k]*xV;
},
x.data_shape(),
x);
```
```
```	  ```// Heterogeneous typing:
// x is Tensor<double>
// y is Tensor<int>
apply_tensors([](double & xV, int yV) {
xV = yV;
},
x.data_shape(),
x, y);
```
```
```	  ```// TensorView: Copy a matrix x into piece of a larger matrix y:
// y_view is a matrix looking at y from rows >0 and columns >2:
TensorView y_view = y.start_at({1,3});
apply_tensors([](double & yV, double xV) {
yV = xV;
},
x.data_shape(),
y_view, x);

// Standard TRIOT function for this (made possible by rvalue references):
embed(y.start_at({1,3}), x);
```
```