Member functions and variables
Source:vignettes/member-functions-and-variables.Rmd
member-functions-and-variables.Rmd
This vignette is adapted from the official Armadillo documentation.
Attributes
n_*
provides information for different objects:
-
.n_rows
number of rows forMat
,Col
,Row
,Cube
,field
, andSpMat
. -
.n_cols
number of columns forMat
,Col
,Row
,Cube
,field
, andSpMat
. -
.n_elem
total number of elements forMat
,Col
,Row
,Cube
,field
, andSpMat
. -
.n_slices
number of slices forCube
andfield
. -
.n_nonzero
number of non-zero elements forSpMat
.
For the Col
and Row
classes, n_elem
also indicates vector length.
The variables are read-only and of type uword
. To change the size, use set_size
, copy_size
, zeros_member
, ones_member
, or reset
.
To avoid compiler warnings about implicit conversion when operating uword
with integers
/doubles
to pass data to R, converte uword
to int
with static_cast<int>
or declare these as int
.
Examples
cpp11::register]] integers attr1_(const doubles_matrix<>& a) {
[[// convert from R to C++
mat A = as_Mat(a);
// uword or int can be used
int n_rows = A.n_rows; // number of rows
int n_cols = A.n_cols; // number of columns
int n_elem = A.n_elem; // number of elements
writable::integers res({n_rows, n_cols, n_elem});"names") = strings({"n_rows", "n_cols", "n_elem"});
res.attr(
return res;
}
Element/object access
Provide access to individual elements or objects stored in a container object (e.g., Mat
, Col
, Row
, Cube
, field
).
-
(i)
Forvec
androwvec
, access the element stored at indexi
. ForMat
,Cube
andfield
, access the element/object stored at indexi
under the assumption of a flat layout, with column-major ordering of data (e.g., column by column). An exception is thrown if the requested element is out of bounds. -
.at(i)
or[i]
As for(i)
, but without a bounds check. Not recommended. -
(r,c)
ForMat
and 2D field classes, access the element/object stored at rowr
and columnc
. An exception is thrown if the requested element is out of bounds. -
.at(r,c)
As for(r,c)
, but without a bounds check. Not recommended. -
(r,c,s)
ForCube
and 3D field classes, access the element/object stored at rowr
, columnc
, and slices
. An exception is thrown if the requested element is out of bounds. -
.at(r,c,s)
As for(r,c,s)
, but without a bounds check. Not recommended.
Examples
cpp11::register]] doubles_matrix<> access1_(const doubles_matrix<>& a) {
[[// convert from R to C++
mat A = as_Mat(a); 1,1) = 123.0; // set element at row 2, column 2
A(
2, fill::randu);
vec B(
double x = A(0,1); // copy element at row 1, column 2 to a double
double y = B(1); // copy element at coordinate 2 to a double
// int also works
uword i, j;
uword N = A.n_rows;
uword M = A.n_cols;
for(i = 0; i < N; ++i) {
for(j = 0; j < M; ++j) {
A(i,j) = A(i,j) + x + y;
}
}
return as_doubles_matrix(A); // convert from C++ to R
}
Caveats
For .at()
or [i]
, .at(r,c)
and .at(r,c,s)
:
- Indexing in C++ starts at 0
- Accessing elements without bounds checks is slightly faster, but is not recommended until your code has been thoroughly debugged first
- Accessing elements via
[r,c]
and[r,c,s]
does not work correctly in C++; instead use(r,c)
and(r,c,s)
The indices of elements are specified via the uword
type, which is a typedef
for an unsigned integer type. When using loops to access elements, it more efficient to use uword
instead of int
.
Element initialisation
Set elements in Mat
, Col
and Row
via braced initialiser lists.
Examples
cpp11::register]] doubles_matrix<> initialization1_(const doubles_matrix<>& a) {
[[// convert from R to C++
mat A = as_Mat(a); 1, 2}, {3, 4}}; // create new matrix
mat B = {{1, 2}; // create new column vector
vec C = {
// sum C to the diagonal of A
0,0) = A(0,0) + C(0);
A(1,1) = A(1,1) + C(1);
A(
mat D = A + B;
return as_doubles_matrix(D); // convert from C++ to R
}
Zeros
Set the elements of an object to zero, optionally first changing the size to specified dimensions.
.zeros()
(member function of Mat
, Col
, Row
, SpMat
, Cube
) .zeros(n_elem)
(member function of Col
and Row
) .zeros(n_rows, n_cols)
(member function of Mat
and SpMat
) .zeros(n_rows, n_cols, n_slices)
(member function of Cube
) .zeros(size(X))
(member function of Mat
, Col
, Row
, Cube
, SpMat
)
Examples
cpp11::register]] doubles_matrix<> zeros1_(const doubles_matrix<>& a) {
[[// convert from R to C++
mat A = as_Mat(a); // set all elements to zero
A.zeros();
mat B;// set size to be the same as A and set all elements to zero
B.zeros(size(A));
mat C(A.n_rows, A.n_cols, fill::zeros);
mat D = A + B + C;
return as_doubles_matrix(D); // convert from C++ to R
}
Ones
Set all the elements of an object to one, optionally first changing the size to specified dimensions.
Function | Mat | Col | Row | Cube |
---|---|---|---|---|
.ones() |
✓ | ✓ | ✓ | ✓ |
.ones(n_elem) |
✓ | ✓ | ||
.ones(n_rows, n_cols) |
✓ | |||
.ones(n_rows, n_cols, n_slices) |
✓ | |||
.ones(size(X)) |
✓ | ✓ | ✓ | ✓ |
Examples
cpp11::register]] doubles_matrix<> ones1_(const doubles_matrix<>& a) {
[[// convert from R to C++
mat A = as_Mat(a); // set all elements to zero
A.ones();
mat B;// set size to be the same as A and set all elements to zero
B.ones(size(A));
mat C(A.n_rows, A.n_cols, fill::ones);
mat D = A + B + C;
return as_doubles_matrix(D); // convert from C++ to R
}
Eye
.eye()
is member function of Mat
and SpMat
. .eye(n_rows, n_cols)
sets the elements along the main diagonal to one and off-diagonal elements to zero, optionally first changing the size to specified dimensions. .eye(size(X))
creates an identity matrix is generated when n_rows = n_cols
.
Examples
cpp11::register]] doubles_matrix<> eye1_(const doubles_matrix<>& a) {
[[// convert from R to C++
mat A = as_Mat(a); // create an identity matrix
A.eye();
mat B;// another identity matrix
B.eye(size(A));
uword N = A.n_rows;
uword M = A.n_cols;
mat C(N, M, fill::randu);// yet another identity matrix
C.eye(N, M);
mat D = A + B + C;
return as_doubles_matrix(D); // convert from C++ to R
}
Random uniform
Set all the elements to random values from a uniform distribution in the [0,1] interval, optionally first changing the size to specified dimensions.
For complex elements, the real and imaginary parts are treated separately.
Function/Method | Mat | Col | Row | Cube |
---|---|---|---|---|
.randu() |
✓ | ✓ | ✓ | ✓ |
.randu(n_elem) |
✓ | ✓ | ||
.randu(n_rows, n_cols) |
✓ | |||
.randu(n_rows, n_cols, n_slices) |
✓ | |||
.randu(size(X)) |
✓ | ✓ | ✓ | ✓ |
cpp11::register]] doubles_matrix<> randu1_(const doubles_matrix<>& a) {
[[// convert from R to C++
mat A = as_Mat(a);
mat B;// random uniform matrix with the same size as A
B.randu(size(A));
mat C(A.n_rows, A.n_cols, fill::randu);
mat D = A + B + C;
return as_doubles_matrix(D); // convert from C++ to R
}
cpp11::register]] doubles_matrix<> randu2_(const int& n) {
[[// Ensure R's RNG state is synchronized
GetRNGstate();
mat y(n, n);double>::fill(y.memptr(), y.n_elem);
::arma_rng::randu<
PutRNGstate();
return as_doubles_matrix(y);
}
Normal distribution
Set all the elements to random values from a normal distribution with zero mean and unit variance, optionally first changing the size to specified dimensions.
For complex elements, the real and imaginary parts are treated separately.
Function/Method | Mat | Col | Row | Cube |
---|---|---|---|---|
.randn() |
✓ | ✓ | ✓ | ✓ |
.randn(n_elem) |
✓ | ✓ | ||
.randn(n_rows, n_cols) |
✓ | |||
.randn(n_rows, n_cols, n_slices) |
✓ | |||
.randn(size(X)) |
✓ | ✓ | ✓ | ✓ |
Examples
cpp11::register]] doubles_matrix<> randn1_(const doubles_matrix<>& a) {
[[// convert from R to C++
mat A = as_Mat(a);
mat B;// random normal matrix with the same size as A
B.randn(size(A));
mat C(A.n_rows, A.n_cols, fill::randn);
mat D = A + B + C;
return as_doubles_matrix(D); // convert from C++ to R
}
cpp11::register]] doubles_matrix<> randn2_(const int& n) {
[[// Ensure R's RNG state is synchronized
GetRNGstate();
mat y(n, n);double>::fill(y.memptr(), y.n_elem);
::arma_rng::randn<
PutRNGstate();
return as_doubles_matrix(y);
}
Fill
Sets the elements to a specified value
.fill(value)
is a member function of Mat
, Col
, Row
, Cube
, field
.
The type of value must match the type of elements used by the container object (e.g., for Mat
the type is double
)
Examples
cpp11::register]] doubles_matrix<> fill1_(const doubles_matrix<>& a) {
[[// convert from R to C++
mat A = as_Mat(a);
uword N = A.n_rows;
uword M = A.n_cols;
200.0)); // create a matrix filled with 200.0
mat B(size(A), fill::value(100.0)); // matrix filled with 100.0
mat C(N, M, fill::value(// matrix filled with zeros
mat D(N, M, fill::zeros); // matrix filled with ones
mat E(N, M, fill::ones);
mat F = A + B + C + D + E;
return as_doubles_matrix(F); // convert from C++ to R
}
Imbue
.imbue(functor)
is a member function of Mat
, Col
, Row
and Cube
, it fills the elements with values provided by a functor. The argument can be a functor or lambda function.
For matrices, filling is done column-by-column (e.g., column 0 is filled, then column 1, etc.)
For cubes, filling is done slice-by-slice, with each slice treated as a matrix
Examples
cpp11::register]] doubles_matrix<> imbue1_(const doubles_matrix<>& a) {
[[// convert from R to C++
mat A = as_Mat(a);
std::mt19937 engine; // Mersenne twister random number engine
std::uniform_real_distribution<double> distr(0.0, 1.0);
// create an empty matrix
mat B(size(A), fill::none); return distr(engine); }); // fill with random values
B.imbue([&]() {
mat C = A + B;
return as_doubles_matrix(C); // convert from C++ to R
}
cpp11::register]] doubles_matrix<> imbue2_(const doubles_matrix<>& a) {
[[// Ensure R's RNG state is synchronized
GetRNGstate();
// Convert from R to C++
mat A = as_Mat(a);
// Create an empty matrix
mat B(size(A), fill::none); return unif_rand(); }); // Fill with random values
B.imbue([]() {
mat C = A + B;
PutRNGstate();
return as_doubles_matrix(C); // Convert from C++ to R
}
Clean
.clean(threshold)
is a member function of Mat
, Col
, Row
, Cube
, and SpMat
. It can be used to sparsify a matrix, in the sense of zeroing values with small magnitudes.
- For objects with non-complex elements: each element with an absolute value less or equal to the threshold is replaced by zero.
- For objects with complex elements: for each element, each component (real and imaginary) with an absolute value less or equal to the threshold is replaced by zero.
Examples
cpp11::register]] doubles_matrix<> clean1_(const int& n) {
[[// create a random matrix
mat A(n, n, fill::randu);
0, 0) = datum::eps; // set the diagonal with small values (+/- epsilon)
A(1, 1) = -datum::eps;
A(
// set elements with small values to zero
A.clean(datum::eps);
return as_doubles_matrix(A); // Convert from C++ to R
}
Replace
.replace( old_value, new_value )
is a member function of Mat
, Col
, Row
, Cube
, and SpMat
.
For all elements equal to old_value
, set them to new_value
.
Examples
cpp11::register]] doubles_matrix<> replace1_(const int& n) {
[[// create a random matrix
mat A(n, n, fill::randu);
// set the diagonal with NaN values
A.diag().fill(datum::nan); 0); // replace each NaN with 0
A.replace(datum::nan,
return as_doubles_matrix(A); // Convert from C++ to R
}
Caveats
- The type of
old_value
andnew_value
must match the type of elements used by the container object (e.g., forMat
the type isdouble
). - Floating point numbers (
float
anddouble
) are approximations due to their limited precision. - For sparse matrices (
SpMat
), replacement is not done whenold_value = 0
.
Clamp
.clamp(min_value, max_value)
is a member function of Mat
, Col
, Row
, Cube
and SpMat
that transforms all values lower than min_val
to min_val
, and all values higher than max_val
to max_val
.
- For complex elements, the real and imaginary components are clamped separately.
- For sparse matrices, clamping is applied only to the non-zero elements.
Transform
.transform(functor)
is a member function of Mat
, Col
, Row
, Cube
, and SpMat
. The argument can be a functor or lambda function.
- For dense matrices, transformation is done column-by-column for all elements.
- For sparse matrices, transformation is done column-by-column for non-zero elements.
- For cubes, transformation is done slice-by-slice, with each slice treated as a matrix.
For each
.for_each(functor)
is a member function of Mat
, Col
, Row
, Cube
, SpMat
, and field
. The argument can be a functor or lambda function.
- For dense matrices and fields, the processing is done column-by-column for all elements.
- For sparse matrices, the processing is done column-by-column for non-zero elements.
- For cubes, processing is done slice-by-slice, with each slice treated as a matrix.
Examples
cpp11::register]] doubles_matrix<> for_each1_(const int& n) {
[[// add 122 to each element in a dense matrix, the '&' is important
mat D(n, n, fill::ones);elem_type& val) { val += 122.0; });
D.for_each([](mat::
// add 122 to each non-zero element in a sparse matrix
sp_mat S;1.0);
S.sprandu(n, n, elem_type& val) { val += 123.0; });
S.for_each([](sp_mat::
// set the size of all matrices in a field
2, 2);
field<mat> F(// capture n for the lambda
F.for_each([n](mat& X) { X.zeros(n, n); });
0) + F(1);
mat res = D + S + F(
return as_doubles_matrix(res); // Convert from C++ to R
}
Set size
Change the size of an object, without explicitly preserving data and without initialising the elements (e.g., elements may contain garbage values, including NaN
).
-
.set_size(n_elem)
(member function ofCol
,Row
,field
) -
.set_size(n_rows, n_cols)
(member function ofMat
,SpMat
,field
) -
.set_size(n_rows, n_cols, n_slices)
(member function ofCube
andfield
) -
.set_size(size(X))
(member function ofMat
,Col
,Row
,Cube
,SpMat
,field
)
To initialise the elements to zero while changing the size, use .zeros()
instead. To explicitly preserve data while changing the size, use .reshape()
or .resize()
instead.
Examples
cpp11::register]] doubles set_size1_(const int& n) {
[[
mat A;// or: mat A(n, n, fill::none);
A.set_size(n, n);
mat B;// or: mat B(size(A), fill::none);
B.set_size(size(A));
vec C;// or: vec v(n, fill::none);
C.set_size(n);
1.0); // set all elements to 1.0
A.fill(2.0); // set all elements to 2.0
B.fill(3.0); // set all elements to 3.0
C.fill(
0) + B.col(1) + C;
vec res = A.col(
return as_doubles(res); // Convert from C++ to R
}
Reshape
Recreate an object according to given size specifications, with the elements taken from the previous version of the object in a column-wise manner. The elements in the generated object are placed column-wise (e.g., the first column is filled up before filling the second column)
-
.reshape(n_rows, n_cols)
(member function ofMat
andSpMat
) -
.reshape(n_rows, n_cols, n_slices)
(member function ofCube
) -
.reshape(size(X))
(member function ofMat
,Cube
,SpMat
)
The layout of the elements in the recreated object will be different to the layout in the previous version of the object
If the total number of elements in the previous version of the object is less than the specified size, the extra elements in the recreated object are set to zero
If the total number of elements in the previous version of the object is greater than the specified size, only a subset of the elements is taken
Resize
Resize an object according to given size specifications, while preserving the elements and the layout of the elements. It can be used for growing or shrinking an object (e.g., adding/removing rows, and/or columns, and/or slices).
-
.resize(n_elem)
: member function ofCol
,Row
. -
.resize(n_rows, n_cols)
: member function ofMat
andSpMat
. -
.resize(n_rows, n_cols, n_slices)
: member function ofCube
. -
.resize(size(X))
: member function ofMat
,Col
,Row
,Cube
,SpMat
.
Copy size
.copy_size(A)
sets the size of a matrix/vector/cube to be the same as matrix/vector/cube A
.
Submatrix views
A collection of member functions of Mat
, Col
and Row
classes that provide read/write access to submatrix views.
Contiguous views for matrix
X.col(col_number)
X.row(row_number)
-
X.cols(first_col, last_col)
X.rows(first_row, last_row)
X.submat(first_row, first_col, last_row, last_col)
X(span(first_row, last_row), span(first_col, last_col))
X(first_row, first_col, size(n_rows, n_cols))
-
X(first_row, first_col, size(Y))
(Y
is a matrix) X(span(first_row, last_row), col_number)
X(row_number, span(first_col, last_col))
X.head_cols(number_of_cols)
X.head_rows(number_of_rows)
X.tail_cols(number_of_cols)
X.tail_rows(number_of_rows)
-
X.unsafe_col(col_number)
(use with caution)
Contiguous views for vector
Y(span(first_index, last_index))
Y.subvec(first_index, last_index)
-
Y.subvec(first_index, size(X))
(X
is a vector)
Y.head(number_of_elements)
Y.tail(number_of_elements)
Non-contiguous views for matrix or vector:
X.elem(vector_of_indices)
X(vector_of_indices)
X.cols(vector_of_column_indices)
X.rows(vector_of_row_indices)
X.submat(vector_of_row_indices, vector_of_column_indices)
X(vector_of_row_indices, vector_of_column_indices)
Instances of span(start, end)
can be replaced by span::all_
to indicate the entire range.
For functions requiring one or more vector of indices, for example X.submat(vector_of_row_indices, vector_of_column_indices)
, each vector of indices must be of type uvec
.
In the function X.elem(vector_of_indices)
, elements specified in vector_of_indices
are accessed. X
is interpreted as one long vector, with column-by-column ordering of the elements of X
. The vector_of_indices
must evaluate to a vector of type uvec
(e.g., generated by the find()
function). The aggregate set of the specified elements is treated as a column vector (e.g., the output of X.elem()
is always a column vector).
The function .unsafe_col()
is provided for speed reasons and should be used only if you know what you are doing. It creates a seemingly independent Col
vector object (e.g., vec
), but uses memory from the existing matrix object. As such, the created vector is not alias safe, and does not take into account that the underlying matrix memory could be freed (e.g., due to any operation involving a size change of the matrix).
Examples
cpp11::register]] doubles_matrix<> subview1_(const int& n) {
[[
mat A(n, n, fill::zeros);
0,1,2,3) = randu<mat>(3,3);
A.submat(0,2), span(1,3)) = randu<mat>(3,3);
A(span(0,1, size(3,3)) = randu<mat>(3,3);
A(
0,1,2,3);
mat B = A.submat(0,2), span(1,3) );
mat C = A(span(0, 1, size(3,3) );
mat D = A(
1) = randu<mat>(5,1);
A.col(1) = randu<mat>(5,1);
A(span::all,
5, 5, fill::randu);
mat X(
// get all elements of X that are greater than 0.5
0.5) );
vec q = X.elem( find(X >
// add 123 to all elements of X greater than 0.5
0.5) ) += 123.0;
X.elem( find(X >
// set four specific elements of X to 1
2, 3, 6, 8 };
uvec indices = {
4);
X.elem(indices) = ones<vec>(
// add 123 to the last 5 elements of vector a
10, fill::randu);
vec a(5) += 123.0;
a.tail(
// add 123 to the first 3 elements of column 2 of X
2).head(3) += 123;
X.col(
return as_doubles_matrix(X); // Convert from C++ to R
}
Subcube views and slices
A collection of member functions of the Cube
class that provide subcube views.
Contiguous views for cube
Q.slice(slice_number)
Q.slices(first_slice, last_slice)
Q.row(row_number)
Q.rows(first_row, last_row)
Q.col(col_number)
Q.cols(first_col, last_col)
Q.subcube( first_row, first_col, first_slice, last_row, last_col, last_slice)
Q(span(first_row, last_row), span(first_col, last_col), span(first_slice, last_slice))
Q(first_row, first_col, first_slice, size(n_rows, n_cols, n_slices))
-
Q(first_row, first_col, first_slice, size(R))
(R
is a cube)
Q.head_slices(number_of_slices)
Q.tail_slices(number_of_slices)
Q.tube(row, col)
Q.tube(first_row, first_col, last_row, last_col)
Q.tube(span(first_row, last_row), span(first_col, last_col))
Q.tube(first_row, first_col, size(n_rows, n_cols))
Non-contiguous views for cube
Q.elem(vector_of_indices)
, Q(vector_of_indices)
, and Q.slices( vector_of_slice_indices)
are instances of span(a,b)
that can be replaced by:
-
span()
orspan::all
, to indicate the entire range. -
span(a)
, to indicate a particular row, column or slice.
An individual slice, accessed via .slice()
, is an instance of the Mat
class (a reference to a matrix is provided).
All .tube()
forms are variants of .subcube()
, using first_slice = 0
and last_slice = Q.n_slices-1
. The .tube(row,col)
form uses row = first_row = last_row
, and col = first_col = last_col
.
In the function Q.elem(vector_of_indices)
, elements specified in vector_of_indices
are accessed. Q
is interpreted as one long vector, with slice-by-slice and column-by-column ordering of the elements of Q
. The vector_of_indices
must evaluate to a vector of type uvec
(e.g., generated by the find()
function). The aggregate set of the specified elements is treated as a column vector (e.g., the output of Q.elem()
is always a column vector).
In the function Q.slices(vector_of_slice_indices)
, slices specified in vector_of_slice_indices
are accessed. The vector_of_slice_indices
must evaluate to a vector of type uvec
.
Examples
cpp11::register]] doubles_matrix<> subview2_(const int& n) {
[[3, 4, fill::randu);
cube A(n,
1); // each slice is a matrix
mat B = A.slice(
0) = randu<mat>(2,3);
A.slice(0)(1,2) = 99.0;
A.slice(
0,0,1, 1,1,2) = randu<cube>(2,2,2);
A.subcube(0,1), span(0,1), span(1,2)) = randu<cube>(2,2,2);
A(span(0,0,1, size(2,2,2)) = randu<cube>(2,2,2);
A(
// add 123 to all elements of A greater than 0.5
0.5) ) += 123.0;
A.elem( find(A >
2); // get first two slices
cube C = A.head_slices(
2) += 123.0;
A.head_slices(
0) + B + C.slice(1);
mat res = A.slice(
return as_doubles_matrix(res); // Convert from C++ to R
}
Subfield views
A collection of member functions of the field
class that provide subfield views.
For a 2D field F
, the subfields are accessed as:
F.row(row_number)
F.col(col_number)
F.rows(first_row, last_row)
F.cols(first_col, last_col)
F.subfield(first_row, first_col, last_row, last_col)
F(span(first_row, last_row), span(first_col, last_col))
-
F(first_row, first_col, size(G))
(G
is a 2D field) F(first_row, first_col, size(n_rows, n_cols))
For a 3D field F
, the subfields are accessed as:
F.slice(slice_number)
F.slices(first_slice, last_slice)
F.subfield(first_row, first_col, first_slice, last_row, last_col, last_slice)
F(span(first_row, last_row), span(first_col, last_col), span(first_slice, last_slice))
-
F(first_row, first_col, first_slice, size(G))
(G
is a 3D field) F(first_row, first_col, first_slice, size(n_rows, n_cols, n_slices))
Instances of span(a,b)
can be replaced by:
-
span()
orspan::all
, to indicate the entire range. -
span(a)
, to indicate a particular row or column.
Diagonal
.diag()
is a member functions of Mat
and SpMat
with read/write access to the diagonal in a matrix. The argument can be empty or a value k
to specify the diagonal to (k = 0
by default). The diagonal is interpreted as a column vector within expressions.
-
k = 0
indicates the main diagonal (default setting) -
k < 0
indicates thek
-th sub-diagonal (below main diagonal, towards bottom-left corner) -
k > 0
indicates thek
-th super-diagonal (above main diagonal, towards top-right corner)
Examples
cpp11::register]] doubles diagonal1_(const int& n) {
[[
mat X(n, n, fill::randu);
// extract the main diagonal
vec A = X.diag(); double B = accu(X.diag(1)); // sum of elements on the first upper diagonal
double C = accu(X.diag(-1)); // sum of elements on the first lower diagonal
X.diag() = randu<vec>(n);
X.diag() += A;
X.diag() /= B;
X.diag() *= C;
0.0);
sp_mat S = sprandu<sp_mat>(n, n,
S.diag().ones();
// copy sparse diagonal to dense vector
vec v(S.diag());
v += X.diag();
return as_doubles(v); // Convert from C++ to R
}
Each col
.each_col()
is a member function of Mat
. It applies a vector operation to each column of a matrix, and are similar to “broadcasting” in Matlab/Octave. The argument can be empty, a vector of indices, or a lambda function.
Operation | .each_col() |
.each_col(vector_of_indices) |
.each_col(lambda) |
---|---|---|---|
+ addition |
✓ | ✓ | |
+= in-place addition |
✓ | ✓ | |
- subtraction |
✓ | ✓ | |
-= in-place subtraction |
✓ | ✓ | |
% element-wise multiplication |
✓ | ✓ | |
%= in-place element-wise multiplication |
✓ | ✓ | |
/ element-wise division |
✓ | ✓ | |
/= in-place element-wise division |
✓ | ✓ | |
= assignment (copy) |
✓ | ✓ | |
lambda (lambda function) |
✓ |
Examples
cpp11::register]] doubles_matrix<> each_col1_(const int& n) {
[[1, fill::ones);
mat X(n, n +
// create a vector with n elements ranging from 5 to 10
5, 10, n);
vec v = linspace<vec>(
// in-place addition of v to each column vector of X
X.each_col() += v;
// generate Y by adding v to each column vector of X
mat Y = X.each_col() + v;
// subtract v from columns 1 and 2 of X
0, 1).each_col() -= v;
X.cols(
2);
uvec indices(0) = 1;
indices(1) = 2;
indices(
// copy v to columns 1 and 2 of X
X.each_col(indices) = v;
// lambda function with non-const vector
2 * a; });
X.each_col([](vec& a) {
const mat& XX = X;
// lambda function with const vector
const vec& b) { 3 * b; });
XX.each_col([](
mat res = X + Y + XX;
return as_doubles_matrix(res); // Convert from C++ to R
}
Each row
.each_row()
, .each_row(vector_of_indices)
, .each_row(lambdaction)
are member functions of Mat
. These apply a vector operation to each row of a matrix, and are similar to “broadcasting” in Matlab/Octave.
Form 1
.each_row()
supports the following operations:
-
+
addition -
+=
in-place addition -
-
subtraction -
-=
in-place subtraction -
%
element-wise multiplication -
%=
in-place element-wise multiplication -
/
element-wise division -
/=
in-place element-wise division -
=
assignment (copy)
Form 2
.each_row(vector_of_indices)
supports the same operations as form 1. The argument vector_of_indices
contains a list of indices of the rows to be used, and it must evaluate to a vector of type uvec
.
Form 3
.each_col(lambdaction)
applies the given lambdaction
to each column vector. The function must accept a reference to a Row
object with the same element type as the underlying matrix.
Examples
cpp11::register]] doubles_matrix<> each_row1_(const int& n) {
[[1, n, fill::ones);
mat X(n +
// create a vector with n elements ranging from 5 to 10
5, 10, n);
rowvec v = linspace<rowvec>(
// in-place addition of v to each rows vector of X
X.each_row() += v;
// generate Y by adding v to each rows vector of X
mat Y = X.each_row() + v;
// subtract v from rows 1 and 2 of X
0, 1).each_row() -= v;
X.rows(
2);
uvec indices(0) = 1;
indices(1) = 2;
indices(
// copy v to columns 1 and 2 of X
X.each_row(indices) = v;
// lambda function with non-const vector
2; });
X.each_row([](rowvec& a) { a /
const mat& XX = X;
// lambda function with const vector
const rowvec& b) { b / 3; });
XX.each_row([](
mat res = X + Y + XX;
return as_doubles_matrix(res); // Convert from C++ to R
}
Each slice
.each_slice()
is a member function of Cube
that applies a matrix operation to each slice of a cube, with each slice treated as a matrix. It is similar to “broadcasting” in Matlab/Octave.
Form 1
.each_slice(vector_of_indices)
Supported operations:
-
+
addition -
+=
in-place addition -
-
subtraction -
-=
in-place subtraction -
%
element-wise multiplication -
%=
in-place element-wise multiplication -
/
element-wise division -
/=
in-place element-wise division -
*
matrix multiplication -
*=
in-place matrix multiplication -
=
assignment (copy)
Form 2
.each_slice(lambdaction)
- The argument vector_of_indices contains a list of indices of the slices to be used; it must evaluate to a vector of type
uvec
. - Arithmetic operations as per form 1 are supported, except for
*
and*=
(e.g., matrix multiplication).
Form 3
.each_slice(lambdaction, use_mp)
- Apply the given
lambdaction
to each slice. - The function must accept a reference to a
Mat
object with the same element type as the underlying cube.
Form 4
- Apply the given
lambdaction
to each slice, as per form 3. - The argument
use_mp
is a bool to enable the use of OpenMP for multi-threaded execution oflambdaction
on multiple slices at the same time. - The order of processing the slices is not deterministic (e.g., slice 2 can be processed before slice 1).
-
lambdaction
must be thread-safe, e.g., it must not write to variables outside of its scope.
Examples:
cpp11::register]] doubles_matrix<> each_slice1_(const int& n) {
[[1, 6, fill::randu);
cube C(n, n +
1, n, n), 1, n + 1);
mat M = repmat(linspace<vec>(
// in-place addition of M to each slice of C
C.each_slice() += M;
// generate D by adding M to each slice of C
cube D = C.each_slice() + M;
// sum all slices of D into a single n x (n + 1) matrix
2);
mat D_flat = sum(D,
2);
uvec indices(0) = 2;
indices(1) = 4;
indices(
// copy M to slices 2 and 4 in C
C.each_slice(indices) = M; 2.0; }); // lambda function with non-const matrix
C.each_slice([](mat& X) { X * 2);
mat C_flat = sum(C,
const cube& CC = C;
const mat& X) { X / 3.0; }); // lambda function with const matrix
CC.each_slice([](
2);
mat CC_flat = sum(CC,
mat res = C_flat + D_flat + CC_flat;
return as_doubles_matrix(res); // Convert from C++ to R
}
Set real
.set_real(X)
sets the real part of an object. X
must have the same size as the recipient object.
Examples
cpp11::register]] list set_real1_(const int& n) {
[[1, n - 1, fill::randu);
mat A(n +
1, n - 1, fill::zeros);
cx_mat C(n +
C.set_real(A);
return as_complex_matrix(C); // Convert from C++ to R
}
Caveat
To directly construct a complex matrix out of two real matrices, the following code is faster:
cpp11::register]] list set_real2_(const int& n) {
[[1, n + 1, fill::randu);
mat A(n - 1, n + 1, fill::randu);
mat B(n -
cx_mat C = cx_mat(A,B);
return as_complex_matrix(C); // Convert from C++ to R
}
Set imaginary
.set_imaginary(X)
sets the imaginary part of an object. X
must have the same size as the recipient object.
Examples
cpp11::register]] list set_imag1_(const int& n) {
[[1, n - 1, fill::randu);
mat B(n +
1, n - 1, fill::zeros);
cx_mat C(n +
C.set_imag(B);
return as_complex_matrix(C); // Convert from C++ to R
}
Caveat
To directly construct a complex matrix out of two real matrices, the following code is faster:
cpp11::register]] list set_imag2_(const int& n) {
[[1, n + 1, fill::randu);
mat A(n - 1, n + 1, fill::randu);
mat B(n -
cx_mat C = cx_mat(A,B);
return as_complex_matrix(C); // Convert from C++ to R
}
Insert columns
.insert_cols()
is a member function of Mat
, Row
and Cube
. The arguments can be colnumber, X
to indicate the column number and the matrix to insert, or colnumber, number_of_cols
to indicate the column number and the number of columns to insert.
The X
argument inserts a copy of X
at the specified column. X
must have the same number of rows (and slices) as the recipient object.
The number_of_cols
argument expands the object by creating new columns that are set to zero.
Examples
cpp11::register]] doubles_matrix<> insert_columns1_(const int& n) {
[[2, fill::randu);
mat A(n, n * 1, fill::ones);
mat B(n, n -
// at column n - 1, insert a copy of B
// A will now have 3n - 1 columns
1, B);
A.insert_cols(n -
// at column 1, insert 2n zeroed columns
// B will now have 3n - 1 columns
1, n * 2);
B.insert_cols(
mat res = A + B;
return as_doubles_matrix(res); // Convert from C++ to R
}
Insert rows
.insert_rows()
is a member function of Mat
, Row
and Cube
. The arguments can be rownumber, X
to indicate the row number and the matrix to insert, or rownumber, number_of_rows
to indicate the row number and the number of rows to insert.
The X
argument inserts a copy of X
at the specified column. X
must have the same number of columns (and slices) as the recipient object.
The number_of_rows
argument expands the object by creating new rows that are set to zero.
Examples
cpp11::register]] doubles_matrix<> insert_rows1_(const int& n) {
[[2, n, fill::randu);
mat A(n * 1, n, fill::ones);
mat B(n -
// at row n - 1, insert a copy of B
// A will now have 3n - 1 rows
1, B);
A.insert_rows(n -
// at row 1, insert 2n zeroed rows
// B will now have 3n - 1 columns
1, n * 2);
B.insert_rows(
mat res = A + B;
return as_doubles_matrix(res); // Convert from C++ to R
}
Insert slice
.insert_slices()
is a member function of Cube
. The arguments can be slice_number, X
to indicate the slice number and the matrix to insert, or slice_number, number_of_slices
to indicate the slice number and the number of slices to insert.
The X
argument inserts a copy of X
at the specified slice. X
must have the same number of columns and rows as the recipient object.
The number_of_slices
argument expands the object by creating new slices that are set to zero.
Examples
cpp11::register]] doubles_matrix<> insert_slices1_(const int& n) {
[[2, fill::randu);
cube A(n, n, n * 1, fill::ones);
cube B(n, n, n -
// At slice n - 1, insert a copy of B
// A will now have 3n - 1 slices
1, B);
A.insert_slices(n -
// At slice 1, insert 2n zeroed slices
// B will now have 3n - 1 slices
1, n * 2);
B.insert_slices(
mat res = sum(A + B);
return as_doubles_matrix(res); // Convert from C++ to R
}
Shed columns
.shed_col(row_number)
and .shed_cols(first_row, last_row)
are member functions of Mat
, Col
, SpMat
, and Cube
. With a single scalar argument it remove the specified column, and with two scalar arguments it removes the specified range of columns.
.shed_cols(vector_of_indices)
is a member function of Mat
and Col
. With a vector of indices it must evaluate to a vector of type uvec
containing the indices of the columns to remove.
Examples
cpp11::register]] doubles_matrix<> shed_columns1_(const int& n) {
[[5, fill::randu);
mat A(n, n *
// remove the first column
0);
A.shed_col(
// remove columns 1 and 2
0, 1);
A.shed_cols(
// remove columns 2 and 4
2);
uvec indices(0) = 1;
indices(1) = 3;
indices(
A.shed_cols(indices);
return as_doubles_matrix(A); // Convert from C++ to R
}
Shed rows
.shed_row(row_number)
and .shed_rows(first_row, last_row)
are member functions of Mat
, Col
, SpMat
, and Cube
. With a single scalar argument it remove the specified rows, and with two scalar arguments it removes the specified range of rows.
.shed_rows(vector_of_indices)
is a member function of Mat
and Row
. With a vector of indices it must evaluate to a vector of type uvec
containing the indices of the rows to remove.
Examples
cpp11::register]] doubles_matrix<> shed_rows1_(const int& n) {
[[5, n, fill::randu);
mat A(n *
// remove the first row
0);
A.shed_row(
// remove rows 1 and 2
0, 1);
A.shed_rows(
// remove rows 2 and 4
2);
uvec indices(0) = 1;
indices(1) = 3;
indices(
A.shed_rows(indices);
return as_doubles_matrix(A); // Convert from C++ to R
}
Shed slices
.shed_slices()
is a member function of Cube
. With a single scalar argument it remove the specified slices, and with two scalar arguments it removes the specified range of slices. With a vector of indices it must evaluate to a vector of type uvec
containing the indices of the rows to remove. The arguments can be slice_number
to indicate the slice number to remove, first_slice, last_slice
to indicate the range of slices to remove, or vector_of_indices
to indicate the indices of the slices to remove.
Examples
cpp11::register]] doubles_matrix<> shed_slices1_(const int& n) {
[[5, fill::randu);
cube A(n, n, n *
// remove the first slice
0);
A.shed_slice(
// remove slices 1 and 2
0, 1);
A.shed_slices(
// remove slices 2 and 4
2);
uvec indices(0) = 1;
indices(1) = 3;
indices(
A.shed_slices(indices);
2);
mat res = sum(A,
return as_doubles_matrix(res); // Convert from C++ to R
}
Swap columns
.swap_cols( col1, col2 )
is a member functions of Mat
, Col
, Row
, and SpMat
. It swaps the contents of the specified columns.
Swap rows
.swap_rows( col1, col2 )
is a member functions of Mat
, Col
, Row
, and SpMat
. It swaps the contents of the specified rows.
Swap
.swap( X )
is a member function of Mat
, Col
, Row
, and Cube
. It swaps the contents with object X
.
Memory pointer
.memptr()
is a member function of Mat
, Col
, Row
, and Cube
. It obtains a raw pointer to the memory used for storing elements. Data for matrices is stored in a column-by-column order. Data for cubes is stored in a slice-by-slice (matrix-by-matrix) order.
Examples
cpp11::register]] doubles_matrix<> memptr1_(const int& n) {
[[
mat A(n, n, fill::randu);const mat B(n, n, fill::randu);
double* A_mem = A.memptr();
const double* B_mem = B.memptr();
// alter A_mem
// B_mem is const, so it cannot be altered
for (int i = 0; i < n * n; ++i) {
123.0 + B_mem[i];
A_mem[i] +=
}
return as_doubles_matrix(A); // Convert from C++ to R
}
Column pointer
.colptr( col_number )
is a member function of the Mat
class that obtains a raw pointer to the memory used by elements in the specified column.
Examples
cpp11::register]] doubles_matrix<> colptr1_(const int& n) {
[[
mat A(n, n, fill::randu);
// pointer to the memory of the first column of A
double* Acol1_mem = A.colptr(0);
// alter memory
for (int i = 0; i < n; ++i) {
123.0;
Acol1_mem[i] +=
}
return as_doubles_matrix(A); // Convert from C++ to R
}
Iterators
Iterators for traverse over all elements within the specified range. These return the column/row/slice of an object as a uword
type.
Member functions
Dense matrices and vectors (Mat
, Col
, and Row
):
-
.begin()
is an iterator referring to the first element. -
.end()
is an iterator referring to the past the end element. -
.begin_col(col_number)
is an iterator referring to the first element of the specified column. -
.end_col(col_number)
is an iterator referring to the past-the-end element of the specified column. -
begin_row(row_number)
is an iterator referring to the first element of the specified row. -
end_row(row_number)
is an iterator referring to the past-the-end element of the specified row.
Cubes (Cube
):
-
begin()
is an iterator referring to the first element. -
end()
is an iterator referring to the past-the-end element. -
begin_slice(slice_number)
iterator referring to the first element of the specified slice. -
end_slice(slice_number)
iterator referring to the past-the-end element of the specified slice.
Sparse matrices (SpMat
):
-
begin()
is an iterator referring to the first element. -
end()
is an iterator referring to the past-the-end element. -
begin_col(col_number)
is an iterator referring to the first element of the specified column. -
end_col(col_number)
is an iterator referring to the past-the-end element of the specified column. -
begin_row(row_number)
is an iterator referring to the first element of the specified row. -
end_row(row_number)
is an iterator referring to the past-the-end element of the specified row.
Dense submatrices and subcubes (submatrix
and subcube
):
-
span(row, col)
andspan(row, col, slice)
can be used to specify the range of elements to iterate over.
Iterator types
Dense matrices and vectors (Mat
, Col
, and Row
):
-
mat::iterator
,vec::iterator
androwvec::iterator
are random access iterators, for read/write access to elements (which are stored column by column). -
mat::const_iterator
,vec::const_iterator
androwvec::const_iterator
are random access iterators, for read-only access to elements (which are stored column by column) -
mat::col_iterator
,vec::col_iterator
androwvec::col_iterator
random access iterators, for read/write access to the elements of specified columns. -
mat::const_col_iterator
,vec::const_col_iterator
androwvec::const_col_iterator
are random access iterators, for read-only access to the elements of specified columns. -
mat::row_iterator
is a bidirectional iterator, for read/write access to the elements of specified rows. -
mat::const_row_iterator
is a bidirectional iterator, for read-only access to the elements of specified rows. -
vec::row_iterator
androwvec::row_iterator
are random access iterators, for read/write access to the elements of specified rows. -
vec::const_row_iterator
androwvec::const_row_iterator
are random access iterators, for read-only access to the elements of specified rows.
Cubes (Cube
):
-
cube::iterator
is a random access iterator, for read/write access to elements. The elements are ordered slice by slice; the elements within each slice are ordered column by column. -
cube::const_iterator
is a random access iterator, for read-only access to elements. -
cube::slice_iterator
is a random access iterator, for read/write access to the elements of a particular slice. The elements are ordered column by column. -
cube::const_slice_iterator
is a random access iterator, for read-only access to the elements of a particular slice.
Sparse matrices (SpMat
):
-
sp_mat::iterator
is a bidirectional iterator, for read/write access to elements (which are stored column by column). -
sp_mat::const_iterator
is a bidirectional iterator, for read-only access to elements (which are stored column by column). -
sp_mat::col_iterator
is a bidirectional iterator, for read/write access to the elements of a specific column. -
sp_mat::const_col_iterator
is a bidirectional iterator, for read-only access to the elements of a specific column. -
sp_mat::row_iterator
is a bidirectional iterator, for read/write access to the elements of a specific row. -
sp_mat::const_row_iterator
is a bidirectional iterator, for read-only access to the elements of a specific row.
Examples
cpp11::register]] doubles_matrix<> iterators1_(const int& n) {
[[1, fill::randu);
mat X(n, n +
mat::iterator it = X.begin();
mat::iterator it_end = X.end();
for (; it != it_end; ++it) {
123.0;
(*it) +=
}
1); // start of column 1
mat::col_iterator col_it = X.begin_col(// end of column n
mat::col_iterator col_it_end = X.end_col(n);
for (; col_it != col_it_end; ++col_it) {
321.0;
(*col_it) =
}
return as_doubles_matrix(X); // Convert from C++ to R
}
cpp11::register]] doubles_matrix<> iterators2_(const int& n) {
[[1, n + 2, fill::randu);
cube X(n, n +
cube::iterator it = X.begin();
cube::iterator it_end = X.end();
for (; it != it_end; ++it) {
123.0;
(*it) +=
}
s_it = X.begin_slice(1); // start of slice 1
cube::slice_iterator s_it_end = X.end_slice(n); // end of slice n
cube::slice_iterator
for (; s_it != s_it_end; ++s_it) {
s_it) = 321.0;
(*
}
2);
mat res = sum(X,
return as_doubles_matrix(res); // Convert from C++ to R
}
cpp11::register]] doubles_matrix<> iterators3_(const int& n) {
[[2, 0.1);
sp_mat X = sprandu<sp_mat>(n, n *
sp_mat::iterator it = X.begin();
sp_mat::iterator it_end = X.end();
for (; it != it_end; ++it) {
123.0;
(*it) +=
}
return as_doubles_matrix(X); // Convert from C++ to R
}
cpp11::register]] doubles_matrix<> iterators4_(const int& n) {
[[
mat X(n, n, fill::randu);
for (double& val : X(span(0, 1), span(1, 1))) {
123.0;
val =
}
return as_doubles_matrix(X); // Convert from C++ to R
}
Caveats
- Writing a zero value into a sparse matrix through an iterator will invalidate all current iterators associated with the sparse matrix.
- To modify the non-zero elements in a safer manner, use
.transform()
or.for_each()
instead of iterators. - For
submatrix
andsubcube
the iterators are intended only to be used with range-based for loops. Any other use is not supported. For example, the direct use of the.begin()
and.end()
functions, as well as the underlying iterators types is not supported. The implementation of submatrices and subcubes uses short-lived temporary objects that are subject to automatic deletion, and as such are error-prone to handle manually.
Compatibility container functions
Member functions for the Col
and Row
classes to mimic the functionality of containers in the C++ standard library:
-
.front()
accesses the first element in a vector. -
.back()
accesses the last element in a vector.
Member functions for the Col
, Row
, Mat
, Cube
and SpMat
classes to mimic the functionality of containers in the C++ standard library:
-
.clear()
removes the elements from an object. -
.empty()
returnstrue
if the object has no elements andfalse
if the object has one or more elements.
-
.size()
returns the total number of elements in an object.
Examples
cpp11::register]] doubles compatibility1_(const int& n) {
[[
vec X(n, fill::randu);
writable::doubles res = {X.front(), X.back()};
"names") = strings({"front", "back"});
res.attr(
return res;
}
cpp11::register]] integers compatibility2_(const int& n) {
[[
mat X(n, n, fill::randu);
2);
writable::integers res(0] = X.n_rows;
res[
X.clear();1] = X.n_rows;
res[
"names") = strings({"before", "after"});
res.attr(
return res;
}
Convert matrix to column
.as_col()
is a member function of the Mat
class, it returns a flattened version of the matrix as a column vector. Flattening is done by concatenating all columns.
Convert matrix to row
.as_row()
is a member function of the Mat
class, it returns a flattened version of the matrix as a row vector. Flattening is done by concatenating all rows.
Convert column to matrix
.col_as_mat(col_number)
is a member function of the Cube
class, it returns a matrix of the specified cube column and the number of rows is preserved. Given a cube of size R x C x S
, the resultant matrix size is R x S
.
Examples
cpp11::register]] list col_as_mat1_(const int& n) {
[[1, n + 2, fill::randu);
cube C(n, n + 0); // size n x (n + 1)
mat M = C.col_as_mat(
5);
writable::list res(0] = as_doubles_matrix(C.slice(0));
res[1] = as_doubles_matrix(C.slice(1));
res[2] = as_doubles_matrix(C.slice(2));
res[3] = as_doubles_matrix(C.slice(3));
res[4] = as_doubles_matrix(M);
res[
"names") = strings({"slice0", "slice1", "slice2", "slice3",
res.attr("col_as_mat"});
return res;
}
Convert column to matrix
.row_as_mat(row_number)
is a member function of the Cube
class, it returns a matrix of the specified cube row and the number of columns is preserved. Given a cube of size R x C x S
, the resultant matrix size is S x C
.
Examples
cpp11::register]] list row_as_mat1_(const int& n) {
[[1, n + 2, fill::randu);
cube C(n, n + 0); // size (n + 2) x (n + 1)
mat M = C.row_as_mat(
5);
writable::list res(0] = as_doubles_matrix(C.slice(0));
res[1] = as_doubles_matrix(C.slice(1));
res[2] = as_doubles_matrix(C.slice(2));
res[3] = as_doubles_matrix(C.slice(3));
res[4] = as_doubles_matrix(M);
res[
"names") = strings({"slice0", "slice1", "slice2", "slice3",
res.attr("row_as_mat"});
return res;
}
Convert sparse matrix to dense matrix
.as_dense()
is a member function of the SpMat
class, it avoids the construction of an intermediate sparse matrix representation of the expression.
Examples
cpp11::register]] doubles as_dense1_(const int& n) {
[[
sp_mat A;0.1);
A.sprandu(n, n,
// extract column 1 of A directly into dense column vector
0).as_dense();
colvec c = A.col(
// store the sum of each column of A directly in dense row vector
rowvec r = sum(A).as_dense();
return as_doubles(c + r.t());
}
Dense matrix and vector transposition
.t()
is a member function of the Mat
, Col
and Row
classes, it returns a transposed copy of the object. For real matrices, the transpose is a simple transposition of the elements. For complex matrices, the transpose is a Hermitian conjugate transposition of the elements (e.g., the signs of the imaginary components are flipped).
Sparse matrix transposition
.st()
is a member function of the SpMat
classe, it returns a transposed copy of the object. For real matrices, it is not applicable. For complex matrices, the transpose is a simple transposition of the elements (e.g., the signs of imaginary components are not flipped).
Matrix inversion
.i()
is a member function of the Mat
class, it provides an inverse of the matrix. If the matrix is not square sized, a std::logic_error
exception is thrown. If the matrix appears to be singular, the output matrix is reset and a std::runtime_error
exception is thrown.
Examples
cpp11::register]] doubles inverse1_(const doubles_matrix<>& a,
[[const doubles b) {
mat A = as_Mat(a);
vec B = as_Col(b);
mat X = inv(A);
vec Y = X * B;
return as_doubles(Y);
}
Caveats
- If the matrix is known to be symmetric positive definite,
inv_sympd()
. - To solve a system of linear equations, such as
Z = inv(X) * Y
,solve()
can be faster and/or more accurate.
Maximum and minimum
.min()
and .max()
are member functions of the Mat
, Col
, Row
, and Cube
classes. These return the minimum and maximum values of the object, respectively. For objects with complex numbers, absolute values are used for comparison.
Linear index of maximum and minimum
.index_min()
and .index_max()
are member functions of the Mat
, Col
, Row
, and Cube
classes. They return the linear index of the minimum and maximum values of the object, respectively. For objects with complex numbers, absolute values are used for comparison. The returned index is of type uword
.
Examples
cpp11::register]] doubles index_maxmin1_(const int& n) {
[[
mat A = randu<mat>(n, n);
6);
writable::doubles res(0] = static_cast<int>(A.index_max());
res[1] = static_cast<int>(A.index_min());
res[2] = A(0, 0);
res[3] = A(1, 0);
res[4] = A(0, 1);
res[5] = A(1, 1);
res[
"names") = strings({"index_max", "index_min", "element0", "element1",
res.attr("element2", "element3"});
return res;
}
In-range
.in_range(** i **)
is a member function of Mat
, Col
, Row
, Cube
, SpMat
and field
, it returns true
if the given location or span is currently valid and false
if the object is empty, the location is out of bounds, or the span is out of bounds.
Function | Mat | Col | Row | Cube | SpMat | Field |
---|---|---|---|---|---|---|
.in_range(span(start, end)) |
✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
.in_range(row, col) |
✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
.in_range(span(start_row, end_row), span(start_col, end_col)) |
✓ | ✓ | ✓ | ✓ | ✓ | |
.in_range(row, col, slice) |
✓ | ✓ | ||||
.in_range(span(start_row, end_row), span(start_col, end_col), span(start_slice, end_slice)) |
✓ | ✓ | ||||
.in_range(first_row, first_col, size(X)) (X is a matrix or field) |
✓ | ✓ | ✓ | ✓ | ✓ | |
.in_range(first_row, first_col, size(n_rows, n_cols)) |
✓ | ✓ | ✓ | ✓ | ✓ | |
.in_range(first_row, first_col, first_slice, size(Q)) (Q is a cube or field) |
✓ | ✓ | ||||
.in_range(first_row, first_col, first_slice, size(n_rows, n_cols, n_slices)) |
✓ | ✓ |
Instances of span(a,b)
can be replaced by:
-
span()
orspan::all
to indicate the entire range. -
span(a)
to indicate a particular row, column, or slice.
Is empty
.is_empty()
is a member function of the Mat
, Col
, Row
, Cube
, SpMat
, and field
classes. It returns true
if the object has no elements and false
if the object has one or more elements.
Is vector/column vector/row vector
.is_vec()
, .is_colvec()
and .is_rowvec()
are member functions of Mat
and SpMat
.
-
.is_vec()
returnstrue
if the matrix can be interpreted as a vector (either column or row vector) andfalse
otherwise. -
.is_colvec()
returnstrue
if the matrix can be interpreted as a column vector andfalse
otherwise.
-
.is_rowvec()
returnstrue
if the matrix can be interpreted as a row vector andfalse
otherwise.
Examples
cpp11::register]] logicals is_vec1_(const int& n) {
[[1, fill::randu);
mat A(n, 1, n, fill::randu);
mat B(0, 1, fill::randu);
mat C(1, 0, fill::randu);
mat D(
5);
writable::logicals res(0] = A.is_vec();
res[1] = A.is_colvec();
res[2] = B.is_rowvec();
res[3] = C.is_colvec();
res[4] = D.is_rowvec();
res[
"names") = strings({"Nx1_is_vec", "Nx1_is_colvec", "1xN_is_rowvec",
res.attr("0x1_is_colvec", "1x0_is_rowvec"});
return res;
}
Is sorted
.is_sorted()
, .is_sorted(sort_direction)
and .is_sorted(sort_direction, dim)
are member function of Mat
, Row
, and Col
. For matrices and vectors with complex numbers, order is checked via absolute values.
If the object is a vector, these return a bool
indicating whether the elements are sorted. If the object is a matrix, these return a bool
indicating whether the elements are sorted in each column (dim = 0
, default) or each row (dim = 1
), and the dim
argument is optional.
The sort_direction
argument is optional, sort_direction
can be one of the following strings:
-
"ascend"
: the elements are ascending, consecutive elements can be equal, and this is the default operation. -
"descend"
: the elements are descending, and consecutive elements can be equal. -
"strictascend"
: the elements are strictly ascending, and consecutive elements cannot be equal. -
"strictdescend"
: the elements are strictly descending, and consecutive elements cannot be equal.
Examples
cpp11::register]] logicals is_sorted1_(const int& n) {
[[
vec a(n, fill::randu);
vec b = sort(a);10, 10, fill::randu);
mat A(
4);
writable::logicals res(0] = a.is_sorted();
res[1] = b.is_sorted();
res[2] = A.is_sorted("descend", 1);
res[4] = A.is_sorted("ascend", 1);
res[
"names") = strings({"a_sorted", "b_sorted", "A_descend",
res.attr("A_ascend"});
return res;
}
Is upper triangular/lower triangular
.is_trimatu()
and .is_trimatl()
are member functions of Mat
and SpMat
. .is_trimatu()
returns true
if the matrix is upper triangular (e.g., the matrix is square sized and all elements below the main diagonal are zero) and false
otherwise. .is_trimatl()
returns true
if the matrix is lower triangular (e.g., the matrix is square sized and all elements above the main diagonal are zero) and false
otherwise.
Examples
cpp11::register]] logicals is_triangular1_(const int& n) {
[[
mat A(n, n, fill::randu);
mat B = trimatl(A);
3);
writable::logicals res(0] = B.is_trimatu();
res[1] = B.is_trimatl();
res[
B.reset();2] = B.is_trimatu();
res[
"names") = strings({"is_trimatu", "is_trimatl",
res.attr("is_trimatu_after_reset"});
return res;
}
Is diagonal
is_diagmat()
is a member function of Mat
and SpMat
. It returns true
if the matrix is diagonal (e.g., all elements outside of the main diagonal are zero). If the matrix is not square sized, a std::logic_error
exception is thrown.
Examples
cpp11::register]] logicals is_diagonal1_(const int& n) {
[[
mat A(n, n, fill::randu);
mat B = diagmat(A);
3);
writable::logicals res(0] = A.is_diagmat();
res[1] = B.is_diagmat();
res[
A.reset();2] = A.is_diagmat();
res[
"names") = strings({"A_diagmat", "B_diagmat",
res.attr("A_diagmat_after_reset"});
return res;
}
Is square
.is_square()
is a member function of the Mat
and SpMat
classes. It returns true
if the matrix is square sized (e.g., the number of rows is equal to the number of columns) and false
otherwise.
Examples
cpp11::register]] logicals is_square1_(const int& n) {
[[
mat A(n, n, fill::randu);
mat B = diagmat(A);
3);
writable::logicals res(0] = A.is_square();
res[1] = B.is_square();
res[
A.reset();2] = A.is_square();
res[
"names") = strings({"A_square", "B_square",
res.attr("A_square_after_reset"});
return res;
}
Is symmetric
.is_symmetric()
is a member function of the Mat
and SpMat
classes. It returns true
if the matrix is symmetric (e.g., the matrix is square sized and the transpose is equal to the original matrix) and false
otherwise.
Examples
cpp11::register]] logicals is_symmetric1_(const int& n) {
[[
mat A(n, n, fill::randu);
mat B = symmatu(A);
3);
writable::logicals res(0] = A.is_symmetric();
res[1] = B.is_symmetric();
res[
A.reset();2] = A.is_symmetric();
res[
"names") = strings({"A_symmetric", "B_symmetric",
res.attr("A_symmetric_after_reset"});
return res;
}
Is hermitian
.is_hermitian()
is a member function of the Mat
and SpMat
classes. It returns true
if the matrix is Hermitian or self-adjoint (e.g., the matrix is square sized and the conjugate transpose is equal to the original matrix) and false
otherwise.
Examples
cpp11::register]] logicals is_hermitian1_(const int& n) {
[[
cx_mat A(n, n, fill::randu);
cx_mat B = A.t() * A;
3);
writable::logicals res(0] = A.is_hermitian();
res[1] = B.is_hermitian();
res[
A.reset();2] = A.is_hermitian();
res[
"names") = strings({"A_hermitian", "B_hermitian",
res.attr("A_hermitian_after_reset"});
return res;
}
Is symmetric/hermitian positive definite
.is_sympd()
and .is_sympd(tol)
are a member function of the Mat
and SpMat
classes. It returns true
if the matrix is symmetric/hermitian positive definite within a tolerance (e.g., the matrix is square sized and all its eigenvalues are positive) and false
otherwise. The tol
argument is optional, the default is tol = 100 * datum::eps * norm(X, "fro")
.
Examples
cpp11::register]] logicals is_sympd1_(const int& n) {
[[
mat A(n, n, fill::randu);
mat B = A * A.t();
3);
writable::logicals res(0] = A.is_sympd();
res[1] = B.is_sympd();
res[
A.reset();2] = A.is_sympd();
res[
"names") = strings({"A_sympd", "B_sympd",
res.attr("A_sympd_after_reset"});
return res;
}
Is zero
.is_zero()
and .is_zero(tol)
are a member function of the Mat
, Col
, Row
, Cube
, and SpMat
classes. It returns true
if all elements are zero within a tolerance and false
otherwise. For complex numbers, each component (real and imaginary) is checked separately. The tol
argument is optional.
Examples
cpp11::register]] logicals is_zero1_(const int& n) {
[[
mat A(n, n, fill::randu);
cube B(n, n, n, fill::zeros);
sp_mat C(n, n);
3);
writable::logicals res(0] = A.is_zero(0.005);
res[1] = B.is_zero(0.005);
res[2] = C.is_zero(0.005);
res[
"names") = strings({"A_is_zero", "B_is_zero", "C_is_zero"});
res.attr(
return res;
}
Is finite
.is_finite()
is a member function of the Mat
, Col
, Row
, Cube
, and SpMat
classes. It returns true
if all elements are finite and false
otherwise.
Examples
cpp11::register]] logicals is_finite1_(const int& n) {
[[
mat A(n, n, fill::randu);
cube B(n, n, n, fill::randu);
sp_mat C(n, n);
// Insert infinite values
0, 0, 0) = datum::inf;
B(0, 0) = -1.0 * datum::inf;
C(
3);
writable::logicals res(0] = A.is_finite();
res[1] = B.is_finite();
res[2] = C.is_finite();
res[
"names") = strings({"A_is_finite", "B_is_finite", "C_is_finite"});
res.attr(
return res;
}
Has infinity
.has_inf()
is a member function of the Mat
, Col
, Row
, Cube
, and SpMat
classes. It returns true
if the object contains at least one infinite value and false
otherwise.
Examples
cpp11::register]] logicals has_inf1_(const int& n) {
[[
mat A(n, n, fill::randu);
cube B(n, n, n, fill::randu);
sp_mat C(n, n);
// Insert infinite values
0, 0, 0) = datum::inf;
B(0, 0) = -1.0 * datum::inf;
C(
3);
writable::logicals res(0] = A.has_inf();
res[1] = B.has_inf();
res[2] = C.has_inf();
res[
"names") = strings({"A_has_inf", "B_has_inf", "C_has_inf"});
res.attr(
return res;
}
Has not-a-number
.has_nan()
is a member function of the Mat
, Col
, Row
, Cube
, and SpMat
classes. It returns true
if the object contains at least one not-a-number (NaN) value and false
otherwise.
Examples
cpp11::register]] logicals has_nan1_(const int& n) {
[[
mat A(n, n, fill::randu);
cube B(n, n, n, fill::randu);
sp_mat C(n, n);
// Insert NaN values
0, 0, 0) = datum::nan;
B(0, 0) = -1.0 * datum::nan;
C(
3);
writable::logicals res(0] = A.has_nan();
res[1] = B.has_nan();
res[2] = C.has_nan();
res[
"names") = strings({"A_has_nan", "B_has_nan", "C_has_nan"});
res.attr(
return res;
}