.. include:: defs.rst ============== Introduction ============== |tenscalc| is a |matlab| toolbox that generates optimized code to perform computations involving *tensors*, i.e., multi-dimensional arrays. |tenscalc| was specifically designed to solve nonlinear constrained optimizations very efficiently, but its code generation engine can be used to generate code to perform much more general computations. |tenscalc| is aimed at scenarios where one needs to perform very fast a large number of computations (e.g., optimizations) that depend on parameters that change from one instance of the computation to the next instance, but the overall structure of the computation remains the same. This is common in applications where the computations/optimizations depend on measured data and one wants to compute optima for large or evolving datasets, e.g., in robust estimation and classification, maximum likelihood estimation, model predictive control (MPC), moving horizon estimation (MHE), and combined MPC-MHE (which requires the computation of a saddle-point equilibrium). What type of code is generated by |tenscalc|? ============================================= |tenscalc| can either produce optimized |matlab| or |C| code. The former is only preferable for very large problems with mild speed requirements, whereas the latter is aimed at small to medium-size problems that need to be solved in just a few milliseconds. The |C| code is completely self-contained and library free (aside from the |C| standard library), making it extremely portable. For ease of use within |matlab|, both the |C| and |matlab| code are encapsulated into |matlab| classes that appear indistinguishable to the |matlab| user, aside from the speed of execution. Within the class wrapper, the |C| code is called from |matlab| using the `cmex` interface and dynamic libraries. **Typically, C code is 10-100 times faster.** Which optimizations is |tenscalc| best at? ========================================== In the context of optimizations, |tenscalc| is mostly aimed at generating solvers for optimizations with up to a few thousands of optimization variables/constraints and solve times up to a few milliseconds. The variables to be optimized can be multi-dimensional arrays of any dimension (tensors) and the cost functions and inequality constraints are specified using |matlab|-like formulas. |tenscalc|'s optimization solvers uses primal-dual interior point methods and uses formulas for the gradient and the hessian matrix that are computed symbolically in an automated fashion. Why is |tenscalc|-generated code fast? ====================================== The speed achieved by code generated by |tenscalc| arises from a combination of features: reuse of intermediate computations across and within iterations of the solver, detection and exploitation of matrix sparsity, avoidance of run-time memory allocation and garbage collection, and reliance on flat code that improves the efficiency of the micro-processor pipelining and caching. All these features have been automated and embedded into the code generation process. A price to pay for |tenscalc|'s speed is that the structure of the computation/optimization is fixed at code-generation time. This has two important consequences: * the sizes of all variables must be specified at code-generation time, and * the sparsity structure of all computations is automatically determined at code-generation time and assume that all external parameters will generally be nonzero. How does |tenscalc| syntax compare to |matlab|? =============================================== |tenscalc| computations are defined using operations on symbolic variables that very much resemble |matlab|'s functions and operators. This means that |matlab| user's will easily understand |tenscalc|'s syntax. However, there are a few key issues that must be kept in mind: * |tenscalc| is very picky about the sizes of tensors and several conversions of sizes that |matlab| performs automatically must be done manually in |tenscalc|. For example, |tenscalc| distinguishes between 2-by-1 matrices and 2-vector (see :ref:`tensors-section`), which cannot be added together in |tenscalc| without an explicit |reshape| operation. .. warning:: This is likely the case for most syntax errors when seasoned |matlab| users first start to work with |tenscalc|. * A few |tenscalc| functions have slightly different behavior (and sometimes syntax) than the corresponding |matlab| function with the same name. Examples of this include the matrix inverse ``inv`` and determinant ``det`` that in |tenscalc| can only be applied to matrices that have been factorized using ``lu`` or ``ldl``. * |tenscalc| has a few functions that do not exist in |matlab|, but can be used to generate more efficient code; most notably the function |tprod| that provides a very general multiplication operation between tensors (see :ref:`tprod-section`). This operation includes the usual matrix multiplication |*| as a special case, the summation over rows and/or columns |sum|, computing the trace of a matrix |trace|, extracting a matrix main diagonal |diag|, computing the euclidean norm of a vectors |norm|; as well as generalizations of all these operations to ``n``-dimensional tensors. .. LocalWords: tenscalc pipelining inv det lu ldl tprod diag defs