16b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua/*
26b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * Copyright (C) 2011 The Android Open Source Project
36b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *
46b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * Licensed under the Apache License, Version 2.0 (the "License");
56b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * you may not use this file except in compliance with the License.
66b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * You may obtain a copy of the License at
76b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *
86b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *    http://www.apache.org/licenses/LICENSE-2.0
96b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *
106b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * Unless required by applicable law or agreed to in writing, software
116b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * distributed under the License is distributed on an "AS IS" BASIS,
126b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * See the License for the specific language governing permissions and
146b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * limitations under the License.
156b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua */
166b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
176b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua#include "jni/jni_stochastic_linear_ranker.h"
186b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua#include "native/common_defs.h"
196b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua#include "native/sparse_weight_vector.h"
206b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua#include "native/stochastic_linear_ranker.h"
216b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
226b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua#include <vector>
236b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua#include <string>
246b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huausing std::string;
256b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huausing std::vector;
266b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huausing std::hash_map;
276b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huausing learning_stochastic_linear::StochasticLinearRanker;
286b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huausing learning_stochastic_linear::SparseWeightVector;
296b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
306b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huavoid CreateSparseWeightVector(JNIEnv* env, const jobjectArray keys, const float* values,
316b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    const int length, SparseWeightVector<string> * sample) {
32b019e89cbea221598c482b05ab68b7660b41aa23saberian
336b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  for (int i = 0; i < length; ++i) {
346b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    jboolean iscopy;
356b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    jstring s = (jstring) env->GetObjectArrayElement(keys, i);
366b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    const char *key = env->GetStringUTFChars(s, &iscopy);
376b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    sample->SetElement(key, static_cast<double>(values[i]));
386b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    env->ReleaseStringUTFChars(s,key);
396b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  }
406b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua}
416b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
42b019e89cbea221598c482b05ab68b7660b41aa23saberianvoid ConvertParameter2Object(JNIEnv* env, jobjectArray *keys, jobjectArray *values,
43b019e89cbea221598c482b05ab68b7660b41aa23saberian    const char * name , const char * paramValue, int index) {
44b019e89cbea221598c482b05ab68b7660b41aa23saberian
45b019e89cbea221598c482b05ab68b7660b41aa23saberian    jstring jstrK = env->NewStringUTF(name);
46b019e89cbea221598c482b05ab68b7660b41aa23saberian    jstring jstrV = env->NewStringUTF(paramValue);
47b019e89cbea221598c482b05ab68b7660b41aa23saberian    env->SetObjectArrayElement(*keys, index, jstrK);
48b019e89cbea221598c482b05ab68b7660b41aa23saberian    env->SetObjectArrayElement(*values, index, jstrV);
49b019e89cbea221598c482b05ab68b7660b41aa23saberian}
50b019e89cbea221598c482b05ab68b7660b41aa23saberian
516b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huavoid DecomposeSparseWeightVector(JNIEnv* env, jobjectArray *keys, jfloatArray *values,
526b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    const int length, SparseWeightVector<string> *sample) {
536b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
546b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  SparseWeightVector<string>::Wmap w_ = sample->GetMap();
556b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  int i=0;
566b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  for ( SparseWeightVector<string>::Witer_const iter = w_.begin();
576b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    iter != w_.end(); ++iter) {
586b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    std::string key = iter->first;
59b019e89cbea221598c482b05ab68b7660b41aa23saberian    float value = (float) iter->second;
606b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    jstring jstr = env->NewStringUTF(key.c_str());
616b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    env->SetObjectArrayElement(*keys, i, jstr);
626b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    jfloat s[1];
636b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    s[0] = value;
646b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    env->SetFloatArrayRegion(*values, i, 1, s);
656b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    i++;
666b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  }
676b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua}
686b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
69b019e89cbea221598c482b05ab68b7660b41aa23saberianjboolean Java_android_bordeaux_learning_StochasticLinearRanker_nativeSetWeightClassifier(
706b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    JNIEnv* env,
716b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    jobject thiz,
726b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    jobjectArray key_array_model,
736b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    jfloatArray value_array_model,
74b019e89cbea221598c482b05ab68b7660b41aa23saberian    jfloat normalizer_model,
7555f6e8b32805d662fe05e2e3a8ea6dd9d303a324Marcus Oakland    jlong paPtr) {
766b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
776b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
78b019e89cbea221598c482b05ab68b7660b41aa23saberian  if (classifier && key_array_model && value_array_model && normalizer_model) {
796b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    const int keys_m_len = env->GetArrayLength(key_array_model);
806b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    jfloat* values_m = env->GetFloatArrayElements(value_array_model, NULL);
816b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    const int values_m_len = env->GetArrayLength(value_array_model);
826b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
836b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    if (values_m && key_array_model && values_m_len == keys_m_len) {
846b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua      SparseWeightVector<string> model;
856b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua      CreateSparseWeightVector(env, key_array_model, values_m, values_m_len, &model);
86b019e89cbea221598c482b05ab68b7660b41aa23saberian      model.SetNormalizer(normalizer_model);
876b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua      classifier->LoadWeights(model);
886b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua      env->ReleaseFloatArrayElements(value_array_model, values_m, JNI_ABORT);
896b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua      return JNI_TRUE;
906b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    }
916b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  }
926b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  return JNI_FALSE;
936b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua}
946b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
95b019e89cbea221598c482b05ab68b7660b41aa23saberianjboolean Java_android_bordeaux_learning_StochasticLinearRanker_nativeSetParameterClassifier(
96b019e89cbea221598c482b05ab68b7660b41aa23saberian    JNIEnv* env,
97b019e89cbea221598c482b05ab68b7660b41aa23saberian    jobject thiz,
98b019e89cbea221598c482b05ab68b7660b41aa23saberian    jstring key,
99b019e89cbea221598c482b05ab68b7660b41aa23saberian    jstring value,
10055f6e8b32805d662fe05e2e3a8ea6dd9d303a324Marcus Oakland    jlong paPtr) {
101b019e89cbea221598c482b05ab68b7660b41aa23saberian
102b019e89cbea221598c482b05ab68b7660b41aa23saberian  StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
103b019e89cbea221598c482b05ab68b7660b41aa23saberian  jboolean iscopy;
104b019e89cbea221598c482b05ab68b7660b41aa23saberian  const char *cKey = env->GetStringUTFChars(key, &iscopy);
105b019e89cbea221598c482b05ab68b7660b41aa23saberian  const char *cValue = env->GetStringUTFChars(value, &iscopy);
106b019e89cbea221598c482b05ab68b7660b41aa23saberian  float v;
107b019e89cbea221598c482b05ab68b7660b41aa23saberian  if (strcmp(cKey, ITR_NUM) == 0){
108b019e89cbea221598c482b05ab68b7660b41aa23saberian    sscanf(cValue, "%f", &v);
109b019e89cbea221598c482b05ab68b7660b41aa23saberian    classifier->SetIterationNumber((uint64) v);
110b019e89cbea221598c482b05ab68b7660b41aa23saberian    return JNI_TRUE;
111b019e89cbea221598c482b05ab68b7660b41aa23saberian  }
112b019e89cbea221598c482b05ab68b7660b41aa23saberian  else if (strcmp(cKey, NORM_CONSTRAINT) == 0){
113b019e89cbea221598c482b05ab68b7660b41aa23saberian    sscanf(cValue, "%f", &v);
114b019e89cbea221598c482b05ab68b7660b41aa23saberian    classifier->SetNormConstraint((double) v);
115b019e89cbea221598c482b05ab68b7660b41aa23saberian    return JNI_TRUE;
116b019e89cbea221598c482b05ab68b7660b41aa23saberian  }
117b019e89cbea221598c482b05ab68b7660b41aa23saberian  else if (strcmp(cKey, REG_TYPE) == 0){
118b019e89cbea221598c482b05ab68b7660b41aa23saberian    if (strcmp(cValue, REG_TYPE_L0 ) == 0)
119b019e89cbea221598c482b05ab68b7660b41aa23saberian      classifier->SetRegularizationType(learning_stochastic_linear::L0);
120b019e89cbea221598c482b05ab68b7660b41aa23saberian    else if (strcmp(cValue, REG_TYPE_L1 ) == 0)
121b019e89cbea221598c482b05ab68b7660b41aa23saberian      classifier->SetRegularizationType(learning_stochastic_linear::L1);
122b019e89cbea221598c482b05ab68b7660b41aa23saberian    else if (strcmp(cValue, REG_TYPE_L2 ) == 0)
123b019e89cbea221598c482b05ab68b7660b41aa23saberian      classifier->SetRegularizationType(learning_stochastic_linear::L2);
124b019e89cbea221598c482b05ab68b7660b41aa23saberian    else if (strcmp(cValue, REG_TYPE_L1L2 ) == 0)
125b019e89cbea221598c482b05ab68b7660b41aa23saberian      classifier->SetRegularizationType(learning_stochastic_linear::L1L2);
126b019e89cbea221598c482b05ab68b7660b41aa23saberian    else if (strcmp(cValue, REG_TYPE_L1LInf ) == 0)
127b019e89cbea221598c482b05ab68b7660b41aa23saberian      classifier->SetRegularizationType(learning_stochastic_linear::L1LInf);
128b019e89cbea221598c482b05ab68b7660b41aa23saberian    else {
129b019e89cbea221598c482b05ab68b7660b41aa23saberian      ALOGE("Error: %s is not a Regularization Type", cValue);
130b019e89cbea221598c482b05ab68b7660b41aa23saberian      return JNI_FALSE;
131b019e89cbea221598c482b05ab68b7660b41aa23saberian    }
132b019e89cbea221598c482b05ab68b7660b41aa23saberian    return JNI_TRUE;
133b019e89cbea221598c482b05ab68b7660b41aa23saberian  }
134b019e89cbea221598c482b05ab68b7660b41aa23saberian  else if (strcmp(cKey, LAMBDA) == 0){
135b019e89cbea221598c482b05ab68b7660b41aa23saberian    sscanf(cValue, "%f", &v);
136b019e89cbea221598c482b05ab68b7660b41aa23saberian    classifier->SetLambda((double) v);
137b019e89cbea221598c482b05ab68b7660b41aa23saberian    return JNI_TRUE;
138b019e89cbea221598c482b05ab68b7660b41aa23saberian  }
139b019e89cbea221598c482b05ab68b7660b41aa23saberian  else if (strcmp(cKey, UPDATE_TYPE) == 0){
140b019e89cbea221598c482b05ab68b7660b41aa23saberian    if (strcmp(cValue, UPDATE_TYPE_FULL_CS) == 0)
141b019e89cbea221598c482b05ab68b7660b41aa23saberian      classifier->SetUpdateType(learning_stochastic_linear::FULL_CS);
142b019e89cbea221598c482b05ab68b7660b41aa23saberian    else if (strcmp(cValue, UPDATE_TYPE_CLIP_CS) == 0)
143b019e89cbea221598c482b05ab68b7660b41aa23saberian      classifier->SetUpdateType(learning_stochastic_linear::CLIP_CS);
144b019e89cbea221598c482b05ab68b7660b41aa23saberian    else if (strcmp(cValue, UPDATE_TYPE_REG_CS ) == 0)
145b019e89cbea221598c482b05ab68b7660b41aa23saberian      classifier->SetUpdateType(learning_stochastic_linear::REG_CS);
146b019e89cbea221598c482b05ab68b7660b41aa23saberian    else if (strcmp(cValue, UPDATE_TYPE_SL) == 0)
147b019e89cbea221598c482b05ab68b7660b41aa23saberian      classifier->SetUpdateType(learning_stochastic_linear::SL);
148b019e89cbea221598c482b05ab68b7660b41aa23saberian    else if (strcmp(cValue, UPDATE_TYPE_ADAPTIVE_REG) == 0)
149b019e89cbea221598c482b05ab68b7660b41aa23saberian      classifier->SetUpdateType(learning_stochastic_linear::ADAPTIVE_REG);
150b019e89cbea221598c482b05ab68b7660b41aa23saberian    else {
151b019e89cbea221598c482b05ab68b7660b41aa23saberian      ALOGE("Error: %s is not an Update Type", cValue);
152b019e89cbea221598c482b05ab68b7660b41aa23saberian      return JNI_FALSE;
153b019e89cbea221598c482b05ab68b7660b41aa23saberian    }
154b019e89cbea221598c482b05ab68b7660b41aa23saberian    return JNI_TRUE;
155b019e89cbea221598c482b05ab68b7660b41aa23saberian  }
156b019e89cbea221598c482b05ab68b7660b41aa23saberian  else if (strcmp(cKey, ADAPT_MODE) == 0){
157b019e89cbea221598c482b05ab68b7660b41aa23saberian    if (strcmp(cValue, ADAPT_MODE_CONST ) == 0)
158b019e89cbea221598c482b05ab68b7660b41aa23saberian      classifier->SetAdaptationMode(learning_stochastic_linear::CONST);
159b019e89cbea221598c482b05ab68b7660b41aa23saberian    else if (strcmp(cValue, ADAPT_MODE_INV_LINEAR ) == 0)
160b019e89cbea221598c482b05ab68b7660b41aa23saberian      classifier->SetAdaptationMode(learning_stochastic_linear::INV_LINEAR);
161b019e89cbea221598c482b05ab68b7660b41aa23saberian    else if (strcmp(cValue, ADAPT_MODE_INV_QUADRATIC ) == 0)
162b019e89cbea221598c482b05ab68b7660b41aa23saberian      classifier->SetAdaptationMode(learning_stochastic_linear::INV_QUADRATIC);
163b019e89cbea221598c482b05ab68b7660b41aa23saberian    else if (strcmp(cValue, ADAPT_MODE_INV_SQRT ) == 0)
164b019e89cbea221598c482b05ab68b7660b41aa23saberian      classifier->SetAdaptationMode(learning_stochastic_linear::INV_SQRT);
165b019e89cbea221598c482b05ab68b7660b41aa23saberian    else {
166b019e89cbea221598c482b05ab68b7660b41aa23saberian      ALOGE("Error: %s is not an Adaptation Mode", cValue);
167b019e89cbea221598c482b05ab68b7660b41aa23saberian      return JNI_FALSE;
168b019e89cbea221598c482b05ab68b7660b41aa23saberian    }
169b019e89cbea221598c482b05ab68b7660b41aa23saberian    return JNI_TRUE;
170b019e89cbea221598c482b05ab68b7660b41aa23saberian  }
171b019e89cbea221598c482b05ab68b7660b41aa23saberian  else if (strcmp(cKey, KERNEL_TYPE) == 0){
172b019e89cbea221598c482b05ab68b7660b41aa23saberian    if (strcmp(cValue, KERNEL_TYPE_LINEAR ) == 0)
173b019e89cbea221598c482b05ab68b7660b41aa23saberian      classifier->SetKernelType(learning_stochastic_linear::LINEAR);
174b019e89cbea221598c482b05ab68b7660b41aa23saberian    else if (strcmp(cValue, KERNEL_TYPE_POLY ) == 0)
175b019e89cbea221598c482b05ab68b7660b41aa23saberian      classifier->SetKernelType(learning_stochastic_linear::POLY);
176b019e89cbea221598c482b05ab68b7660b41aa23saberian    else if (strcmp(cValue, KERNEL_TYPE_RBF ) == 0)
177b019e89cbea221598c482b05ab68b7660b41aa23saberian      classifier->SetKernelType(learning_stochastic_linear::RBF);
178b019e89cbea221598c482b05ab68b7660b41aa23saberian    else {
179b019e89cbea221598c482b05ab68b7660b41aa23saberian      ALOGE("Error: %s is not a Kernel Type", cValue);
180b019e89cbea221598c482b05ab68b7660b41aa23saberian      return JNI_FALSE;
181b019e89cbea221598c482b05ab68b7660b41aa23saberian    }
182b019e89cbea221598c482b05ab68b7660b41aa23saberian    return JNI_TRUE;
183b019e89cbea221598c482b05ab68b7660b41aa23saberian  }
184b019e89cbea221598c482b05ab68b7660b41aa23saberian  else if (strcmp(cKey, KERNEL_PARAM) == 0){
185b019e89cbea221598c482b05ab68b7660b41aa23saberian    sscanf(cValue, "%f", &v);
186b019e89cbea221598c482b05ab68b7660b41aa23saberian    classifier->SetKernelParam((double) v);
187b019e89cbea221598c482b05ab68b7660b41aa23saberian    return JNI_TRUE;
188b019e89cbea221598c482b05ab68b7660b41aa23saberian  }
189b019e89cbea221598c482b05ab68b7660b41aa23saberian  else if (strcmp(cKey, KERNEL_GAIN) == 0){
190b019e89cbea221598c482b05ab68b7660b41aa23saberian    sscanf(cValue, "%f", &v);
191b019e89cbea221598c482b05ab68b7660b41aa23saberian    classifier->SetKernelGain((double) v);
192b019e89cbea221598c482b05ab68b7660b41aa23saberian    return JNI_TRUE;
193b019e89cbea221598c482b05ab68b7660b41aa23saberian  }
194b019e89cbea221598c482b05ab68b7660b41aa23saberian  else if (strcmp(cKey, KERNEL_BIAS) == 0){
195b019e89cbea221598c482b05ab68b7660b41aa23saberian    sscanf(cValue, "%f", &v);
196b019e89cbea221598c482b05ab68b7660b41aa23saberian    classifier->SetKernelBias((double) v);
197b019e89cbea221598c482b05ab68b7660b41aa23saberian    return JNI_TRUE;
198b019e89cbea221598c482b05ab68b7660b41aa23saberian  }
199b019e89cbea221598c482b05ab68b7660b41aa23saberian  else if (strcmp(cKey, LOSS_TYPE) == 0){
200b019e89cbea221598c482b05ab68b7660b41aa23saberian    if (strcmp(cValue, LOSS_TYPE_PAIRWISE ) == 0)
201b019e89cbea221598c482b05ab68b7660b41aa23saberian      classifier->SetRankLossType(learning_stochastic_linear::PAIRWISE);
202b019e89cbea221598c482b05ab68b7660b41aa23saberian    else if (strcmp(cValue, LOSS_TYPE_RECIPROCAL_RANK ) == 0)
203b019e89cbea221598c482b05ab68b7660b41aa23saberian      classifier->SetRankLossType(learning_stochastic_linear::RECIPROCAL_RANK);
204b019e89cbea221598c482b05ab68b7660b41aa23saberian    else {
205b019e89cbea221598c482b05ab68b7660b41aa23saberian      ALOGE("Error: %s is not a Kernel Type", cValue);
206b019e89cbea221598c482b05ab68b7660b41aa23saberian      return JNI_FALSE;
207b019e89cbea221598c482b05ab68b7660b41aa23saberian    }
208b019e89cbea221598c482b05ab68b7660b41aa23saberian    return JNI_TRUE;
209b019e89cbea221598c482b05ab68b7660b41aa23saberian  }
210b019e89cbea221598c482b05ab68b7660b41aa23saberian  else if (strcmp(cKey, ACC_PROB) == 0){
211b019e89cbea221598c482b05ab68b7660b41aa23saberian    sscanf(cValue, "%f", &v);
212b019e89cbea221598c482b05ab68b7660b41aa23saberian    classifier->SetAcceptanceProbability((double) v);
213b019e89cbea221598c482b05ab68b7660b41aa23saberian    return JNI_TRUE;
214b019e89cbea221598c482b05ab68b7660b41aa23saberian  }
215b019e89cbea221598c482b05ab68b7660b41aa23saberian  else if (strcmp(cKey, MIN_BATCH_SIZE) == 0){
216b019e89cbea221598c482b05ab68b7660b41aa23saberian    sscanf(cValue, "%f", &v);
217b019e89cbea221598c482b05ab68b7660b41aa23saberian    classifier->SetMiniBatchSize((uint64) v);
218b019e89cbea221598c482b05ab68b7660b41aa23saberian    return JNI_TRUE;
219b019e89cbea221598c482b05ab68b7660b41aa23saberian  }
220b019e89cbea221598c482b05ab68b7660b41aa23saberian  else if (strcmp(cKey, GRAD_L0_NORM) == 0){
221b019e89cbea221598c482b05ab68b7660b41aa23saberian    sscanf(cValue, "%f", &v);
222b019e89cbea221598c482b05ab68b7660b41aa23saberian    classifier->SetGradientL0Norm((int32) v);
223b019e89cbea221598c482b05ab68b7660b41aa23saberian    return JNI_TRUE;
224b019e89cbea221598c482b05ab68b7660b41aa23saberian  }
225b019e89cbea221598c482b05ab68b7660b41aa23saberian  ALOGE("Error: %s is not a ranker parameter", cKey);
226b019e89cbea221598c482b05ab68b7660b41aa23saberian  return JNI_FALSE;
227b019e89cbea221598c482b05ab68b7660b41aa23saberian}
228b019e89cbea221598c482b05ab68b7660b41aa23saberian
2296b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huajint Java_android_bordeaux_learning_StochasticLinearRanker_nativeGetLengthClassifier(
2306b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  JNIEnv* env,
2316b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  jobject thiz,
23255f6e8b32805d662fe05e2e3a8ea6dd9d303a324Marcus Oakland  jlong paPtr) {
2336b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
2346b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
2356b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  SparseWeightVector<string> M_weights;
2366b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  classifier->SaveWeights(&M_weights);
2376b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
2386b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  SparseWeightVector<string>::Wmap w_map = M_weights.GetMap();
2396b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  int len = w_map.size();
2406b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  return len;
2416b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua}
2426b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
243b019e89cbea221598c482b05ab68b7660b41aa23saberianstd::string ConvertFloat2String(float v){
244b019e89cbea221598c482b05ab68b7660b41aa23saberian    std::stringstream converter;
245b019e89cbea221598c482b05ab68b7660b41aa23saberian    converter << v;
246b019e89cbea221598c482b05ab68b7660b41aa23saberian    return converter.str();
247b019e89cbea221598c482b05ab68b7660b41aa23saberian}
248b019e89cbea221598c482b05ab68b7660b41aa23saberian
249b019e89cbea221598c482b05ab68b7660b41aa23saberianvoid Java_android_bordeaux_learning_StochasticLinearRanker_nativeGetParameterClassifier(
250b019e89cbea221598c482b05ab68b7660b41aa23saberian    JNIEnv* env,
251b019e89cbea221598c482b05ab68b7660b41aa23saberian    jobject thiz,
252b019e89cbea221598c482b05ab68b7660b41aa23saberian    jobjectArray key_array_param,
253b019e89cbea221598c482b05ab68b7660b41aa23saberian    jobjectArray value_array_param,
25455f6e8b32805d662fe05e2e3a8ea6dd9d303a324Marcus Oakland    jlong paPtr){
255b019e89cbea221598c482b05ab68b7660b41aa23saberian
256b019e89cbea221598c482b05ab68b7660b41aa23saberian  std::string s;
257b019e89cbea221598c482b05ab68b7660b41aa23saberian  StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
258b019e89cbea221598c482b05ab68b7660b41aa23saberian  s = ConvertFloat2String((float) classifier->GetIterationNumber());
259b019e89cbea221598c482b05ab68b7660b41aa23saberian  ConvertParameter2Object(env, &key_array_param, &value_array_param, ITR_NUM, s.c_str(), 0 );
260b019e89cbea221598c482b05ab68b7660b41aa23saberian
261b019e89cbea221598c482b05ab68b7660b41aa23saberian  s = ConvertFloat2String((float) classifier->GetNormContraint());
262b019e89cbea221598c482b05ab68b7660b41aa23saberian  ConvertParameter2Object(env, &key_array_param, &value_array_param, NORM_CONSTRAINT, s.c_str(), 1 );
263b019e89cbea221598c482b05ab68b7660b41aa23saberian
264b019e89cbea221598c482b05ab68b7660b41aa23saberian  float value = (float) classifier->GetRegularizationType();
265b019e89cbea221598c482b05ab68b7660b41aa23saberian  switch ((int) value) {
266b019e89cbea221598c482b05ab68b7660b41aa23saberian    case learning_stochastic_linear::L0 :
267b019e89cbea221598c482b05ab68b7660b41aa23saberian      s = REG_TYPE_L0;
268b019e89cbea221598c482b05ab68b7660b41aa23saberian      break;
269b019e89cbea221598c482b05ab68b7660b41aa23saberian    case learning_stochastic_linear::L1 :
270b019e89cbea221598c482b05ab68b7660b41aa23saberian      s = REG_TYPE_L1;
271b019e89cbea221598c482b05ab68b7660b41aa23saberian      break;
272b019e89cbea221598c482b05ab68b7660b41aa23saberian    case learning_stochastic_linear::L2 :
273b019e89cbea221598c482b05ab68b7660b41aa23saberian      s = REG_TYPE_L2;
274b019e89cbea221598c482b05ab68b7660b41aa23saberian      break;
275b019e89cbea221598c482b05ab68b7660b41aa23saberian    case learning_stochastic_linear::L1L2 :
276b019e89cbea221598c482b05ab68b7660b41aa23saberian      s = REG_TYPE_L1L2;
277b019e89cbea221598c482b05ab68b7660b41aa23saberian      break;
278b019e89cbea221598c482b05ab68b7660b41aa23saberian    case learning_stochastic_linear::L1LInf :
279b019e89cbea221598c482b05ab68b7660b41aa23saberian      s = REG_TYPE_L1LInf;
280b019e89cbea221598c482b05ab68b7660b41aa23saberian      break;
281b019e89cbea221598c482b05ab68b7660b41aa23saberian  }
282b019e89cbea221598c482b05ab68b7660b41aa23saberian  ConvertParameter2Object(env, &key_array_param, &value_array_param, REG_TYPE, s.c_str(), 2 );
283b019e89cbea221598c482b05ab68b7660b41aa23saberian
284b019e89cbea221598c482b05ab68b7660b41aa23saberian  s = ConvertFloat2String((float) classifier->GetLambda());
285b019e89cbea221598c482b05ab68b7660b41aa23saberian  ConvertParameter2Object(env, &key_array_param, &value_array_param, LAMBDA, s.c_str(), 3 );
286b019e89cbea221598c482b05ab68b7660b41aa23saberian
287b019e89cbea221598c482b05ab68b7660b41aa23saberian  value = (float) classifier->GetUpdateType();
288b019e89cbea221598c482b05ab68b7660b41aa23saberian  switch ((int) value) {
289b019e89cbea221598c482b05ab68b7660b41aa23saberian    case learning_stochastic_linear::FULL_CS :
290b019e89cbea221598c482b05ab68b7660b41aa23saberian      s = UPDATE_TYPE_FULL_CS;
291b019e89cbea221598c482b05ab68b7660b41aa23saberian      break;
292b019e89cbea221598c482b05ab68b7660b41aa23saberian    case learning_stochastic_linear::CLIP_CS :
293b019e89cbea221598c482b05ab68b7660b41aa23saberian      s = UPDATE_TYPE_CLIP_CS;
294b019e89cbea221598c482b05ab68b7660b41aa23saberian      break;
295b019e89cbea221598c482b05ab68b7660b41aa23saberian    case learning_stochastic_linear::REG_CS :
296b019e89cbea221598c482b05ab68b7660b41aa23saberian      s = UPDATE_TYPE_REG_CS;
297b019e89cbea221598c482b05ab68b7660b41aa23saberian      break;
298b019e89cbea221598c482b05ab68b7660b41aa23saberian    case learning_stochastic_linear::SL :
299b019e89cbea221598c482b05ab68b7660b41aa23saberian      s = UPDATE_TYPE_SL;
300b019e89cbea221598c482b05ab68b7660b41aa23saberian      break;
301b019e89cbea221598c482b05ab68b7660b41aa23saberian    case learning_stochastic_linear::ADAPTIVE_REG :
302b019e89cbea221598c482b05ab68b7660b41aa23saberian      s = UPDATE_TYPE_ADAPTIVE_REG;
303b019e89cbea221598c482b05ab68b7660b41aa23saberian      break;
304b019e89cbea221598c482b05ab68b7660b41aa23saberian  }
305b019e89cbea221598c482b05ab68b7660b41aa23saberian  ConvertParameter2Object(env, &key_array_param, &value_array_param, UPDATE_TYPE, s.c_str(), 4 );
306b019e89cbea221598c482b05ab68b7660b41aa23saberian
307b019e89cbea221598c482b05ab68b7660b41aa23saberian  value = (float) classifier->GetAdaptationMode();
308b019e89cbea221598c482b05ab68b7660b41aa23saberian  switch ((int) value) {
309b019e89cbea221598c482b05ab68b7660b41aa23saberian    case learning_stochastic_linear::CONST :
310b019e89cbea221598c482b05ab68b7660b41aa23saberian      s = ADAPT_MODE_CONST;
311b019e89cbea221598c482b05ab68b7660b41aa23saberian      break;
312b019e89cbea221598c482b05ab68b7660b41aa23saberian    case learning_stochastic_linear::INV_LINEAR :
313b019e89cbea221598c482b05ab68b7660b41aa23saberian      s = ADAPT_MODE_INV_LINEAR;
314b019e89cbea221598c482b05ab68b7660b41aa23saberian      break;
315b019e89cbea221598c482b05ab68b7660b41aa23saberian    case learning_stochastic_linear::INV_QUADRATIC :
316b019e89cbea221598c482b05ab68b7660b41aa23saberian      s = ADAPT_MODE_INV_QUADRATIC;
317b019e89cbea221598c482b05ab68b7660b41aa23saberian      break;
318b019e89cbea221598c482b05ab68b7660b41aa23saberian    case learning_stochastic_linear::INV_SQRT :
319b019e89cbea221598c482b05ab68b7660b41aa23saberian      s = ADAPT_MODE_INV_SQRT;
320b019e89cbea221598c482b05ab68b7660b41aa23saberian      break;
321b019e89cbea221598c482b05ab68b7660b41aa23saberian  }
322b019e89cbea221598c482b05ab68b7660b41aa23saberian  ConvertParameter2Object(env, &key_array_param, &value_array_param, ADAPT_MODE, s.c_str(), 5 );
323b019e89cbea221598c482b05ab68b7660b41aa23saberian
324b019e89cbea221598c482b05ab68b7660b41aa23saberian  value = (float) classifier->GetKernelType();
325b019e89cbea221598c482b05ab68b7660b41aa23saberian  switch ((int) value) {
326b019e89cbea221598c482b05ab68b7660b41aa23saberian    case learning_stochastic_linear::LINEAR :
327b019e89cbea221598c482b05ab68b7660b41aa23saberian      s = KERNEL_TYPE_LINEAR;
328b019e89cbea221598c482b05ab68b7660b41aa23saberian      break;
329b019e89cbea221598c482b05ab68b7660b41aa23saberian    case learning_stochastic_linear::POLY :
330b019e89cbea221598c482b05ab68b7660b41aa23saberian      s = KERNEL_TYPE_POLY;
331b019e89cbea221598c482b05ab68b7660b41aa23saberian      break;
332b019e89cbea221598c482b05ab68b7660b41aa23saberian    case learning_stochastic_linear::RBF :
333b019e89cbea221598c482b05ab68b7660b41aa23saberian      s = KERNEL_TYPE_RBF;
334b019e89cbea221598c482b05ab68b7660b41aa23saberian      break;
335b019e89cbea221598c482b05ab68b7660b41aa23saberian  }
336b019e89cbea221598c482b05ab68b7660b41aa23saberian  ConvertParameter2Object(env, &key_array_param, &value_array_param, KERNEL_TYPE, s.c_str(), 6 );
337b019e89cbea221598c482b05ab68b7660b41aa23saberian
338b019e89cbea221598c482b05ab68b7660b41aa23saberian  s = ConvertFloat2String((float) classifier->GetKernelParam());
339b019e89cbea221598c482b05ab68b7660b41aa23saberian  ConvertParameter2Object(env, &key_array_param, &value_array_param, KERNEL_PARAM, s.c_str(), 7 );
340b019e89cbea221598c482b05ab68b7660b41aa23saberian
341b019e89cbea221598c482b05ab68b7660b41aa23saberian  s = ConvertFloat2String((float) classifier->GetKernelGain());
342b019e89cbea221598c482b05ab68b7660b41aa23saberian  ConvertParameter2Object(env, &key_array_param, &value_array_param, KERNEL_GAIN, s.c_str(), 8 );
343b019e89cbea221598c482b05ab68b7660b41aa23saberian
344b019e89cbea221598c482b05ab68b7660b41aa23saberian  s = ConvertFloat2String((float)classifier->GetKernelBias());
345b019e89cbea221598c482b05ab68b7660b41aa23saberian  ConvertParameter2Object(env, &key_array_param, &value_array_param, KERNEL_BIAS, s.c_str(), 9 );
346b019e89cbea221598c482b05ab68b7660b41aa23saberian
347b019e89cbea221598c482b05ab68b7660b41aa23saberian  value = (float) classifier->GetRankLossType();
348b019e89cbea221598c482b05ab68b7660b41aa23saberian  switch ((int) value) {
349b019e89cbea221598c482b05ab68b7660b41aa23saberian    case learning_stochastic_linear::PAIRWISE :
350b019e89cbea221598c482b05ab68b7660b41aa23saberian      s = LOSS_TYPE_PAIRWISE;
351b019e89cbea221598c482b05ab68b7660b41aa23saberian      break;
352b019e89cbea221598c482b05ab68b7660b41aa23saberian    case learning_stochastic_linear::RECIPROCAL_RANK :
353b019e89cbea221598c482b05ab68b7660b41aa23saberian      s = LOSS_TYPE_RECIPROCAL_RANK;
354b019e89cbea221598c482b05ab68b7660b41aa23saberian      break;
355b019e89cbea221598c482b05ab68b7660b41aa23saberian  }
356b019e89cbea221598c482b05ab68b7660b41aa23saberian  ConvertParameter2Object(env, &key_array_param, &value_array_param, LOSS_TYPE, s.c_str(), 10 );
357b019e89cbea221598c482b05ab68b7660b41aa23saberian
358b019e89cbea221598c482b05ab68b7660b41aa23saberian  s = ConvertFloat2String((float) classifier->GetAcceptanceProbability());
359b019e89cbea221598c482b05ab68b7660b41aa23saberian  ConvertParameter2Object(env, &key_array_param, &value_array_param, ACC_PROB, s.c_str(), 11 );
360b019e89cbea221598c482b05ab68b7660b41aa23saberian
361b019e89cbea221598c482b05ab68b7660b41aa23saberian  s = ConvertFloat2String((float) classifier->GetMiniBatchSize());
362b019e89cbea221598c482b05ab68b7660b41aa23saberian  ConvertParameter2Object(env, &key_array_param, &value_array_param, MIN_BATCH_SIZE, s.c_str(), 12 );
363b019e89cbea221598c482b05ab68b7660b41aa23saberian
364b019e89cbea221598c482b05ab68b7660b41aa23saberian  s = ConvertFloat2String((float) classifier->GetGradientL0Norm());
365b019e89cbea221598c482b05ab68b7660b41aa23saberian  ConvertParameter2Object(env, &key_array_param, &value_array_param, GRAD_L0_NORM, s.c_str(), 13 );
366b019e89cbea221598c482b05ab68b7660b41aa23saberian}
367b019e89cbea221598c482b05ab68b7660b41aa23saberian
368b019e89cbea221598c482b05ab68b7660b41aa23saberianvoid Java_android_bordeaux_learning_StochasticLinearRanker_nativeGetWeightClassifier(
3696b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  JNIEnv* env,
3706b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  jobject thiz,
3716b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  jobjectArray key_array_model,
3726b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  jfloatArray value_array_model,
373b019e89cbea221598c482b05ab68b7660b41aa23saberian  jfloat normalizer,
37455f6e8b32805d662fe05e2e3a8ea6dd9d303a324Marcus Oakland  jlong paPtr) {
3756b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
3766b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
3776b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  SparseWeightVector<string> M_weights;
3786b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  classifier->SaveWeights(&M_weights);
3796b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  SparseWeightVector<string>::Wmap w_map = M_weights.GetMap();
3806b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  int array_len = w_map.size();
3816b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
382b019e89cbea221598c482b05ab68b7660b41aa23saberian  normalizer = M_weights.GetNormalizer();
3836b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  DecomposeSparseWeightVector(env, &key_array_model, &value_array_model, array_len, &M_weights);
3846b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua}
3856b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
38655f6e8b32805d662fe05e2e3a8ea6dd9d303a324Marcus Oaklandjlong Java_android_bordeaux_learning_StochasticLinearRanker_initNativeClassifier(JNIEnv* env,
3876b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua                             jobject thiz) {
3886b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  StochasticLinearRanker<string>* classifier = new StochasticLinearRanker<string>();
38955f6e8b32805d662fe05e2e3a8ea6dd9d303a324Marcus Oakland  return ((jlong) classifier);
3906b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua}
3916b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
3926b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huajboolean Java_android_bordeaux_learning_StochasticLinearRanker_deleteNativeClassifier(JNIEnv* env,
3936b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua                               jobject thiz,
39455f6e8b32805d662fe05e2e3a8ea6dd9d303a324Marcus Oakland                               jlong paPtr) {
3956b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
3966b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  delete classifier;
3976b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  return JNI_TRUE;
3986b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua}
3996b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
4006b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huajboolean Java_android_bordeaux_learning_StochasticLinearRanker_nativeUpdateClassifier(
4016b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  JNIEnv* env,
4026b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  jobject thiz,
4036b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  jobjectArray key_array_positive,
4046b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  jfloatArray value_array_positive,
4056b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  jobjectArray key_array_negative,
4066b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  jfloatArray value_array_negative,
40755f6e8b32805d662fe05e2e3a8ea6dd9d303a324Marcus Oakland  jlong paPtr) {
4086b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
4096b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
4106b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  if (classifier && key_array_positive && value_array_positive &&
4116b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua      key_array_negative && value_array_negative) {
4126b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
4136b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    const int keys_p_len = env->GetArrayLength(key_array_positive);
4146b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    jfloat* values_p = env->GetFloatArrayElements(value_array_positive, NULL);
4156b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    const int values_p_len = env->GetArrayLength(value_array_positive);
4166b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    jfloat* values_n = env->GetFloatArrayElements(value_array_negative, NULL);
4176b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    const int values_n_len = env->GetArrayLength(value_array_negative);
4186b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    const int keys_n_len = env->GetArrayLength(key_array_negative);
4196b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
4206b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    if (values_p && key_array_positive && values_p_len == keys_p_len &&
4216b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua      values_n && key_array_negative && values_n_len == keys_n_len) {
4226b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
4236b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua      SparseWeightVector<string> sample_pos;
4246b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua      SparseWeightVector<string> sample_neg;
4256b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua      CreateSparseWeightVector(env, key_array_positive, values_p, values_p_len, &sample_pos);
4266b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua      CreateSparseWeightVector(env, key_array_negative, values_n, values_n_len, &sample_neg);
4276b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua      classifier->UpdateClassifier(sample_pos, sample_neg);
4286b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua      env->ReleaseFloatArrayElements(value_array_negative, values_n, JNI_ABORT);
4296b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua      env->ReleaseFloatArrayElements(value_array_positive, values_p, JNI_ABORT);
4306b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
4316b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua      return JNI_TRUE;
4326b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    }
4336b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    env->ReleaseFloatArrayElements(value_array_negative, values_n, JNI_ABORT);
4346b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    env->ReleaseFloatArrayElements(value_array_positive, values_p, JNI_ABORT);
4356b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  }
4366b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  return JNI_FALSE;
4376b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua}
4386b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
4396b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huajfloat Java_android_bordeaux_learning_StochasticLinearRanker_nativeScoreSample(
4406b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  JNIEnv* env,
4416b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  jobject thiz,
4426b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  jobjectArray key_array,
4436b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  jfloatArray value_array,
44455f6e8b32805d662fe05e2e3a8ea6dd9d303a324Marcus Oakland  jlong paPtr) {
4456b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
4466b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
4476b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
4486b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  if (classifier && key_array && value_array) {
4496b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
4506b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    jfloat* values = env->GetFloatArrayElements(value_array, NULL);
4516b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    const int values_len = env->GetArrayLength(value_array);
4526b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    const int keys_len = env->GetArrayLength(key_array);
4536b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
4546b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    if (values && key_array && values_len == keys_len) {
4556b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua      SparseWeightVector<string> sample;
4566b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua      CreateSparseWeightVector(env, key_array, values, values_len, &sample);
4576b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua      env->ReleaseFloatArrayElements(value_array, values, JNI_ABORT);
4586b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua      return classifier->ScoreSample(sample);
4596b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    }
4606b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  }
4616b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua  return -1;
4626b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua}
463