template < class Q1, class R1> BOOST_FORCEINLINE void do_it(A0& a0, const char& orient, Q1 & q1, R1 & r1) const { BOOST_AUTO_TPL(q, boost::proto::child_c<0>(a0)); BOOST_AUTO_TPL(r, boost::proto::child_c<1>(a0)); size_t j = boost::proto::child_c<2>(a0); BOOST_AUTO_TPL(x, boost::proto::child_c<3>(a0)); table<value_t, nt2::of_size_<2, 2> > g; size_t n = size(r, 2); size_t m = size(r, 1); if (orient == 'c') { // Make room and insert x before j-th column. r1.resize(nt2::of_size(m, n+1)); q1 = q; r1(nt2::_,nt2::_(1, j-1)) = r(nt2::_,nt2::_(1, j-1)); r1(nt2::_,nt2::_(j+1, n+1)) = r(nt2::_,nt2::_(j, n)); r1(nt2::_,j) = nt2::mtimes(nt2::ct(q), x); ++n; // now r has nonzeros below the diagonal in the j-th column, // and "extra" zeros on the diagonal in later columns. // r = [x x x x x [x x x x x // 0 x x x x g 0 x x x x // 0 0 + x x ---> 0 0 * * * // 0 0 + 0 x 0 0 0 * * // 0 0 + 0 0] 0 0 0 0 *] // use givens rotations to zero the +'s, one at a time, from bottom to top. // // q is treated to (the transpose of) the same rotations. // q = [x x x x x g' [x x * * * // x x x x x ---> x x * * * // x x x x x x x * * * // x x x x x x x * * * // x x x x x] x x * * *] for(size_t k = m-1; k >= j; --k) { BOOST_AUTO_TPL(p, nt2::cons(k, k+1)); nt2::tie(g,r1(p,j)) = nt2::planerot(r1(p,j)); if (k < n) { r1(p,nt2::_(k+1, n)) = nt2::mtimes(g, r1(p,nt2::_(k+1, n))); } q1(nt2::_,p) = nt2::mtimes(q1(nt2::_,p), nt2::ct(g)); } } else { r1 = catv(x, r); q1 = catv(cath(nt2::One<value_t>(), nt2::zeros(1,m,meta::as_<value_t>())), cath(nt2::zeros(m,1,meta::as_<value_t>()),q)); // now r is upper hessenberg. // r = [x x x x [* * * * // + x x x g * * * // + x x ---> * * // + x * // + 0 0 0 0 // 0 0 0 0 0 0 0 0 // 0 0 0 0] 0 0 0 0] // use givens rotations to zero the +'s, one at a time, from top to bottom. // // q is treated to (the transpose of) the same rotations and then a row // permutation, p, to shuffle row 1 down to row j. // q = [1 | 0 0 0 0 0 [# # # # # # [* * * * * * // --|---------- ----------- ----------- // 0 | x x x x x g' * * * * * * p * * * * * * // 0 | x x x x x ---> * * * * * * ---> # # # # # # // 0 | x x x x x * * * * * * * * * * * * // 0 | x x x x x * * * * * * * * * * * * // 0 | x x x x x] * * * * * *] * * * * * *] for(size_t i = 1; i <= nt2::min(m,n); ++i) { BOOST_AUTO_TPL(p, nt2::cons(i, i+1)); nt2::tie(g,r1(p,i)) = nt2::planerot(r1(p,i)); r1(p,nt2::_(i+1, n)) = nt2::mtimes(g, r1(p,nt2::_(i+1, n))); q1(nt2::_,p) = nt2::mtimes(q1(nt2::_,p), nt2::ct(g)); } // this permutes row 1 of q*r to row j of q(p,:)*r if (j != 1) { BOOST_AUTO_TPL(p, nt2::cath(nt2::cath(nt2::_(size_t(2), j), size_t(1)), nt2::_(j+1, m+1))); table<value_t> qq = q1(p,nt2::_); q1 = qq; } } }
{ value_type nn = n; BOOST_AUTO_TPL(p, nt2::_(value_type(1), nn)); BOOST_AUTO_TPL(j, nt2::trunc(nt2::mod(p,nt2::Four<value_type>())*nt2::Half<value_type>())); BOOST_AUTO_TPL(k, nt2::sx(nt2::tag::is_equal_(), j, nt2::colvect(j))); BOOST_AUTO_TPL(p1, colvect(nt2::_(value_type(1), nn, nt2::sqr(nn)))); out = nt2::sx(nt2::tag::plus_(),p1,nt2::minusone(p)); out(k) = nt2::oneplus(sqr(nn)) - out(k); } static void evenx1(A0& out, std::size_t n) { std::size_t m = n >> 1; //m is odd. oddOrderMagicSquare(out, m); value_type m2 = sqr(m); container::table<value_type> t = nt2::catv(cath(out, out+Two<value_type>()*m2), cath(out+Three<value_type>()*m2, out+m2)); BOOST_AUTO_TPL(i, colvect(nt2::_(1, m))); std::size_t k = (n-2) >> 2; BOOST_AUTO_TPL(j, nt2::cath(nt2::_(std::size_t(1), k), nt2::_(n-k+2, n))); swap_lines(t, i, i+m, j); std::size_t k1 = k+1; BOOST_AUTO_TPL(ii, nt2::_(k1, k1)); BOOST_AUTO_TPL(jj, nt2::_(std::size_t(1), k+1)); swap_lines(t, ii, ii+m, jj); out = t; } template < class M, class I1, class I2, class IDX > static void swap_lines(M& m, I1 i1, I2 i2, const IDX & j) {