section 6G
X_lens_less_dimen

home

Classes var_lens_less_dimen and con_lens_less_dimen cause a matrix to appear to have fewer dimensions, without affecting the ranges of the remaining subscripts. These lenses have an internal state rather like the state of a Standard Library iterator. An X_lens_less_dimen's state is called a marker.

As an example, with a matrix whose form is ( 1 =< 3, 2 =< 6, 5 =< 8, 4 =< 7 ), an X_lens_less_dimen constructor would need a parameter similar to this:

```    vec_si const w {1, null_int, 7, null_int};
```
where the number of components is equal to the dimensionality of the matrix being lensed. How this is interpreted:
• The marker has an element for the 1 =< 3 dimension, and its initial value is 1.
• The marker does not have an element for the 2 =< 6 dimension, therefore the resultant apparent matrix will have blt{2,6} in its form.
• The marker has an element for the 5 =< 8 dimension, and its initial value is 7.
• The marker does not have an element for the 4 =< 7 dimension, therefore the resultant apparent matrix will have blt{4,7} in its form.
The form of the apparent resultant matrix will be ( 2 =< 6, 4 =< 7 ). The marker elements determine how this form will be mapped onto the underlying matrix when the apparent matrix is subscripted. When marker elements are changed, the window into the underlying matrix is moved, and a different set of component values will appear.

There are eight functions to manage markers:

```    vec_si const & marker_get () const;
sign_int marker_get (sign_int const pos) const;
sign_int marker_bot (sign_int const pos) const;
sign_int marker_top (sign_int const pos) const;

void marker_set (vec_si const & v);
void marker_set (sign_int const pos, sign_int const val);
void marker_add (sign_int const pos, sign_int const val);
void marker_sub (sign_int const pos, sign_int const val);
```
Available for all X_lens_less_dimen:
• marker_get without parameters returns a constant reference to the entire marker.
• marker_get with sign_int parameter returns the current value of the marker in that subscript position.
• marker_bot returns the minimum legal value of the marker in that subscript position.
• marker_top returns one more than the maximum legal value of the marker in that subscript position.
Not available for X_lens_less_dimen const:
• marker_set with vec_si parameter replaces the entire marker.
• marker_set with sign_int parameter replaces the value of the marker in that subscript position.
• marker_add increases the value of the marker in that subscript position.
• marker_sub decreases the value of the marker in that subscript position.
As with X_less_final, no alarm is given if the programmer sets the marker to a value out of range — this is analogous to when the programmer sets a Standard Library iterator to a value that does not reference a component. The bool function can_deref is available, and it returns true when the marker is within range; false when is out of range. Setting a marker out of range does not cause malfunction as long as it is not deferenced; subsequently setting the marker to a value within range will allow it to be deferenced without trouble.

Function alone_non_var which is used below will be fully described later. However, a brief explanation is that it performs the same operation on every element of a matrix. Then this program:

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

struct triple {
void operator () (double & a) { a *= 3.0; }
};

int main () {
form const frm_a {blt{1,3},blt{2,6},blt{5,8},blt{4,7}};
cout << "\nfrm_a: " << frm_a;
var_matrix<double> mat_a {sub_matrix_linear (frm_a, 0.0)};
cout << "\nmat_a before: " << mat_a;

vec_si const w {2, null_int, 6, null_int};
var_lens_less_dimen<double> ald_b {mat_a, w};
cout << "\nald_b with marker at (2, null, 6, null): " << ald_b;

ald_b.marker_set (0, 1);
ald_b.marker_set (2, 7);
cout << "\nald_b with marker moved to (1, null, 7, null): " << ald_b;

alone_non_var<triple,double> (ald_b);

cout << "\nald_b after tripling: " << ald_b;
cout << "\nmat_a after tripling: " << mat_a;

return 0;
}
```
yields this output:
```frm_a: ( 1 =< 3, 2 =< 6, 5 =< 8, 4 =< 7 )
mat_a before:
( 1 2 5 4 ) = 0.1254    ( 1 2 5 5 ) = 0.1255    ( 1 2 5 6 ) = 0.1256
( 1 2 6 4 ) = 0.1264    ( 1 2 6 5 ) = 0.1265    ( 1 2 6 6 ) = 0.1266
( 1 2 7 4 ) = 0.1274    ( 1 2 7 5 ) = 0.1275    ( 1 2 7 6 ) = 0.1276
( 1 3 5 4 ) = 0.1354    ( 1 3 5 5 ) = 0.1355    ( 1 3 5 6 ) = 0.1356
( 1 3 6 4 ) = 0.1364    ( 1 3 6 5 ) = 0.1365    ( 1 3 6 6 ) = 0.1366
( 1 3 7 4 ) = 0.1374    ( 1 3 7 5 ) = 0.1375    ( 1 3 7 6 ) = 0.1376
( 1 4 5 4 ) = 0.1454    ( 1 4 5 5 ) = 0.1455    ( 1 4 5 6 ) = 0.1456
( 1 4 6 4 ) = 0.1464    ( 1 4 6 5 ) = 0.1465    ( 1 4 6 6 ) = 0.1466
( 1 4 7 4 ) = 0.1474    ( 1 4 7 5 ) = 0.1475    ( 1 4 7 6 ) = 0.1476
( 1 5 5 4 ) = 0.1554    ( 1 5 5 5 ) = 0.1555    ( 1 5 5 6 ) = 0.1556
( 1 5 6 4 ) = 0.1564    ( 1 5 6 5 ) = 0.1565    ( 1 5 6 6 ) = 0.1566
( 1 5 7 4 ) = 0.1574    ( 1 5 7 5 ) = 0.1575    ( 1 5 7 6 ) = 0.1576
( 2 2 5 4 ) = 0.2254    ( 2 2 5 5 ) = 0.2255    ( 2 2 5 6 ) = 0.2256
( 2 2 6 4 ) = 0.2264    ( 2 2 6 5 ) = 0.2265    ( 2 2 6 6 ) = 0.2266
( 2 2 7 4 ) = 0.2274    ( 2 2 7 5 ) = 0.2275    ( 2 2 7 6 ) = 0.2276
( 2 3 5 4 ) = 0.2354    ( 2 3 5 5 ) = 0.2355    ( 2 3 5 6 ) = 0.2356
( 2 3 6 4 ) = 0.2364    ( 2 3 6 5 ) = 0.2365    ( 2 3 6 6 ) = 0.2366
( 2 3 7 4 ) = 0.2374    ( 2 3 7 5 ) = 0.2375    ( 2 3 7 6 ) = 0.2376
( 2 4 5 4 ) = 0.2454    ( 2 4 5 5 ) = 0.2455    ( 2 4 5 6 ) = 0.2456
( 2 4 6 4 ) = 0.2464    ( 2 4 6 5 ) = 0.2465    ( 2 4 6 6 ) = 0.2466
( 2 4 7 4 ) = 0.2474    ( 2 4 7 5 ) = 0.2475    ( 2 4 7 6 ) = 0.2476
( 2 5 5 4 ) = 0.2554    ( 2 5 5 5 ) = 0.2555    ( 2 5 5 6 ) = 0.2556
( 2 5 6 4 ) = 0.2564    ( 2 5 6 5 ) = 0.2565    ( 2 5 6 6 ) = 0.2566
( 2 5 7 4 ) = 0.2574    ( 2 5 7 5 ) = 0.2575    ( 2 5 7 6 ) = 0.2576
ald_b with marker at (2, null, 6, null):
( 2 4 ) = 0.2264    ( 2 5 ) = 0.2265    ( 2 6 ) = 0.2266
( 3 4 ) = 0.2364    ( 3 5 ) = 0.2365    ( 3 6 ) = 0.2366
( 4 4 ) = 0.2464    ( 4 5 ) = 0.2465    ( 4 6 ) = 0.2466
( 5 4 ) = 0.2564    ( 5 5 ) = 0.2565    ( 5 6 ) = 0.2566
ald_b with marker moved to (1, null, 7, null):
( 2 4 ) = 0.1274    ( 2 5 ) = 0.1275    ( 2 6 ) = 0.1276
( 3 4 ) = 0.1374    ( 3 5 ) = 0.1375    ( 3 6 ) = 0.1376
( 4 4 ) = 0.1474    ( 4 5 ) = 0.1475    ( 4 6 ) = 0.1476
( 5 4 ) = 0.1574    ( 5 5 ) = 0.1575    ( 5 6 ) = 0.1576
ald_b after tripling:
( 2 4 ) = 0.3822    ( 2 5 ) = 0.3825    ( 2 6 ) = 0.3828
( 3 4 ) = 0.4122    ( 3 5 ) = 0.4125    ( 3 6 ) = 0.4128
( 4 4 ) = 0.4422    ( 4 5 ) = 0.4425    ( 4 6 ) = 0.4428
( 5 4 ) = 0.4722    ( 5 5 ) = 0.4725    ( 5 6 ) = 0.4728
mat_a after tripling:
( 1 2 5 4 ) = 0.1254    ( 1 2 5 5 ) = 0.1255    ( 1 2 5 6 ) = 0.1256
( 1 2 6 4 ) = 0.1264    ( 1 2 6 5 ) = 0.1265    ( 1 2 6 6 ) = 0.1266
( 1 2 7 4 ) = 0.3822    ( 1 2 7 5 ) = 0.3825    ( 1 2 7 6 ) = 0.3828
( 1 3 5 4 ) = 0.1354    ( 1 3 5 5 ) = 0.1355    ( 1 3 5 6 ) = 0.1356
( 1 3 6 4 ) = 0.1364    ( 1 3 6 5 ) = 0.1365    ( 1 3 6 6 ) = 0.1366
( 1 3 7 4 ) = 0.4122    ( 1 3 7 5 ) = 0.4125    ( 1 3 7 6 ) = 0.4128
( 1 4 5 4 ) = 0.1454    ( 1 4 5 5 ) = 0.1455    ( 1 4 5 6 ) = 0.1456
( 1 4 6 4 ) = 0.1464    ( 1 4 6 5 ) = 0.1465    ( 1 4 6 6 ) = 0.1466
( 1 4 7 4 ) = 0.4422    ( 1 4 7 5 ) = 0.4425    ( 1 4 7 6 ) = 0.4428
( 1 5 5 4 ) = 0.1554    ( 1 5 5 5 ) = 0.1555    ( 1 5 5 6 ) = 0.1556
( 1 5 6 4 ) = 0.1564    ( 1 5 6 5 ) = 0.1565    ( 1 5 6 6 ) = 0.1566
( 1 5 7 4 ) = 0.4722    ( 1 5 7 5 ) = 0.4725    ( 1 5 7 6 ) = 0.4728
( 2 2 5 4 ) = 0.2254    ( 2 2 5 5 ) = 0.2255    ( 2 2 5 6 ) = 0.2256
( 2 2 6 4 ) = 0.2264    ( 2 2 6 5 ) = 0.2265    ( 2 2 6 6 ) = 0.2266
( 2 2 7 4 ) = 0.2274    ( 2 2 7 5 ) = 0.2275    ( 2 2 7 6 ) = 0.2276
( 2 3 5 4 ) = 0.2354    ( 2 3 5 5 ) = 0.2355    ( 2 3 5 6 ) = 0.2356
( 2 3 6 4 ) = 0.2364    ( 2 3 6 5 ) = 0.2365    ( 2 3 6 6 ) = 0.2366
( 2 3 7 4 ) = 0.2374    ( 2 3 7 5 ) = 0.2375    ( 2 3 7 6 ) = 0.2376
( 2 4 5 4 ) = 0.2454    ( 2 4 5 5 ) = 0.2455    ( 2 4 5 6 ) = 0.2456
( 2 4 6 4 ) = 0.2464    ( 2 4 6 5 ) = 0.2465    ( 2 4 6 6 ) = 0.2466
( 2 4 7 4 ) = 0.2474    ( 2 4 7 5 ) = 0.2475    ( 2 4 7 6 ) = 0.2476
( 2 5 5 4 ) = 0.2554    ( 2 5 5 5 ) = 0.2555    ( 2 5 5 6 ) = 0.2556
( 2 5 6 4 ) = 0.2564    ( 2 5 6 5 ) = 0.2565    ( 2 5 6 6 ) = 0.2566
( 2 5 7 4 ) = 0.2574    ( 2 5 7 5 ) = 0.2575    ( 2 5 7 6 ) = 0.2576
```