Chapter 1. API overview

Table of Contents

1.1. Views
1.2. Blocks
1.3. Matlab IO

1.1. Views

VSIPL++ defines a number of mathematical types for linear algebra: vectors, matrices, and (3D) tensors. They provide a high-level interface suitable for solving linear algebra equations. All these types give an intuitive access to their elements. They are collectively referred to as views as the actual data they provide access to is sharable among views.

// create an uninitialized vector of 10 elements
Vector<float> vector1(10);

// create a zero-initialized vector of 10 elements
Vector<float> vector2(10, 0.f);

// assign vector2 to vector1
vector1 = vector2;

// set the first element to 1.f
vector1(0) = 1.f;

// access the last element
float value = vector1(9);

Every view has an associated Block, which is responsible for storing or computing the data in the view. More than one view may be associated with the same block.

Depending on how a view is constructed it may allocate the block, or refer to a block from another view. All views created via copy-construction will share the blocks with the views they were constructed with.

// copy-construct a new vector from an existing one
Vector<float> vector3(vector1);

// modify the original vector
vector1.put(1, 1.f);

// the new vector reflects the new value
assert(vector3(1) == 1.f);

1.1.1. Domains

A domain represents a logical set of indices. Constructing a one-dimensional domain requires a start index, a stride, and a length. For convenience an additional constructor is provided that only takes a length argument, setting the starting index to 0 and the stride to 1.

// [0...9]
vsip::Domain<1> all(10);

// [0, 2, 4, 6, 8]
vsip::Domain<1> pair(0, 2, 5);

// [1, 3, 5, 7, 9]
vsip::Domain<1> impair(1, 2, 5);

Two- and three-dimensional domains are composed out of one-dimensional ones.

// [(0,0), (0,2), (0,4),...,(1,0),...]
vsip::Domain<2> dom(Domain<1>(10), Domain<1>(0, 2, 5));

Views provide convenient access to subviews in terms of subdomains. For example, to assign new values to every second element of a vector, simply write:

// assign 1.f to all elements in [0, 2, 4, 6, 8]
vector1(pair) = 1.f;

All complex views provide real and imaginary subviews:

// a function manipulating a float vector in-place
void filter(Vector<float>);

// create a complex vector
Vector<complex> vector(10);

// filter the real part of the vector
filter(vector.real());

1.1.2. Elementwise Operations

VSIPL++ provides elementwise functions and operations that are defined in terms of their scalar counterpart.

Vector<float> vector1(10, 1.f);

Vector<complex<float> > vector2(10, complex<float>(2.f, 1.f));

// apply operator+ elementwise
Vector<complex<float> > sum = vector1 + vector2;

// apply conj(complex<float>) elementwise
Vector<complex<float> > result = conj(sum);

For binary and ternary functions VSIPL++ provides overloaded versions with mixed view / scalar parameter types:

// delegates to operator*=(complex<float>, complex<float>)
result *= complex<float>(2.f, 0.f);

// error: no operator*=(complex<float>, complex<double>)
result *= complex<double>(5., 0.);

1.1.3. Vectors

1.1.4. Matrices

Matrices provide a number of additional subviews. All of them

Matrix<float> matrix(10, 10);
//...

// return the first column vector
Matrix<float>::col_type column = matrix.col(0);

// return the first row vector
Matrix<float>::row_type row = matrix.row(0);

// return the diagonal vector
Matrix<float>::diag_type diag = matrix.diag();

// return the transpose of the matrix
Matrix<float>::transpose_type trans = matrix.trans();

1.1.5. Tensors

Tensors are three-dimensional views. In addition to the types, methods, and operations defined for all view types, they provide additional methods to access specific subviews:

// a 5x6x3 cube initialized to 0.f
Tensor<float> tensor(5, 6, 3, 0.f);

// a subvector
Vector<float> vector1 = tensor(0, 0, whole_domain);

The symbolic constant whole_domain is used to indicate that the whole domain the target view holds in a particular dimension should be used. In the example above that not only provides a more compact syntax compared to explicitly writing Domain<1>(6) but it also enables better optimization opportunities.

// a submatrix
Matrix<float> plane = tensor(whole_domain, 0, whole_domain);

Tensor<float> upper_half = tensor(whole_domain, Domain<1>(3), whole_domain);