Last active
July 21, 2019 13:05
-
-
Save horitaku1124/8f2b09179e95f1f6ae8026faa22af473 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Save as "HelloJNI.c" | |
#include <jni.h> // JNI header provided by JDK | |
#include <stdio.h> // C Standard IO Header | |
#include <math.h> | |
#include <immintrin.h> | |
#include "HelloJNI.h" // Generated | |
JNIEXPORT jfloat JNICALL Java_HelloJNI_calcCoff | |
(JNIEnv * env, jobject jObj, jfloatArray array1, jint len1, jfloatArray array2) { | |
jboolean ji1,ji2; | |
float * floatArray1 = (*env)->GetFloatArrayElements(env, (jfloatArray)array1, &ji1); | |
float * floatArray2 = (*env)->GetFloatArrayElements(env, (jfloatArray)array2, &ji2); | |
float mean1 = 0.0; | |
float mean2 = 0.0; | |
for (int i = 0;i < len1;i++) { | |
mean1 += floatArray1[i]; | |
} | |
mean1 = mean1 / len1; | |
for (int i = 0;i < len1;i++) { | |
mean2 += floatArray2[i]; | |
} | |
mean2 = mean2 / len1; | |
// printf("mean1 = %.16f\n", mean1); | |
// printf("mean2 = %.16f\n", mean2); | |
float devmul = 0.0; | |
for (int i = 0;i < len1;i++) { | |
devmul += (floatArray1[i] - mean1) * (floatArray2[i] - mean2); | |
} | |
float covar = devmul / len1; | |
// printf("devmul = %.16f\n", devmul); | |
// printf("covar = %.16f\n", covar); | |
float stdevp1 = 0.0; | |
for (int i = 0;i < len1;i++) { | |
float m = floatArray1[i] - mean1; | |
stdevp1 += m * m; | |
} | |
stdevp1 = sqrt(stdevp1 / len1); | |
float stdevp2 = 0.0; | |
for (int i = 0;i < len1;i++) { | |
float m = floatArray2[i] - mean2; | |
stdevp2 += m * m; | |
} | |
stdevp2 = sqrt(stdevp2 / len1); | |
(*env)->ReleaseFloatArrayElements(env, (jfloatArray)array1, floatArray1, 0); | |
(*env)->ReleaseFloatArrayElements(env, (jfloatArray)array2, floatArray2, 0); | |
// printf("stdevp1 = %.16f\n", stdevp1); | |
// printf("stdevp2 = %.16f\n", stdevp2); | |
return covar / stdevp1 / stdevp2; | |
} | |
JNIEXPORT jfloat JNICALL Java_HelloJNI_calcCoff2 | |
(JNIEnv * env, jobject jObj, jfloatArray array1, jint len1, jfloatArray array2) { | |
jboolean ji1,ji2; | |
float * floatArray1 = (*env)->GetFloatArrayElements(env, (jfloatArray)array1, &ji1); | |
float * floatArray2 = (*env)->GetFloatArrayElements(env, (jfloatArray)array2, &ji2); | |
float __attribute__((aligned(32))) out[8] = {}; | |
__m256 sum0; | |
// mean1 | |
sum0 = _mm256_setzero_ps(); | |
for (int i = 0;i < len1;i += 8) { | |
__m256 v0 = _mm256_loadu_ps(&floatArray1[i]); | |
sum0 = _mm256_add_ps(v0 , sum0); | |
} | |
_mm256_store_ps(out, sum0); | |
float mean1 = 0.0; | |
for (int i = 0;i < 8;i++) { | |
mean1 += out[i]; | |
} | |
mean1 = mean1 / len1; | |
// printf("mean1 = %.16f\n", mean1); | |
// mean2 | |
sum0 = _mm256_setzero_ps(); | |
for (int i = 0;i < len1;i += 8) { | |
__m256 v0 = _mm256_loadu_ps(&floatArray2[i]); | |
sum0 = _mm256_add_ps(v0 , sum0); | |
} | |
_mm256_store_ps(out, sum0); | |
float mean2 = 0.0; | |
for (int i = 0;i < 8;i++) { | |
mean2 += out[i]; | |
} | |
mean2 = mean2 / len1; | |
// printf("mean2 = %.16f\n", mean2); | |
// devmul | |
sum0 = _mm256_setzero_ps(); | |
__m256 mm_mean1 = _mm256_broadcast_ss(&mean1); | |
__m256 mm_mean2 = _mm256_broadcast_ss(&mean2); | |
for (int i = 0;i < len1;i += 8) { | |
__m256 v0 = _mm256_loadu_ps(&floatArray1[i]); | |
__m256 v1 = _mm256_loadu_ps(&floatArray2[i]); | |
v0 = _mm256_sub_ps(v0, mm_mean1); | |
v1 = _mm256_sub_ps(v1, mm_mean2); | |
// v0 = _mm256_mul_ps(v0 , v1); | |
// sum0 = _mm256_add_ps(v0 , sum0); | |
sum0 = _mm256_fmadd_ps(v0, v1, sum0); | |
} | |
_mm256_store_ps(out, sum0); | |
float devmul = 0.0; | |
for (int i = 0;i < 8;i++) { | |
devmul += out[i]; | |
} | |
float covar = devmul / len1; | |
// printf("devmul = %.16f\n", devmul); | |
// printf("covar = %.16f\n", covar); | |
// stdevp1 | |
sum0 = _mm256_setzero_ps(); | |
for (int i = 0;i < len1;i += 8) { | |
__m256 v0 = _mm256_loadu_ps(&floatArray1[i]); | |
v0 = _mm256_sub_ps(v0 , mm_mean1); | |
// v0 = _mm256_mul_ps(v0 , v0); | |
// sum0 = _mm256_add_ps(v0 , sum0); | |
sum0 = _mm256_fmadd_ps(v0, v0, sum0); | |
} | |
_mm256_store_ps(out, sum0); | |
float stdevp1 = 0.0; | |
for (int i = 0;i < 8;i++) { | |
stdevp1 += out[i]; | |
} | |
stdevp1 = sqrt(stdevp1 / len1); | |
// printf("stdevp1 = %.16f\n", stdevp1); | |
// stdevp2 | |
sum0 = _mm256_setzero_ps(); | |
for (int i = 0;i < len1;i += 8) { | |
__m256 v0 = _mm256_loadu_ps(&floatArray2[i]); | |
v0 = _mm256_sub_ps(v0 , mm_mean2); | |
// v0 = _mm256_mul_ps(v0 , v0); | |
// sum0 = _mm256_add_ps(v0 , sum0); | |
sum0 = _mm256_fmadd_ps(v0, v0, sum0); | |
} | |
_mm256_store_ps(out, sum0); | |
float stdevp2 = 0.0; | |
for (int i = 0;i < 8;i++) { | |
stdevp2 += out[i]; | |
} | |
stdevp2 = sqrt(stdevp2 / len1); | |
// printf("stdevp2 = %.16f\n", stdevp2); | |
return covar / stdevp1 / stdevp2; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* DO NOT EDIT THIS FILE - it is machine generated */ | |
#include <jni.h> | |
/* Header for class HelloJNI */ | |
#ifndef _Included_HelloJNI | |
#define _Included_HelloJNI | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
/* | |
* Class: HelloJNI | |
* Method: calcCoff | |
* Signature: ([FI[F)F | |
*/ | |
JNIEXPORT jfloat JNICALL Java_HelloJNI_calcCoff | |
(JNIEnv *, jobject, jfloatArray, jint, jfloatArray); | |
/* | |
* Class: HelloJNI | |
* Method: calcCoff2 | |
* Signature: ([FI[F)F | |
*/ | |
JNIEXPORT jfloat JNICALL Java_HelloJNI_calcCoff2 | |
(JNIEnv *, jobject, jfloatArray, jint, jfloatArray); | |
#ifdef __cplusplus | |
} | |
#endif | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class HelloJNI { | |
static { | |
System.loadLibrary("hello"); | |
} | |
public native float calcCoff(float[] array1, int len1, float[] array2); | |
public native float calcCoff2(float[] array1, int len1, float[] array2); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import kotlin.math.sqrt | |
class MyArray { | |
companion object { | |
/** | |
* 相加平均 | |
*/ | |
fun mean(array1: List<Float>): Float { | |
var sum = 0f | |
array1.forEach { | |
sum += it | |
} | |
return sum / array1.size | |
} | |
fun mean(array1: FloatArray): Float { | |
var sum = 0f | |
array1.forEach { | |
sum += it | |
} | |
return sum / array1.size | |
} | |
/** | |
* 偏差平方和 | |
*/ | |
fun devsq(array1: List<Float>): Float { | |
val mean = mean(array1) | |
var d = 0f | |
array1.forEach { | |
d += (it - mean) * (it - mean) | |
} | |
return d | |
} | |
/** | |
* 標準偏差 | |
*/ | |
fun stdevp(array1: List<Float>): Float { | |
return sqrt(devsq(array1) / array1.size) | |
} | |
/** | |
* 偏差積和 | |
*/ | |
fun devmulOf(array1: List<Float>, array2: List<Float>): Float { | |
val mean1 = mean(array1) | |
val mean2 = mean(array2) | |
var mul = 0f | |
for (i in 0 until array1.size) { | |
mul += (array1[i] - mean1) * (array2[i] - mean2) | |
} | |
return mul | |
} | |
/** | |
* 共分散 | |
*/ | |
fun covarOf(array1: List<Float>, array2: List<Float>): Float { | |
return devmulOf(array1, array2) / array1.size | |
} | |
/** | |
* 相関係数 | |
*/ | |
fun correlOf(array1: List<Float>, array2: List<Float>): Float { | |
return covarOf(array1, array2) / stdevp(array1) / stdevp(array2) | |
} | |
/** | |
* 相関係数 | |
*/ | |
fun correlOf2(array1: FloatArray, array2: FloatArray): Float { | |
val mean1 = mean(array1) | |
val mean2 = mean(array2) | |
val devmul = { | |
var mul = 0f | |
for (i in 0 until array1.size) { | |
mul += (array1[i] - mean1) * (array2[i] - mean2) | |
} | |
mul | |
}() | |
val covar = devmul / array1.size | |
val stdevp1 = { | |
var devsq = 0f | |
array1.forEach { | |
var m = (it - mean1) | |
devsq += m * m | |
} | |
sqrt(devsq / array1.size) | |
}() | |
val stdevp2 = { | |
var devsq = 0f | |
array2.forEach { | |
var m = (it - mean2) | |
devsq += m * m | |
} | |
sqrt(devsq / array2.size) | |
}() | |
return covar / stdevp1 / stdevp2 | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.List; | |
import static java.lang.Math.sqrt; | |
public class MyArrayD { | |
/** | |
* 相加平均 | |
*/ | |
public static double mean(List<Double> array1) { | |
var sum = 0f; | |
for (double f: array1) { | |
sum += f; | |
} | |
return sum / array1.size(); | |
} | |
/** | |
* 偏差平方和 | |
*/ | |
public static double devsq(List<Double> array1) { | |
var mean = mean(array1); | |
var d = 0f; | |
for (double f: array1) { | |
d += (f - mean) * (f - mean); | |
} | |
return d; | |
} | |
/** | |
* 標準偏差 | |
*/ | |
public static double stdevp(List<Double> array1) { | |
return sqrt(devsq(array1) / array1.size()); | |
} | |
/** | |
* 偏差積和 | |
*/ | |
public static double devmulOf(List<Double> array1, List<Double> array2) { | |
var mean1 = mean(array1); | |
var mean2 = mean(array2); | |
var mul = 0f; | |
for (var i = 0;i < array1.size();i++) { | |
mul += (array1.get(i) - mean1) * (array2.get(i) - mean2); | |
} | |
return mul; | |
} | |
/** | |
* 共分散 | |
*/ | |
public static double covarOf(List<Double> array1, List<Double> array2) { | |
return devmulOf(array1, array2) / array1.size(); | |
} | |
/** | |
* 相関係数 | |
*/ | |
public static double correlOf(List<Double> array1, List<Double> array2) { | |
return covarOf(array1, array2) / stdevp(array1) / stdevp(array2); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.List; | |
import static java.lang.Math.sqrt; | |
public class MyArrayF { | |
/** | |
* 相加平均 | |
*/ | |
public static float mean(List<Float> array1) { | |
var sum = 0f; | |
for (float f: array1) { | |
sum += f; | |
} | |
return sum / array1.size(); | |
} | |
/** | |
* 偏差平方和 | |
*/ | |
public static float devsq(List<Float> array1) { | |
var mean = mean(array1); | |
var d = 0f; | |
for (float f: array1) { | |
d += (f - mean) * (f - mean); | |
} | |
return d; | |
} | |
/** | |
* 標準偏差 | |
*/ | |
public static float stdevp(List<Float> array1) { | |
return (float) sqrt(devsq(array1) / array1.size()); | |
} | |
/** | |
* 偏差積和 | |
*/ | |
public static float devmulOf(List<Float> array1, List<Float> array2) { | |
var mean1 = mean(array1); | |
var mean2 = mean(array2); | |
var mul = 0f; | |
for (var i = 0;i < array1.size();i++) { | |
mul += (array1.get(i) - mean1) * (array2.get(i) - mean2); | |
} | |
return mul; | |
} | |
/** | |
* 共分散 | |
*/ | |
public static float covarOf(List<Float> array1, List<Float> array2) { | |
return devmulOf(array1, array2) / array1.size(); | |
} | |
/** | |
* 相関係数 | |
*/ | |
public static float correlOf(List<Float> array1, List<Float> array2) { | |
return covarOf(array1, array2) / stdevp(array1) / stdevp(array2); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment