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?

• A matrix of integers could be added to a matrix of pointers yielding a matrix of pointers. Mistakes such as adding one pointer to another would be caught by the compiler.
• In physics, many calculations involve units as in direct-current electricity where amps times volts equals watts. A rigorous calculating environment could provide a separate type for each kind of unit, detecting at compile time errors such as adding amps to volts.
• In finance, a dollar (or euro or yen) type could be devised permitting addition, subtraction, and division but not multiplication. Additional functions would allow multiplication or division between a dollar and a number, but not addition or subtraction.

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); }
};

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
(mat_y, which)
};
cout << "\n contraction of outer product: " << mat_z1;

var_matrix<type_z> const mat_z2 { inner_product
(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
```