Commit b843b601 by Lucas Serrano

Matrix inversion

parent bfd54bf3
 ... ... @@ -6,7 +6,8 @@ #include #include #include #include #include #include namespace bs = boost::simd; ... ... @@ -19,6 +20,9 @@ constexpr int nearest_power_of_two(int min_value, int current_value) { template class BaseMatrix; template class IdentityMatrix; template class Matrix: public BaseMatrix { }; ... ... @@ -100,7 +104,7 @@ static inline void matrix_mul_m_m(M &a, M &b, M &c) { } template static inline void matrix_mul_tm_m(M &a, M &b, M &c) { static inline void matrix_mul_mt_m(M &a, M &b, M &c) { /* * Computes the following matrix product C = t(A)*B * where A, B and C are BaseMatrix objects. ... ... @@ -174,27 +178,58 @@ static constexpr int blend_for_size(int i, int c) { } template void protect_for_division(pack_t &vector) { pack_t& protect_for_division(pack_t &vector) { vector = bs::shuffle>>(vector, bs::One()); return vector; } template void matrix_inv(M &matrix, M &inverse) { void matrix_inv(M &A, M &X) { using pack_t = bs::pack; static BaseMatrix Id(1); M R, P, AP, AlphaP, AlphaAP; pack_t alpha, rs_old, rs_new, tmp; X = Id; matrix_sub(Id, A, R); P = R; rs_old = column_dot_product(R, R); for (int i=0; i(tmp); column_scalar_product(alpha, P, AlphaP); matrix_add(X, AlphaP, X); column_scalar_product(alpha, AP, AlphaAP); matrix_sub(R, AlphaAP, R); rs_new = column_dot_product(R, R); tmp = rs_new / protect_for_division(rs_old); column_scalar_product(tmp, P, P); matrix_add(R, P, P); rs_old = rs_new; } /* matrix_mul_m_m(A, P, AP); tmp = column_dot_product(P, AP); alpha = rs_old / protect_for_division(tmp); column_scalar_product(alpha, P, AlphaP); matrix_add(X, AlphaP, X); */ } template template class BaseMatrix { /* Class for matrix object * Matrix object are linearized 2D array with padded line to fit vector size */ static_assert(MatrixSize <= MaxVecSize, "Matrix size must be less than maximum vector size"); static_assert((MaxVecSize >= 4) & !(MaxVecSize & (MaxVecSize - 1)), "Maximum vector size must be a power of two."); static_assert(MatrixSize <= MaximumVectorSize, "Matrix size must be less than maximum vector size"); static_assert((MaximumVectorSize >= 4) & !(MaximumVectorSize & (MaximumVectorSize - 1)), "Maximum vector size must be a power of two."); protected: static constexpr int MatSize = MatrixSize; static constexpr int MaxVecSize = MaximumVectorSize; // We use the smallest vector size possible static constexpr int VecSize = nearest_power_of_two(MatrixSize, MaxVecSize); static constexpr int VecSize = nearest_power_of_two(MatrixSize, MaximumVectorSize); using matrix_t = BaseMatrix; using pack_t = bs::pack; ... ... @@ -202,7 +237,7 @@ class BaseMatrix { public: BaseMatrix() = default; BaseMatrix(float const a[]) { BaseMatrix(T const a[]) { if (MatSize == VecSize) { // In this case there is no padding, we can copy directly the array std::memcpy(this->array, a, sizeof(T)*MatSize*VecSize); } ... ... @@ -213,7 +248,13 @@ class BaseMatrix { } } matrix_t operator=(float const a[]) { BaseMatrix(T const a) { for (int i=0; iarray, a, sizeof(T)*MatSize*VecSize); } ... ... @@ -243,20 +284,22 @@ class BaseMatrix { } private: friend void matrix_add(matrix_t &a, matrix_t &b, matrix_t &c); friend void matrix_sub(matrix_t &a, matrix_t &b, matrix_t &c); friend void matrix_mul_m_m(matrix_t &a, matrix_t &b, matrix_t &c); friend void matrix_mul_tm_m(matrix_t &a, matrix_t &b, matrix_t &c); friend void matrix_mul_mt_m(matrix_t &a, matrix_t &b, matrix_t &c); friend void matrix_mul_m_mt(matrix_t &a, matrix_t &b, matrix_t &c); friend bs::pack column_dot_product(matrix_t &a, matrix_t &b); friend void column_scalar_product(pack_t &scalar, matrix_t &b, matrix_t &c); template friend void matrix_inv(M &a, M &b); friend std::ostream & operator<<(std::ostream &os, matrix_t &mat); protected: alignas(sizeof(T)*VecSize) float array[MatSize*VecSize] = {0}; }; /* template class IdentityMatrix: public BaseMatrix { using BaseMatrix::VecSize; ... ... @@ -267,4 +310,4 @@ class IdentityMatrix: public BaseMatrix { this->array[VecSize*i+i] = 1; } } }; };*/
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!