mat_gen_dim section 8E.
home

This program shows the inner product being calculated, first by contracting the outer product, and second directly. Four different types are used as matrix components.

Because the template parameter defaults are being overridden, some of the function calls are lengthy — but mixing of types is at least possible. Where might mixed-type calculations be used?

The sometimes lengthy template parameter lists (inner_product has ten, seven with defaults) incur no runtime overhead, no matter what types are used.

#include "SOME_DIRECTORY/mat_gen_dim.h"
using namespace mat_gen_dim;

form const frm_a {blt{3,7},blt{6,9},blt{3,7}};
form const frm_b {blt{0,2},blt{3,7}};
vec_bool const which {true,false,true,false,true};

struct type_a { 
    double x; 
    type_a (double const p = 0.0) : x (p) { } 
};
ostream & operator<< (ostream & o, type_a const a) { o << a.x << "_a"; return o; }

struct type_b { 
    double x; 
    type_b (double const p = 0.0) : x (p) { } 
};
ostream & operator<< (ostream & o, type_b const b) { o << b.x << "_b"; return o; }

struct type_y { 
    double x; 
    type_y (double const p = 0.0) : x (p) { } 
};
ostream & operator<< (ostream & o, type_y const y) { o << y.x << "_y"; return o; }

struct type_z { 
    double x; 
    type_z (double const p = 0.0) : x (p) { } 
};
ostream & operator<< (ostream & o, type_z const z) { o << z.x << "_z"; return o; }

namespace std {
    template<>
    struct is_floating_point<type_a> : std::integral_constant<bool,true> {};

    template<>
    struct is_floating_point<type_b> : std::integral_constant<bool,true> {};

    template<>
    struct is_floating_point<type_y> : std::integral_constant<bool,true> {};

    template<>
    struct is_floating_point<type_z> : std::integral_constant<bool,true> {};
}

struct mul_y_ab {
    type_y operator() (type_a const a, type_b const b) { return type_y (a.x * b.x); }
};

struct add_asgn_z_zy {
    type_z operator() (type_z & z, type_y const y) { return type_z (z.x += y.x); }
};

int main() {
    cout.setf (std::ios::fixed, std::ios::floatfield);
    cout.precision (6);

    rand_double const rand {0.0, 1.0};

    var_matrix<type_a> mat_a {sub_matrix_random<type_a> (frm_a,rand)};
    cout << "\n matrix a: " << mat_a;

    var_matrix<type_b> mat_b {sub_matrix_random<type_b> (frm_b,rand)};
    cout << "\n matrix b: " << mat_b;

    var_matrix<type_y> const mat_y { outer_product
        <mul_y_ab,type_a,type_b,type_y>
        (mat_a, mat_b)
    };
    cout << "\n outer product of a and b: " << mat_y;
 
    var_matrix<type_z> const mat_z1 { contraction
        <add_asgn_z_zy,type_y,type_z>
        (mat_y, which)
    };
    cout << "\n contraction of outer product: " << mat_z1;

    var_matrix<type_z> const mat_z2 { inner_product
            <mul_y_ab,add_asgn_z_zy,type_a,type_b,type_y,type_z>
            (mat_a, mat_b, which)
    };
    cout << "\n equivalent inner product of a and b: " << mat_z2;

    return 0;
}
yields this output:
 matrix a: 
    ( 3 6 3 ) = 0.085032_a    ( 3 6 4 ) = 0.891611_a    ( 3 6 5 ) = 0.189690_a    ( 3 6 6 ) = 0.398008_a
    ( 3 7 3 ) = 0.743512_a    ( 3 7 4 ) = 0.560390_a    ( 3 7 5 ) = 0.809567_a    ( 3 7 6 ) = 0.511713_a
    ( 3 8 3 ) = 0.995085_a    ( 3 8 4 ) = 0.966611_a    ( 3 8 5 ) = 0.426051_a    ( 3 8 6 ) = 0.652999_a
    ( 4 6 3 ) = 0.961533_a    ( 4 6 4 ) = 0.857987_a    ( 4 6 5 ) = 0.294026_a    ( 4 6 6 ) = 0.414645_a
    ( 4 7 3 ) = 0.514893_a    ( 4 7 4 ) = 0.789785_a    ( 4 7 5 ) = 0.544273_a    ( 4 7 6 ) = 0.093630_a
    ( 4 8 3 ) = 0.432260_a    ( 4 8 4 ) = 0.844927_a    ( 4 8 5 ) = 0.772846_a    ( 4 8 6 ) = 0.191859_a
    ( 5 6 3 ) = 0.780367_a    ( 5 6 4 ) = 0.181343_a    ( 5 6 5 ) = 0.579141_a    ( 5 6 6 ) = 0.314131_a
    ( 5 7 3 ) = 0.411985_a    ( 5 7 4 ) = 0.992305_a    ( 5 7 5 ) = 0.163922_a    ( 5 7 6 ) = 0.334848_a
    ( 5 8 3 ) = 0.076218_a    ( 5 8 4 ) = 0.174524_a    ( 5 8 5 ) = 0.037300_a    ( 5 8 6 ) = 0.467415_a
    ( 6 6 3 ) = 0.674113_a    ( 6 6 4 ) = 0.066703_a    ( 6 6 5 ) = 0.389782_a    ( 6 6 6 ) = 0.165399_a
    ( 6 7 3 ) = 0.990804_a    ( 6 7 4 ) = 0.870639_a    ( 6 7 5 ) = 0.672653_a    ( 6 7 6 ) = 0.587706_a
    ( 6 8 3 ) = 0.255014_a    ( 6 8 4 ) = 0.593045_a    ( 6 8 5 ) = 0.271720_a    ( 6 8 6 ) = 0.270481_a
 matrix b: 
    ( 0 3 ) = 0.095930_b    ( 0 4 ) = 0.632556_b    ( 0 5 ) = 0.151273_b    ( 0 6 ) = 0.948862_b
    ( 1 3 ) = 0.042604_b    ( 1 4 ) = 0.735089_b    ( 1 5 ) = 0.465497_b    ( 1 6 ) = 0.222540_b
 outer product of a and b: 
    ( 3 6 3 0 3 ) = 0.008157_y    ( 3 6 3 0 4 ) = 0.053788_y    ( 3 6 3 0 5 ) = 0.012863_y    ( 3 6 3 0 6 ) = 0.080684_y
    ( 3 6 3 1 3 ) = 0.003623_y    ( 3 6 3 1 4 ) = 0.062506_y    ( 3 6 3 1 5 ) = 0.039582_y    ( 3 6 3 1 6 ) = 0.018923_y
    ( 3 6 4 0 3 ) = 0.085532_y    ( 3 6 4 0 4 ) = 0.563994_y    ( 3 6 4 0 5 ) = 0.134877_y    ( 3 6 4 0 6 ) = 0.846016_y
    ( 3 6 4 1 3 ) = 0.037986_y    ( 3 6 4 1 4 ) = 0.655414_y    ( 3 6 4 1 5 ) = 0.415042_y    ( 3 6 4 1 6 ) = 0.198419_y
    ( 3 6 5 0 3 ) = 0.018197_y    ( 3 6 5 0 4 ) = 0.119989_y    ( 3 6 5 0 5 ) = 0.028695_y    ( 3 6 5 0 6 ) = 0.179990_y
    ( 3 6 5 1 3 ) = 0.008082_y    ( 3 6 5 1 4 ) = 0.139439_y    ( 3 6 5 1 5 ) = 0.088300_y    ( 3 6 5 1 6 ) = 0.042213_y
    ( 3 6 6 0 3 ) = 0.038181_y    ( 3 6 6 0 4 ) = 0.251763_y    ( 3 6 6 0 5 ) = 0.060208_y    ( 3 6 6 0 6 ) = 0.377655_y
    ( 3 6 6 1 3 ) = 0.016957_y    ( 3 6 6 1 4 ) = 0.292572_y    ( 3 6 6 1 5 ) = 0.185272_y    ( 3 6 6 1 6 ) = 0.088573_y
    ( 3 7 3 0 3 ) = 0.071325_y    ( 3 7 3 0 4 ) = 0.470313_y    ( 3 7 3 0 5 ) = 0.112473_y    ( 3 7 3 0 6 ) = 0.705491_y
    ( 3 7 3 1 3 ) = 0.031677_y    ( 3 7 3 1 4 ) = 0.546548_y    ( 3 7 3 1 5 ) = 0.346103_y    ( 3 7 3 1 6 ) = 0.165461_y
    ( 3 7 4 0 3 ) = 0.053758_y    ( 3 7 4 0 4 ) = 0.354478_y    ( 3 7 4 0 5 ) = 0.084772_y    ( 3 7 4 0 6 ) = 0.531733_y
    ( 3 7 4 1 3 ) = 0.023875_y    ( 3 7 4 1 4 ) = 0.411937_y    ( 3 7 4 1 5 ) = 0.260860_y    ( 3 7 4 1 6 ) = 0.124709_y
    ( 3 7 5 0 3 ) = 0.077662_y    ( 3 7 5 0 4 ) = 0.512096_y    ( 3 7 5 0 5 ) = 0.122465_y    ( 3 7 5 0 6 ) = 0.768167_y
    ( 3 7 5 1 3 ) = 0.034491_y    ( 3 7 5 1 4 ) = 0.595104_y    ( 3 7 5 1 5 ) = 0.376851_y    ( 3 7 5 1 6 ) = 0.180161_y
    ( 3 7 6 0 3 ) = 0.049089_y    ( 3 7 6 0 4 ) = 0.323687_y    ( 3 7 6 0 5 ) = 0.077408_y    ( 3 7 6 0 6 ) = 0.485545_y
    ( 3 7 6 1 3 ) = 0.021801_y    ( 3 7 6 1 4 ) = 0.376154_y    ( 3 7 6 1 5 ) = 0.238201_y    ( 3 7 6 1 6 ) = 0.113876_y
    ( 3 8 3 0 3 ) = 0.095459_y    ( 3 8 3 0 4 ) = 0.629447_y    ( 3 8 3 0 5 ) = 0.150529_y    ( 3 8 3 0 6 ) = 0.944198_y
    ( 3 8 3 1 3 ) = 0.042395_y    ( 3 8 3 1 4 ) = 0.731476_y    ( 3 8 3 1 5 ) = 0.463209_y    ( 3 8 3 1 6 ) = 0.221446_y
    ( 3 8 4 0 3 ) = 0.092727_y    ( 3 8 4 0 4 ) = 0.611436_y    ( 3 8 4 0 5 ) = 0.146222_y    ( 3 8 4 0 6 ) = 0.917181_y
    ( 3 8 4 1 3 ) = 0.041182_y    ( 3 8 4 1 4 ) = 0.710545_y    ( 3 8 4 1 5 ) = 0.449955_y    ( 3 8 4 1 6 ) = 0.215109_y
    ( 3 8 5 0 3 ) = 0.040871_y    ( 3 8 5 0 4 ) = 0.269501_y    ( 3 8 5 0 5 ) = 0.064450_y    ( 3 8 5 0 6 ) = 0.404264_y
    ( 3 8 5 1 3 ) = 0.018152_y    ( 3 8 5 1 4 ) = 0.313185_y    ( 3 8 5 1 5 ) = 0.198325_y    ( 3 8 5 1 6 ) = 0.094813_y
    ( 3 8 6 0 3 ) = 0.062642_y    ( 3 8 6 0 4 ) = 0.413058_y    ( 3 8 6 0 5 ) = 0.098781_y    ( 3 8 6 0 6 ) = 0.619606_y
    ( 3 8 6 1 3 ) = 0.027821_y    ( 3 8 6 1 4 ) = 0.480012_y    ( 3 8 6 1 5 ) = 0.303969_y    ( 3 8 6 1 6 ) = 0.145318_y

    // ( 4 x x x x ) and ( 5 x x x x ) omitted for brevity

    ( 6 6 3 0 3 ) = 0.064668_y    ( 6 6 3 0 4 ) = 0.426414_y    ( 6 6 3 0 5 ) = 0.101975_y    ( 6 6 3 0 6 ) = 0.639640_y
    ( 6 6 3 1 3 ) = 0.028720_y    ( 6 6 3 1 4 ) = 0.495533_y    ( 6 6 3 1 5 ) = 0.313797_y    ( 6 6 3 1 6 ) = 0.150017_y
    ( 6 6 4 0 3 ) = 0.006399_y    ( 6 6 4 0 4 ) = 0.042194_y    ( 6 6 4 0 5 ) = 0.010090_y    ( 6 6 4 0 6 ) = 0.063292_y
    ( 6 6 4 1 3 ) = 0.002842_y    ( 6 6 4 1 4 ) = 0.049033_y    ( 6 6 4 1 5 ) = 0.031050_y    ( 6 6 4 1 6 ) = 0.014844_y
    ( 6 6 5 0 3 ) = 0.037392_y    ( 6 6 5 0 4 ) = 0.246559_y    ( 6 6 5 0 5 ) = 0.058963_y    ( 6 6 5 0 6 ) = 0.369850_y
    ( 6 6 5 1 3 ) = 0.016606_y    ( 6 6 5 1 4 ) = 0.286525_y    ( 6 6 5 1 5 ) = 0.181443_y    ( 6 6 5 1 6 ) = 0.086742_y
    ( 6 6 6 0 3 ) = 0.015867_y    ( 6 6 6 0 4 ) = 0.104624_y    ( 6 6 6 0 5 ) = 0.025020_y    ( 6 6 6 0 6 ) = 0.156941_y
    ( 6 6 6 1 3 ) = 0.007047_y    ( 6 6 6 1 4 ) = 0.121583_y    ( 6 6 6 1 5 ) = 0.076993_y    ( 6 6 6 1 6 ) = 0.036808_y
    ( 6 7 3 0 3 ) = 0.095048_y    ( 6 7 3 0 4 ) = 0.626739_y    ( 6 7 3 0 5 ) = 0.149882_y    ( 6 7 3 0 6 ) = 0.940137_y
    ( 6 7 3 1 3 ) = 0.042212_y    ( 6 7 3 1 4 ) = 0.728329_y    ( 6 7 3 1 5 ) = 0.461216_y    ( 6 7 3 1 6 ) = 0.220493_y
    ( 6 7 4 0 3 ) = 0.083521_y    ( 6 7 4 0 4 ) = 0.550728_y    ( 6 7 4 0 5 ) = 0.131704_y    ( 6 7 4 0 6 ) = 0.826117_y
    ( 6 7 4 1 3 ) = 0.037093_y    ( 6 7 4 1 4 ) = 0.639997_y    ( 6 7 4 1 5 ) = 0.405280_y    ( 6 7 4 1 6 ) = 0.193752_y
    ( 6 7 5 0 3 ) = 0.064528_y    ( 6 7 5 0 4 ) = 0.425491_y    ( 6 7 5 0 5 ) = 0.101754_y    ( 6 7 5 0 6 ) = 0.638255_y
    ( 6 7 5 1 3 ) = 0.028658_y    ( 6 7 5 1 4 ) = 0.494460_y    ( 6 7 5 1 5 ) = 0.313118_y    ( 6 7 5 1 6 ) = 0.149692_y
    ( 6 7 6 0 3 ) = 0.056379_y    ( 6 7 6 0 4 ) = 0.371757_y    ( 6 7 6 0 5 ) = 0.088904_y    ( 6 7 6 0 6 ) = 0.557652_y
    ( 6 7 6 1 3 ) = 0.025039_y    ( 6 7 6 1 4 ) = 0.432016_y    ( 6 7 6 1 5 ) = 0.273575_y    ( 6 7 6 1 6 ) = 0.130788_y
    ( 6 8 3 0 3 ) = 0.024464_y    ( 6 8 3 0 4 ) = 0.161311_y    ( 6 8 3 0 5 ) = 0.038577_y    ( 6 8 3 0 6 ) = 0.241974_y
    ( 6 8 3 1 3 ) = 0.010865_y    ( 6 8 3 1 4 ) = 0.187458_y    ( 6 8 3 1 5 ) = 0.118708_y    ( 6 8 3 1 6 ) = 0.056751_y
    ( 6 8 4 0 3 ) = 0.056891_y    ( 6 8 4 0 4 ) = 0.375135_y    ( 6 8 4 0 5 ) = 0.089712_y    ( 6 8 4 0 6 ) = 0.562719_y
    ( 6 8 4 1 3 ) = 0.025266_y    ( 6 8 4 1 4 ) = 0.435941_y    ( 6 8 4 1 5 ) = 0.276061_y    ( 6 8 4 1 6 ) = 0.131976_y
    ( 6 8 5 0 3 ) = 0.026066_y    ( 6 8 5 0 4 ) = 0.171878_y    ( 6 8 5 0 5 ) = 0.041104_y    ( 6 8 5 0 6 ) = 0.257825_y
    ( 6 8 5 1 3 ) = 0.011576_y    ( 6 8 5 1 4 ) = 0.199738_y    ( 6 8 5 1 5 ) = 0.126485_y    ( 6 8 5 1 6 ) = 0.060468_y
    ( 6 8 6 0 3 ) = 0.025947_y    ( 6 8 6 0 4 ) = 0.171095_y    ( 6 8 6 0 5 ) = 0.040916_y    ( 6 8 6 0 6 ) = 0.256649_y
    ( 6 8 6 1 3 ) = 0.011524_y    ( 6 8 6 1 4 ) = 0.198828_y    ( 6 8 6 1 5 ) = 0.125908_y    ( 6 8 6 1 6 ) = 0.060193_y
 contraction of outer product: 
    ( 6 0 ) = 0.795431_z    ( 6 1 ) = 0.940716_z
    ( 7 0 ) = 1.153358_z    ( 7 1 ) = 0.819332_z
    ( 8 0 ) = 0.892215_z    ( 8 1 ) = 0.741048_z
 equivalent inner product of a and b: 
    ( 6 0 ) = 0.795431_z    ( 6 1 ) = 0.940716_z
    ( 7 0 ) = 1.153358_z    ( 7 1 ) = 0.819332_z
    ( 8 0 ) = 0.892215_z    ( 8 1 ) = 0.741048_z