Chapter IV.5. Bringing multiple selectors together

Table of Contents

IV.5.1. Composition
IV.5.2. Tensorization

IV.5.1. Composition

Selector composition means that multiple selectors are applied in a sequential way, each one being used as input to the next. As we have already seen, this behavior can be achieved manually, simply by constructing the selectors one after the other, for exemple thanks to the select template function:

					item1_type item1;
					item2_type item2;
					result_of::select<result_of::select<a1_type,item1_type>::type,item2_type>::type a3 = select(select(a1,item1),item2);
				

However, in some cases, it is preferable to obtain the same result with only one call to select. This is done by passing a composite_item, which can be constructed by calling the compose_items template function as follows:

					typedef result_of::compose_items<item1_type,item2_type>::type item_type;
					result_of::select<a1_type,item_type>::type a3 = select(a1,compose_items(item1,item2));
				

IV.5.2. Tensorization

For arrays having a dimension higher than one, it can be useful to obtain a selection in certain directions, coupled with a possibly different kind of selection in the remaining directions. For example, this would allow iteration through only the first half in one out of two columns of a matrix, as with the Matlab syntax:

					A(1:2:end,1:fix(end/2));
				

In the SPAL this kind of behavior is supported via the tensorized_selector mechanism. The specification of the associated tensorized_item is as follows.

Template parameters :

class FirstItem The type of item describing the first selector.
rank_t first_rank The number of leading directions in the input array to which the first selector will be applied.
class SecondItem The type of item describing the second selector.

Public members and typedefs:

FirstItem first The first item.
SecondItem second The second item.

Now the behavior mentioned in the above example is obtained by doing:

						typedef cartesian::subsample_item item1_type;
						typedef cartesian::subregion_item<0u> item2_type;
						typedef tensorized_item<item1_type,1,item2_type> item_type;
						size_t N2 = a1.domain()[1]; 
						result_of::select<a1_type,item_type>::type a2 = select(a1,item_type(item1_type(2),item2_type(N2/2));
					

A tensorized_item can also be conveniently constructed using the tensorize_items template function:

						template<rank_t first_rank, class FirstItem, class SecondItem>
						result_of::tensorize_items<first_rank,FirstItem,SecondItem>::type 
						tensorize_items(const FirstItem&, const SecondItem&);