cofactor_impl.hpp 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #ifndef BOOST_QVM_DETAIL_COFACTOR_IMPL_HPP_INCLUDED
  2. #define BOOST_QVM_DETAIL_COFACTOR_IMPL_HPP_INCLUDED
  3. /// Copyright (c) 2008-2021 Emil Dotchevski and Reverge Studios, Inc.
  4. /// Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. /// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #include <boost/qvm/detail/determinant_impl.hpp>
  7. #include <boost/qvm/mat_traits.hpp>
  8. #include <boost/qvm/static_assert.hpp>
  9. namespace boost { namespace qvm {
  10. namespace
  11. qvm_detail
  12. {
  13. template <class A>
  14. BOOST_QVM_INLINE_OPERATIONS
  15. typename deduce_mat<A>::type
  16. cofactor_impl( A const & a )
  17. {
  18. BOOST_QVM_STATIC_ASSERT(mat_traits<A>::rows==mat_traits<A>::cols);
  19. int const N=mat_traits<A>::rows;
  20. typedef typename mat_traits<A>::scalar_type T;
  21. T c[N-1][N-1];
  22. typedef typename deduce_mat<A>::type R;
  23. R b;
  24. for( int j=0; j!=N; ++j )
  25. {
  26. for( int i=0; i!=N; ++i )
  27. {
  28. int i1=0;
  29. for( int ii=0; ii!=N; ++ii )
  30. {
  31. if( ii==i )
  32. continue;
  33. int j1=0;
  34. for( int jj=0; jj!=N; ++jj )
  35. {
  36. if( jj==j )
  37. continue;
  38. c[i1][j1] = mat_traits<A>::read_element_idx(ii,jj,a);
  39. ++j1;
  40. }
  41. ++i1;
  42. }
  43. T det = determinant_impl(c);
  44. if( (i+j)&1 )
  45. det=-det;
  46. mat_traits<R>::write_element_idx(i,j,b) = det;
  47. }
  48. }
  49. return b;
  50. }
  51. }
  52. } }
  53. #endif