blob: 6984a667db40171b4816942056cb8d1742050fa7 [file] [log] [blame]
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (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
*
* 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.
*/
#include "jni/jni_stochastic_linear_ranker.h"
#include "native/common_defs.h"
#include "native/sparse_weight_vector.h"
#include "native/stochastic_linear_ranker.h"
#include <vector>
#include <string>
using std::string;
using std::vector;
using std::hash_map;
using learning_stochastic_linear::StochasticLinearRanker;
using learning_stochastic_linear::SparseWeightVector;
void CreateSparseWeightVector(JNIEnv* env, const jobjectArray keys, const float* values,
const int length, SparseWeightVector<string> * sample) {
for (int i = 0; i < length; ++i) {
jboolean iscopy;
jstring s = (jstring) env->GetObjectArrayElement(keys, i);
const char *key = env->GetStringUTFChars(s, &iscopy);
sample->SetElement(key, static_cast<double>(values[i]));
env->ReleaseStringUTFChars(s,key);
}
}
void DecomposeSparseWeightVector(JNIEnv* env, jobjectArray *keys, jfloatArray *values,
const int length, SparseWeightVector<string> *sample) {
SparseWeightVector<string>::Wmap w_ = sample->GetMap();
int i=0;
for ( SparseWeightVector<string>::Witer_const iter = w_.begin();
iter != w_.end(); ++iter) {
std::string key = iter->first;
jstring jstr = env->NewStringUTF(key.c_str());
env->SetObjectArrayElement(*keys, i, jstr);
double value = iter->second;
jfloat s[1];
s[0] = value;
env->SetFloatArrayRegion(*values, i, 1, s);
i++;
}
}
jboolean Java_android_bordeaux_learning_StochasticLinearRanker_nativeLoadClassifier(
JNIEnv* env,
jobject thiz,
jobjectArray key_array_model,
jfloatArray value_array_model,
jfloatArray value_array_param,
jint paPtr) {
StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
if (classifier && key_array_model && value_array_model && value_array_param) {
const int keys_m_len = env->GetArrayLength(key_array_model);
jfloat* values_m = env->GetFloatArrayElements(value_array_model, NULL);
const int values_m_len = env->GetArrayLength(value_array_model);
jfloat* param_m = env->GetFloatArrayElements(value_array_param, NULL);
if (values_m && key_array_model && values_m_len == keys_m_len) {
SparseWeightVector<string> model;
CreateSparseWeightVector(env, key_array_model, values_m, values_m_len, &model);
model.SetNormalizer((double) param_m[0]);
classifier->LoadWeights(model);
classifier->SetIterationNumber((uint64) param_m[1]);
classifier->SetNormConstraint((double) param_m[2]);
switch ((int) param_m[3]){
case 0 :
classifier->SetRegularizationType(learning_stochastic_linear::L0);
break;
case 1 :
classifier->SetRegularizationType(learning_stochastic_linear::L1);
break;
case 2 :
classifier->SetRegularizationType(learning_stochastic_linear::L2);
break;
case 3 :
classifier->SetRegularizationType(learning_stochastic_linear::L1L2);
break;
case 4 :
classifier->SetRegularizationType(learning_stochastic_linear::L1LInf);
break;
}
classifier->SetLambda((double) param_m[4]);
switch ((int) param_m[5]){
case 0 :
classifier->SetUpdateType(learning_stochastic_linear::FULL_CS);
break;
case 1 :
classifier->SetUpdateType(learning_stochastic_linear::CLIP_CS);
break;
case 2 :
classifier->SetUpdateType(learning_stochastic_linear::REG_CS);
break;
case 3 :
classifier->SetUpdateType(learning_stochastic_linear::SL);
break;
case 4 :
classifier->SetUpdateType(learning_stochastic_linear::ADAPTIVE_REG);
break;
}
switch ((int) param_m[6]){
case 0 :
classifier->SetAdaptationMode(learning_stochastic_linear::CONST);
break;
case 1 :
classifier->SetAdaptationMode(learning_stochastic_linear::INV_LINEAR);
break;
case 2 :
classifier->SetAdaptationMode(learning_stochastic_linear::INV_QUADRATIC);
break;
case 3 :
classifier->SetAdaptationMode(learning_stochastic_linear::INV_SQRT);
break;
}
switch ((int) param_m[7]){
case 0 :
classifier->SetKernelType(learning_stochastic_linear::LINEAR, (double) param_m[8],
(double) param_m[9],(double) param_m[10]);
break;
case 1 : classifier->SetKernelType(learning_stochastic_linear::POLY, (double) param_m[8],
(double) param_m[9],(double) param_m[10]);
break;
case 2 : classifier->SetKernelType(learning_stochastic_linear::RBF, (double) param_m[8],
(double) param_m[9],(double) param_m[10]);
break;
}
switch ((int) param_m[11]){
case 0 :
classifier->SetRankLossType(learning_stochastic_linear::PAIRWISE);
break;
case 1 :
classifier->SetRankLossType(learning_stochastic_linear::RECIPROCAL_RANK);
break;
}
classifier->SetAcceptanceProbability((double) param_m[12]);
classifier->SetMiniBatchSize((uint64)param_m[13]);
classifier->SetGradientL0Norm((int32)param_m[14]);
env->ReleaseFloatArrayElements(value_array_model, values_m, JNI_ABORT);
env->ReleaseFloatArrayElements(value_array_param, param_m, JNI_ABORT);
return JNI_TRUE;
}
}
return JNI_FALSE;
}
jint Java_android_bordeaux_learning_StochasticLinearRanker_nativeGetLengthClassifier(
JNIEnv* env,
jobject thiz,
jint paPtr) {
StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
SparseWeightVector<string> M_weights;
classifier->SaveWeights(&M_weights);
SparseWeightVector<string>::Wmap w_map = M_weights.GetMap();
int len = w_map.size();
return len;
}
void Java_android_bordeaux_learning_StochasticLinearRanker_nativeGetClassifier(
JNIEnv* env,
jobject thiz,
jobjectArray key_array_model,
jfloatArray value_array_model,
jfloatArray value_array_param,
jint paPtr) {
StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
SparseWeightVector<string> M_weights;
classifier->SaveWeights(&M_weights);
double Jni_weight_normalizer = M_weights.GetNormalizer();
int Jni_itr_num = classifier->GetIterationNumber();
double Jni_norm_cont = classifier->GetNormContraint();
int Jni_reg_type = classifier->GetRegularizationType();
double Jni_lambda = classifier->GetLambda();
int Jni_update_type = classifier->GetUpdateType();
int Jni_AdaptationMode = classifier->GetAdaptationMode();
double Jni_kernel_param, Jni_kernel_gain, Jni_kernel_bias;
int Jni_kernel_type = classifier->GetKernelType(&Jni_kernel_param, &Jni_kernel_gain, &Jni_kernel_bias);
int Jni_rank_loss_type = classifier->GetRankLossType();
double Jni_accp_prob = classifier->GetAcceptanceProbability();
uint64 Jni_min_batch_size = classifier->GetMiniBatchSize();
int32 Jni_GradL0Norm = classifier->GetGradientL0Norm();
const int Var_num = 15;
jfloat s[Var_num]= { (float) Jni_weight_normalizer,
(float) Jni_itr_num,
(float) Jni_norm_cont,
(float) Jni_reg_type,
(float) Jni_lambda,
(float) Jni_update_type,
(float) Jni_AdaptationMode,
(float) Jni_kernel_type,
(float) Jni_kernel_param,
(float) Jni_kernel_gain,
(float) Jni_kernel_bias,
(float) Jni_rank_loss_type,
(float) Jni_accp_prob,
(float) Jni_min_batch_size,
(float) Jni_GradL0Norm};
env->SetFloatArrayRegion(value_array_param, 0, Var_num, s);
SparseWeightVector<string>::Wmap w_map = M_weights.GetMap();
int array_len = w_map.size();
DecomposeSparseWeightVector(env, &key_array_model, &value_array_model, array_len, &M_weights);
}
jint Java_android_bordeaux_learning_StochasticLinearRanker_initNativeClassifier(JNIEnv* env,
jobject thiz) {
StochasticLinearRanker<string>* classifier = new StochasticLinearRanker<string>();
classifier->SetUpdateType(learning_stochastic_linear::REG_CS);
classifier->SetRegularizationType(learning_stochastic_linear::L2);
return ((jint) classifier);
}
jboolean Java_android_bordeaux_learning_StochasticLinearRanker_deleteNativeClassifier(JNIEnv* env,
jobject thiz,
jint paPtr) {
StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
delete classifier;
return JNI_TRUE;
}
jboolean Java_android_bordeaux_learning_StochasticLinearRanker_nativeUpdateClassifier(
JNIEnv* env,
jobject thiz,
jobjectArray key_array_positive,
jfloatArray value_array_positive,
jobjectArray key_array_negative,
jfloatArray value_array_negative,
jint paPtr) {
StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
if (classifier && key_array_positive && value_array_positive &&
key_array_negative && value_array_negative) {
const int keys_p_len = env->GetArrayLength(key_array_positive);
jfloat* values_p = env->GetFloatArrayElements(value_array_positive, NULL);
const int values_p_len = env->GetArrayLength(value_array_positive);
jfloat* values_n = env->GetFloatArrayElements(value_array_negative, NULL);
const int values_n_len = env->GetArrayLength(value_array_negative);
const int keys_n_len = env->GetArrayLength(key_array_negative);
if (values_p && key_array_positive && values_p_len == keys_p_len &&
values_n && key_array_negative && values_n_len == keys_n_len) {
SparseWeightVector<string> sample_pos;
SparseWeightVector<string> sample_neg;
CreateSparseWeightVector(env, key_array_positive, values_p, values_p_len, &sample_pos);
CreateSparseWeightVector(env, key_array_negative, values_n, values_n_len, &sample_neg);
classifier->UpdateClassifier(sample_pos, sample_neg);
env->ReleaseFloatArrayElements(value_array_negative, values_n, JNI_ABORT);
env->ReleaseFloatArrayElements(value_array_positive, values_p, JNI_ABORT);
return JNI_TRUE;
}
env->ReleaseFloatArrayElements(value_array_negative, values_n, JNI_ABORT);
env->ReleaseFloatArrayElements(value_array_positive, values_p, JNI_ABORT);
}
return JNI_FALSE;
}
jfloat Java_android_bordeaux_learning_StochasticLinearRanker_nativeScoreSample(
JNIEnv* env,
jobject thiz,
jobjectArray key_array,
jfloatArray value_array,
jint paPtr) {
StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
if (classifier && key_array && value_array) {
jfloat* values = env->GetFloatArrayElements(value_array, NULL);
const int values_len = env->GetArrayLength(value_array);
const int keys_len = env->GetArrayLength(key_array);
if (values && key_array && values_len == keys_len) {
SparseWeightVector<string> sample;
CreateSparseWeightVector(env, key_array, values, values_len, &sample);
env->ReleaseFloatArrayElements(value_array, values, JNI_ABORT);
return classifier->ScoreSample(sample);
}
}
return -1;
}