As a follow-through of vector, we go on matrix construction. Starting from the definition, matrix is a rectangular array of numbers, symbols, or expressions, arranged in rows and columns. The individual items in an matrix often denoted by or so-called elements, where is row index and is column index.
Because of there is no container for matrix in C/C++ standard library, let’s make our way construction matrix. In C we could use pointer of array or pointer of pointer as follows :
int m = 4, n = 3, i;
// Using pointer of array
int *B[m];
for (i = 0; i < m; i++) {
A[i] = (int *) calloc(n, sizeof(int));
}
// Using pointer of pointer
int **B = (int **) calloc(m, sizeof(int *));
for (i = 0; i < m; i++) {
B[i] = (int *) calloc(n, sizeof(int));
}
In C++ way :
int m = 4, n = 3;
std::vector<std::vector<int>> C(m, std::vector(n));
Accessing both in C and C++ would be not much differed which is generally using bracket just as in vector. For instance, we want to print the value within,
// Printing in C
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("%d ", A[i][j]);
}
printf("\n");
}
// Printing in C++
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
std::cout << C[i][j] << " ";
}
std::cout << std::endl;
}
For further construction for different data type of matrix in C++, it may more convenient to define a class,
template <typename T>
class Matrix {
protected :
std::vector<std::vector<T>> data;
public :
Matrix(const int m, const int n) {
data.resize(m);
for (auto &i : data) {
i.resize(n);
}
}
};
Using this class we can freely declare matrix for any type of data,
Matrix<double> D(m, n);
Matrix<float> E(m, n);
Matrix<size_t> F(m, n);
Because of utilizing template, it’s no longer necessary to define how matrix for each data type is constructed. As long as the data type is legal, it’s okay.
Likely, Armadillo using the same approach as out Matrix
class. It is called Mat
in Armadillo. For convenience certain type have been defined :
Mat typedef |
---|
mat = Mat<double> |
dmat = Mat<double> |
fmat = Mat<float> |
cx_mat = Mat<cx_double> |
cx_dmat = Mat<cx_double> |
cx_fmat = Mat<cx_float> |
umat = Mat<uword> |
imat = Mat<sword> |
Mat
can be constructed in several ways,
Constructor | Note |
---|---|
Mat<T> () |
void argument constructor |
Mat<T> (n_rows, n_cols) |
using number of rows and columns |
Mat<T> (n_rows, n_cols, fill_type) |
idem, specify initial value with fill_type |
Mat<T> (size(X)) |
adopt other matrix size |
Mat<T> (size(X), fill_type) |
idem, specify initial value with fill_type |
Mat<T> (mat) |
copying matrix mat |
Mat<T> (sp_mat) |
copying sparse matrix sp_mat |
Mat<T> (vec) |
copying vector vec |
Mat<T> (rowvec) |
copying row vector rowvec |
Mat<T> (initializer_list) |
using curly bracket |
Mat<T> (std::vector) |
copying std::vector and treated as vec |
Mat<T> (mat, mat) |
construct complex matrix using two real matrix. |
For extent, fill_type
mentioned above comprise :
Fill type | Note |
---|---|
fill::zeros |
set all elements to 0 |
fill::ones |
set all elements to 1 |
fill::eye |
set the main diagonal to 1 and off-diagonal elements to 0 |
fill::randu |
set each element to a uniform random value |
fill::randn |
set each element to a gaussian random value |
fill::none |
do not modify the elements |
Let’s take a look for example
mat A(4, 3);
mat B(size(A), fill::randu);
mat C(std::vector<double>(6));
mat D = {{0.1, 0.2, 0.3}, {3, 4, 5}, {0, 1, 0}};
The first line declares 4 x 3 dimension matrix and filled by default fill_type of zero. The second line declares matrix based on B and fills with uniform random value. The third line declares a 6x1 matrix based on vector inserted as argument. And the last one declares matrix based on initializer list.
No comments:
Post a Comment