7 #ifndef MACHINE_LEARNING_MATRIX_HPP 8 #define MACHINE_LEARNING_MATRIX_HPP 19 #include "include/nr3/nr3.h" 20 #include "include/nr3/eigen_unsym.h" 21 #include "include/csv_reader/CSVReader.hpp" 29 typename =
typename std::enable_if<std::is_arithmetic<T>::value, T>::type>
41 if (row < 0 or row >= mRows)
42 throw invalid_argument(
43 "Invalid row index (" + to_string(row) +
"): should be between 0 and " + to_string(mRows - 1));
44 if (col < 0 or col >= mCols)
45 throw invalid_argument(
46 "Invalid column index (" + to_string(col) +
"): should be between 0 and " + to_string(mCols - 1));
62 vector<size_t> newOrder;
63 for (
size_t i = 0; i < eigenvalues.
nRows(); i++) {
65 for (
int j = 0; j < newOrder.size(); j++)
66 if (eigenvalues(i, 0) < eigenvalues(newOrder[j], 0))
68 newOrder.insert(newOrder.begin() + position, i);
72 for (
size_t i = 0; i < newOrder.size(); i++) {
73 eigval(i, 0) = eigenvalues(newOrder[i], 0);
75 for (
int j = 0; j < eigenvectors.
nRows(); j++) {
76 eigvec(static_cast<size_t>(j), i) = eigenvectors(j, newOrder[i]);
80 return make_pair(eigval, eigvec);
87 size_t nCols()
const {
return mCols; }
89 size_t nRows()
const {
return mRows; }
101 Matrix(dimension, dimension);
117 Matrix(
size_t rows,
size_t cols,
const vector<T> &data)
120 if (data.size() != rows * cols)
121 throw invalid_argument(
"Matrix dimension incompatible with its initializing vector.");
125 template<std::
size_t N>
126 Matrix(
size_t rows,
size_t cols, T (&data)[N]) {
127 if (N != rows * cols)
128 throw invalid_argument(
"Matrix dimension incompatible with its initializing vector.");
129 vector<T> v(data, data + N);
145 #pragma omp parallel for collapse(2) 146 for (
size_t i = 0; i < m.
mRows; i++) {
147 for (
size_t j = 0; j < m.
mCols; j++) {
148 result(i, j) = value + m(i, j);
186 #pragma omp parallel for collapse(2) 187 for (
size_t i = 0; i < m.
mRows; i++) {
188 for (
size_t j = 0; j < m.
mCols; j++) {
189 result(i, j) = value * m(i, j);
211 #pragma omp parallel for collapse(2) 212 for (
size_t i = 0; i < m.
mRows; i++) {
213 for (
size_t j = 0; j < m.
mCols; j++) {
214 result(i, j) = m(i, j) / value;
229 #pragma omp parallel for collapse(2) 230 for (
size_t i = 0; i < m.
mRows; i++) {
231 for (
size_t j = 0; j < m.
mCols; j++) {
232 result(i, j) = value / m(i, j);
240 #pragma omp parallel for 241 for (
int i = 0; i < mData.size(); i++)
247 #pragma omp parallel for 248 for (
int i = 0; i < mData.size(); i++)
254 #pragma omp parallel for 255 for (
int i = 0; i < mData.size(); i++)
261 #pragma omp parallel for 262 for (
int i = 0; i < mData.size(); i++)
275 throw invalid_argument(
"Cannot add these matrices: L = " + to_string(mRows) +
"x" + to_string(mCols) +
", R = " 276 + to_string(b.
mRows) +
"x" + to_string(b.
mCols));
278 Matrix result(mRows, mCols);
280 #pragma omp parallel for collapse(2) 281 for (
size_t i = 0; i < mRows; i++) {
282 for (
size_t j = 0; j < mCols; j++) {
283 result(i, j) = operator()(i, j) + b(i, j);
295 throw invalid_argument(
296 "Cannot subtract these matrices: L = " + to_string(mRows) +
"x" + to_string(mCols) +
", R = " 297 + to_string(b.
mRows) +
"x" + to_string(b.
mCols));
299 Matrix result(mRows, mCols);
301 #pragma omp parallel for collapse(2) 302 for (
size_t i = 0; i < mRows; i++) {
303 for (
size_t j = 0; j < mCols; j++) {
304 result(i, j) = operator()(i, j) - b(i, j);
315 if (mCols != b.
mRows)
316 throw invalid_argument(
317 "Cannot multiply these matrices: L = " + to_string(this->mRows) +
"x" +
318 to_string(this->mCols) +
", R = " + to_string(b.
mRows) +
"x" + to_string(b.
mCols));
322 #pragma omp parallel for if(result.mRows * result.mCols > 250) 323 for (
size_t i = 0; i < result.
mRows; i++) {
324 for (
size_t k = 0; k < mCols; k++) {
325 double tmp = operator()(i, k);
326 for (
size_t j = 0; j < result.
mCols; j++) {
327 result(i, j) += tmp * b(k, j);
336 if (mRows != other.
mRows || mCols != other.
mCols)
337 throw invalid_argument(
"Cannot add these matrices: L = " + to_string(mRows) +
"x" + to_string(mCols) +
", R = " 338 + to_string(other.
mRows) +
"x" + to_string(other.
mCols));
339 #pragma omp parallel for collapse(2) 340 for (
size_t i = 0; i < other.
mRows; i++) {
341 for (
size_t j = 0; j < other.
mCols; j++) {
342 operator()(i, j) += other(i, j);
350 if (mRows != other.
mRows || mCols != other.
mCols)
351 throw invalid_argument(
352 "Cannot subtract these matrices: L = " + to_string(mRows) +
"x" + to_string(mCols) +
", R = " 353 + to_string(other.
mRows) +
"x" + to_string(other.
mCols));
355 #pragma omp parallel for collapse(2) 356 for (
size_t i = 0; i < other.
mRows; i++) {
357 for (
size_t j = 0; j < other.
mCols; j++) {
358 operator()(i, j) -= other(i, j);
366 if (mCols != other.
mRows)
367 throw invalid_argument(
368 "Cannot multiply these matrices: L " + to_string(mRows) +
"x" +
369 to_string(mCols) +
", R " + to_string(other.
mRows) +
"x" + to_string(other.
mCols));
373 #pragma omp parallel for collapse(2) 375 for (
size_t i = 0; i < result.
mRows; i++) {
376 for (
size_t j = 0; j < result.
mCols; j++) {
379 for (
size_t ii = 0; ii < mCols; ii++)
380 result(i, j) += operator()(i, ii) * other(ii, j);
384 mRows = result.
mRows;
385 mCols = result.
mCols;
386 mData = result.
mData;
396 #pragma omp parallel for collapse(2) 397 for (
size_t i = 0; i < mRows; i++) {
398 for (
size_t j = 0; j < mCols; j++) {
399 result(i, j) = operator()(i, j) == value;
407 if (mData.size() != other.
mData.size() || mRows != other.
mRows || mCols != other.
mCols)
410 for (
int k = 0; k < mData.size(); k++) {
411 if (mData[k] != other.
mData[k])
return false;
420 return -((*
this == value) - 1);
426 return !(*
this == other);
433 Matrix result(this->mRows, this->mCols);
435 #pragma omp parallel for collapse(2) 436 for (
size_t i = 0; i < mCols; i++) {
437 for (
size_t j = 0; j < mRows; j++) {
438 result(i, j) = -operator()(i, j);
452 validateIndexes(i, j);
453 return mData[i * mCols + j];
461 validateIndexes(i, j);
462 return mData[i * mCols + j];
473 Matrix result(rows, cols, vector<T>(rows * cols, value));
482 Matrix result = zeros(size, size);
483 for (
size_t i = 0; i < size; i++)
484 result(i, i) = value;
490 return mCols == mRows;
496 throw runtime_error(
"Can't get the diagonal, not a square matrix");
502 for (
size_t i = 0; i < mRows; i++)
503 result(i, 0) = operator()(i, i);
512 return diagonal(size, 1);
520 return fill(rows, cols, 1);
528 return fill(rows, cols, 0);
536 throw invalid_argument(
537 "Cannot multiply these matrices element-wise: L = " + to_string(mRows) +
"x" +
538 to_string(mCols) +
", R = " + to_string(b.
mRows) +
"x" + to_string(b.
mCols));
540 Matrix result(mRows, mCols);
542 #pragma omp parallel for collapse(2) 543 for (
size_t i = 0; i < mRows; i++) {
544 for (
size_t j = 0; j < mCols; j++) {
545 result(i, j) = operator()(i, j) * b(i, j);
557 Matrix result(mRows - 1, mCols - 1);
561 #pragma omp parallel for 562 for (
size_t i = 0; i < mRows; i++) {
564 if (i == row)
continue;
565 for (
size_t j = 0; j < mCols; j++) {
566 if (j == column)
continue;
567 result(subi, subj) = operator()(i, j);
584 if (mRows == 2 and mCols == 2) {
586 result(0, 0) = operator()(1, 1);
587 result(0, 1) = operator()(1, 0);
588 result(1, 0) = operator()(0, 1);
589 result(1, 1) = operator()(0, 0);
593 return submatrix(row, column).determinant();
604 if (mRows == 2 and mCols == 2) {
605 if (row == 0 and column == 0)
606 minor = operator()(1, 1);
607 else if (row == 1 and column == 1)
608 minor = operator()(0, 0);
609 else if (row == 0 and column == 1)
610 minor = operator()(1, 0);
611 else if (row == 1 and column == 0)
612 minor = operator()(0, 1);
614 minor = this->getMinor(row, column);
615 return (row + column) % 2 == 0 ? minor : -minor;
621 Matrix result(mRows, mCols);
623 #pragma omp parallel for collapse(2) 624 for (
size_t i = 0; i < mRows; i++) {
625 for (
size_t j = 0; j < mCols; j++) {
626 result(i, j) = cofactor(i, j);
643 throw runtime_error(
"Cannot invert a non-square matrix");
645 double det = determinant();
648 throw runtime_error(
"Matrix is singular");
651 return adjugate() / det;
658 throw runtime_error(
"Cannot calculate the determinant of a non-square matrix");
664 return ((
operator()(0, 0) *
operator()(1, 1)) -
665 (
operator()(1, 0) *
operator()(0, 1)));
667 #pragma omp parallel for reduction (+:d) 668 for (
size_t c = 0; c < n; c++) {
669 d += pow(-1, c) * operator()(0, c) * submatrix(0, c).determinant();
678 Matrix result(mCols, mRows);
680 #pragma omp parallel for collapse(2) 681 for (
size_t i = 0; i < mRows; i++) {
682 for (
size_t j = 0; j < mCols; j++) {
683 result(j, i) = operator()(i, j);
693 addColumn(values, mCols);
699 addRow(values, mRows);
707 if (!isEmpty() and values.
nRows() != mRows)
708 throw invalid_argument(
"Wrong number of values passed for new column");
709 if (values.
nCols() != 1)
710 throw invalid_argument(
"Can't add multiple columns at once");
713 mRows = values.
mRows;
714 mCols = values.
mCols;
715 mData = values.
mData;
719 vector<T> newData(mData.size() + values.
mRows);
721 size_t newData_mCols = mCols + 1;
722 for (
size_t i = 0; i < mRows; i++) {
723 for (
size_t j = 0; j < newData_mCols; j++) {
725 newData[i * newData_mCols + j] = values(i, 0);
727 int a = j > position;
728 newData[i * newData_mCols + j] = operator()(i, j - (j > position));
741 if (!isEmpty() and values.
mRows != mCols)
742 throw invalid_argument(
"Wrong number of values passed for new row");
743 if (values.
mCols != 1)
744 throw invalid_argument(
"Can't add multiple rows at once");
747 mRows = values.
mCols;
748 mCols = values.
mRows;
749 mData = values.
mData;
755 vector<T> newData(mData.size() + values.
mRows);
758 for (
size_t i = 0; i < mRows; i++) {
759 for (
size_t j = 0; j < mCols; j++) {
761 newData[i * mCols + j] = values(j, 0);
763 newData[i * mCols + j] = operator()(i - (i > position), j);
774 for (
size_t i = mRows - 1; i != (size_t) -1; i--)
775 mData.erase(mData.begin() + (i * mCols + position));
785 unsigned long size = mData.size();
787 for (
unsigned i = 0; i < size; ++i)
792 auxVec.assign(s.begin(), s.end());
795 return Matrix(auxVec.size(), 1, auxVec);
801 std::sort(mData.begin(), mData.end());
810 vector<T> data = m.
mData;
811 std::sort(data.begin(), data.end());
824 for (
size_t i = 0; i < mRows; i++)
825 for (
size_t j = 0; j < mCols; j++)
826 for (
size_t g = 0; g < result.
mRows; g++)
827 if (
operator()(i, j) == result(g, 0)) {
841 if (mRows != groups.
mRows)
842 throw invalid_argument(
"Not enough groups for every element in the matrix");
847 for (
size_t i = 0; i < mRows; i++) {
848 for (
size_t g = 0; g < groupCount.
mRows; g++) {
849 if (groups(i, 0) == groupCount(g, 0)) {
850 for (
size_t j = 0; j < mCols; j++) {
851 result(g, j) += operator()(i, j);
858 for (
size_t i = 0; i < result.
mRows; i++)
859 for (
size_t j = 0; j < result.
mCols; j++)
860 result(i, j) /= groupCount(i, 1);
868 Matrix result = zeros(mCols, 1);
870 for (
size_t i = 0; i < mRows; i++) {
871 for (
size_t j = 0; j < mCols; j++) {
872 result(j, 0) += operator()(i, j);
885 Matrix result(mCols, mCols);
887 for (
size_t i = 0; i < mRows; i++) {
888 Matrix rowDiff = getRow(i) - means;
898 return scatter() / (mRows - 1);
905 Matrix result = zeros(mCols, 1);
907 for (
size_t i = 0; i < mCols; i++) {
908 for (
size_t ii = 0; ii < mRows; ii++)
909 result(i, 0) += pow((
operator()(ii, i) - means(i, 0)), 2);
911 result(i, 0) /= (mRows - 1);
922 #pragma omp parallel for 923 for (
size_t i = 0; i < mCols; i++)
924 result(i, 0) = sqrt(result(i, 0));
933 if (mData.size() != rows * cols)
934 throw invalid_argument(
935 "Invalid shape (" + to_string(rows) +
"x" +
936 to_string(cols) +
" = " + to_string(rows * cols) +
937 ") for a matrix with" + to_string(mData.size()) +
" elements");
948 throw invalid_argument(
"Column index out of bounds");
951 #pragma omp parallel for 952 for (
size_t i = 0; i < mRows; i++)
953 result(i, 0) = operator()(i, index);
963 throw invalid_argument(
"Row index out of bounds");
966 #pragma omp parallel for 967 for (
size_t i = 0; i < mCols; i++)
968 result(i, 0) = operator()(index, i);
978 const int numWidth = 13;
981 for (
int i = 0; i < matrix.
mRows; i++) {
982 for (
int j = 0; j < matrix.
mCols; j++) {
985 os << left << setw(numWidth) << setfill(fill) << to_string(matrix(i, j));
997 vector<vector<double>> outer = CSVReader::csvToNumericVecVec(path,
true);
999 Matrix result(outer.size(), outer[0].size());
1001 for (
size_t i = 0; i < result.mRows; i++)
1002 for (
size_t j = 0; j < result.mCols; j++)
1003 result(i, j) = outer[i][j];
1011 if (mRows != 1 and mCols != 1)
1012 throw runtime_error(
"Can't diagonalize, not a vector");
1014 size_t dimension = mCols > 1 ? mCols : mRows;
1016 Matrix result = zeros(dimension, dimension);
1018 #pragma omp parallel for 1019 for (
size_t i = 0; i < dimension; i++) {
1020 result(i, i) = mCols > 1 ? operator()(0, i) : operator()(i, 0);
1028 Matrix result(mRows, mCols);
1029 result.
mData = mData;
1037 return standardize(mean(), stdev());
1047 throw invalid_argument(
"Argument \"mean\" must have exactly one column");
1049 throw invalid_argument(
"Argument \"stds\" must have exactly one column");
1050 if (means.
mRows != mCols)
1051 throw invalid_argument(
"Number of mean values is different than number of features");
1052 if (stds.
mRows != mCols)
1053 throw invalid_argument(
"Number of std. dev. values is different than number of features");
1055 Matrix result(mRows, mCols);
1057 #pragma omp parallel for collapse(2) 1058 for (
size_t i = 0; i < mRows; i++) {
1059 for (
size_t j = 0; j < mCols; j++) {
1060 result(i, j) = (operator()(i, j) - means(j, 0)) / stds(j, 0);
1068 Matrix result(mRows, mCols), means = mean();
1070 #pragma omp parallel for collapse(2) 1071 for (
size_t i = 0; i < mRows; i++) {
1072 for (
size_t j = 0; j < mCols; j++) {
1073 result(i, j) = operator()(i, j) - means(j, 0);
1084 return std::find(mData.begin(), mData.end(), value) != mData.end();
1090 return mCols == 0 and mRows == 0;
1099 size_t dimension = columns ? mCols : mRows;
1101 if (bin.
nCols() != 1)
1102 throw invalid_argument(
"Binary filter must have only one column");
1103 if (bin.
nRows() != dimension)
1104 throw invalid_argument(
"Binary filter has the wrong number of row entries");
1108 for (
size_t i = 0; i < bin.
nRows(); i++) {
1113 result.
addRow(getRow(i));
1131 return filter(bin,
true);
1137 return *
this == transpose();
1144 Matrix result(mRows, mCols, mData);
1147 for (
size_t j = 0; j < mCols; j++) {
1149 #pragma omp parallel for reduction(+:length) 1150 for (
size_t i = 0; i < mRows; i++) {
1151 length += pow(result(i, j), 2);
1153 length = sqrt(length);
1156 for (
size_t i = 0; i < mRows; i++) {
1157 result(i, j) /= length;
1169 return isSymmetric() ? eigenSymmetric() : eigenNonSymmetric();
1185 double eps = numeric_limits<double>::epsilon();
1186 unsigned iterations = 0;
1193 for (
size_t i = 0; i < A.
mRows; i++) {
1194 for (
size_t j = 0; j < A.
mCols; j++) {
1196 if (i != j and abs(A(i, j)) > largest) {
1197 largest = abs(A(i, j));
1207 if (largest < 2 * eps or iterations >= 1000) {
1215 double phi = (A(q, q) - A(p, p)) / (2 * A(p, q));
1216 double sign = (phi > 0) - (phi < 0);
1217 double t = phi == 0 ? 1 : 1 / (phi + sign * sqrt(pow(phi, 2) + 1));
1218 double cos = 1 / (sqrt(1 + pow(t, 2)));
1219 double sin = t / (sqrt(1 + pow(t, 2)));
1225 U(p, p) = U(q, q) = cos;
1244 MatDoub unholyConvertion(static_cast<int>(mRows), static_cast<int>(mCols));
1246 #pragma omp parallel for collapse(2) 1247 for (
size_t i = 0; i < mRows; i++) {
1248 for (
size_t j = 0; j < mCols; j++) {
1249 unholyConvertion[i][j] = operator()(i, j);
1253 Unsymmeig nr3Miracle(unholyConvertion,
true, hes);
1255 Matrix eigenvalues(1, static_cast<size_t>(nr3Miracle.wri.size()));
1257 for (
size_t i = 0; i < nr3Miracle.wri.size(); i++) {
1258 eigenvalues(0, i) = nr3Miracle.wri[i].real();
1261 Matrix eigenvectors(static_cast<size_t>(nr3Miracle.zz.nrows()),
1262 static_cast<size_t>(nr3Miracle.zz.ncols()));
1264 for (
size_t i = 0; i < nr3Miracle.zz.nrows(); i++)
1265 for (
size_t j = 0; j < nr3Miracle.zz.ncols(); j++)
1266 eigenvectors(i, j) = nr3Miracle.zz[i][j];
1268 return make_pair(eigenvalues, eigenvectors);
1272 Matrix Sw = zeros(mCols, mCols);
1275 for (
size_t i = 0; i < uniqueClasses.
nRows(); i++) {
1276 Matrix classElements = getRows(y == i);
1279 Sw += scatterMatrix;
1286 Matrix innerMean = mean(y);
1287 Matrix grandMean = mean();
1288 Matrix Sb = zeros(mCols, mCols);
1291 for (
size_t i = 0; i < uniqueClasses.
nRows(); i++) {
1292 Matrix classElements = getRows(y == i);
1305 return sum_of_elems;
1317 return *std::min_element(std::begin(mData), std::end(mData));
1321 return *std::max_element(std::begin(mData), std::end(mData));
1325 Matrix<T> result(mRows, mCols, vector<T>(mRows * mCols, 0));
1326 std::transform(mData.begin(), mData.end(), result.
mData.begin(), f);
1331 Matrix uniqueValues = unique();
1332 Matrix oneHotUnique = identity(uniqueValues.
mRows);
1335 for (
size_t i = 0; i < mRows; i++) {
1336 for (
size_t ii = 0; ii < uniqueValues.
mRows; ++ii) {
1337 if (getRow(i) == uniqueValues.
getRow(ii)) {
1348 throw invalid_argument(
"Invalid row index, matrix is not that large");
1349 if (mCols != row.
mCols)
1350 throw invalid_argument(
"Incompatible number of columns");
1352 throw invalid_argument(
"Row matrix contains more than one row");
1354 for (
size_t col = 0; col < mCols; col++)
1355 operator()(index, col) = row(0, col);
1360 throw invalid_argument(
"Invalid row column, matrix is not that large");
1361 if (mRows != column.
mRows)
1362 throw invalid_argument(
"Incompatible number of rows");
1363 if (column.
mCols > 1)
1364 throw invalid_argument(
"Column matrix contains more than one column");
1366 for (
size_t row = 0; row < mCols; row++)
1367 operator()(row, index) = column(row, 0);
1379 #endif //MACHINE_LEARNING_MATRIX_HPP
Matrix hadamard(const Matrix &b)
Executes the Hadamard, or entrywise multiplication between two matrices.
static Matrix diagonal(size_t size, double value)
Creates a square matrix with a fixed value on the diagonal.
bool isEmpty()
Checks if the matrix is empty or uninitialized.
Matrix getRows(const Matrix< int > bin)
Selects a subset of rows of the matrix.
Matrix inverse() const
Calculates the inverse of the current matrix.
Matrix(size_t rows, size_t cols, const vector< T > &data)
Initializes a matrix with a predetermined number of rows and columns and populates it with data...
Matrix normalize()
Normalizes the column vectors of the matrix.
void validateIndexes(size_t row, size_t col) const
Validates if indices are contained inside the matrix.
pair< Matrix, Matrix > eigenSymmetric()
Calculates the eigenvalues and eigenvectors of a symmetric matrix using the Jacobi eigenvalue algorit...
Matrix var()
Calculates the variance of the columns of the matrix.
static Matrix fromCSV(const string &path)
Loads CSV data into a matrix.
void addRow(Matrix values, size_t position)
Adds a row to the matrix at the given position.
void addColumn(Matrix values, size_t position)
Adds a column to the matrix at the given position.
T & operator()(size_t i, size_t j)
Functor used to access elements in the matrix.
bool operator!=(const Matrix &other)
Matrix operator*=(double value)
Matrix operator-=(double value)
bool contains(T value)
Checks if the matrix contains a value.
pair< Matrix, Matrix > eigenNonSymmetric(bool hes=true)
Calculates the eigenvalues and eigenvectors of a on-symmetric matrix.
Matrix implementation, with a series of linear algebra functions.
void setColumn(size_t index, Matrix< T > column)
Matrix mean(Matrix groups)
Calculates means of a matrix, grouped by classes.
static Matrix sort(Matrix m)
Sorts the elements of a matrix.
void setRow(size_t index, Matrix< T > row)
static Matrix identity(size_t size)
Returns the identity matrix.
Matrix stdev()
Calculates the standard deviation of the columns of the matrix.
friend Matrix operator-(double value, const Matrix &m)
Scalar subtraction.
Matrix copy()
Returns a copy of the matrix.
Matrix unique() const
Returns only unique values from the matrix.
friend Matrix operator*(double value, const Matrix &m)
Scalar multiplication.
Matrix cofactorMatrix() const
Calculates the cofactor matrix.
Matrix & operator*=(const Matrix &other)
friend Matrix operator-(const Matrix &m, double value)
Scalar subtraction.
Matrix WithinClassScatter(Matrix y)
void removeColumn(int position)
Removes a column from the matrix.
Matrix operator/=(double value)
Matrix operator+(const Matrix &b)
Matrix addition operation.
void addColumn(Matrix values)
Adds a column at the end of the matrix.
Matrix operator+=(double value)
Matrix operator!=(const double &value)
Matrix getColumn(size_t index)
Gets a column from the matrix.
static Matrix ones(size_t rows, size_t cols)
Returns a matrix filled with ones.
friend Matrix operator+(const Matrix &m, double value)
Scalar addition.
Matrix operator-()
Matrix negative operation.
bool isSymmetric()
Checks if the matrix is symmetric.
Matrix count()
Counts occurrences of elements in a matrix.
Matrix standardize(Matrix means, Matrix stds)
Standardizes the columns of the matrix, subtracting each element of a column by the mean argument and...
Matrix BetweenClassScatter(Matrix y)
Matrix implementation, with a series of linear algebra functions.
Matrix & operator-=(const Matrix &other)
Matrix< T > apply(function< T(T)> f)
friend Matrix operator/(const Matrix &m, double value)
Scalar division.
Matrix cov()
Calculates the covariance matrix of the current matrix.
Matrix asDiagonal()
Creates a diagonal matrix from a row or column vector.
Matrix mean()
Calculates the mean of the columns of the matrix.
Matrix standardize()
Standardizes the columns of the matrix, subtracting each element of a column by the column mean and d...
double determinant() const
Calculates the determinant of the matrix.
void sort()
Sorts elements of the matrix inplace.
Matrix(size_t rows, size_t cols, T(&data)[N])
Matrix(size_t dimension)
Initializes a square matrix.
Matrix(size_t rows, size_t cols)
Initializes a matrix with a predetermined number of rows and columns.
Matrix adjugate() const
Returns the adjugate of the current matrix, which is the transpose of its cofactor matrix...
friend Matrix operator/(double value, const Matrix &m)
Scalar division.
bool operator==(const Matrix &other)
void reshape(size_t rows, size_t cols)
Reshapes the current matrix.
Matrix operator*(const Matrix &b) const
Matrix multiplication operation.
static Matrix fill(size_t rows, size_t cols, double value)
Returns a matrix filled with a single value.
Matrix filter(const Matrix< int > bin, bool columns=false)
Selects a subset of either columns or rows of the matrix.
pair< Matrix, Matrix > eigen()
Calculates the eigenvalues and eigenvectors of a matrix.
Matrix submatrix(size_t row, size_t column) const
Returns a submatrix of the current matrix, removing one row and column of the original matrix...
Matrix< int > operator==(const T &value)
friend ostream & operator<<(ostream &os, const Matrix &matrix)
Prints a matrix.
Matrix getRow(size_t index)
Gets a row from the matrix.
double getMinor(size_t row, size_t column) const
Returns the minor of a matrix, which is the determinant of a submatrix where a single row and column ...
Matrix & operator+=(const Matrix &other)
Matrix()
Initializes an empty matrix.
static pair< Matrix, Matrix > eigsort(Matrix eigenvalues, Matrix eigenvectors)
Sorts eigenvalues by magnitude, sorting their corresponding eigenvectors in te same order...
Matrix getColumns(const Matrix< int > bin)
Selects a subset of columns of the matrix.
void addRow(Matrix values)
Adds a row at the end of the matrix.
double cofactor(size_t row, size_t column) const
Calculates the cofactor of a matrix at a given point.
Matrix operator-(const Matrix &b)
Matrix subtraction operation.
static Matrix zeros(size_t rows, size_t cols)
Returns a matrix filled with zeros.
friend Matrix operator+(double value, const Matrix &m)
Scalar addition.
Matrix transpose() const
Returns the transpose of a matrix.
friend Matrix operator*(const Matrix &m, double value)
Scalar multiplication.
T operator()(size_t i, size_t j) const
Functor used to access elements in the matrix.
Matrix scatter()
Calculates the scatter matrix.