HyperslabIndex.java
/*
* Copyright (C) 2020 Matteo Di Giovinazzo
*
* Licensed either under the Apache License, Version 2.0, or (at your option)
* under the terms of the GNU General Public License as published by
* the Free Software Foundation (subject to the "Classpath" exception),
* either version 2, or any later version (collectively, the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.gnu.org/licenses/
* http://www.gnu.org/software/classpath/license.html
*
* or as provided in the LICENSE.txt file that accompanied this code.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.bytedeco.javacpp.indexer;
/**
* A hyperslab is a rectangular pattern defined by four arrays.
* <p>
* The {@code start} defines the origin of the hyperslab in the original coordinates.
* The {@code stride} is the number of elements to increment between selected elements.
* A stride of '1' is every element, a stride of '2' is every second element, etc.
* The default stride is 1.
* The {@code count} is the number of elements in the hyperslab selection.
* When the stride is 1, the selection is a hyper rectangle with a corner at {@code start}
* and size {@code count[0]} by {@code count[1]} by ...
* When stride is greater than one, the hyperslab bounded by start and the corners
* defined by {@code stride[n] * count[n]}.
* The {@code block} is a count on the number of repetitions of the hyperslab.
* The default block size is '1', which is one hyperslab. A block of 2 would be
* two hyperslabs in that dimension, with the second starting at {@code start[n]+ (count[n] * stride[n]) + 1}.
*
* @author Matteo Di Giovinazzo
* @see <a href="https://portal.hdfgroup.org/display/HDF5/Reading+From+or+Writing+To+a+Subset+of+a+Dataset">Reading From
* or Writing To a Subset of a Dataset</a>
* @see <a href="https://portal.hdfgroup.org/display/HDF5/H5S_SELECT_HYPERSLAB">H5S_SELECT_HYPERSLAB</a>
* @see <a href="https://support.hdfgroup.org/HDF5/doc1.6/UG/12_Dataspaces.html">Dataspaces</a>
*/
public class HyperslabIndex extends StrideIndex {
protected long[] selectionOffsets;
protected long[] selectionStrides;
protected long[] selectionCounts;
protected long[] selectionBlocks;
/** Calls {@code HyperslabIndex(sizes, defaultStrides(sizes), selectionOffsets, selectionStrides, selectionCounts, selectionBlocks)}. */
public HyperslabIndex(long[] sizes, long[] selectionOffsets, long[] selectionStrides,
long[] selectionCounts, long[] selectionBlocks) {
this(sizes, defaultStrides(sizes), selectionOffsets, selectionStrides, selectionCounts, selectionBlocks);
}
/** Constructor to set the {@link #sizes}, {@link #strides}, {@link #selectionOffsets}, {@link #selectionStrides},
* {@link #selectionCounts}, and {@link #selectionBlocks}. Also updates the {@link #sizes} for the resulting selection. */
public HyperslabIndex(long[] sizes, long[] strides, long[] selectionOffsets, long[] selectionStrides,
long[] selectionCounts, long[] selectionBlocks) {
super(sizes, strides);
this.selectionOffsets = selectionOffsets;
this.selectionStrides = selectionStrides;
this.selectionCounts = selectionCounts;
this.selectionBlocks = selectionBlocks;
for (int i = 0; i < selectionCounts.length; i++) {
this.sizes[i] = selectionCounts[i] * selectionBlocks[i];
}
}
@Override
public long index(long i) {
return (selectionOffsets[0] + selectionStrides[0] * (i / selectionBlocks[0]) + (i % selectionBlocks[0])) * strides[0];
}
@Override
public long index(long i, long j) {
return (selectionOffsets[0] + selectionStrides[0] * (i / selectionBlocks[0]) + (i % selectionBlocks[0])) * strides[0]
+ (selectionOffsets[1] + selectionStrides[1] * (j / selectionBlocks[1]) + (j % selectionBlocks[1])) * strides[1];
}
@Override
public long index(long i, long j, long k) {
return (selectionOffsets[0] + selectionStrides[0] * (i / selectionBlocks[0]) + (i % selectionBlocks[0])) * strides[0]
+ (selectionOffsets[1] + selectionStrides[1] * (j / selectionBlocks[1]) + (j % selectionBlocks[1])) * strides[1]
+ (selectionOffsets[2] + selectionStrides[2] * (k / selectionBlocks[2]) + (k % selectionBlocks[2])) * strides[2];
}
@Override
public long index(long... indices) {
long index = 0;
for (int i = 0; i < indices.length; i++) {
long coordinate = indices[i];
long mappedCoordinate = selectionOffsets[i] + selectionStrides[i] * (coordinate / selectionBlocks[i]) + (coordinate % selectionBlocks[i]);
index += mappedCoordinate * strides[i];
}
return index;
}
}