Skip to content

Commit

Permalink
bytedeco#391 Move out Index as an interface and separate a `Default…
Browse files Browse the repository at this point in the history
…Index` and a `CustomStridesIndex` to keep the previous logic
  • Loading branch information
matteodg committed Apr 19, 2020
1 parent 01b234a commit ff2ec4c
Show file tree
Hide file tree
Showing 5 changed files with 228 additions and 45 deletions.
76 changes: 76 additions & 0 deletions src/main/java/org/bytedeco/javacpp/indexer/CustomStridesIndex.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright (C) 2016-2019 Samuel Audet
*
* 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;

/**
* TODO
*
* @author Matteo Di Giovinazzo
*/
public class CustomStridesIndex implements Index {

protected final long[] strides;

/**
* TODO
*
* @param strides The number of elements to skip to reach the next element in a given dimension.
* {@code strides[i] > strides[i + 1] && strides[strides.length - 1] == 1} preferred.
*/
protected CustomStridesIndex(long[] strides) {
this.strides = strides;
}

public static Index customStrides(long[] strides) {
return new CustomStridesIndex(strides);
}

@Override
public long index(long i) {
return i * strides[0];
}

@Override
public long index(long i, long j) {
return i * strides[0] + j * strides[1];
}

@Override
public long index(long i, long j, long k) {
return i * strides[0] + j * strides[1] + k * strides[2];
}

/**
* Computes the linear index as the dot product of indices and strides.
*
* @param indices of each dimension
* @return index to access array or buffer
*/
@Override
public long index(long... indices) {
long index = 0;
for (int i = 0; i < indices.length && i < strides.length; i++) {
index += indices[i] * strides[i];
}
return index;
}
}
51 changes: 51 additions & 0 deletions src/main/java/org/bytedeco/javacpp/indexer/DefaultIndex.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright (C) 2016-2019 Samuel Audet
*
* 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;

/**
* TODO
*
* @author Matteo Di Giovinazzo
*/
public class DefaultIndex extends CustomStridesIndex {

protected DefaultIndex(long... sizes) {
super(strides(sizes));
}

public static Index defaultIndex(long[] sizes) {
return new DefaultIndex(sizes);
}

/**
* Returns default (row-major contiguous) strides for the given sizes.
*/
public static long[] strides(long... sizes) {
long[] strides = new long[sizes.length];
strides[sizes.length - 1] = 1;
for (int i = sizes.length - 2; i >= 0; i--) {
strides[i] = strides[i + 1] * sizes[i + 1];
}
return strides;
}

}
66 changes: 66 additions & 0 deletions src/main/java/org/bytedeco/javacpp/indexer/Index.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright (C) 2016-2019 Samuel Audet
*
* 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;

/**
* TODO
*
* @author Matteo Di Giovinazzo
*/
public interface Index {

/**
* TODO
*
* @param i
* @return
*/
long index(long i);

/**
* TODO
*
* @param i
* @param j
* @return
*/
long index(long i, long j);

/**
* TODO
*
* @param i
* @param j
* @param k
* @return
*/
long index(long i, long j, long k);

/**
* TODO
*
* @param indices
* @return
*/
long index(long... indices);

}
75 changes: 32 additions & 43 deletions src/main/java/org/bytedeco/javacpp/indexer/Indexer.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@

package org.bytedeco.javacpp.indexer;

import java.nio.Buffer;
import org.bytedeco.javacpp.Pointer;

import java.nio.Buffer;

import static org.bytedeco.javacpp.indexer.CustomStridesIndex.customStrides;
import static org.bytedeco.javacpp.indexer.DefaultIndex.defaultIndex;

/**
* Top-level class of all data indexers, providing easy-to-use and efficient
* multidimensional access to primitive arrays, NIO buffers, and the raw memory interface.
Expand All @@ -49,7 +53,7 @@ public abstract class Indexer implements AutoCloseable {
release();
}

protected static final long[] ONE_STRIDE = { 1 };
@Deprecated protected static final long[] ONE_STRIDE = { 1 };

/**
* The number of elements in each dimension.
Expand All @@ -60,23 +64,42 @@ public abstract class Indexer implements AutoCloseable {
* The number of elements to skip to reach the next element in a given dimension.
* {@code strides[i] > strides[i + 1] && strides[strides.length - 1] == 1} preferred.
*/
protected long[] strides;
@Deprecated protected long[] strides;
/**
* TODO
*/
protected Index index;

/** Constructor to set the {@link #sizes}. */
protected Indexer(long[] sizes) {
this(sizes, defaultIndex(sizes));
// XXX: access to strides for backward compatiility
assert index instanceof DefaultIndex;
this.strides = ((DefaultIndex) index).strides;
}

/** Constructor to set the {@link #sizes} and {@link #strides}. */
protected Indexer(long[] sizes, long[] strides) {
/** Constructor to set the {@link #sizes} and {@link #index}. */
protected Indexer(long[] sizes, Index index) {
this.sizes = sizes;
this.index = index;
// XXX: what value should have strides in this case?
}

/** Constructor to set the {@link #sizes} and {@link #strides}. */
@Deprecated protected Indexer(long[] sizes, long[] strides) {
this(sizes, customStrides(strides));
this.strides = strides;
}

/** Returns {@link #sizes} */
public long[] sizes() { return sizes; }
/** Returns {@link #strides} */
public long[] strides() { return strides; }
@Deprecated public long[] strides() { return strides; }

/** Returns {@code sizes[i]} */
public long size(int i) { return sizes[i]; }
/** Returns {@code strides[i]} */
public long stride(int i) { return strides[i]; }
@Deprecated public long stride(int i) { return strides[i]; }

/** Returns {@code sizes.length > 0 && sizes.length < 4 ? sizes[0] : -1} */
@Deprecated public long rows() { return sizes.length > 0 && sizes.length < 4 ? sizes[0] : -1; }
Expand All @@ -99,45 +122,11 @@ protected static final long checkIndex(long i, long size) {
/**
* Returns default (row-major contiguous) strides for the given sizes.
*/
@Deprecated
public static long[] strides(long... sizes) {
long[] strides = new long[sizes.length];
strides[sizes.length - 1] = 1;
for (int i = sizes.length - 2; i >= 0; i--) {
strides[i] = strides[i + 1] * sizes[i + 1];
}
return strides;
return DefaultIndex.strides(sizes);
}

protected class Index {
public long index(long i) {
return i * strides[0];
}

public long index(long i, long j) {
return i * strides[0] + j * strides[1];
}

public long index(long i, long j, long k) {
return i * strides[0] + j * strides[1] + k * strides[2];
}

/**
* Computes the linear index as the dot product of indices and strides.
*
* @param indices of each dimension
* @return index to access array or buffer
*/
public long index(long... indices) {
long index = 0;
for (int i = 0; i < indices.length && i < strides.length; i++) {
index += indices[i] * strides[i];
}
return index;
}
}

protected Index index = new Index();

/** Returns {@code index.index(i)}. */
public long index(long i) {
return index.index(i);
Expand Down
5 changes: 3 additions & 2 deletions src/test/java/org/bytedeco/javacpp/IndexerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.bytedeco.javacpp.indexer.UShortIndexer;
import org.bytedeco.javacpp.indexer.UIntIndexer;
import org.bytedeco.javacpp.indexer.ULongIndexer;
import org.bytedeco.javacpp.indexer.DefaultIndex;
import org.bytedeco.javacpp.tools.Builder;
import org.junit.AfterClass;
import org.junit.BeforeClass;
Expand Down Expand Up @@ -74,7 +75,7 @@ public class IndexerTest {
}

static class TestIndexer extends Indexer {
TestIndexer(long[] sizes) { super(sizes, Indexer.strides(sizes)); }
TestIndexer(long[] sizes) { super(sizes, DefaultIndex.strides(sizes)); }
public void release() { }
public double getDouble(long... indices) { return 0; }
public Indexer putDouble(long[] indices, double value) { return this; }
Expand All @@ -83,7 +84,7 @@ public void release() { }
@Test public void testIndexer() {
System.out.println("Indexer");
long[] sizes = {640, 480, 3};
long[] strides = Indexer.strides(sizes);
long[] strides = DefaultIndex.strides(sizes);
System.out.println(Arrays.toString(strides));
assertEquals(1440, strides[0]);
assertEquals( 3, strides[1]);
Expand Down

0 comments on commit ff2ec4c

Please sign in to comment.