Four binary functions greatly simplify the notation for ordinary matrix addition and subtraction:
template < typename compo_a, typename compo_b = compo_a, typename alloc_a = std::allocator <compo_a>, typename alloc_b = std::allocator <compo_b> > var_matrix<compo_a,alloc_a> operator+= ( var_matrix_base<compo_a,alloc_a> const & mat_a, sub_matrix_base<compo_b,alloc_b> const & mat_b ) { struct add_asgn { compo_a operator() (compo_a & a, compo_b const b) { return a += b; } }; return parallel_ret_var_con < add_asgn, compo_a, compo_b, alloc_a, alloc_b > (mat_a, mat_b); }
template < typename compo_a, typename compo_b = compo_a, typename compo_z = compo_a, typename alloc_a = std::allocator <compo_a>, typename alloc_b = std::allocator <compo_b>, typename alloc_z = std::allocator <compo_z> > var_matrix<compo_z,alloc_z> operator+ ( sub_matrix_base<compo_a,alloc_a> const & mat_a, sub_matrix_base<compo_b,alloc_b> const & mat_b ) { struct add { compo_z operator() (compo_a const a, compo_b const b) { return a + b; } }; return parallel_ret_con_con< add, compo_a, compo_b, compo_z, alloc_a, alloc_b, alloc_z > (mat_a, mat_b); }
For example, this program:
#include "SOME_DIRECTORY/mat_gen_dim.h" using namespace mat_gen_dim; form const frm {blt{1,3},blt{2,6},blt{5,7}}; int main () { std::cout.setf (std::ios::fixed, std::ios::floatfield); std::cout.precision (3); { cout << "\n\n -- increment the first matrix by the second, return a copy of the first"; var_matrix<double> mat_a8 {sub_matrix_linear (frm,1.0)}; cout << "\n mat_a8 before: " << mat_a8; var_matrix<double> mat_b8 {sub_matrix_linear (frm,2.0)}; cout << "\n mat_b8 before: " << mat_b8; var_matrix<double> mat_z8 {mat_a8 += mat_b8}; cout << "\n mat_a8 after: " << mat_a8; cout << "\n mat_b8 after: " << mat_b8; cout << "\n mat_a8 == what is returned: " << mat_z8; } { cout << "\n\n -- add the two matrices, return the sum"; var_matrix<double> mat_a9 {sub_matrix_linear (frm,1.0)}; cout << "\n mat_a9 before: " << mat_a9; var_matrix<double> mat_b9 {sub_matrix_linear (frm,2.0)}; cout << "\n mat_b9 before: " << mat_b9; var_matrix<double> mat_z9 {mat_a9 + mat_b9}; cout << "\n mat_a9 after: " << mat_a9; cout << "\n mat_b9 after: " << mat_b9; cout << "\n mat_z9 == what is returned: " << mat_z9; } return 0; }yields this output:
-- increment the first matrix by the second, return a copy of the first mat_a8 before: ( 1 2 5 ) = 1.125 ( 1 2 6 ) = 1.126 ( 1 3 5 ) = 1.135 ( 1 3 6 ) = 1.136 ( 1 4 5 ) = 1.145 ( 1 4 6 ) = 1.146 ( 1 5 5 ) = 1.155 ( 1 5 6 ) = 1.156 ( 2 2 5 ) = 1.225 ( 2 2 6 ) = 1.226 ( 2 3 5 ) = 1.235 ( 2 3 6 ) = 1.236 ( 2 4 5 ) = 1.245 ( 2 4 6 ) = 1.246 ( 2 5 5 ) = 1.255 ( 2 5 6 ) = 1.256 mat_b8 before: ( 1 2 5 ) = 2.125 ( 1 2 6 ) = 2.126 ( 1 3 5 ) = 2.135 ( 1 3 6 ) = 2.136 ( 1 4 5 ) = 2.145 ( 1 4 6 ) = 2.146 ( 1 5 5 ) = 2.155 ( 1 5 6 ) = 2.156 ( 2 2 5 ) = 2.225 ( 2 2 6 ) = 2.226 ( 2 3 5 ) = 2.235 ( 2 3 6 ) = 2.236 ( 2 4 5 ) = 2.245 ( 2 4 6 ) = 2.246 ( 2 5 5 ) = 2.255 ( 2 5 6 ) = 2.256 mat_a8 after: ( 1 2 5 ) = 3.250 ( 1 2 6 ) = 3.252 ( 1 3 5 ) = 3.270 ( 1 3 6 ) = 3.272 ( 1 4 5 ) = 3.290 ( 1 4 6 ) = 3.292 ( 1 5 5 ) = 3.310 ( 1 5 6 ) = 3.312 ( 2 2 5 ) = 3.450 ( 2 2 6 ) = 3.452 ( 2 3 5 ) = 3.470 ( 2 3 6 ) = 3.472 ( 2 4 5 ) = 3.490 ( 2 4 6 ) = 3.492 ( 2 5 5 ) = 3.510 ( 2 5 6 ) = 3.512 mat_b8 after: ( 1 2 5 ) = 2.125 ( 1 2 6 ) = 2.126 ( 1 3 5 ) = 2.135 ( 1 3 6 ) = 2.136 ( 1 4 5 ) = 2.145 ( 1 4 6 ) = 2.146 ( 1 5 5 ) = 2.155 ( 1 5 6 ) = 2.156 ( 2 2 5 ) = 2.225 ( 2 2 6 ) = 2.226 ( 2 3 5 ) = 2.235 ( 2 3 6 ) = 2.236 ( 2 4 5 ) = 2.245 ( 2 4 6 ) = 2.246 ( 2 5 5 ) = 2.255 ( 2 5 6 ) = 2.256 mat_a8 == what is returned: ( 1 2 5 ) = 3.250 ( 1 2 6 ) = 3.252 ( 1 3 5 ) = 3.270 ( 1 3 6 ) = 3.272 ( 1 4 5 ) = 3.290 ( 1 4 6 ) = 3.292 ( 1 5 5 ) = 3.310 ( 1 5 6 ) = 3.312 ( 2 2 5 ) = 3.450 ( 2 2 6 ) = 3.452 ( 2 3 5 ) = 3.470 ( 2 3 6 ) = 3.472 ( 2 4 5 ) = 3.490 ( 2 4 6 ) = 3.492 ( 2 5 5 ) = 3.510 ( 2 5 6 ) = 3.512 -- add the two matrices, return the sum mat_a9 before: ( 1 2 5 ) = 1.125 ( 1 2 6 ) = 1.126 ( 1 3 5 ) = 1.135 ( 1 3 6 ) = 1.136 ( 1 4 5 ) = 1.145 ( 1 4 6 ) = 1.146 ( 1 5 5 ) = 1.155 ( 1 5 6 ) = 1.156 ( 2 2 5 ) = 1.225 ( 2 2 6 ) = 1.226 ( 2 3 5 ) = 1.235 ( 2 3 6 ) = 1.236 ( 2 4 5 ) = 1.245 ( 2 4 6 ) = 1.246 ( 2 5 5 ) = 1.255 ( 2 5 6 ) = 1.256 mat_b9 before: ( 1 2 5 ) = 2.125 ( 1 2 6 ) = 2.126 ( 1 3 5 ) = 2.135 ( 1 3 6 ) = 2.136 ( 1 4 5 ) = 2.145 ( 1 4 6 ) = 2.146 ( 1 5 5 ) = 2.155 ( 1 5 6 ) = 2.156 ( 2 2 5 ) = 2.225 ( 2 2 6 ) = 2.226 ( 2 3 5 ) = 2.235 ( 2 3 6 ) = 2.236 ( 2 4 5 ) = 2.245 ( 2 4 6 ) = 2.246 ( 2 5 5 ) = 2.255 ( 2 5 6 ) = 2.256 mat_a9 after: ( 1 2 5 ) = 1.125 ( 1 2 6 ) = 1.126 ( 1 3 5 ) = 1.135 ( 1 3 6 ) = 1.136 ( 1 4 5 ) = 1.145 ( 1 4 6 ) = 1.146 ( 1 5 5 ) = 1.155 ( 1 5 6 ) = 1.156 ( 2 2 5 ) = 1.225 ( 2 2 6 ) = 1.226 ( 2 3 5 ) = 1.235 ( 2 3 6 ) = 1.236 ( 2 4 5 ) = 1.245 ( 2 4 6 ) = 1.246 ( 2 5 5 ) = 1.255 ( 2 5 6 ) = 1.256 mat_b9 after: ( 1 2 5 ) = 2.125 ( 1 2 6 ) = 2.126 ( 1 3 5 ) = 2.135 ( 1 3 6 ) = 2.136 ( 1 4 5 ) = 2.145 ( 1 4 6 ) = 2.146 ( 1 5 5 ) = 2.155 ( 1 5 6 ) = 2.156 ( 2 2 5 ) = 2.225 ( 2 2 6 ) = 2.226 ( 2 3 5 ) = 2.235 ( 2 3 6 ) = 2.236 ( 2 4 5 ) = 2.245 ( 2 4 6 ) = 2.246 ( 2 5 5 ) = 2.255 ( 2 5 6 ) = 2.256 mat_z9 == what is returned: ( 1 2 5 ) = 3.250 ( 1 2 6 ) = 3.252 ( 1 3 5 ) = 3.270 ( 1 3 6 ) = 3.272 ( 1 4 5 ) = 3.290 ( 1 4 6 ) = 3.292 ( 1 5 5 ) = 3.310 ( 1 5 6 ) = 3.312 ( 2 2 5 ) = 3.450 ( 2 2 6 ) = 3.452 ( 2 3 5 ) = 3.470 ( 2 3 6 ) = 3.472 ( 2 4 5 ) = 3.490 ( 2 4 6 ) = 3.492 ( 2 5 5 ) = 3.510 ( 2 5 6 ) = 3.512