File indexing completed on 2025-09-13 08:50:03
0001 #ifndef BOOST_QVM_DETAIL_DETERMINANT_IMPL_HPP_INCLUDED
0002 #define BOOST_QVM_DETAIL_DETERMINANT_IMPL_HPP_INCLUDED
0003
0004
0005
0006
0007
0008 #include <boost/qvm/config.hpp>
0009 #include <boost/qvm/mat_traits_array.hpp>
0010 #include <boost/qvm/static_assert.hpp>
0011
0012 namespace boost { namespace qvm {
0013
0014 namespace
0015 qvm_detail
0016 {
0017 template <int N>
0018 struct
0019 det_size
0020 {
0021 };
0022
0023 template <class M>
0024 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0025 typename mat_traits<M>::scalar_type
0026 determinant_impl_( M const & a, det_size<2> )
0027 {
0028 return
0029 mat_traits<M>::template read_element<0,0>(a) * mat_traits<M>::template read_element<1,1>(a) -
0030 mat_traits<M>::template read_element<1,0>(a) * mat_traits<M>::template read_element<0,1>(a);
0031 }
0032
0033 template <class M,int N>
0034 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_RECURSION
0035 typename mat_traits<M>::scalar_type
0036 determinant_impl_( M const & a, det_size<N> )
0037 {
0038 typedef typename mat_traits<M>::scalar_type T;
0039 T m[N-1][N-1];
0040 T det=T(0);
0041 for( int j1=0; j1!=N; ++j1 )
0042 {
0043 for( int i=1; i!=N; ++i )
0044 {
0045 int j2 = 0;
0046 for( int j=0; j!=N; ++j )
0047 {
0048 if( j==j1 )
0049 continue;
0050 m[i-1][j2] = mat_traits<M>::read_element_idx(i,j,a);
0051 ++j2;
0052 }
0053 }
0054 T d=determinant_impl_(m,det_size<N-1>());
0055 if( j1&1 )
0056 d=-d;
0057 det += mat_traits<M>::read_element_idx(0,j1,a) * d;
0058 }
0059 return det;
0060 }
0061
0062 template <class M>
0063 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0064 typename mat_traits<M>::scalar_type
0065 determinant_impl( M const & a )
0066 {
0067 BOOST_QVM_STATIC_ASSERT(mat_traits<M>::rows==mat_traits<M>::cols);
0068 return determinant_impl_(a,det_size<mat_traits<M>::rows>());
0069 }
0070 }
0071
0072 } }
0073
0074 #endif