mirror of https://github.com/jlizier/jidt
1389 lines
36 KiB
C++
1389 lines
36 KiB
C++
#include <iostream>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include "lest.hpp"
|
|
|
|
#include "gpuKnnLibrary.h"
|
|
#include "gpuMILibrary.h"
|
|
#include "gpuCMILibrary.h"
|
|
#include "digamma.h"
|
|
|
|
using lest::approx;
|
|
|
|
const lest::test specification[] = {
|
|
|
|
CASE("Basic kNN test in 1D")
|
|
{
|
|
int thelier = 0;
|
|
int useMaxNorm = 1;
|
|
int N = 4;
|
|
int dims = 1;
|
|
int k = 1;
|
|
int nchunks = 1;
|
|
int indexes[4];
|
|
float distances[4];
|
|
float pointset[4] = {-1, -1.2, 1, 1.1};
|
|
|
|
int err = cudaFindKnn(indexes, distances, pointset, pointset, k, thelier,
|
|
nchunks, dims, N, useMaxNorm);
|
|
|
|
EXPECT(err == 1);
|
|
|
|
EXPECT(indexes[0] == 1);
|
|
EXPECT(indexes[1] == 0);
|
|
EXPECT(indexes[2] == 3);
|
|
EXPECT(indexes[3] == 2);
|
|
|
|
EXPECT(distances[0] == approx(0.2));
|
|
EXPECT(distances[1] == approx(0.2));
|
|
EXPECT(distances[2] == approx(0.1));
|
|
EXPECT(distances[3] == approx(0.1));
|
|
|
|
},
|
|
|
|
CASE("Basic kNN test in 2D")
|
|
{
|
|
int thelier = 0;
|
|
int useMaxNorm = 1;
|
|
int N = 4;
|
|
int dims = 2;
|
|
int k = 1;
|
|
int nchunks = 1;
|
|
int indexes[4];
|
|
float distances[4];
|
|
float pointset[8] = {-1, 0.5, 1.1, 2,
|
|
-1, 0.5, 1.1, 2};
|
|
|
|
int err = cudaFindKnn(indexes, distances, pointset, pointset, k, thelier,
|
|
nchunks, dims, N, useMaxNorm);
|
|
|
|
EXPECT(err == 1);
|
|
|
|
EXPECT(indexes[0] == 1);
|
|
EXPECT(indexes[1] == 2);
|
|
EXPECT(indexes[2] == 1);
|
|
EXPECT(indexes[3] == 2);
|
|
|
|
EXPECT(distances[0] == approx(1.5));
|
|
EXPECT(distances[1] == approx(0.6));
|
|
EXPECT(distances[2] == approx(0.6));
|
|
EXPECT(distances[3] == approx(0.9));
|
|
|
|
},
|
|
|
|
CASE("Basic kNN test with L2 norm")
|
|
{
|
|
int thelier = 0;
|
|
int useMaxNorm = 0;
|
|
int N = 4;
|
|
int dims = 2;
|
|
int k = 1;
|
|
int nchunks = 1;
|
|
int indexes[4];
|
|
float distances[4];
|
|
|
|
// Points: X Y
|
|
// -1 -1
|
|
// 0.5 0.5
|
|
// 1.1 1.1
|
|
// 2 2
|
|
|
|
float pointset[8] = {-1, 0.5, 1.1, 2,
|
|
-1, 0.5, 1.1, 2};
|
|
|
|
int err = cudaFindKnn(indexes, distances, pointset, pointset, k, thelier,
|
|
nchunks, dims, N, useMaxNorm);
|
|
|
|
EXPECT(err == 1);
|
|
|
|
EXPECT(indexes[0] == 1);
|
|
EXPECT(indexes[1] == 2);
|
|
EXPECT(indexes[2] == 1);
|
|
EXPECT(indexes[3] == 2);
|
|
|
|
EXPECT(distances[0] == approx(4.5));
|
|
EXPECT(distances[1] == approx(0.72));
|
|
EXPECT(distances[2] == approx(0.72));
|
|
EXPECT(distances[3] == approx(1.62));
|
|
|
|
},
|
|
|
|
CASE("Test kNN test with longer sequences")
|
|
{
|
|
int thelier = 0;
|
|
int useMaxNorm = 0;
|
|
int N = 10;
|
|
int dims = 2;
|
|
int k = 1;
|
|
int nchunks = 1;
|
|
int indexes[10];
|
|
float distances[10];
|
|
// This is the same sequence as in the previous test case, padded with a
|
|
// bunch of points very far away.
|
|
float pointset[20] = {-1, 0.5, 1.1, 2, 10, 11, 10.5, -100, -50, 666,
|
|
-1, 0.5, 1.1, 2, 98, -9, -200, 45.3, -53, 0.1};
|
|
|
|
int err = cudaFindKnn(indexes, distances, pointset, pointset, k, thelier,
|
|
nchunks, dims, N, useMaxNorm);
|
|
|
|
EXPECT(err == 1);
|
|
|
|
EXPECT(indexes[0] == 1);
|
|
EXPECT(indexes[1] == 2);
|
|
EXPECT(indexes[2] == 1);
|
|
EXPECT(indexes[3] == 2);
|
|
|
|
EXPECT(distances[0] == approx(4.5));
|
|
EXPECT(distances[1] == approx(0.72));
|
|
EXPECT(distances[2] == approx(0.72));
|
|
EXPECT(distances[3] == approx(1.62));
|
|
|
|
},
|
|
|
|
CASE("Smoke kNN test with big random dataset")
|
|
{
|
|
int thelier = 0;
|
|
int useMaxNorm = 1;
|
|
int N = 1000;
|
|
int dims = 5;
|
|
int k = 4;
|
|
int nchunks = 1;
|
|
int *indexes = (int *) malloc(N * k * sizeof(int));
|
|
float *distances = (float *) malloc(N * k * sizeof(float));
|
|
float *pointset = (float *) malloc(N * dims * sizeof(float));
|
|
|
|
int err = cudaFindKnn(indexes, distances, pointset, pointset, k, thelier,
|
|
nchunks, dims, N, useMaxNorm);
|
|
|
|
free(indexes); free(distances); free(pointset);
|
|
|
|
EXPECT(err == 1);
|
|
|
|
},
|
|
|
|
CASE("Test kNN with two trials in the same call")
|
|
{
|
|
int thelier = 0;
|
|
int useMaxNorm = 1;
|
|
int N = 4;
|
|
int dims = 1;
|
|
int k = 1;
|
|
int nchunks = 2;
|
|
int signalLength = N*nchunks;
|
|
int indexes[8];
|
|
float distances[8];
|
|
float pointset[8] = {5, 6, -5, -7,
|
|
50, -50, 60, -70};
|
|
|
|
int err = cudaFindKnn(indexes, distances, pointset, pointset, k, thelier,
|
|
nchunks, dims, signalLength, useMaxNorm);
|
|
|
|
EXPECT(err == 1);
|
|
|
|
EXPECT(indexes[0] == 1);
|
|
EXPECT(indexes[1] == 0);
|
|
EXPECT(indexes[2] == 3);
|
|
EXPECT(indexes[3] == 2);
|
|
EXPECT(indexes[4] == 2);
|
|
EXPECT(indexes[5] == 3);
|
|
EXPECT(indexes[6] == 0);
|
|
EXPECT(indexes[7] == 1);
|
|
|
|
EXPECT(distances[0] == approx(1));
|
|
EXPECT(distances[1] == approx(1));
|
|
EXPECT(distances[2] == approx(2));
|
|
EXPECT(distances[3] == approx(2));
|
|
EXPECT(distances[4] == approx(10));
|
|
EXPECT(distances[5] == approx(20));
|
|
EXPECT(distances[6] == approx(10));
|
|
EXPECT(distances[7] == approx(20));
|
|
|
|
},
|
|
|
|
CASE("Test kNN with three trials in the same call")
|
|
{
|
|
int thelier = 0;
|
|
int useMaxNorm = 1;
|
|
int N = 4;
|
|
int dims = 1;
|
|
int k = 1;
|
|
int nchunks = 3;
|
|
int signalLength = N*nchunks;
|
|
int indexes[12];
|
|
float distances[12];
|
|
float pointset[12] = { 5, 6, -5, -7,
|
|
50, -50, 60, -70,
|
|
500, -500, 600, -700};
|
|
|
|
int err = cudaFindKnn(indexes, distances, pointset, pointset, k, thelier,
|
|
nchunks, dims, signalLength, useMaxNorm);
|
|
|
|
EXPECT(err == 1);
|
|
|
|
EXPECT(indexes[0] == 1);
|
|
EXPECT(indexes[1] == 0);
|
|
EXPECT(indexes[2] == 3);
|
|
EXPECT(indexes[3] == 2);
|
|
EXPECT(indexes[4] == 2);
|
|
EXPECT(indexes[5] == 3);
|
|
EXPECT(indexes[6] == 0);
|
|
EXPECT(indexes[7] == 1);
|
|
EXPECT(indexes[8] == 2);
|
|
EXPECT(indexes[9] == 3);
|
|
EXPECT(indexes[10] == 0);
|
|
EXPECT(indexes[11] == 1);
|
|
|
|
EXPECT(distances[0] == approx(1));
|
|
EXPECT(distances[1] == approx(1));
|
|
EXPECT(distances[2] == approx(2));
|
|
EXPECT(distances[3] == approx(2));
|
|
EXPECT(distances[4] == approx(10));
|
|
EXPECT(distances[5] == approx(20));
|
|
EXPECT(distances[6] == approx(10));
|
|
EXPECT(distances[7] == approx(20));
|
|
EXPECT(distances[8] == approx(100));
|
|
EXPECT(distances[9] == approx(200));
|
|
EXPECT(distances[10] == approx(100));
|
|
EXPECT(distances[11] == approx(200));
|
|
|
|
},
|
|
|
|
CASE("Test kNN with two trials of 2D data in the same call")
|
|
{
|
|
int thelier = 0;
|
|
int useMaxNorm = 1;
|
|
int N = 4;
|
|
int dims = 2;
|
|
int k = 1;
|
|
int nchunks = 2;
|
|
int signalLength = N*nchunks;
|
|
int indexes[8];
|
|
float distances[8];
|
|
|
|
// Points: X Y y
|
|
// 1 1 | o o
|
|
// 1.1 1 |
|
|
// -1 -1 ----+----x
|
|
// -1.2 -1 |
|
|
// o o |
|
|
|
|
float pointset[16] = {1, 1.1, -1, -1.2, 1, 1.1, -1, -1.2,
|
|
1, 1, -1, -1, 1, 1, -1, -1};
|
|
|
|
int err = cudaFindKnn(indexes, distances, pointset, pointset, k, thelier,
|
|
nchunks, dims, signalLength, useMaxNorm);
|
|
|
|
EXPECT(err == 1);
|
|
|
|
EXPECT(indexes[0] == 1);
|
|
EXPECT(indexes[1] == 0);
|
|
EXPECT(indexes[2] == 3);
|
|
EXPECT(indexes[3] == 2);
|
|
EXPECT(indexes[4] == 1);
|
|
EXPECT(indexes[5] == 0);
|
|
EXPECT(indexes[6] == 3);
|
|
EXPECT(indexes[7] == 2);
|
|
|
|
EXPECT(distances[0] == approx(0.1));
|
|
EXPECT(distances[1] == approx(0.1));
|
|
EXPECT(distances[2] == approx(0.2));
|
|
EXPECT(distances[3] == approx(0.2));
|
|
EXPECT(distances[4] == approx(0.1));
|
|
EXPECT(distances[5] == approx(0.1));
|
|
EXPECT(distances[6] == approx(0.2));
|
|
EXPECT(distances[7] == approx(0.2));
|
|
},
|
|
|
|
CASE("Test kNN with two trials of data with odd dimension")
|
|
{
|
|
int thelier = 0;
|
|
int useMaxNorm = 1;
|
|
int N = 4;
|
|
int dims = 3;
|
|
int k = 1;
|
|
int nchunks = 2;
|
|
int signalLength = N*nchunks;
|
|
int indexes[8];
|
|
float distances[8];
|
|
|
|
// Points: X Y Z y
|
|
// 1 1 1.02 | o o
|
|
// 1.1 1 1.03 |
|
|
// -1 -1 -1.04 ----+----x
|
|
// -1.2 -1 -1.05 |
|
|
// o o |
|
|
|
|
float pointset[24] = {1, 1.1, -1, -1.2, 1, 1.1, -1, -1.2,
|
|
1, 1, -1, -1, 1, 1, -1, -1,
|
|
1.02, 1.03, 1.04, 1.05, 1.02, 1.03, 1.04, 1.05};
|
|
|
|
int err = cudaFindKnn(indexes, distances, pointset, pointset, k, thelier,
|
|
nchunks, dims, signalLength, useMaxNorm);
|
|
|
|
EXPECT(err == 1);
|
|
|
|
EXPECT(indexes[0] == 1);
|
|
EXPECT(indexes[1] == 0);
|
|
EXPECT(indexes[2] == 3);
|
|
EXPECT(indexes[3] == 2);
|
|
EXPECT(indexes[4] == 1);
|
|
EXPECT(indexes[5] == 0);
|
|
EXPECT(indexes[6] == 3);
|
|
EXPECT(indexes[7] == 2);
|
|
|
|
EXPECT(distances[0] == approx(0.1));
|
|
EXPECT(distances[1] == approx(0.1));
|
|
EXPECT(distances[2] == approx(0.2));
|
|
EXPECT(distances[3] == approx(0.2));
|
|
EXPECT(distances[4] == approx(0.1));
|
|
EXPECT(distances[5] == approx(0.1));
|
|
EXPECT(distances[6] == approx(0.2));
|
|
EXPECT(distances[7] == approx(0.2));
|
|
},
|
|
|
|
CASE("Smoke test for kNN with custom GPU")
|
|
{
|
|
int thelier = 0;
|
|
int useMaxNorm = 1;
|
|
int N = 4;
|
|
int dims = 2;
|
|
int k = 1;
|
|
int nchunks = 1;
|
|
int indexes[4];
|
|
float distances[4];
|
|
float pointset[8] = {-1, 0.5, 1.1, 2,
|
|
-1, 0.5, 1.1, 2};
|
|
|
|
int err = cudaFindKnnSetGPU(indexes, distances, pointset, pointset, k, thelier,
|
|
nchunks, dims, N, useMaxNorm, 0);
|
|
|
|
EXPECT(err == 1);
|
|
|
|
EXPECT(indexes[0] == 1);
|
|
EXPECT(indexes[1] == 2);
|
|
EXPECT(indexes[2] == 1);
|
|
EXPECT(indexes[3] == 2);
|
|
|
|
EXPECT(distances[0] == approx(1.5));
|
|
EXPECT(distances[1] == approx(0.6));
|
|
EXPECT(distances[2] == approx(0.6));
|
|
EXPECT(distances[3] == approx(0.9));
|
|
|
|
},
|
|
|
|
CASE("Basic RS test")
|
|
{
|
|
int thelier = 0;
|
|
int nchunks = 1;
|
|
int dim = 1;
|
|
int N = 5;
|
|
int useMaxNorm = 1;
|
|
int npoints[5];
|
|
float pointset[] = {0, 2, 2.1, 3.2, 3.5};
|
|
float radii[] = {1, 1, 1, 1, 1};
|
|
|
|
int err = cudaFindRSAll(npoints, pointset, pointset, radii, thelier, nchunks,
|
|
dim, N, useMaxNorm);
|
|
|
|
EXPECT(err == 1);
|
|
|
|
EXPECT(npoints[0] == 0);
|
|
EXPECT(npoints[1] == 1);
|
|
EXPECT(npoints[2] == 1);
|
|
EXPECT(npoints[3] == 1);
|
|
EXPECT(npoints[4] == 1);
|
|
|
|
},
|
|
|
|
CASE("Test RS with different radii")
|
|
{
|
|
int thelier = 0;
|
|
int nchunks = 1;
|
|
int dim = 1;
|
|
int N = 5;
|
|
int useMaxNorm = 1;
|
|
int npoints[5];
|
|
float pointset[] = { 0, 2, 2.1, 3.2, 3.5};
|
|
float radii[] = {2.05, 6, 0.01, 1, 1};
|
|
|
|
int err = cudaFindRSAll(npoints, pointset, pointset, radii, thelier, nchunks,
|
|
dim, N, useMaxNorm);
|
|
|
|
EXPECT(err == 1);
|
|
|
|
EXPECT(npoints[0] == 1);
|
|
EXPECT(npoints[1] == 4);
|
|
EXPECT(npoints[2] == 0);
|
|
EXPECT(npoints[3] == 1);
|
|
EXPECT(npoints[4] == 1);
|
|
|
|
},
|
|
|
|
CASE("Test RS with multiple trials in the same call")
|
|
{
|
|
int thelier = 0;
|
|
int nchunks = 2;
|
|
int dim = 1;
|
|
int N = 10;
|
|
int useMaxNorm = 1;
|
|
int npoints[10];
|
|
float pointset[] = {0, 2, 2.1, 3.2, 3.5, 0, 2, 2.1, 3.2, 3.5};
|
|
float radii[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
|
|
|
int err = cudaFindRSAll(npoints, pointset, pointset, radii, thelier, nchunks,
|
|
dim, N, useMaxNorm);
|
|
|
|
EXPECT(err == 1);
|
|
|
|
EXPECT(npoints[0] == 0);
|
|
EXPECT(npoints[1] == 1);
|
|
EXPECT(npoints[2] == 1);
|
|
EXPECT(npoints[3] == 1);
|
|
EXPECT(npoints[4] == 1);
|
|
EXPECT(npoints[5] == 0);
|
|
EXPECT(npoints[6] == 1);
|
|
EXPECT(npoints[7] == 1);
|
|
EXPECT(npoints[8] == 1);
|
|
EXPECT(npoints[9] == 1);
|
|
|
|
},
|
|
|
|
CASE("Test RS with multiple trials and different radii")
|
|
{
|
|
int thelier = 0;
|
|
int nchunks = 2;
|
|
int dim = 1;
|
|
int N = 10;
|
|
int useMaxNorm = 1;
|
|
int npoints[10];
|
|
float pointset[] = { 0, 2, 2.1, 3.2, 3.5, 0, 2, 2.1, 3.2, 3.5};
|
|
float radii[] = {2.05, 6, 0.01, 1, 1, 2.05, 6, 0.01, 1, 1};
|
|
|
|
int err = cudaFindRSAll(npoints, pointset, pointset, radii, thelier, nchunks,
|
|
dim, N, useMaxNorm);
|
|
|
|
EXPECT(err == 1);
|
|
|
|
EXPECT(npoints[0] == 1);
|
|
EXPECT(npoints[1] == 4);
|
|
EXPECT(npoints[2] == 0);
|
|
EXPECT(npoints[3] == 1);
|
|
EXPECT(npoints[4] == 1);
|
|
EXPECT(npoints[5] == 1);
|
|
EXPECT(npoints[6] == 4);
|
|
EXPECT(npoints[7] == 0);
|
|
EXPECT(npoints[8] == 1);
|
|
EXPECT(npoints[9] == 1);
|
|
|
|
},
|
|
|
|
CASE("Smoke test for RS with custom GPU")
|
|
{
|
|
int thelier = 0;
|
|
int nchunks = 1;
|
|
int dim = 1;
|
|
int N = 5;
|
|
int useMaxNorm = 1;
|
|
int npoints[5];
|
|
float pointset[] = {0, 2, 2.1, 3.2, 3.5};
|
|
float radii[] = {1, 1, 1, 1, 1};
|
|
|
|
int err = cudaFindRSAllSetGPU(npoints, pointset, pointset, radii, thelier, nchunks,
|
|
dim, N, useMaxNorm, 0);
|
|
|
|
EXPECT(err == 1);
|
|
|
|
EXPECT(npoints[0] == 0);
|
|
EXPECT(npoints[1] == 1);
|
|
EXPECT(npoints[2] == 1);
|
|
EXPECT(npoints[3] == 1);
|
|
EXPECT(npoints[4] == 1);
|
|
|
|
},
|
|
|
|
CASE("Smoke test of random permutation function")
|
|
{
|
|
int N = 30;
|
|
int perm[30];
|
|
for (int i = 0; i < N; i++) {
|
|
perm[i] = i;
|
|
}
|
|
randperm(perm, N);
|
|
|
|
},
|
|
|
|
CASE("Statistical test for unbiasedness of random permutation function")
|
|
{
|
|
// Initialise permutation
|
|
int N = 3;
|
|
int perm[3];
|
|
for (int i = 0; i < N; i++) {
|
|
perm[i] = i;
|
|
}
|
|
|
|
// Sample a bunch of times and store results in a histogram
|
|
int nb_samples = 150000;
|
|
double hist[6] = {0};
|
|
for (int i = 0; i < nb_samples; i++) {
|
|
randperm(perm, N);
|
|
if ((perm[0] == 0) && (perm[1] == 1) && (perm[2] == 2)){
|
|
hist[0]++;
|
|
} else if ((perm[0] == 0) && (perm[1] == 2) && (perm[2] == 1)){
|
|
hist[1]++;
|
|
} else if ((perm[0] == 1) && (perm[1] == 0) && (perm[2] == 2)){
|
|
hist[2]++;
|
|
} else if ((perm[0] == 1) && (perm[1] == 2) && (perm[2] == 0)){
|
|
hist[3]++;
|
|
} else if ((perm[0] == 2) && (perm[1] == 0) && (perm[2] == 1)){
|
|
hist[4]++;
|
|
} else if ((perm[0] == 2) && (perm[1] == 1) && (perm[2] == 0)){
|
|
hist[5]++;
|
|
} else {
|
|
std::cout << "This permutation is certainly wrong\n";
|
|
EXPECT(0);
|
|
}
|
|
}
|
|
|
|
// Check that all perturbations happen more or less equally often
|
|
for (int i = 0; i < 6; i++) {
|
|
EXPECT(hist[i]/((double) nb_samples) == approx(1.0/6.0).epsilon(0.02));
|
|
}
|
|
|
|
},
|
|
|
|
CASE("Smoke test of full MI function")
|
|
{
|
|
int N = 10;
|
|
int dimx = 1;
|
|
int dimy = 1;
|
|
float source[10] = {0.4, 1, -4, 1, 1, 0.2, 98, 12, 1.2, 1.3};
|
|
float dest[10] = {-3, 1, 3, -2, 2.1, 8.5, 4.2, 100, 12, 0};
|
|
int k = 2;
|
|
int thelier = 0;
|
|
int nb_surrogates = 0;
|
|
int returnLocals = 0;
|
|
int useMaxNorm = 1;
|
|
int isAlgorithm1 = 1;
|
|
float result[3];
|
|
|
|
jidt_error_t err = MIKraskov_C(N, source, dimx, dest, dimy, k, thelier,
|
|
nb_surrogates, returnLocals, useMaxNorm, isAlgorithm1, result);
|
|
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
|
|
},
|
|
|
|
CASE("Test correct pointset arrangement without reorderings")
|
|
{
|
|
int N = 10;
|
|
int dimx = 1;
|
|
int dimy = 1;
|
|
int k = 2;
|
|
int thelier = 0;
|
|
int returnLocals = 0;
|
|
int useMaxNorm = 1;
|
|
int isAlgorithm1 = 1;
|
|
|
|
float source[10] = {0.4, 1, -4, 1, 1, 0.2, 98, 12, 1.2, 1.3};
|
|
float dest[10] = { -3, 1, 3, -2, 2.1, 8.5, 4.2, 100, 12, 0};
|
|
|
|
float pointset[20] = {0.4, 1, -4, 1, 1, 0.2, 98, 12, 1.2, 1.3,
|
|
-3, 1, 3, -2, 2.1, 8.5, 4.2, 100, 12, 0};
|
|
|
|
float result1[3];
|
|
float result2[3];
|
|
jidt_error_t err;
|
|
|
|
err = MIKraskov_C(N, source, dimx, dest, dimy, k, thelier,
|
|
0, returnLocals, useMaxNorm, isAlgorithm1, result1);
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
|
|
err = MIKraskovByPointsetChunks(N, source, dimx, dest, dimy, k, thelier,
|
|
1, returnLocals, useMaxNorm, isAlgorithm1, result2, pointset);
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
|
|
EXPECT(result1[0] == approx(result2[0]));
|
|
EXPECT(result1[1] == approx(result2[1]));
|
|
EXPECT(result1[2] == approx(result2[2]));
|
|
},
|
|
|
|
CASE("Test correct pointset arrangement without reorderings in CMI")
|
|
{
|
|
int N = 10;
|
|
int dimx = 1;
|
|
int dimy = 1;
|
|
int dimz = 1;
|
|
int k = 2;
|
|
int thelier = 0;
|
|
int returnLocals = 0;
|
|
int useMaxNorm = 1;
|
|
int isAlgorithm1 = 1;
|
|
|
|
float source[10] = {0.4, 1, -4, 1, 1, 0.2, 98, 12, 1.2, 1.3};
|
|
float dest[10] = { -3, 1, 3, -2, 2.1, 8.5, 4.2, 100, 12, 0};
|
|
float cond[10] = { -1, 4, 3, -8, 0.3, 2.1, 3.2, 111, 32, 7};
|
|
|
|
float pointset[30] = {0.4, 1, -4, 1, 1, 0.2, 98, 12, 1.2, 1.3,
|
|
-1, 4, 3, -8, 0.3, 2.1, 3.2, 111, 32, 7,
|
|
-3, 1, 3, -2, 2.1, 8.5, 4.2, 100, 12, 0};
|
|
|
|
float result1[6];
|
|
float result2[6];
|
|
jidt_error_t err;
|
|
|
|
err = CMIKraskov_C(N, source, dimx, dest, dimy, cond, dimz, k, thelier,
|
|
0, returnLocals, useMaxNorm, isAlgorithm1, result1, 1);
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
|
|
err = CMIKraskovByPointsetChunks(N, source, dimx, dest, dimy, cond, dimz, k, thelier,
|
|
1, returnLocals, useMaxNorm, isAlgorithm1, result2, pointset);
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
|
|
EXPECT(result1[0] == approx(result2[0]));
|
|
EXPECT(result1[1] == approx(result2[1]));
|
|
EXPECT(result1[2] == approx(result2[2]));
|
|
EXPECT(result1[3] == approx(result2[3]));
|
|
EXPECT(result1[4] == approx(result2[4]));
|
|
EXPECT(result1[5] == approx(result2[5]));
|
|
},
|
|
|
|
CASE("Test correct pointset arrangement in more than one dimension")
|
|
{
|
|
int N = 5;
|
|
int dimx = 2;
|
|
int dimy = 2;
|
|
int k = 2;
|
|
int thelier = 0;
|
|
int returnLocals = 0;
|
|
int useMaxNorm = 1;
|
|
int isAlgorithm1 = 1;
|
|
|
|
// Source points: X Y
|
|
// 0.4 0.2
|
|
// 1 98
|
|
// -4 12
|
|
// 1 1.2
|
|
// 1 1.3
|
|
//
|
|
// Dest points: X Y
|
|
// -3 8.5
|
|
// 1 4.2
|
|
// 3 100
|
|
// -2 12
|
|
// 2.1 0
|
|
|
|
float source[10] = {0.4, 1, -4, 1, 1, 0.2, 98, 12, 1.2, 1.3};
|
|
float dest[10] = { -3, 1, 3, -2, 2.1, 8.5, 4.2, 100, 12, 0};
|
|
|
|
float pointset[20] = {0.4, 1, -4, 1, 1, 0.2, 98, 12, 1.2, 1.3,
|
|
-3, 1, 3, -2, 2.1, 8.5, 4.2, 100, 12, 0};
|
|
|
|
float result1[3];
|
|
float result2[3];
|
|
jidt_error_t err;
|
|
|
|
err = MIKraskov_C(N, source, dimx, dest, dimy, k, thelier,
|
|
0, returnLocals, useMaxNorm, isAlgorithm1, result1);
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
|
|
err = MIKraskovByPointsetChunks(N, source, dimx, dest, dimy, k, thelier,
|
|
1, returnLocals, useMaxNorm, isAlgorithm1, result2, pointset);
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
|
|
EXPECT(result1[0] == approx(result2[0]));
|
|
EXPECT(result1[1] == approx(result2[1]));
|
|
EXPECT(result1[2] == approx(result2[2]));
|
|
},
|
|
|
|
CASE("Test correct pointset arrangement in more than one dimension for CMI")
|
|
{
|
|
int N = 5;
|
|
int dimx = 2;
|
|
int dimy = 2;
|
|
int dimz = 2;
|
|
int k = 2;
|
|
int thelier = 0;
|
|
int returnLocals = 0;
|
|
int useMaxNorm = 1;
|
|
int isAlgorithm1 = 1;
|
|
|
|
// Source points: X Y
|
|
// 0.4 0.2
|
|
// 1 98
|
|
// -4 12
|
|
// 1 1.2
|
|
// 1 1.3
|
|
//
|
|
// Dest points: X Y
|
|
// -3 8.5
|
|
// 1 4.2
|
|
// 3 100
|
|
// -2 12
|
|
// 2.1 0
|
|
//
|
|
// Cond points: X Y
|
|
// -1 2.1
|
|
// 4 3.2
|
|
// 3 111
|
|
// -8 32
|
|
// 0.3 7
|
|
|
|
float source[10] = {0.4, 1, -4, 1, 1, 0.2, 98, 12, 1.2, 1.3};
|
|
float dest[10] = { -3, 1, 3, -2, 2.1, 8.5, 4.2, 100, 12, 0};
|
|
float cond[10] = { -1, 4, 3, -8, 0.3, 2.1, 3.2, 111, 32, 7};
|
|
|
|
float pointset[30] = {0.4, 1, -4, 1, 1, 0.2, 98, 12, 1.2, 1.3,
|
|
-1, 4, 3, -8, 0.3, 2.1, 3.2, 111, 32, 7,
|
|
-3, 1, 3, -2, 2.1, 8.5, 4.2, 100, 12, 0};
|
|
|
|
float result1[6];
|
|
float result2[6];
|
|
jidt_error_t err;
|
|
|
|
err = CMIKraskov_C(N, source, dimx, dest, dimy, cond, dimz, k, thelier,
|
|
0, returnLocals, useMaxNorm, isAlgorithm1, result1, 1);
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
|
|
err = CMIKraskovByPointsetChunks(N, source, dimx, dest, dimy, cond, dimz, k, thelier,
|
|
1, returnLocals, useMaxNorm, isAlgorithm1, result2, pointset);
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
|
|
EXPECT(result1[0] == approx(result2[0]));
|
|
EXPECT(result1[1] == approx(result2[1]));
|
|
EXPECT(result1[2] == approx(result2[2]));
|
|
EXPECT(result1[3] == approx(result2[3]));
|
|
EXPECT(result1[4] == approx(result2[4]));
|
|
EXPECT(result1[5] == approx(result2[5]));
|
|
},
|
|
|
|
CASE("Test that same sample in repeated chunks gives same result")
|
|
{
|
|
int N = 5;
|
|
int dimx = 1;
|
|
int dimy = 1;
|
|
|
|
// Sample source and dest data
|
|
float source[5] = {0.4, 1, -4, 1, 1};
|
|
float dest[5] = { -3, 1, 3, -2, 2.1};
|
|
|
|
// Pointset with source and dest repeated twice
|
|
float double_pointset[20] = {0.4, 1, -4, 1, 1, 0.4, 1, -4, 1, 1,
|
|
-3, 1, 3, -2, 2.1, -3, 1, 3, -2, 2.1};
|
|
|
|
int k = 2;
|
|
int thelier = 0;
|
|
int returnLocals = 0;
|
|
int useMaxNorm = 1;
|
|
int isAlgorithm1 = 1;
|
|
float result1[3];
|
|
float result2[2];
|
|
jidt_error_t err;
|
|
|
|
err = MIKraskov_C(N, source, dimx, dest, dimy, k, thelier,
|
|
0, returnLocals, useMaxNorm, isAlgorithm1, result1);
|
|
|
|
err = MIKraskovByPointsetChunks(N*2, source, dimx, dest, dimy, k, thelier,
|
|
2, returnLocals, useMaxNorm, isAlgorithm1, result2, double_pointset);
|
|
|
|
float MI1 = cpuDigamma(k) + cpuDigamma(N) - result1[0]/((double) N);
|
|
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
EXPECT(result2[0] == approx(MI1));
|
|
EXPECT(result2[0] == approx(result2[1]));
|
|
|
|
},
|
|
|
|
CASE("Test that same sample in repeated chunks gives same result in CMI")
|
|
{
|
|
int N = 5;
|
|
int dimx = 1;
|
|
int dimy = 1;
|
|
int dimz = 1;
|
|
|
|
// Sample source and dest data
|
|
float source[5] = {0.4, 1, -4, 1, 1};
|
|
float dest[5] = { -3, 1, 3, -2, 2.1};
|
|
float cond[5] = { -1, 4, 3, -8, 0.3};
|
|
|
|
// Pointset with source and dest repeated twice
|
|
float double_pointset[30] = {0.4, 1, -4, 1, 1, 0.4, 1, -4, 1, 1,
|
|
-1, 4, 3, -8, 0.3, -1, 4, 3, -8, 0.3,
|
|
-3, 1, 3, -2, 2.1, -3, 1, 3, -2, 2.1};
|
|
|
|
int k = 2;
|
|
int thelier = 0;
|
|
int returnLocals = 0;
|
|
int useMaxNorm = 1;
|
|
int isAlgorithm1 = 1;
|
|
float result1[3];
|
|
float result2[2];
|
|
jidt_error_t err;
|
|
|
|
err = CMIKraskov_C(N, source, dimx, dest, dimy, cond, dimz, k, thelier,
|
|
0, returnLocals, useMaxNorm, isAlgorithm1, result1, 1);
|
|
|
|
err = CMIKraskovByPointsetChunks(N*2, source, dimx, dest, dimy, cond, dimz, k, thelier,
|
|
2, returnLocals, useMaxNorm, isAlgorithm1, result2, double_pointset);
|
|
|
|
float CMI1 = cpuDigamma(k) + result1[0]/((double) N);
|
|
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
EXPECT(result2[0] == approx(CMI1));
|
|
EXPECT(result2[0] == approx(result2[1]));
|
|
|
|
},
|
|
|
|
CASE("Test that same sample of 2D data in repeated chunks gives same result")
|
|
{
|
|
int N = 5;
|
|
int dimx = 2;
|
|
int dimy = 2;
|
|
|
|
// Source points: X Y
|
|
// 0.4 0.2
|
|
// 1 98
|
|
// -4 12
|
|
// 1 1.2
|
|
// 1 1.3
|
|
//
|
|
// Dest points: X Y
|
|
// -3 8.5
|
|
// 1 4.2
|
|
// 3 100
|
|
// -2 12
|
|
// 2.1 0
|
|
|
|
// Sample source and dest data
|
|
float source[10] = {0.4, 1, -4, 1, 1, 0.2, 98, 12, 1.2, 1.3};
|
|
float dest[10] = { -3, 1, 3, -2, 2.1, 8.5, 4.2, 100, 12, 0};
|
|
|
|
// Pointset with source and dest repeated twice
|
|
float double_pointset[40] = {0.4, 1, -4, 1, 1, 0.4, 1, -4, 1, 1,
|
|
0.2, 98, 12, 1.2, 1.3, 0.2, 98, 12, 1.2, 1.3,
|
|
-3, 1, 3, -2, 2.1, -3, 1, 3, -2, 2.1,
|
|
8.5, 4.2, 100, 12, 0, 8.5, 4.2, 100, 12, 0};
|
|
|
|
int k = 2;
|
|
int thelier = 0;
|
|
int returnLocals = 0;
|
|
int useMaxNorm = 1;
|
|
int isAlgorithm1 = 1;
|
|
float result1[3];
|
|
float result2[2];
|
|
jidt_error_t err;
|
|
|
|
err = MIKraskov_C(N, source, dimx, dest, dimy, k, thelier,
|
|
0, returnLocals, useMaxNorm, isAlgorithm1, result1);
|
|
|
|
err = MIKraskovByPointsetChunks(N*2, source, dimx, dest, dimy, k, thelier,
|
|
2, returnLocals, useMaxNorm, isAlgorithm1, result2, double_pointset);
|
|
|
|
float MI1 = cpuDigamma(k) + cpuDigamma(N) - result1[0]/((double) N);
|
|
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
EXPECT(result2[0] == approx(MI1));
|
|
EXPECT(result2[0] == approx(result2[1]));
|
|
|
|
},
|
|
|
|
CASE("Test that sample and identity reordering have same MI")
|
|
{
|
|
int N = 5;
|
|
int dimx = 1;
|
|
int dimy = 1;
|
|
float source[5] = {0.4, 1, -4, 1, 1};
|
|
float dest[5] = { -3, 1, 3, -2, 2.1};
|
|
int k = 2;
|
|
int thelier = 0;
|
|
int returnLocals = 0;
|
|
int useMaxNorm = 1;
|
|
int isAlgorithm1 = 1;
|
|
float result[2];
|
|
int reorderingsGiven = 1;
|
|
int order[5] = {0, 1, 2, 3, 4};
|
|
int *order_p = order;
|
|
int **reorderings = &order_p;
|
|
jidt_error_t err;
|
|
|
|
err = MIKraskovWithReorderings(N, source, dimx, dest, dimy, k, thelier,
|
|
1, returnLocals, useMaxNorm, isAlgorithm1, result, reorderingsGiven, reorderings);
|
|
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
EXPECT(result[0] == approx(result[1]));
|
|
|
|
},
|
|
|
|
CASE("Test that sample and identity reordering have same CMI")
|
|
{
|
|
int N = 5;
|
|
int dimx = 1;
|
|
int dimy = 1;
|
|
int dimz = 1;
|
|
float source[5] = {0.4, 1, -4, 1, 1};
|
|
float dest[5] = { -3, 1, 3, -2, 2.1};
|
|
float cond[5] = { -1, 4, 3, -8, 0.3};
|
|
int k = 2;
|
|
int thelier = 0;
|
|
int returnLocals = 0;
|
|
int useMaxNorm = 1;
|
|
int isAlgorithm1 = 1;
|
|
float result[2];
|
|
int reorderingsGiven = 1;
|
|
int order[5] = {0, 1, 2, 3, 4};
|
|
int *order_p = order;
|
|
int **reorderings = &order_p;
|
|
jidt_error_t err;
|
|
|
|
err = CMIKraskovWithReorderings(N, source, dimx, dest, dimy, cond, dimz, k, thelier,
|
|
1, returnLocals, useMaxNorm, isAlgorithm1, result, reorderingsGiven, reorderings, 1);
|
|
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
EXPECT(result[0] == approx(result[1]));
|
|
|
|
},
|
|
|
|
CASE("Test identity reordering with more than one dimension")
|
|
{
|
|
int N = 5;
|
|
int dimx = 3;
|
|
int dimy = 2;
|
|
|
|
// Source points: X Y Z
|
|
// 0.4 0.2 0
|
|
// 1 98 13
|
|
// -4 12 7
|
|
// 1 1.2 -1
|
|
// 1 1.3 0
|
|
//
|
|
// Dest points: X Y
|
|
// -3 8.5
|
|
// 1 4.2
|
|
// 3 100
|
|
// -2 13
|
|
// 2.1 0
|
|
|
|
float source[15] = {0.4, 1, -4, 1, 1, 0.2, 98, 12, 1.2, 1.3, 0, 13, 7, -1, 0};
|
|
float dest[10] = { -3, 1, 3, -2, 2.1, 8.5, 4.2, 100, 13, 0};
|
|
int k = 1;
|
|
int thelier = 0;
|
|
int returnLocals = 0;
|
|
int useMaxNorm = 1;
|
|
int isAlgorithm1 = 1;
|
|
float result1[3], result2[2];
|
|
int reorderingsGiven = 1;
|
|
int order[5] = {0, 1, 2, 3, 4};
|
|
int *order_p = order;
|
|
int **reorderings = &order_p;
|
|
jidt_error_t err;
|
|
|
|
err = MIKraskovWithReorderings(N, source, dimx, dest, dimy, k, thelier,
|
|
0, returnLocals, useMaxNorm, isAlgorithm1, result1, reorderingsGiven, reorderings);
|
|
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
|
|
err = MIKraskovWithReorderings(N, source, dimx, dest, dimy, k, thelier,
|
|
1, returnLocals, useMaxNorm, isAlgorithm1, result2, reorderingsGiven, reorderings);
|
|
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
EXPECT(result2[0] == approx(result2[1]));
|
|
|
|
},
|
|
|
|
CASE("Test identity reordering with larger dataset")
|
|
{
|
|
int thelier = 0;
|
|
int useMaxNorm = 1;
|
|
int N = 10;
|
|
int dimx = 3;
|
|
int dimy = 2;
|
|
int k = 4;
|
|
int isAlgorithm1 = 1;
|
|
int returnLocals = 0;
|
|
|
|
float *source = (float *) malloc(N * dimx * sizeof(float));
|
|
for (int i = 0; i < N*dimx; i++) { source[i] = rand()/((float) RAND_MAX); };
|
|
|
|
float *dest = (float *) malloc(N * dimy * sizeof(float));
|
|
for (int i = 0; i < N*dimy; i++) { dest[i] = rand()/((float) RAND_MAX); };
|
|
|
|
int reorderingsGiven = 1;
|
|
int *order = (int *) malloc(N * sizeof(int));
|
|
for (int i = 0; i < N; i++) { order[i] = i; };
|
|
int **reorderings = ℴ
|
|
|
|
float result[2];
|
|
|
|
jidt_error_t err;
|
|
err = MIKraskovWithReorderings(N, source, dimx, dest, dimy, k, thelier,
|
|
1, returnLocals, useMaxNorm, isAlgorithm1, result, reorderingsGiven, reorderings);
|
|
|
|
free(source); free(dest); free(order);
|
|
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
EXPECT(result[0] == approx(result[1]));
|
|
|
|
},
|
|
|
|
CASE("Test non-identity reordering in 2D")
|
|
{
|
|
int thelier = 0;
|
|
int useMaxNorm = 1;
|
|
int N = 5;
|
|
int dimx = 2;
|
|
int dimy = 2;
|
|
int k = 2;
|
|
int isAlgorithm1 = 1;
|
|
int returnLocals = 0;
|
|
|
|
// Source points: X Y Z
|
|
// 0.4 0.2 0
|
|
// 1 98 13
|
|
// -4 12 7
|
|
// 1 1.2 -1
|
|
// 1 1.3 0
|
|
//
|
|
// Dest points: X Y
|
|
// -3 8.5
|
|
// 1 4.2
|
|
// 3 100
|
|
// -2 13
|
|
// 2.1 0
|
|
|
|
float source[15] = {0.4, 1, -4, 1, 1, 0.2, 98, 12, 1.2, 1.3, 0, 13, 7, -1, 0};
|
|
float dest[10] = { -3, 1, 3, -2, 2.1, 8.5, 4.2, 100, 13, 0};
|
|
|
|
|
|
int reorderingsGiven = 1;
|
|
int order[5] = {4, 2, 3, 0, 1};
|
|
int *order_p = order;
|
|
int **reorderings = &order_p;
|
|
|
|
float result[2];
|
|
|
|
jidt_error_t err;
|
|
err = MIKraskovWithReorderings(N, source, dimx, dest, dimy, k, thelier,
|
|
1, returnLocals, useMaxNorm, isAlgorithm1, result, reorderingsGiven, reorderings);
|
|
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
EXPECT(result[0] != approx(result[1]));
|
|
|
|
},
|
|
|
|
CASE("Test random surrogates in 2D")
|
|
{
|
|
int thelier = 0;
|
|
int useMaxNorm = 1;
|
|
int N = 20;
|
|
int dimx = 2;
|
|
int dimy = 2;
|
|
int k = 2;
|
|
int isAlgorithm1 = 1;
|
|
int returnLocals = 0;
|
|
|
|
|
|
float *source = (float *) malloc(N * dimx * sizeof(float));
|
|
for (int i = 0; i < N*dimx; i++) { source[i] = rand()/((float) RAND_MAX); };
|
|
|
|
float *dest = (float *) malloc(N * dimy * sizeof(float));
|
|
for (int i = 0; i < N*dimy; i++) { dest[i] = rand()/((float) RAND_MAX); };
|
|
|
|
float result[3];
|
|
|
|
jidt_error_t err;
|
|
err = MIKraskov_C(N, source, dimx, dest, dimy, k, thelier,
|
|
2, returnLocals, useMaxNorm, isAlgorithm1, result);
|
|
|
|
free(source); free(dest);
|
|
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
EXPECT(result[0] != result[1]);
|
|
EXPECT(result[0] != result[2]);
|
|
EXPECT(result[1] != result[2]);
|
|
|
|
},
|
|
|
|
CASE("Test that the first result of calculation with surrogates is the same as without")
|
|
{
|
|
int thelier = 0;
|
|
int useMaxNorm = 1;
|
|
int N = 10;
|
|
int dimx = 1;
|
|
int dimy = 1;
|
|
int k = 2;
|
|
int isAlgorithm1 = 1;
|
|
int returnLocals = 0;
|
|
|
|
// Source points: X Y Z
|
|
// 0.4 0.2 0
|
|
// 1 98 13
|
|
// -4 12 7
|
|
// 1 1.2 -1
|
|
// 1 1.3 0
|
|
//
|
|
// Dest points: X Y
|
|
// -3 8.5
|
|
// 1 4.2
|
|
// 3 100
|
|
// -2 13
|
|
// 2.1 0
|
|
|
|
float source[15] = {0.4, 1, -4, 1, 1, 0.2, 98, 12, 1.2, 1.3, 0, 13, 7, -1, 0};
|
|
float dest[10] = { -3, 1, 3, -2, 2.1, 8.5, 4.2, 100, 13, 0};
|
|
|
|
float result1[3];
|
|
float result2[2];
|
|
|
|
jidt_error_t err;
|
|
err = MIKraskov_C(N, source, dimx, dest, dimy, k, thelier,
|
|
0, returnLocals, useMaxNorm, isAlgorithm1, result1);
|
|
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
|
|
float MI1 = cpuDigamma(k) + cpuDigamma(N) - result1[0]/((double) N);
|
|
|
|
err = MIKraskov_C(N, source, dimx, dest, dimy, k, thelier,
|
|
1, returnLocals, useMaxNorm, isAlgorithm1, result2);
|
|
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
EXPECT(MI1 == approx(result2[0]));
|
|
EXPECT(result2[0] != result2[1]);
|
|
},
|
|
|
|
CASE("Test that the first result of calculation with surrogates is the same as without in CMI")
|
|
{
|
|
int thelier = 0;
|
|
int useMaxNorm = 1;
|
|
int N = 10;
|
|
int dimx = 1;
|
|
int dimy = 1;
|
|
int dimz = 1;
|
|
int k = 2;
|
|
int isAlgorithm1 = 1;
|
|
int returnLocals = 0;
|
|
|
|
// Source points: X Y Z
|
|
// 0.4 0.2 0
|
|
// 1 98 13
|
|
// -4 12 7
|
|
// 1 1.2 -1
|
|
// 1 1.3 0
|
|
//
|
|
// Dest points: X Y
|
|
// -3 8.5
|
|
// 1 4.2
|
|
// 3 100
|
|
// -2 13
|
|
// 2.1 0
|
|
//
|
|
// Cond points: X Y
|
|
// -1 2.1
|
|
// 4 3.2
|
|
// 3 111
|
|
// -8 32
|
|
// 0.3 7
|
|
|
|
float source[15] = {0.4, 1, -4, 1, 1, 0.2, 98, 12, 1.2, 1.3, 0, 13, 7, -1, 0};
|
|
float dest[10] = { -3, 1, 3, -2, 2.1, 8.5, 4.2, 100, 13, 0};
|
|
float cond[10] = { -1, 4, 3, -8, 0.3, 2.1, 3.2, 111, 32, 7};
|
|
|
|
float result1[6];
|
|
float result2[2];
|
|
|
|
jidt_error_t err;
|
|
err = CMIKraskov_C(N, source, dimx, dest, dimy, cond, dimz, k, thelier,
|
|
0, returnLocals, useMaxNorm, isAlgorithm1, result1, 1);
|
|
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
|
|
float CMI1 = cpuDigamma(k) + result1[0]/((double) N);
|
|
|
|
err = CMIKraskov_C(N, source, dimx, dest, dimy, cond, dimz, k, thelier,
|
|
1, returnLocals, useMaxNorm, isAlgorithm1, result2, 1);
|
|
|
|
EXPECT(err == JIDT_SUCCESS);
|
|
EXPECT(CMI1 == approx(result2[0]));
|
|
EXPECT(result2[0] != result2[1]);
|
|
},
|
|
|
|
CASE("Basic digamma sum test")
|
|
{
|
|
int N = 2;
|
|
int nx[2] = {10, 12};
|
|
int ny[2] = {2, 5};
|
|
float sumDiGammas;
|
|
|
|
int err = cudaSumDigammas(&sumDiGammas, nx, ny, N, 1);
|
|
|
|
EXPECT(err == 1);
|
|
|
|
float cpu_sumDigammas = 0;
|
|
for (int i = 0; i < N; i++) {
|
|
cpu_sumDigammas += cpuDigamma(nx[i] + 1) + cpuDigamma(ny[i] + 1);
|
|
}
|
|
|
|
EXPECT(sumDiGammas == approx(cpu_sumDigammas));
|
|
|
|
},
|
|
|
|
CASE("Digamma sum test with more data (but still one GPU block)")
|
|
{
|
|
int N = 500;
|
|
int *nx = (int *) malloc(N * sizeof(int));
|
|
int *ny = (int *) malloc(N * sizeof(int));
|
|
float sumDiGammas;
|
|
|
|
for (int i = 0; i < N; i++) {
|
|
nx[i] = rand() % 300;
|
|
ny[i] = rand() % 300;
|
|
}
|
|
|
|
int err = cudaSumDigammas(&sumDiGammas, nx, ny, N, 1);
|
|
|
|
EXPECT(err == 1);
|
|
|
|
float cpu_sumDigammas = 0;
|
|
for (int i = 0; i < N; i++) {
|
|
cpu_sumDigammas += cpuDigamma(nx[i] + 1) + cpuDigamma(ny[i] + 1);
|
|
}
|
|
|
|
free(nx); free(ny);
|
|
|
|
EXPECT(sumDiGammas == approx(cpu_sumDigammas));
|
|
|
|
},
|
|
|
|
CASE("Digamma sum test in single chunk with multiple GPU blocks")
|
|
{
|
|
int N = 5000;
|
|
int *nx = (int *) malloc(N * sizeof(int));
|
|
int *ny = (int *) malloc(N * sizeof(int));
|
|
float sumDiGammas;
|
|
|
|
for (int i = 0; i < N; i++) {
|
|
nx[i] = rand() % 300;
|
|
ny[i] = rand() % 300;
|
|
}
|
|
|
|
int err = cudaSumDigammas(&sumDiGammas, nx, ny, N, 1);
|
|
|
|
EXPECT(err == 1);
|
|
|
|
float cpu_sumDigammas = 0;
|
|
for (int i = 0; i < N; i++) {
|
|
cpu_sumDigammas += cpuDigamma(nx[i] + 1) + cpuDigamma(ny[i] + 1);
|
|
}
|
|
|
|
free(nx); free(ny);
|
|
|
|
EXPECT(sumDiGammas == approx(cpu_sumDigammas));
|
|
|
|
},
|
|
|
|
CASE("Test GPU parallel digamma calculation (no sum) in single block")
|
|
{
|
|
int N = 500;
|
|
int *nx = (int *) malloc(N * sizeof(int));
|
|
int *ny = (int *) malloc(N * sizeof(int));
|
|
float *gpu_digammas = (float *) malloc(N * sizeof(float));
|
|
|
|
for (int i = 0; i < N; i++) {
|
|
nx[i] = rand() % 300;
|
|
ny[i] = rand() % 300;
|
|
}
|
|
|
|
int err = parallelDigammas(gpu_digammas, nx, ny, N);
|
|
|
|
EXPECT(err == 1);
|
|
|
|
for (int i = 0; i < N; i++) {
|
|
double cpu_digamma = cpuDigamma(nx[i] + 1) + cpuDigamma(ny[i] + 1);
|
|
EXPECT(gpu_digammas[i] == approx(cpu_digamma));
|
|
}
|
|
|
|
free(nx); free(ny); free(gpu_digammas);
|
|
},
|
|
|
|
CASE("Test GPU parallel digamma calculation (no sum) in multiple blocks")
|
|
{
|
|
int N = 5000;
|
|
int *nx = (int *) malloc(N * sizeof(int));
|
|
int *ny = (int *) malloc(N * sizeof(int));
|
|
float *gpu_digammas = (float *) malloc(N * sizeof(float));
|
|
|
|
for (int i = 0; i < N; i++) {
|
|
nx[i] = rand() % 300;
|
|
ny[i] = rand() % 300;
|
|
}
|
|
|
|
int err = parallelDigammas(gpu_digammas, nx, ny, N);
|
|
|
|
EXPECT(err == 1);
|
|
|
|
for (int i = 0; i < N; i++) {
|
|
double cpu_digamma = cpuDigamma(nx[i] + 1) + cpuDigamma(ny[i] + 1);
|
|
EXPECT(gpu_digammas[i] == approx(cpu_digamma));
|
|
}
|
|
|
|
free(nx); free(ny); free(gpu_digammas);
|
|
},
|
|
|
|
CASE("Digamma sum with multiple chunks and one block")
|
|
{
|
|
int nx[6] = {4, 6, 8, 10, 12, 14};
|
|
int ny[6] = {3, 5, 7, 9, 11, 13};
|
|
int trialLength = 3;
|
|
int nchunks = 2;
|
|
|
|
float *gpu_sumDiGammas = (float *) malloc(nchunks * sizeof(float));
|
|
int err = cudaSumDigammas(gpu_sumDiGammas, nx, ny, trialLength, nchunks);
|
|
EXPECT(err == 1);
|
|
|
|
for (int i = 0; i < nchunks; i++) {
|
|
float cpu_sumDigammas = 0;
|
|
for (int j = 0; j < trialLength; j++) {
|
|
cpu_sumDigammas += cpuDigamma(nx[trialLength*i + j] + 1)
|
|
+ cpuDigamma(ny[trialLength*i + j] + 1);
|
|
}
|
|
EXPECT(gpu_sumDiGammas[i] == approx(cpu_sumDigammas));
|
|
}
|
|
|
|
free(gpu_sumDiGammas);
|
|
},
|
|
|
|
CASE("Digamma sum with multiple chunks and multiple blocks per chunk")
|
|
{
|
|
int trialLength = 2000;
|
|
int nchunks = 3;
|
|
int signalLength = trialLength * nchunks;
|
|
int *nx = (int *) malloc(signalLength * sizeof(int));
|
|
int *ny = (int *) malloc(signalLength * sizeof(int));
|
|
|
|
for (int i = 0; i < signalLength; i++) {
|
|
nx[i] = rand() % 300;
|
|
ny[i] = rand() % 300;
|
|
}
|
|
|
|
float *gpu_sumDiGammas = (float *) malloc(nchunks * sizeof(float));
|
|
int err = cudaSumDigammas(gpu_sumDiGammas, nx, ny, trialLength, nchunks);
|
|
EXPECT(err == 1);
|
|
|
|
for (int i = 0; i < nchunks; i++) {
|
|
float cpu_sumDigammas = 0;
|
|
for (int j = 0; j < trialLength; j++) {
|
|
cpu_sumDigammas += cpuDigamma(nx[trialLength*i + j] + 1)
|
|
+ cpuDigamma(ny[trialLength*i + j] + 1);
|
|
}
|
|
EXPECT(gpu_sumDiGammas[i] == approx(cpu_sumDigammas));
|
|
}
|
|
free(nx); free(ny); free(gpu_sumDiGammas);
|
|
},
|
|
|
|
};
|
|
|
|
int main(int argc, char *argv[]){
|
|
if (int failures = lest::run(specification, argc, argv))
|
|
return failures;
|
|
return std::cout << "ALL PASSED, YEA BOI\n", EXIT_SUCCESS;
|
|
}
|
|
|