Repeated single-subscript contraction is a (rather inefficient) way to sum the components of a matrix. For example, this program:
#include "YOUR_DIRECTORY/mat_gen_dim.h"
using namespace mat_gen_dim;
struct add_asgn_double {
double operator() (double & z, double const y) { return z += y; }
};
int main () {
cout.setf (std::ios::fixed, std::ios::floatfield);
cout.precision (4);
form const frm_a {blt{1,4},blt{1,4},blt{1,4}};
con_matrix<double> mat_a {sub_matrix_random (frm_a,rand_double(0.0, 1.0))};
cout << "\n matrix a: " << mat_a;
{
cout << "\n\n three contractions on one subscript each: \n";
vec_bool const which_b1 {false,false,true};
con_matrix<double> mat_b1 (contraction<add_asgn_double> (mat_a, which_b1));
cout << "\n matrix b1: " << mat_b1;
vec_bool const which_b2 {false,true};
con_matrix<double> mat_b2 (contraction<add_asgn_double> (mat_b1, which_b2));
cout << "\n matrix b2: " << mat_b2;
vec_bool const which_b3 {true};
con_matrix<double> mat_b3 (contraction<add_asgn_double> (mat_b2, which_b3));
cout << "\n matrix b3: " << mat_b3;
} {
cout << "\n\n one contraction on two subscripts, ";
cout << "\n then one contraction on one subscript: \n";
vec_bool const which_c1 {false,true,true};
con_matrix<double> mat_c1 (contraction<add_asgn_double> (mat_a, which_c1));
cout << "\n matrix c1: " << mat_c1;
vec_bool const which_c2 {true};
con_matrix<double> mat_c2 (contraction<add_asgn_double> (mat_c1, which_c2));
cout << "\n matrix c2: " << mat_c2;
} {
cout << "\n\n one contraction on one subscript, ";
cout << "\n then one contraction on two subscripts: \n";
vec_bool const which_d1 {false,false,true};
con_matrix<double> mat_d1 (contraction<add_asgn_double> (mat_a, which_d1));
cout << "\n matrix d1: " << mat_d1;
vec_bool const which_d2 {true,true};
con_matrix<double> mat_d2 (contraction<add_asgn_double> (mat_d1, which_d2));
cout << "\n matrix d2: " << mat_d2;
} {
cout << "\n\n one contraction on all three subscripts: \n";
vec_bool const which_e {true,true,true};
con_matrix<double> mat_e (contraction<add_asgn_double> (mat_a, which_e));
cout << "\n matrix e: " << mat_e;
}
return 0;
}
yields the following output, with a different result for each sequence of contractions. Matrix b3 is the sum of matrix a's components.
matrix a:
( 1 1 1 ) = 0.0850 ( 1 1 2 ) = 0.8916 ( 1 1 3 ) = 0.1897
( 1 2 1 ) = 0.3980 ( 1 2 2 ) = 0.7435 ( 1 2 3 ) = 0.5604
( 1 3 1 ) = 0.8096 ( 1 3 2 ) = 0.5117 ( 1 3 3 ) = 0.9951
( 2 1 1 ) = 0.9666 ( 2 1 2 ) = 0.4261 ( 2 1 3 ) = 0.6530
( 2 2 1 ) = 0.9615 ( 2 2 2 ) = 0.8580 ( 2 2 3 ) = 0.2940
( 2 3 1 ) = 0.4146 ( 2 3 2 ) = 0.5149 ( 2 3 3 ) = 0.7898
( 3 1 1 ) = 0.5443 ( 3 1 2 ) = 0.0936 ( 3 1 3 ) = 0.4323
( 3 2 1 ) = 0.8449 ( 3 2 2 ) = 0.7728 ( 3 2 3 ) = 0.1919
( 3 3 1 ) = 0.7804 ( 3 3 2 ) = 0.1813 ( 3 3 3 ) = 0.5791
three contractions on one subscript each:
matrix b1:
( 1 1 ) = 1.1663 ( 1 2 ) = 1.7019 ( 1 3 ) = 2.3164
( 2 1 ) = 2.0457 ( 2 2 ) = 2.1135 ( 2 3 ) = 1.7193
( 3 1 ) = 1.0702 ( 3 2 ) = 1.8096 ( 3 3 ) = 1.5409
matrix b2:
( 1 ) = 5.1846 ( 2 ) = 5.8785 ( 3 ) = 4.4206
matrix b3:
( ) = 15.4838
one contraction on two subscripts,
then one contraction on one subscript:
matrix c1:
( 1 ) = 1.8236 ( 2 ) = 2.6144 ( 3 ) = 1.8963
matrix c2:
( ) = 6.3343
one contraction on one subscript,
then one contraction on two subscripts:
matrix d1:
( 1 1 ) = 1.1663 ( 1 2 ) = 1.7019 ( 1 3 ) = 2.3164
( 2 1 ) = 2.0457 ( 2 2 ) = 2.1135 ( 2 3 ) = 1.7193
( 3 1 ) = 1.0702 ( 3 2 ) = 1.8096 ( 3 3 ) = 1.5409
matrix d2:
( ) = 4.8207
one contraction on all three subscripts:
matrix e:
( ) = 1.5222