A lite library for operations in linear algebra
MATRIX_LIB.h@0:33b75d52d2a7, 2017-02-10 (annotated)
- Committer:
- benson516
- Date:
- Fri Feb 10 18:31:32 2017 +0000
- Revision:
- 0:33b75d52d2a7
Speed up the library by using constant references
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
benson516 | 0:33b75d52d2a7 | 1 | #ifndef MATRIX_LIB_H |
benson516 | 0:33b75d52d2a7 | 2 | #define MATRIX_LIB_H |
benson516 | 0:33b75d52d2a7 | 3 | // |
benson516 | 0:33b75d52d2a7 | 4 | #include <vector> |
benson516 | 0:33b75d52d2a7 | 5 | #include <math.h> |
benson516 | 0:33b75d52d2a7 | 6 | |
benson516 | 0:33b75d52d2a7 | 7 | // For printing matrix out |
benson516 | 0:33b75d52d2a7 | 8 | //////////////////////// |
benson516 | 0:33b75d52d2a7 | 9 | #include <sstream> |
benson516 | 0:33b75d52d2a7 | 10 | #include <string> |
benson516 | 0:33b75d52d2a7 | 11 | //////////////////////// end For printing matrix out |
benson516 | 0:33b75d52d2a7 | 12 | |
benson516 | 0:33b75d52d2a7 | 13 | |
benson516 | 0:33b75d52d2a7 | 14 | #include "MATRIX_PRIMITIVE.h" |
benson516 | 0:33b75d52d2a7 | 15 | |
benson516 | 0:33b75d52d2a7 | 16 | using std::vector; |
benson516 | 0:33b75d52d2a7 | 17 | // using std::string; |
benson516 | 0:33b75d52d2a7 | 18 | |
benson516 | 0:33b75d52d2a7 | 19 | // |
benson516 | 0:33b75d52d2a7 | 20 | namespace MP = MATRIX_PRIMITIVE; |
benson516 | 0:33b75d52d2a7 | 21 | // |
benson516 | 0:33b75d52d2a7 | 22 | |
benson516 | 0:33b75d52d2a7 | 23 | /* |
benson516 | 0:33b75d52d2a7 | 24 | // Debugging |
benson516 | 0:33b75d52d2a7 | 25 | ////////////////// |
benson516 | 0:33b75d52d2a7 | 26 | #include <iostream> |
benson516 | 0:33b75d52d2a7 | 27 | using std::cout; |
benson516 | 0:33b75d52d2a7 | 28 | ////////////////// end Debugging |
benson516 | 0:33b75d52d2a7 | 29 | */ |
benson516 | 0:33b75d52d2a7 | 30 | |
benson516 | 0:33b75d52d2a7 | 31 | class Mat{ |
benson516 | 0:33b75d52d2a7 | 32 | public: |
benson516 | 0:33b75d52d2a7 | 33 | // Matrix data |
benson516 | 0:33b75d52d2a7 | 34 | vector<vector<float> > data; // data is a m by n matrix |
benson516 | 0:33b75d52d2a7 | 35 | |
benson516 | 0:33b75d52d2a7 | 36 | |
benson516 | 0:33b75d52d2a7 | 37 | // Create a nRow_in by nCol_in matrix |
benson516 | 0:33b75d52d2a7 | 38 | Mat(void); // No pre-assignments, empty matrix |
benson516 | 0:33b75d52d2a7 | 39 | Mat(size_t nRow_in, size_t nCol_in); // |
benson516 | 0:33b75d52d2a7 | 40 | Mat(size_t nRow_in, size_t nCol_in, float element_in); // Pre-assign elements |
benson516 | 0:33b75d52d2a7 | 41 | |
benson516 | 0:33b75d52d2a7 | 42 | // Public methods |
benson516 | 0:33b75d52d2a7 | 43 | //----------------------------------// |
benson516 | 0:33b75d52d2a7 | 44 | // Size --- |
benson516 | 0:33b75d52d2a7 | 45 | // "Get" the size of the matrix |
benson516 | 0:33b75d52d2a7 | 46 | size_t nRow(); |
benson516 | 0:33b75d52d2a7 | 47 | size_t nCol(); |
benson516 | 0:33b75d52d2a7 | 48 | size_t nElement(); // Number of elements |
benson516 | 0:33b75d52d2a7 | 49 | // const functions |
benson516 | 0:33b75d52d2a7 | 50 | size_t nRow() const; |
benson516 | 0:33b75d52d2a7 | 51 | size_t nCol() const; |
benson516 | 0:33b75d52d2a7 | 52 | size_t nElement() const; // Number of elements |
benson516 | 0:33b75d52d2a7 | 53 | // "Set" and "get" the new size of the matrix |
benson516 | 0:33b75d52d2a7 | 54 | size_t nRow(size_t nRow_in); |
benson516 | 0:33b75d52d2a7 | 55 | size_t nCol(size_t nCol_in); |
benson516 | 0:33b75d52d2a7 | 56 | // "Set" and "get" the new size of the matrix with assignment to new elements |
benson516 | 0:33b75d52d2a7 | 57 | size_t nRow(size_t nRow_in, float element_in); |
benson516 | 0:33b75d52d2a7 | 58 | size_t nCol(size_t nCol_in, float element_in); |
benson516 | 0:33b75d52d2a7 | 59 | // Resize on both row and column |
benson516 | 0:33b75d52d2a7 | 60 | void resize(size_t nRow_in, size_t nCol_in); |
benson516 | 0:33b75d52d2a7 | 61 | void resize(size_t nRow_in, size_t nCol_in, float element_in); // Assign the new element_in to new elements |
benson516 | 0:33b75d52d2a7 | 62 | // Reshape the matrix, keep all the elements but change the shpae of the matrix (eg. 1 by 6 -> 2 by 3 or 3 by 2) |
benson516 | 0:33b75d52d2a7 | 63 | void reshape(size_t nRow_in, size_t n_Col_in, bool is_Row_first); // If is_Row_first, keep the elements' order the same in the row direction; otherwise, keep the order the same in column direction. |
benson516 | 0:33b75d52d2a7 | 64 | // Synchronize the _nRow and _nCol with the true size of data |
benson516 | 0:33b75d52d2a7 | 65 | void syncSizeInData(); |
benson516 | 0:33b75d52d2a7 | 66 | |
benson516 | 0:33b75d52d2a7 | 67 | // Assignment --- |
benson516 | 0:33b75d52d2a7 | 68 | void assign(std::stringstream &ss_in, size_t nRow_in, size_t nCol_in); // The stringstream ss_in contains a nRow_in by nCol_in matrix. |
benson516 | 0:33b75d52d2a7 | 69 | void assign(float* Matrix_in, size_t nRow_in, size_t nCol_in); // From primitive 1-D array in c++, Matrix_in is a nRow_in by nCol_in matrix. |
benson516 | 0:33b75d52d2a7 | 70 | void assign(const vector<float> &vec_in, bool is_RowVec); // From 1-D vector |
benson516 | 0:33b75d52d2a7 | 71 | void assign(const vector<vector<float> > &MatData_in); // A = MatData_in, assign a primitive matrix directly |
benson516 | 0:33b75d52d2a7 | 72 | // Partial asignment |
benson516 | 0:33b75d52d2a7 | 73 | void setPart(const Mat &M_part, size_t m_from, size_t n_from); // The block starts from (m_from, n_from) |
benson516 | 0:33b75d52d2a7 | 74 | // Spetial assignments |
benson516 | 0:33b75d52d2a7 | 75 | void zeros(size_t nRow_in, size_t nCol_in); // zeros(m,n) |
benson516 | 0:33b75d52d2a7 | 76 | void ones(size_t nRow_in, size_t nCol_in); // ones(m,n) |
benson516 | 0:33b75d52d2a7 | 77 | void eye(size_t nRow_in, size_t nCol_in); // Identity matrix, eye(m,n) |
benson516 | 0:33b75d52d2a7 | 78 | void diag(const Mat &M_diag); // Transform the row/column vector to a diagonal matrix and assign into this matrix |
benson516 | 0:33b75d52d2a7 | 79 | |
benson516 | 0:33b75d52d2a7 | 80 | // Get elements --- |
benson516 | 0:33b75d52d2a7 | 81 | float at(size_t m, size_t n); // Get the element at (m,n) |
benson516 | 0:33b75d52d2a7 | 82 | Mat getPart(size_t m_from, size_t m_to, size_t n_from, size_t n_to); // Get partial, M_part = M(m_from:m_to, n_from:n_to) |
benson516 | 0:33b75d52d2a7 | 83 | Mat getCol(size_t n); // Get a specific column vector in 2-D matrix form |
benson516 | 0:33b75d52d2a7 | 84 | Mat getRow(size_t m); // Get a specific row vector in 2-D matrix form |
benson516 | 0:33b75d52d2a7 | 85 | vector<float> getColVec(size_t n); // Return a c++ vector, M(:,n) |
benson516 | 0:33b75d52d2a7 | 86 | vector<float> getRowVec(size_t m); // Return a c++ vector, M(m,:) |
benson516 | 0:33b75d52d2a7 | 87 | |
benson516 | 0:33b75d52d2a7 | 88 | // Print out matrix --- |
benson516 | 0:33b75d52d2a7 | 89 | std::string print(void); // Print this matrix out as string |
benson516 | 0:33b75d52d2a7 | 90 | |
benson516 | 0:33b75d52d2a7 | 91 | |
benson516 | 0:33b75d52d2a7 | 92 | |
benson516 | 0:33b75d52d2a7 | 93 | // Operations ===== |
benson516 | 0:33b75d52d2a7 | 94 | |
benson516 | 0:33b75d52d2a7 | 95 | // Comparison |
benson516 | 0:33b75d52d2a7 | 96 | bool is_equal(const Mat &M_in); |
benson516 | 0:33b75d52d2a7 | 97 | |
benson516 | 0:33b75d52d2a7 | 98 | // Self-operation (affecting on this matrix) --- |
benson516 | 0:33b75d52d2a7 | 99 | void scaleUp(float scale); // M *= scale |
benson516 | 0:33b75d52d2a7 | 100 | void scaleUp_Mat(const Mat &M_right); // M = M.times(M_right), element-wise multiplication |
benson516 | 0:33b75d52d2a7 | 101 | // |
benson516 | 0:33b75d52d2a7 | 102 | void increase(float scale); // M += scale, for each element in M |
benson516 | 0:33b75d52d2a7 | 103 | void decrease(float scale); // M -= scale, for each element in M |
benson516 | 0:33b75d52d2a7 | 104 | // |
benson516 | 0:33b75d52d2a7 | 105 | void increase(const Mat &M_right); // M += M_right |
benson516 | 0:33b75d52d2a7 | 106 | void decrease(const Mat &M_right); // M -= M_right |
benson516 | 0:33b75d52d2a7 | 107 | |
benson516 | 0:33b75d52d2a7 | 108 | |
benson516 | 0:33b75d52d2a7 | 109 | // Single-operation, output another matrix --- |
benson516 | 0:33b75d52d2a7 | 110 | Mat& T(void); // Transpose, return the transposed version of this matrix |
benson516 | 0:33b75d52d2a7 | 111 | Mat& inverse(void); // Inverse, return the inversion of this matrix |
benson516 | 0:33b75d52d2a7 | 112 | Mat& intPower(int power); // M^power, M^0 -> I, M^-1 -> M_inverse |
benson516 | 0:33b75d52d2a7 | 113 | |
benson516 | 0:33b75d52d2a7 | 114 | // Duo-operation, output another matrix --- |
benson516 | 0:33b75d52d2a7 | 115 | // Plus |
benson516 | 0:33b75d52d2a7 | 116 | Mat& plus(float scale); // (M + scale), for each element in M |
benson516 | 0:33b75d52d2a7 | 117 | Mat& minus(float scale); // (M - scale), for each element in M |
benson516 | 0:33b75d52d2a7 | 118 | Mat& minus(float scale, bool is_reversed); // is_reversed -> (scale - M), for each element in M |
benson516 | 0:33b75d52d2a7 | 119 | Mat& plus(const Mat &M_right); |
benson516 | 0:33b75d52d2a7 | 120 | Mat& minus(const Mat &M_right); |
benson516 | 0:33b75d52d2a7 | 121 | // Concatenation |
benson516 | 0:33b75d52d2a7 | 122 | Mat cat_below(const Mat &M_in); // Below this matrix, [A; B] |
benson516 | 0:33b75d52d2a7 | 123 | Mat cat_right(const Mat &M_in); // Right-side of this matrix, [A, B] |
benson516 | 0:33b75d52d2a7 | 124 | Mat cat(const Mat &M_in, bool is_horizontal); // is_horizontal --> cat_Right(); otherwise --> cat_Below() |
benson516 | 0:33b75d52d2a7 | 125 | |
benson516 | 0:33b75d52d2a7 | 126 | |
benson516 | 0:33b75d52d2a7 | 127 | // Scalar/Element-wise multiplication |
benson516 | 0:33b75d52d2a7 | 128 | Mat& times(float scale); // Scalar multiplication |
benson516 | 0:33b75d52d2a7 | 129 | Mat& times(const Mat &M_right); // Element-wise multiplication |
benson516 | 0:33b75d52d2a7 | 130 | |
benson516 | 0:33b75d52d2a7 | 131 | // Matrix multiplication |
benson516 | 0:33b75d52d2a7 | 132 | // Note: this matrix is the "left" one |
benson516 | 0:33b75d52d2a7 | 133 | Mat& dot(const Mat &M_right); // Similar to the nomenclature of numpy in Python |
benson516 | 0:33b75d52d2a7 | 134 | Mat& dot(bool Transpose_left, const Mat &M_right, bool Transpose_right); // Extended version for conbining the ability of transpose of both mtrices |
benson516 | 0:33b75d52d2a7 | 135 | |
benson516 | 0:33b75d52d2a7 | 136 | // Operator overloading |
benson516 | 0:33b75d52d2a7 | 137 | //----------------------------// |
benson516 | 0:33b75d52d2a7 | 138 | // A <- b, assignment |
benson516 | 0:33b75d52d2a7 | 139 | Mat& operator = (float scale); // Assign a real number as 1 by 1 matrix |
benson516 | 0:33b75d52d2a7 | 140 | Mat& operator = (const vector<float> &colVec_in); // A = vec_in, assign as a column vector |
benson516 | 0:33b75d52d2a7 | 141 | Mat& operator = (const vector<vector<float> > &MatData_in); // A = MatData_in, assign a primitive matrix directly |
benson516 | 0:33b75d52d2a7 | 142 | // b <- A, get value, using implicit type conversion |
benson516 | 0:33b75d52d2a7 | 143 | // Note: no implicit conversion to float, since it would be ambiguous in other operator overriding |
benson516 | 0:33b75d52d2a7 | 144 | explicit operator float (); // Get the first element as float, good for a 1 by 1 matrix |
benson516 | 0:33b75d52d2a7 | 145 | explicit operator std::vector<float> (); // Get the column vector as std::vector<float> in c++ |
benson516 | 0:33b75d52d2a7 | 146 | // A[] |
benson516 | 0:33b75d52d2a7 | 147 | vector<float>& operator [] (size_t m); // Indexing the m-th row, equivalent to data[m] |
benson516 | 0:33b75d52d2a7 | 148 | // A == B |
benson516 | 0:33b75d52d2a7 | 149 | bool operator == (Mat const& B); // is_equal() |
benson516 | 0:33b75d52d2a7 | 150 | // A^z, z \in Z |
benson516 | 0:33b75d52d2a7 | 151 | Mat& operator ^ (int power); // A^power, this->intPower() |
benson516 | 0:33b75d52d2a7 | 152 | |
benson516 | 0:33b75d52d2a7 | 153 | //----------------------------// |
benson516 | 0:33b75d52d2a7 | 154 | // end Operator overloading |
benson516 | 0:33b75d52d2a7 | 155 | private: |
benson516 | 0:33b75d52d2a7 | 156 | |
benson516 | 0:33b75d52d2a7 | 157 | size_t _nRow; // Number of rows |
benson516 | 0:33b75d52d2a7 | 158 | size_t _nCol; // Number of columns |
benson516 | 0:33b75d52d2a7 | 159 | |
benson516 | 0:33b75d52d2a7 | 160 | |
benson516 | 0:33b75d52d2a7 | 161 | // Private methods |
benson516 | 0:33b75d52d2a7 | 162 | // void get_maxBound(size_t &M_max, size_t &N_max, size_t M_new, size_t N_new); // Cauculate the approproate size to contain all the matrices |
benson516 | 0:33b75d52d2a7 | 163 | |
benson516 | 0:33b75d52d2a7 | 164 | }; |
benson516 | 0:33b75d52d2a7 | 165 | |
benson516 | 0:33b75d52d2a7 | 166 | // Operator overloading |
benson516 | 0:33b75d52d2a7 | 167 | //---------------------------------------// |
benson516 | 0:33b75d52d2a7 | 168 | |
benson516 | 0:33b75d52d2a7 | 169 | |
benson516 | 0:33b75d52d2a7 | 170 | // -A |
benson516 | 0:33b75d52d2a7 | 171 | Mat& operator - (const Mat &A); |
benson516 | 0:33b75d52d2a7 | 172 | // A + B |
benson516 | 0:33b75d52d2a7 | 173 | Mat& operator + (float a, const Mat &B); |
benson516 | 0:33b75d52d2a7 | 174 | Mat& operator + (const Mat &A, float b); |
benson516 | 0:33b75d52d2a7 | 175 | Mat& operator + (const Mat &A, const Mat &B); |
benson516 | 0:33b75d52d2a7 | 176 | // A - B |
benson516 | 0:33b75d52d2a7 | 177 | Mat& operator - (float a, const Mat &B); |
benson516 | 0:33b75d52d2a7 | 178 | Mat& operator - (const Mat &A, float b); |
benson516 | 0:33b75d52d2a7 | 179 | Mat& operator - (const Mat &A, const Mat &B); |
benson516 | 0:33b75d52d2a7 | 180 | // A * B |
benson516 | 0:33b75d52d2a7 | 181 | Mat& operator * (float a, const Mat &B); |
benson516 | 0:33b75d52d2a7 | 182 | Mat& operator * (const Mat &A, float b); |
benson516 | 0:33b75d52d2a7 | 183 | Mat& operator * (const Mat &A, const Mat &B); // Matrix multiplication |
benson516 | 0:33b75d52d2a7 | 184 | // A/B, including matrix inversion (eg, (1.0/B) <--> B^-1) |
benson516 | 0:33b75d52d2a7 | 185 | Mat& operator / (float a, const Mat &B); // a*(B^-1), for that B to be inversed |
benson516 | 0:33b75d52d2a7 | 186 | Mat& operator / (const Mat &A, float b); // A*(1/b), scalar multiplication of 1/b |
benson516 | 0:33b75d52d2a7 | 187 | Mat& operator / (const Mat &A, const Mat &B); // A*(B^-1), for that B to be inversed |
benson516 | 0:33b75d52d2a7 | 188 | // A += B |
benson516 | 0:33b75d52d2a7 | 189 | Mat& operator += (Mat &A, float b); |
benson516 | 0:33b75d52d2a7 | 190 | Mat& operator += (Mat &A, const Mat &B); |
benson516 | 0:33b75d52d2a7 | 191 | // A -= B |
benson516 | 0:33b75d52d2a7 | 192 | Mat& operator -= (Mat &A, float b); |
benson516 | 0:33b75d52d2a7 | 193 | Mat& operator -= (Mat &A, const Mat &B); |
benson516 | 0:33b75d52d2a7 | 194 | // A *= B |
benson516 | 0:33b75d52d2a7 | 195 | Mat& operator *= (Mat &A, float b); |
benson516 | 0:33b75d52d2a7 | 196 | Mat& operator *= (Mat &A, const Mat &B); // Matrix multiplication |
benson516 | 0:33b75d52d2a7 | 197 | |
benson516 | 0:33b75d52d2a7 | 198 | //---------------------------------------// |
benson516 | 0:33b75d52d2a7 | 199 | // end Operator overloading |
benson516 | 0:33b75d52d2a7 | 200 | |
benson516 | 0:33b75d52d2a7 | 201 | #endif |