Here are three functions that take two matrices of the same form, and apply the same operation to all components in parallel:
template < typename oper, typename compo_a, typename compo_b = compo_a, typename alloc_a = std::allocator <compo_a>, typename alloc_b = std::allocator <compo_b> > void parallel_non_var_con ( var_matrix_base<compo_a,alloc_a> const & mat_a, sub_matrix_base<compo_b,alloc_b> const & mat_b );
template < typename oper, 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> parallel_ret_var_con ( var_matrix_base<compo_a,alloc_a> const & mat_a, sub_matrix_base<compo_b,alloc_b> const & mat_b );
template < typename oper, 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> parallel_ret_con_con ( sub_matrix_base<compo_a,alloc_a> const & mat_a, sub_matrix_base<compo_b,alloc_b> const & mat_b );
As an 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); { struct add_non_var_con { void operator() (double & a, double const b) { a += b; } }; cout << "\n\n -- increment the first matrix by the second, return nothing"; var_matrix<double> mat_a7 {sub_matrix_linear (frm,1.0)}; cout << "\n mat_a7 before: " << mat_a7; var_matrix<double> mat_b7 {sub_matrix_linear (frm,2.0)}; cout << "\n mat_b7 before: " << mat_b7; parallel_non_var_con <add_non_var_con,double> (mat_a7, mat_b7); cout << "\n mat_a7 after: " << mat_a7; cout << "\n mat_b7 after: " << mat_b7; } { struct add_ret_var_con { double operator() (double & a, double const b) { return a += b; } }; 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 {parallel_ret_var_con <add_ret_var_con,double> (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; } { struct add_ret_con_con { double operator() (double const a, double const b) { return a + b; } }; cout << "\n\n -- add the two matrices, return the sum"; con_matrix<double> mat_a9 {sub_matrix_linear (frm,1.0)}; cout << "\n mat_a9 before: " << mat_a9; con_matrix<double> mat_b9 {sub_matrix_linear (frm,2.0)}; cout << "\n mat_b9 before: " << mat_b9; con_matrix<double> mat_z9 {parallel_ret_con_con<add_ret_con_con,double> (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 nothing mat_a7 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_b7 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_a7 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_b7 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 -- 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