mat_gen_dim section 8C2.
home

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