mat_gen_dim section 8C1.
home

This function contracts a matrix according to a supplied vec_bool = std::vector<bool>. This vector must have one component for each dimension of the input matrix, with the value true in each subscript position in which contraction is desired to be done.

The input matrix's form must have equal blts in all the contraction positions; the other blts need not equal each other or anything else. Also, within the contraction blts, the top value must be strictly greater than the bottom value. There is a subtle reason for this latter requirement: with a zero-length blt, the function would have to return the additive identity of the component type, and many types that are not plain old numbers do not have such an identity. Examples:

Related is the case where all the vec_bool's components are false: the output matrix cannot exist. It would have the same form as the input, and every component would be zero, but there is no guarantee that the component type has an additive identity, so this case is barred. If by contrast all the vec_bool's components are true, there is no problem. The output matrix will have zero dimensions, and its one component will be the sum of components on the input's principal diagonal; this is a generalized trace.


The output matrix has one dimension for each false in the vec_bool, and its form's blts are taken from the input matrix's form's blts corresponding to the false vector positions.

Each component of the output matrix is loaded with the sum of certain components of the input matrix. Those input components are the ones where:

If the vec_bool has at least two trues, not all the components of the input matrix will be added into an output component; some will be ignored. This is the source of the inefficiency in calculating an inner product by contracting an outer product: many of the results of the outer product operation are simply never used.

The programmer may supply any desired addition function.


Here is the signature of contraction:

template <
    typename add_asgn_oper,
    typename compo_y,
    typename compo_z = compo_y,
    typename alloc_y = std::allocator <compo_y>,
    typename alloc_z = std::allocator <compo_z>
> var_matrix<compo_z,alloc_z> contraction (
    sub_matrix_base<compo_y,alloc_y> const & mat_y,
    vec_bool const & which
);
As an example, this program:
#include "SOME_DIRECTORY/mat_gen_dim.h"
using namespace mat_gen_dim;

form const frm_a {blt{1,3},blt{4,7},blt{1,3},blt{5,8},blt{1,3}};
vec_bool const which {true,false,true,false,true};

struct add_asgn_double {
    double operator() (double & z, double const y) { return z += y; }
};

int main() {
    var_matrix<double> mat_a {sub_matrix_linear (frm_a,0.0)};
    cout << "\n matrix a: " << mat_a;
    con_matrix<double> mat_acon {mat_a};

    var_matrix<double> const mat_z
        { mat_gen_dim::contraction<add_asgn_double> (mat_a, which) };
    cout << "\n contraction: " << mat_z;

    return 0;
}
yields this annotated output:
 matrix a: 
    ( 1 4 1 5 1 ) = 0.14151    ( 1 4 1 5 2 ) = 0.14152    ( 1 4 1 6 1 ) = 0.14161    ( 1 4 1 6 2 ) = 0.14162
    ( 1 4 1 7 1 ) = 0.14171    ( 1 4 1 7 2 ) = 0.14172    ( 1 4 2 5 1 ) = 0.14251    ( 1 4 2 5 2 ) = 0.14252
    ( 1 4 2 6 1 ) = 0.14261    ( 1 4 2 6 2 ) = 0.14262    ( 1 4 2 7 1 ) = 0.14271    ( 1 4 2 7 2 ) = 0.14272
    ( 1 5 1 5 1 ) = 0.15151    ( 1 5 1 5 2 ) = 0.15152    ( 1 5 1 6 1 ) = 0.15161    ( 1 5 1 6 2 ) = 0.15162
    ( 1 5 1 7 1 ) = 0.15171    ( 1 5 1 7 2 ) = 0.15172    ( 1 5 2 5 1 ) = 0.15251    ( 1 5 2 5 2 ) = 0.15252
    ( 1 5 2 6 1 ) = 0.15261    ( 1 5 2 6 2 ) = 0.15262    ( 1 5 2 7 1 ) = 0.15271    ( 1 5 2 7 2 ) = 0.15272
    ( 1 6 1 5 1 ) = 0.16151    ( 1 6 1 5 2 ) = 0.16152    ( 1 6 1 6 1 ) = 0.16161    ( 1 6 1 6 2 ) = 0.16162
    ( 1 6 1 7 1 ) = 0.16171    ( 1 6 1 7 2 ) = 0.16172    ( 1 6 2 5 1 ) = 0.16251    ( 1 6 2 5 2 ) = 0.16252
    ( 1 6 2 6 1 ) = 0.16261    ( 1 6 2 6 2 ) = 0.16262    ( 1 6 2 7 1 ) = 0.16271    ( 1 6 2 7 2 ) = 0.16272
    ( 2 4 1 5 1 ) = 0.24151    ( 2 4 1 5 2 ) = 0.24152    ( 2 4 1 6 1 ) = 0.24161    ( 2 4 1 6 2 ) = 0.24162
    ( 2 4 1 7 1 ) = 0.24171    ( 2 4 1 7 2 ) = 0.24172    ( 2 4 2 5 1 ) = 0.24251    ( 2 4 2 5 2 ) = 0.24252
    ( 2 4 2 6 1 ) = 0.24261    ( 2 4 2 6 2 ) = 0.24262    ( 2 4 2 7 1 ) = 0.24271    ( 2 4 2 7 2 ) = 0.24272
    ( 2 5 1 5 1 ) = 0.25151    ( 2 5 1 5 2 ) = 0.25152    ( 2 5 1 6 1 ) = 0.25161    ( 2 5 1 6 2 ) = 0.25162
    ( 2 5 1 7 1 ) = 0.25171    ( 2 5 1 7 2 ) = 0.25172    ( 2 5 2 5 1 ) = 0.25251    ( 2 5 2 5 2 ) = 0.25252
    ( 2 5 2 6 1 ) = 0.25261    ( 2 5 2 6 2 ) = 0.25262    ( 2 5 2 7 1 ) = 0.25271    ( 2 5 2 7 2 ) = 0.25272
    ( 2 6 1 5 1 ) = 0.26151    ( 2 6 1 5 2 ) = 0.26152    ( 2 6 1 6 1 ) = 0.26161    ( 2 6 1 6 2 ) = 0.26162
    ( 2 6 1 7 1 ) = 0.26171    ( 2 6 1 7 2 ) = 0.26172    ( 2 6 2 5 1 ) = 0.26251    ( 2 6 2 5 2 ) = 0.26252
    ( 2 6 2 6 1 ) = 0.26261    ( 2 6 2 6 2 ) = 0.26262    ( 2 6 2 7 1 ) = 0.26271    ( 2 6 2 7 2 ) = 0.26272
 contraction: 
    ( 4 5 ) = 0.38403 = ( 1 4 1 5 1 ) + ( 2 4 2 5 2 )
    ( 4 6 ) = 0.38423 = ( 1 4 1 6 1 ) + ( 2 4 2 6 2 )
    ( 4 7 ) = 0.38443 = ( 1 4 1 7 1 ) + ( 2 4 2 7 2 )
    ( 5 5 ) = 0.40403 = ( 1 5 1 5 1 ) + ( 2 5 2 5 2 )
    ( 5 6 ) = 0.40423 = ( 1 5 1 6 1 ) + ( 2 5 2 6 2 )
    ( 5 7 ) = 0.40443 = ( 1 5 1 7 1 ) + ( 2 5 2 7 2 )
    ( 6 5 ) = 0.42403 = ( 1 6 1 5 1 ) + ( 2 6 2 5 2 )
    ( 6 6 ) = 0.42423 = ( 1 6 1 6 1 ) + ( 2 6 2 6 2 )
    ( 6 7 ) = 0.42443 = ( 1 6 1 7 1 ) + ( 2 6 2 7 2 )