det.hpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. // Copyright Louis Dionne 2013-2017
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  4. #ifndef BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_DET_HPP
  5. #define BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_DET_HPP
  6. #include <boost/hana/equal.hpp>
  7. #include <boost/hana/eval_if.hpp>
  8. #include <boost/hana/front.hpp>
  9. #include <boost/hana/functional/always.hpp>
  10. #include <boost/hana/functional/fix.hpp>
  11. #include <boost/hana/functional/flip.hpp>
  12. #include <boost/hana/functional/on.hpp>
  13. #include <boost/hana/functional/partial.hpp>
  14. #include <boost/hana/integral_constant.hpp>
  15. #include <boost/hana/plus.hpp>
  16. #include <boost/hana/power.hpp>
  17. #include <boost/hana/range.hpp>
  18. #include <boost/hana/remove_at.hpp>
  19. #include <boost/hana/transform.hpp>
  20. #include <boost/hana/tuple.hpp>
  21. #include <boost/hana/unpack.hpp>
  22. #include <utility>
  23. #include "matrix.hpp"
  24. namespace cppcon {
  25. namespace hana = boost::hana;
  26. auto det = hana::fix([](auto det, auto&& m) -> decltype(auto) {
  27. auto matrix_minor = [=](auto&& m, auto i, auto j) -> decltype(auto) {
  28. return det(hana::unpack(
  29. hana::transform(
  30. hana::remove_at(rows(std::forward<decltype(m)>(m)), i),
  31. hana::partial(hana::flip(hana::remove_at), j)
  32. ),
  33. matrix
  34. ));
  35. };
  36. auto cofactor = [=](auto&& m, auto i, auto j) {
  37. return hana::power(hana::int_c<-1>, hana::plus(i, j)) *
  38. matrix_minor(std::forward<decltype(m)>(m), i, j);
  39. };
  40. return hana::eval_if(m.size() == hana::size_c<1>,
  41. hana::always(m.at(hana::size_c<0>, hana::size_c<0>)),
  42. [=](auto _) {
  43. auto cofactors_1st_row = hana::unpack(_(hana::make_range)(hana::size_c<0>, m.ncolumns()),
  44. hana::on(hana::make_tuple, hana::partial(cofactor, m, hana::size_c<0>))
  45. );
  46. return detail::tuple_scalar_product(hana::front(rows(m)), cofactors_1st_row);
  47. }
  48. );
  49. });
  50. } // end namespace cppcon
  51. #endif // !BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_DET_HPP