/** This file is a part of the rexy/r0nk/atlas project Copyright (C) 2020 rexy712 This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef REXY_DETAIL_MATRIX_HPP #define REXY_DETAIL_MATRIX_HPP #include //size_t #include //integer_sequence namespace math::detail{ template struct gen_id_tup { using tup = typename gen_id_tup::tup; }; template struct gen_id_tup { using tup = typename gen_id_tup::tup; }; template struct gen_id_tup { using tup = typename gen_id_tup::tup; }; template struct gen_id_tup { using tup = std::integer_sequence; }; template struct gen_zero_tup { using tup = typename gen_zero_tup::tup; }; template struct gen_zero_tup<0,Args...> { using tup = std::integer_sequence; }; template struct id_initialization_matrix { using tuple = typename gen_id_tup::tup; }; template struct default_initialization_matrix { using tuple = typename gen_zero_tup::tup; }; template struct default_initialization_matrix { using tuple = typename id_initialization_matrix::tuple; }; template class mat_ref_obj { public: using size_type = size_t; protected: T* m_data = nullptr; public: constexpr mat_ref_obj(T* d, size_type i); constexpr T& operator[](size_type i); constexpr const T& operator[](size_type i)const; }; template struct determinate_helper { static constexpr T perform(const matrix& m){ T sum = 0; T op = 1; for(size_t i = 0;i < R;++i){ T item = op * m[0][i]; matrix mul(no_initialize); for(size_t j = 1, mj = 0;j < R;++j){ for(size_t k = 0, mk = 0;k < R;++k){ if(k == i) continue; mul[mj][mk] = m[j][k]; ++mk; } ++mj; } sum += item * determinate_helper::perform(mul); op = -op; } return sum; } }; template struct determinate_helper { static constexpr T perform(const matrix& m){ return (m.get(0) * ((m.get(4) * m.get(8)) - (m.get(5) * m.get(7))) - m.get(1) * ((m.get(3) * m.get(8)) - (m.get(5) * m.get(6))) + m.get(2) * ((m.get(3) * m.get(7)) - (m.get(4) * m.get(6)))); } }; template struct determinate_helper { static constexpr T perform(const matrix& m){ return m.get(0) * m.get(3) - m.get(1) * m.get(2); } }; template struct inverse_helper { //TODO generalized inverse }; template struct inverse_helper { static constexpr matrix perform(const matrix& m){ T det = m.determinate(); if(!det) return matrix(zero_initialize); return matrix(m.get(3) / det, -(m.get(1)) / det, -(m.get(2)) / det, m.get(0) / det); } }; template struct inverse_helper { static constexpr matrix perform(const matrix& m){ T det = m.determinate(); if(!det) return matrix(zero_initialize); return matrix(((m.get(4) * m.get(8)) - (m.get(5) * m.get(7))) / det, -((m.get(1) * m.get(8)) - (m.get(2) * m.get(7))) / det, ((m.get(1) * m.get(5)) - (m.get(2) * m.get(4))) / det, -((m.get(3) * m.get(8)) - (m.get(5) * m.get(6))) / det, ((m.get(0) * m.get(8)) - (m.get(2) * m.get(6))) / det, -((m.get(0) * m.get(5)) - (m.get(2) * m.get(3))) / det, ((m.get(3) * m.get(7)) - (m.get(4) * m.get(6))) / det, -((m.get(0) * m.get(7)) - (m.get(1) * m.get(6))) / det, ((m.get(0) * m.get(4)) - (m.get(1) * m.get(3))) / det); } }; template struct inverse_helper { static constexpr matrix perform(const matrix& m){ T det = m.determinate(); if(!det) return matrix(zero_initialize); //Math is power return matrix((m.get(5) * ((m.get(10) * m.get(15)) - (m.get(11) * m.get(14))) - m.get(6) * ((m.get(9) * m.get(15)) - (m.get(11) * m.get(13))) + m.get(7) * ((m.get(9) * m.get(14)) - (m.get(10) * m.get(13)))) / det, -(m.get(1) * ((m.get(10) * m.get(15)) - (m.get(11) * m.get(14))) - m.get(2) * ((m.get(9) * m.get(15)) - (m.get(11) * m.get(13))) + m.get(3) * ((m.get(9) * m.get(14)) - (m.get(10) * m.get(13)))) / det, (m.get(1) * ((m.get(6) * m.get(15)) - (m.get(7) * m.get(14))) - m.get(2) * ((m.get(5) * m.get(15)) - (m.get(7) * m.get(13))) + m.get(3) * ((m.get(5) * m.get(14)) - (m.get(6) * m.get(13)))) / det, -(m.get(1) * ((m.get(6) * m.get(11)) - (m.get(7) * m.get(10))) - m.get(2) * ((m.get(5) * m.get(11)) - (m.get(7) * m.get(9))) + m.get(3) * ((m.get(5) * m.get(10)) - (m.get(6) * m.get(9)))) / det, -(m.get(4) * ((m.get(10) * m.get(15)) - (m.get(11) * m.get(14))) - m.get(6) * ((m.get(8) * m.get(15)) - (m.get(11) * m.get(12))) + m.get(7) * ((m.get(8) * m.get(14)) - (m.get(10) * m.get(12)))) / det, (m.get(0) * ((m.get(10) * m.get(15)) - (m.get(11) * m.get(14))) - m.get(2) * ((m.get(8) * m.get(15)) - (m.get(11) * m.get(12))) + m.get(3) * ((m.get(8) * m.get(14)) - (m.get(10) * m.get(12)))) / det, -(m.get(0) * ((m.get(6) * m.get(15)) - (m.get(7) * m.get(14))) - m.get(2) * ((m.get(4) * m.get(15)) - (m.get(7) * m.get(12))) + m.get(3) * ((m.get(4) * m.get(14)) - (m.get(6) * m.get(12)))) / det, (m.get(0) * ((m.get(6) * m.get(11)) - (m.get(7) * m.get(10))) - m.get(2) * ((m.get(4) * m.get(11)) - (m.get(7) * m.get(8))) + m.get(3) * ((m.get(4) * m.get(10)) - (m.get(6) * m.get(8)))) / det, (m.get(4) * ((m.get(9) * m.get(15)) - (m.get(11) * m.get(13))) - m.get(5) * ((m.get(8) * m.get(15)) - (m.get(11) * m.get(12))) + m.get(7) * ((m.get(8) * m.get(13)) - (m.get(9) * m.get(12)))) / det, -(m.get(0) * ((m.get(9) * m.get(15)) - (m.get(11) * m.get(13))) - m.get(1) * ((m.get(8) * m.get(15)) - (m.get(11) * m.get(12))) + m.get(3) * ((m.get(8) * m.get(13)) - (m.get(9) * m.get(12)))) / det, (m.get(0) * ((m.get(5) * m.get(15)) - (m.get(7) * m.get(13))) - m.get(1) * ((m.get(4) * m.get(15)) - (m.get(7) * m.get(12))) + m.get(3) * ((m.get(4) * m.get(13)) - (m.get(5) * m.get(12)))) / det, -(m.get(0) * ((m.get(5) * m.get(11)) - (m.get(7) * m.get(9))) - m.get(1) * ((m.get(4) * m.get(11)) - (m.get(7) * m.get(8))) + m.get(3) * ((m.get(4) * m.get(9)) - (m.get(5) * m.get(8)))) / det, -(m.get(4) * ((m.get(9) * m.get(14)) - (m.get(10) * m.get(13))) - m.get(5) * ((m.get(8) * m.get(14)) - (m.get(10) * m.get(12))) + m.get(6) * ((m.get(8) * m.get(13)) - (m.get(9) * m.get(12)))) / det, (m.get(0) * ((m.get(9) * m.get(14)) - (m.get(10) * m.get(13))) - m.get(1) * ((m.get(8) * m.get(14)) - (m.get(10) * m.get(12))) + m.get(2) * ((m.get(8) * m.get(13)) - (m.get(9) * m.get(12)))) / det, -(m.get(0) * ((m.get(5) * m.get(14)) - (m.get(6) * m.get(13))) - m.get(1) * ((m.get(4) * m.get(14)) - (m.get(6) * m.get(12))) + m.get(2) * ((m.get(4) * m.get(13)) - (m.get(5) * m.get(12)))) / det, (m.get(0) * ((m.get(5) * m.get(10)) - (m.get(6) * m.get(9))) - m.get(1) * ((m.get(4) * m.get(10)) - (m.get(6) * m.get(8))) + m.get(2) * ((m.get(4) * m.get(9)) - (m.get(5) * m.get(8)))) / det); } }; } #include "matrix.tpp" #endif