tensor-0.1.0
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Enumerator Groups Pages
Introduction

The basic datatype of the library is the class Tensor, which implements the above mentioned multi-dimensional array. This class allows accessing the array elements one by one, extracting pieces of an array, reshaping arrays, etc

Tensor<double> a = Tensor<double>::eye(2,2); // creates a 2x2 identity matrix
double one = a(0,0); // returns the upper left element
Tensor<double> b = a(range(0,-1), range()); // returns first to last row, all columns
Tensor<double> c = reshape(b, 1,4); // converts b into a row vector

Features

There are many philosophical constraints behind the library implementation itself, motivated by the writer's need of a Matlab-like environment that allows quick prototyping of code. Some of them are

  • Automatic memory management
  • Avoiding generic programming
  • Efficiency
  • Simple syntax
  • Safety

The memory management is done using a copy-on-write pointer mechanism, which allows two arrays to share the same data until one of them modifies the shared memory.

Tensor<double> a = Tensor<double>::eye(2,2);
Tensor<double> b = a; // a and b point to the same array
a.at(0,1) = 1.0; // a points now to a different memory

Since copying is cheap, it becomes feasible to have multiple references to the same array in structures such as vectors, lists, etc. It also makes the actual coding straightforward, since no bookkeeping has to be done

We avoid using generic programming or the so called templates. It is true that the headers are full of template<> statements but the implementations are typically not exposed to the users, and the classes are explicitely instantiated inside the library code. For example, only real and complex double precision tensors are supported throughout the code.

Finally some words about safety. The library is configured to have a high level of paranoia by default, including assertions for index bounds, tensor dimensions, etc. Minor errors are usually ignored (such as operations between arrays which are conformant in size but not in the indices), but others will result in expensive checks. To disable these checks, simply add NDEBUG to the list of flags.

Limitations

The automatic memory management imposes a few limitations on the code. First of all, the copy-on-write mechanism is not threadsafe, so you should exercise great caution when sharing a tensor over multiple threads. Also, due to implementation details, it does not always work well with the new "auto" keyword of the C++-11 standard, so you should always explicitly declare variable types for tensors.