Added Java+JNI support for surrogate reorderings.

This commit is contained in:
Pedro Martinez Mediano 2017-05-23 16:19:33 +10:00
parent 4a31d3d7f1
commit 492cfe8b53
2 changed files with 75 additions and 10 deletions

View File

@ -601,7 +601,8 @@ public abstract class MutualInfoCalculatorMultiVariateKraskov
* to the GPU code.
*/
protected double[] gpuComputeFromObservations(int startTimePoint,
int numTimePoints, boolean returnLocals, int nb_surrogates) throws Exception {
int numTimePoints, boolean returnLocals, int nb_surrogates,
int[][] newOrderings) throws Exception {
if (debug) {
System.out.println("Start GPU calculation");
@ -622,8 +623,12 @@ public abstract class MutualInfoCalculatorMultiVariateKraskov
double[] res;
try {
if (debug) {
System.out.printf("Calling GPU calculation with returnLocals=%b and nb_surrogates=%d\n", returnLocals, nb_surrogates);
}
res = MIKraskov(totalObservations, sourceObservations, dimensionsSource,
destObservations, dimensionsDest, k, returnLocals, useMaxNorm, isAlgorithm1, nb_surrogates);
destObservations, dimensionsDest, k, returnLocals, useMaxNorm,
isAlgorithm1, nb_surrogates, null!=newOrderings, newOrderings);
if (debug) {
System.out.println("GPU calculation finished successfully. Returning results");
}
@ -642,7 +647,16 @@ public abstract class MutualInfoCalculatorMultiVariateKraskov
*/
protected double[] gpuComputeFromObservations(int startTimePoint,
int numTimePoints, boolean returnLocals) throws Exception {
return gpuComputeFromObservations(startTimePoint, numTimePoints, returnLocals, 0);
return gpuComputeFromObservations(startTimePoint, numTimePoints, returnLocals, 0, null);
}
/**
* FIXME
*/
protected double[] gpuComputeFromObservations(int startTimePoint,
int numTimePoints, boolean returnLocals, int[][] newOrderings) throws Exception {
return gpuComputeFromObservations(startTimePoint, numTimePoints,
returnLocals, newOrderings.length, newOrderings);
}
/**
@ -651,7 +665,7 @@ public abstract class MutualInfoCalculatorMultiVariateKraskov
private native double[] MIKraskov(
int N, double[][] source, int dimx, double[][] dest, int dimy,
int k, boolean returnLocals, boolean useMaxNorm, boolean isAlgorithm1,
int nb_surrogates);
int nb_surrogates, boolean orderingsGiven, int[][] newOrderings);
/**
* Internal method to ensure that the Kd-tree data structures to represent the
@ -738,13 +752,28 @@ public abstract class MutualInfoCalculatorMultiVariateKraskov
public EmpiricalMeasurementDistribution computeSignificance(int numPermutationsToCheck)
throws Exception {
if (useGPU) {
double[] res = gpuComputeFromObservations(0, totalObservations, false, numPermutationsToCheck);
double[] res = gpuComputeFromObservations(0, totalObservations, false, numPermutationsToCheck, null);
return new EmpiricalMeasurementDistribution(
MatrixUtils.select(res, 1, res.length - 1), res[0]);
} else {
return super.computeSignificance(numPermutationsToCheck);
}
}
/**
* {@inheritDoc}
*/
@Override
public EmpiricalMeasurementDistribution computeSignificance(int[][] newOrderings)
throws Exception {
if (useGPU) {
double[] res = gpuComputeFromObservations(0, totalObservations, false, newOrderings.length, newOrderings);
return new EmpiricalMeasurementDistribution(
MatrixUtils.select(res, 1, res.length - 1), res[0]);
} else {
return super.computeSignificance(newOrderings);
}
}
/**
* Compute the prediction error in one variable from the k nearest neighbours (kNNs) of the observation

View File

@ -12,7 +12,7 @@ extern "C" {
/*
* Class: infodynamics_measures_continuous_kraskov_MutualInfoCalculatorMultiVariateKraskov
* Method: MIKraskov
* Signature: (I[DI[DIIZZZI)[D
* Signature: (I[DI[DIIZZZIZ[I)[D
*/
JNIEXPORT jdoubleArray JNICALL
Java_infodynamics_measures_continuous_kraskov_MutualInfoCalculatorMultiVariateKraskov_MIKraskov(
@ -20,7 +20,8 @@ JNIEXPORT jdoubleArray JNICALL
jobjectArray j_sourceArray, jint j_dimx,
jobjectArray j_destArray, jint j_dimy,
jint j_k, jboolean j_returnLocals, jboolean j_useMaxNorm,
jboolean j_isAlgorithm1, jint j_nbSurrogates) {
jboolean j_isAlgorithm1, jint j_nbSurrogates,
jboolean j_reorderingsGiven, jobjectArray j_orderings) {
int thelier = 0;
@ -55,6 +56,7 @@ JNIEXPORT jdoubleArray JNICALL
int useMaxNorm = j_useMaxNorm ? 1 : 0;
int isAlgorithm1 = j_isAlgorithm1 ? 1 : 0;
int nb_surrogates = j_nbSurrogates;
int reorderingsGiven = j_reorderingsGiven ? 1 : 0;
float *source = (float *) malloc(N * dimx * sizeof(float));
float *dest = (float *) malloc(N * dimy * sizeof(float));
@ -110,6 +112,24 @@ JNIEXPORT jdoubleArray JNICALL
}
int **reorderings = NULL;
if (reorderingsGiven) {
reorderings = (int **) malloc(nb_surrogates * sizeof(int *));
for (int i = 0; i < nb_surrogates; i++) {
jintArray j_order = (jdoubleArray) (*env)->GetObjectArrayElement(env, j_orderings, i);
jint *order = (*env)->GetIntArrayElements(env, j_order, NULL);
reorderings[i] = (int *) malloc(N * sizeof(int));
for (int j = 0; j < N; j++) {
reorderings[i][j] = order[j];
}
(*env)->ReleaseIntArrayElements(env, j_order, order, 0);
(*env)->DeleteLocalRef(env, j_order);
}
}
// Call C function
// =========================
@ -122,9 +142,18 @@ JNIEXPORT jdoubleArray JNICALL
resultSize = 3;
}
float *result = (float *) malloc(resultSize * sizeof(float));
jidt_error_t ret = MIKraskov_C(N, source, dimx, dest, dimy,
k, thelier, nb_surrogates, returnLocals, useMaxNorm,
isAlgorithm1, result);
jidt_error_t ret;
if (!reorderingsGiven) {
ret = MIKraskov_C(N, source, dimx, dest, dimy,
k, thelier, nb_surrogates, returnLocals, useMaxNorm,
isAlgorithm1, result);
} else {
ret = MIKraskovWithReorderings(N, source, dimx, dest, dimy, k, thelier,
nb_surrogates, returnLocals, useMaxNorm,
isAlgorithm1, result, reorderingsGiven,
reorderings);
}
if (JIDT_ERROR == ret) {
jclass Exception = (*env)->FindClass(env, "java/lang/Exception");
@ -136,6 +165,13 @@ JNIEXPORT jdoubleArray JNICALL
if (source) free(source);
if (dest) free(dest);
if (reorderingsGiven) {
for (int i = 0; i < nb_surrogates; i++) {
if (reorderings[i]) free(reorderings[i]);
}
if (reorderings) free (reorderings);
}
jdouble outCArray[resultSize];
for (int i = 0; i < resultSize; i++) {
outCArray[i] = result[i];