jep.NDArray Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jep Show documentation
Show all versions of jep Show documentation
Jep embeds CPython in Java through JNI.
/**
* Copyright (c) 2017 JEP AUTHORS.
*
* This file is licensed under the the zlib/libpng License.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
package jep;
import java.lang.reflect.Array;
import java.util.Arrays;
/**
*
* Represents a numpy.ndarray in Java. If Jep was compiled with numpy support, this
* object will not be wrapped as a PyJobject in the Python
* sub-interpreter(s), it will instead be transformed into a numpy.ndarray
* automatically (and vice versa). The transformation in either direction occurs
* with a memcpy
, therefore changes in the array in one language
* will not affect the array in the other language.
*
*
*
* NDArrays only support Java primitive arrays as the underlying type of data.
* The data can conceptually be multi-dimensional, but it must be represented as
* a one-dimensional array in Java to ensure the memory is contiguous.
*
*
*
* @author Nate Jensen
*
* @since 3.3
*/
public class NDArray extends AbstractNDArray {
/**
* Constructor for a Java NDArray. Presumes the data is one dimensional.
*
* @param data
* a one-dimensional primitive array such as float[], int[]
*/
public NDArray(T data) {
super(data);
}
/**
* Constructor for a Java NDArray. Presumes the data is one dimensional.
*
* @param data
* a one-dimensional primitive array such as float[], int[]
* @param unsigned
* whether the data is to be interpreted as unsigned
*/
public NDArray(T data, boolean unsigned) {
super(data, unsigned);
}
/**
* Constructor for a Java NDArray.
*
* @param data
* a one-dimensional primitive array such as float[], int[]
* @param dimensions
* the conceptual dimensions of the data (corresponds to the
* numpy.ndarray dimensions in C-contiguous order)
*/
public NDArray(T data, int... dimensions) {
super(data, dimensions);
}
/**
* Constructor for a Java NDArray.
*
* @param data
* a one-dimensional primitive array such as float[], int[]
* @param unsigned
* whether the data is to be interpreted as unsigned
* @param dimensions
* the conceptual dimensions of the data (corresponds to the
* numpy.ndarray dimensions in C-contiguous order)
*/
public NDArray(T data, boolean unsigned, int... dimensions) {
super(data, unsigned, dimensions);
}
@Override
protected void validate(T data) {
/*
* java generics don't give us a nice Class that all the primitive
* arrays extend, so we must enforce the type safety at runtime instead
* of compile time
*/
if (!data.getClass().isArray()
|| !data.getClass().getComponentType().isPrimitive()) {
throw new IllegalArgumentException(
"NDArray only supports primitive arrays, received "
+ data.getClass().getName());
} else if (data instanceof char[]) {
throw new IllegalArgumentException(
"NDArray only supports numeric primitives, not char[]");
}
}
@Override
protected int getLength(T data) {
return Array.getLength(data);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
NDArray> other = (NDArray>) obj;
// unsigned should be same
if (this.unsigned != other.unsigned) {
return false;
}
/*
* compare dimensions first cause that's most likely a shorter array to
* compare and will be faster
*/
if (!Arrays.equals(dimensions, other.dimensions)) {
return false;
}
// compare the data
if (other.data == null) {
return false;
}
// neither has null, let's compare values
if (!data.getClass().equals(other.data.getClass())) {
return false;
}
Class> clz = data.getClass().getComponentType();
if (clz == Boolean.TYPE) {
return Arrays.equals((boolean[]) data, (boolean[]) other.data);
} else if (clz == Byte.TYPE) {
return Arrays.equals((byte[]) data, (byte[]) other.data);
} else if (clz == Short.TYPE) {
return Arrays.equals((short[]) data, (short[]) other.data);
} else if (clz == Integer.TYPE) {
return Arrays.equals((int[]) data, (int[]) other.data);
} else if (clz == Long.TYPE) {
return Arrays.equals((long[]) data, (long[]) other.data);
} else if (clz == Float.TYPE) {
return Arrays.equals((float[]) data, (float[]) other.data);
} else if (clz == Double.TYPE) {
return Arrays.equals((double[]) data, (double[]) other.data);
} else {
// should be impossible to get here
throw new IllegalStateException(
"NDArray only supports primitive arrays, received "
+ clz.getName());
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
if (data == null) {
result = prime * result + 0;
} else {
Class> clz = data.getClass().getComponentType();
if (clz == Boolean.TYPE) {
result = prime * result + Arrays.hashCode((boolean[]) data);
} else if (clz == Byte.TYPE) {
result = prime * result + Arrays.hashCode((byte[]) data);
} else if (clz == Short.TYPE) {
result = prime * result + Arrays.hashCode((short[]) data);
} else if (clz == Integer.TYPE) {
result = prime * result + Arrays.hashCode((int[]) data);
} else if (clz == Long.TYPE) {
result = prime * result + Arrays.hashCode((long[]) data);
} else if (clz == Float.TYPE) {
result = prime * result + Arrays.hashCode((float[]) data);
} else if (clz == Double.TYPE) {
result = prime * result + Arrays.hashCode((double[]) data);
} else {
// should be impossible to get here
throw new IllegalStateException(
"NDArray only supports primitive arrays, received "
+ clz.getName());
}
}
result = prime * result + Arrays.hashCode(dimensions)
+ (unsigned ? 1 : 0);
return result;
}
// TODO override toString() to make it look like ndarray.__str__()
}