14.1 Fusion API conventions

14.1.1 General conventions

All the classes of the Fusion interface are contained in the namespace mosek::fusion. The user should not directly instantiate objects of any class other than creating a Model.

    Model::t M = new Model();   auto _M = finally([&]() { M->dispose(); });

The model is the main access point to an optimization problem and its solution. All other objects should be created through the model (Model.variable, Model.constraint, etc.) or using static factory methods (Matrix.sparse etc.).

The C++ Fusion implements its own reference counting and array types to improve garbage collection. The user will require the type definitions from two namespaces:

#include "fusion.h"

using namespace mosek::fusion;
using namespace monty;

The following subsections document the API extensions specific for C++.

14.1.2 C++ Arrays and Pointers

Arrays

All arrays in Fusion are passed as objects of type monty::ndarray wrapped in a shared pointer:

std::shared_ptr<monty::ndarray<T,N>>

where T is the type of the elements and N is an integer denoting the number of dimensions. See monty::ndarray for ways to create, manipulate and iterate over arrays and monty::new_array_ptr for array factory methods.

Shapes and indexes

The shape of arrays is defined by a type monty::shape_t, which is also used to define an \(N\)-dimensional index.

Objects and reference counting

Objects of all classes defined in the mosek::fusion namespace are wrapped in a reference counting pointer of type monty::rc_ptr. Every Fusion class C contains a definition of a type

typedef monty::rc_ptr<C> t;

for example Model::t, Variable::t etc. These pointer types should be used instead of standard pointers to ensure proper garbage collection. It is also recommended to use a finalizer if possible, as below. For example

Model::t M = new Model("MyModel");
auto _M = finally([&]() { M->dispose(); });
Variable::t v = M->variable(5);

An object will be destroyed the moment nobody refers to it any more.

14.1.3 Using vectors

Standard C++ vectors can be converted into a Fusion array using monty::new_array_ptr.

std::vector<double> x(5);
// ....
auto a = monty::new_array_ptr<double>(x);
// Now we can use a in Fusion calls, eg:
auto product = Expr::dot(a, v);

Similar version of monty::new_array_ptr is available for 2D vectors:

std::vector<std::vector<double>> x({{1,1,1,1,1}, {1,2,3,4,5}});
// ....
auto product = Expr::mul(monty::new_array_ptr<double>(x), v);

For more details see monty::new_array_ptr, and monty::new_vector_from_array_ptr.

14.1.4 C++ extension reference

14.1.4.1 Multidimensional arrays

monty::ndarray<T,N>

A template class for all arrays in Fusion.

Template parameters:
  • T – The type of objects stored in the array.

  • N – The number of dimensions.

ndarray<T,N>.ndarray<T,N>
ndarray(shape_t<N> shape)
ndarray(shape_t<N> shape, T value)
ndarray(const shape_t<N> & shape, const std::function<T(ptrdiff_t)> & fLin);
ndarray(const shape_t<N> & shape, const std::function<T(const shape_t<N> &)> & fInd)
ndarray(const T* vals, shape_t<N> shape)
ndarray(init_t & init)
template<typename Iterator> ndarray(const shape_t<N> & shape, Iterator begin, Iterator end)
template<typename Iterable> ndarray(const shape_t<N> & shape, const typename const_iterable_t<Iterable>::t & that)
template<typename Iterable> ndarray(const shape_t<N> & shape, const const_iterable_t<Iterable> & that)
ndarray(const ndarray<T,N> & that)
ndarray(ndarray<T,N> && that)

Constructor of a multidimensional array object. The initializing data can have several forms:

  • Default value, e.g. 0 for numerical types.

  • Create a new array initialized with values generated by a generator function.

    auto a1 = std::make_shared<ndarray<int,1>>(shape(5), [](ptrdiff_t i) { return 5-i; });
    auto a2 = std::make_shared<ndarray<int,2>>(shape(5,5), std::function<int(const shape_t<2> &)>([](const shape_t<2> & p) { return p[0]+p[1]; }));
    
  • Initialized with values from another array.

  • Initialized with an initializer list.

Arrays can also be constructed with the factory method monty::new_array_ptr.

Parameters:
  • shape (shape_t) – The shape of the array.

  • value (T) – The default value for all elements.

  • fLin – An array-filling function taking the linear index as an argument.

  • fInd – An array-filling function taking the multidimensional index as an argument.

  • vals (T*) – An array with element values.

  • init (init_t) – An initializer list. The type init_t is an \(N\)-fold nested initializer list of type std::initializer_list. For example, for 2-dimensional arrays this is an initializer list of initializer lists, and so forth.

  • begin, end – The pointers to an iterator.

  • that – Another iterable object (see monty_base.h) or an ndarray object used as initializer.

ndarray<T,N>.operator()
T& operator()(int i1, ..., int iN)

\(N\)-dimensional access operator. Returns the element at position \((i_1,...,i_N)\).

Example:

auto a = std::make_shared<ndarray<int,2>>(shape(5,5));
(*a)(3,4) = 15;
Parameters:

i1,... iN (int) – The multi-dimensional index of the element.

ndarray<T,N>.operator[]
T& operator[](int i)
T& operator[](const shape_t<N> & idx)

Access operator. Returns a specific element in the array.

Parameters:
  • i (int) – The linear index of the element, referring to its position in the one-dimensional row-wise flattening of the array.

  • idx (shape_t) – The multi-dimensional index of the element.

ndarray<T,N>.begin
T* begin()

An iterator pointing to the beginning of the array. Note that the iterator sees the array as a one dimensional array obtained traversing the \(N\)-dimensional array row-wise.

Example:

auto a = new_array_ptr<double,2>({ { 1.1, 2.2 }, { 3.3, 4.4 } } );
for(auto x : *a) std::cout << x << " ";
ndarray<T,N>.end
T* end()

An iterator pointing to the end of the array.

ndarray<T,N>.raw
T* raw()

Returns a pointer to the raw data array.

ndarray<T,N>.size
size_t size()

Returns the number of elements in the array.

14.1.4.2 Shapes and indices

monty::shape_t<N>

Represents the shape of an \(N\)-dimensional array. It is in fact an \(N\)-tuple of integers. It is also used to specify an index in an \(N\)-dimensional array.

Template parameters:

N – The number of dimensions.

shape_t<N>.shape_t<N>
shape_t(int i1, ..., int iN)
shape_t(int i0, shape_t<N-1> is)
shape_t(const shape_t<N> & that)

Constructor of a new shape. Shapes can also be constructed with the factory method monty::shape.

Parameters:
  • i1, ..., iN (int) – The dimensions.

  • i0 (int) – The first dimension.

  • is (shape_t) – Shape of the remaining \(N-1\) dimensions.

  • that (shape_t) – Another shape to be copied.

shape_t<N>.operator[]
int operator[](int i)

Return the size in a specific dimension.

Parameters:

i (int) – The dimension.

shape_t<N>.tolinear
int tolinear(const shape_t<N> & point)
int tolinear(int i1, ..., int iN)

Compute the linear index of an element within this shape. The linear index is the position of the element in the one-dimensional row-wise flattening of the shape.

Example:

std::cout << shape(2,3).tolinear(1,1);
// 4
Parameters:
  • point (shape_t) – The coordinates of an index within the current shape.

  • i1,...,iN (int) – The coordinates of an index within the current shape.

shape_t<N>.begin
shape_iterator<N> begin()

An iterator to the shape. This iterator will traverse all indices belonging to the shape in increasing linear order, i.e. in the row-wise order in the multidimensional shape, and return a object of type shape_t for each index.

Example:

for(auto p : shape(2,3)) std::cout << p;
// (0,0)(0,1)(0,2)(1,0)(1,1)(1,2)
shape_t<N>.end
shape_iterator<N> end()

An iterator pointing to the end of shape.

14.1.4.3 Reference counting pointers

monty::rc_ptr<T>

A reference counting pointer wrapped around an object of type T. Implements standard pointer type operators such as * and -> in the expected way. For Fusion classes, the reference counting pointer type monty::rc_ptr<C> is defined as C::t.

14.1.4.4 Exceptions

monty::ArrayInitializerException

An exception thrown when the array initializer is incorrect, for instance a 2-dimensional array is initialized with row lists of non-equal lengths.

14.1.4.5 Auxiliary functions in the monty namespace

monty::new_array_ptr
std::shared_ptr<ndarray<T,N>> new_array_ptr(init_t init)
std::shared_ptr<ndarray<T,1>> new_array_ptr(const std::vector<T> & x)
std::shared_ptr<ndarray<T,2>> new_array_ptr(const std::vector<std::vector<T>> & x2)

Create a new \(N\)-dimensional array of type T and wrap it in a shared pointer.

Examples:

auto a1 = new_array_ptr<double,1>({ 1.1, 2.2 , 3.3, 4.4 } );
auto a2 = new_array_ptr<double,2>({ { 1.1, 2.2 }, { 3.3, 4.4 } } );
std::vector<double> x(5);
// ....
auto a = monty::new_array_ptr<double>(x);
// Now we can use a in Fusion calls, eg:
auto product = Expr::dot(a, v);
std::vector<std::vector<double>> x({{1,1,1,1,1}, {1,2,3,4,5}});
// ....
auto product = Expr::mul(monty::new_array_ptr<double>(x), v);
Parameters:
  • init (init_t) – An initializer list. The type init_t is an \(N\)-fold nested initializer list of type std::initializer_list. For example, for 2-dimensional arrays this is an initializer list of initializer lists, and so forth.

  • x (std::vector<T>) – A vector of type T. The new array will have length x.size().

  • x2 (std::vector<std::vector<T>>) – A vector of type T. All rows in x2 must be vectors of the same length, otherwise an exception will be thrown.

monty::new_vector_from_array_ptr
std::vector<T> new_vector_from_array_ptr(const std::shared_ptr<ndarray<T,1>> & a) {

Convert a Fusion array into a C++ vector.

Examples:

auto a = std::make_shared<ndarray<double,1>>(shape(5));
// ....
std::vector<double> v = monty::new_vector_from_array_ptr(a);
Parameters:

a (std::shared_ptr<ndarray<T,1>>) – A one-dimensional array.

monty::shape
shape_t<N> shape(int i1, ..., int iN)

Create a new shape with the given dimensions.

Example:

auto s = shape(2,3,4);
Parameters:

i1, ..., iN (int) – The dimensions.