/* @copyright Louis Dionne 2014 Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) */ #ifndef BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_DET_HPP #define BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_DET_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "matrix.hpp" namespace cppcon { namespace detail { constexpr int power(int x, unsigned int n) { if (n == 0) return 1; else return x * power(x, n - 1); } auto remove_at = [](auto n, auto xs) { using namespace boost::hana; auto with_indices = zip(xs, range(int_<0>, length(xs))); auto removed = filter(with_indices, compose(n != _, last)); return fmap(removed, head); }; } auto det = boost::hana::fix([](auto det, auto&& m) -> decltype(auto) { using namespace boost::hana; auto matrix_minor = [=](auto&& m, auto i, auto j) -> decltype(auto) { return det(unpack( fmap( detail::remove_at(i, rows(std::forward(m))), partial(detail::remove_at, j) ), matrix )); }; auto cofactor = [=](auto&& m, auto i, auto j) { auto i_plus_j = plus(i, j); return int_ * matrix_minor(std::forward(m), i, j); }; return eval_if(m.size() == int_<1>, always(m.at(int_<0>, int_<0>)), [=](auto _) { auto cofactors_1st_row = unpack(_(range)(int_<0>, m.ncolumns()), on(tuple, partial(cofactor, m, int_<0>)) ); return detail::tuple_scalar_product(head(rows(m)), cofactors_1st_row); } ); }); } // end namespace cppcon #endif // !BOOST_HANA_EXAMPLE_CPPCON_2014_MATRIX_DET_HPP