#include "tensorstore/index_space/alignment.h"
Result<IndexTransform<>> tensorstore::AlignDomainTo(
    
IndexDomainView<> source,
    
IndexDomainView<> target,
    
DomainAlignmentOptions options = DomainAlignmentOptions::all);

Attempts to align the source domain to match the target domain.

This is used to align dimensions for TensorStore read/write/copy operations.

First, a subset of dimensions of source is matched to a subset of dimensions of target, according to one of two cases:

M1. At least one of source or target is entirely unlabeled (all

dimension labels are empty). In this case, the last match_rank = std::min(source.rank(), target.rank()) dimensions of source match in order to the last match_rank dimensions of target, i.e. dimension source.rank() - match_rank + i of source matches to dimension target.rank() - match_rank + i of target, for 0 <= i < rank. This case also applies if options excludes DomainAlignmentOptions::permute.

M2. Both source and target have at least one labeled dimension. In this

case, dimensions of source and target with matching labels are matched. Any remaining labeled dimensions remain unmatched. The unlabeled dimensions of source are matched to the unlabeled dimensions of target using the same method as in case M1 (right to left).

The matching is then validated as follows:

V1. For each match between a dimension i of source and a dimension

j of target, if source.shape()[i] != target.shape()[j], the match is dropped. Note that if source.shape()[i] != 1, this leads to an error in the following step (V2).

V2. For every unmatched dimension i of source,

source.shape()[i] must equal 1.

If matching succeeds, a new alignment transform with an (input) domain equal to target and an output rank equal to source.rank() is computed as follows:

A1. For each dimension j of target with a matching dimension

i of source, output dimension i of alignment has a OutputIndexMethod::single_input_dimension map to input dimension j with a stride of 1 and offset of source.origin()[i] - target.origin()[j].

A2. For every unmatched dimension i of source, output dimension

i of alignment is a OutputIndexMethod::constant map with an offset of source.origin()[i]. (It must be the case that source.shape()[i] == 1.)

The return value is alignment.

Examples (input dimensions refer to dimensions of target, while output dimensions refer to dimensions of source):

All unlabeled dimensions:

  • source: [3, 7), [5, 6), [4, 10)

  • target: [2, 6), [0, 4), [6, 12)

  • alignment: rank 3 -> 3, with:

    • output dimension 0 -> input dimension 0, offset 1

    • output dimension 1 -> constant 5

    • output dimension 2 -> input dimension 2, offset -2

All labeled dimensions:

  • source: "x": [3, 7), "y": [5, 6), "z": [4, 10)

  • target: "z": [6, 12), "x": [4, 8), "y": [0, 4)

  • alignment: rank 3 -> 3, with:

    • output dimension 0 -> input dimension 1, offset -1

    • output dimension 1 -> constant 5

    • output dimension 2 -> input dimension 0, offset -2

Partially labeled dimensions:

  • source: "x": [3, 7), "y": [5, 6), "": [4, 10)

  • target: "": [0, 10) "": [6, 12), "x": [4, 8), "y": [0, 4)

  • alignment: rank 4 -> 3, with:

    • output dimension 0 -> input dimension 2, offset -1

    • output dimension 1 -> constant 5

    • output dimension 2 -> input dimension 1, offset -2

Mismatched labeled dimensions:

  • source: "x": [3, 7), "y": [5, 6), "z": [4, 10)

  • target: "z": [6, 12), "w": [4, 8), "y": [0, 4)

  • ERROR: Unmatched source dimension 0 {"x": [3, 7)} does not have a size of 1

Parameters:
IndexDomainView<> source

The source domain.

IndexDomainView<> target

The target domain to which source should be aligned.

DomainAlignmentOptions options = DomainAlignmentOptions::all

Specifies the transformations that are permitted. By default, all transformations (permutation, translation, broadcasting) are permitted.