blob: fd45edaa18755bddc341ac2df5c612593562e300 [file] [log] [blame]
Wei Hua6b4eebc2012-03-09 10:24:16 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "jni/jni_stochastic_linear_ranker.h"
18#include "native/common_defs.h"
19#include "native/sparse_weight_vector.h"
20#include "native/stochastic_linear_ranker.h"
21
22#include <vector>
23#include <string>
24using std::string;
25using std::vector;
Dan Alberta08525e2014-11-15 18:37:07 -080026using std::unordered_map;
Wei Hua6b4eebc2012-03-09 10:24:16 -080027using learning_stochastic_linear::StochasticLinearRanker;
28using learning_stochastic_linear::SparseWeightVector;
29
30void CreateSparseWeightVector(JNIEnv* env, const jobjectArray keys, const float* values,
31 const int length, SparseWeightVector<string> * sample) {
saberianb019e892012-04-19 11:33:44 -070032
Wei Hua6b4eebc2012-03-09 10:24:16 -080033 for (int i = 0; i < length; ++i) {
34 jboolean iscopy;
35 jstring s = (jstring) env->GetObjectArrayElement(keys, i);
36 const char *key = env->GetStringUTFChars(s, &iscopy);
37 sample->SetElement(key, static_cast<double>(values[i]));
38 env->ReleaseStringUTFChars(s,key);
39 }
40}
41
saberianb019e892012-04-19 11:33:44 -070042void ConvertParameter2Object(JNIEnv* env, jobjectArray *keys, jobjectArray *values,
43 const char * name , const char * paramValue, int index) {
44
45 jstring jstrK = env->NewStringUTF(name);
46 jstring jstrV = env->NewStringUTF(paramValue);
47 env->SetObjectArrayElement(*keys, index, jstrK);
48 env->SetObjectArrayElement(*values, index, jstrV);
49}
50
Wei Hua6b4eebc2012-03-09 10:24:16 -080051void DecomposeSparseWeightVector(JNIEnv* env, jobjectArray *keys, jfloatArray *values,
Aurimas Liutikas13223cc2016-02-16 12:25:19 -080052 SparseWeightVector<string> *sample) {
Wei Hua6b4eebc2012-03-09 10:24:16 -080053
54 SparseWeightVector<string>::Wmap w_ = sample->GetMap();
55 int i=0;
56 for ( SparseWeightVector<string>::Witer_const iter = w_.begin();
57 iter != w_.end(); ++iter) {
58 std::string key = iter->first;
saberianb019e892012-04-19 11:33:44 -070059 float value = (float) iter->second;
Wei Hua6b4eebc2012-03-09 10:24:16 -080060 jstring jstr = env->NewStringUTF(key.c_str());
61 env->SetObjectArrayElement(*keys, i, jstr);
Wei Hua6b4eebc2012-03-09 10:24:16 -080062 jfloat s[1];
63 s[0] = value;
64 env->SetFloatArrayRegion(*values, i, 1, s);
65 i++;
66 }
67}
68
saberianb019e892012-04-19 11:33:44 -070069jboolean Java_android_bordeaux_learning_StochasticLinearRanker_nativeSetWeightClassifier(
Wei Hua6b4eebc2012-03-09 10:24:16 -080070 JNIEnv* env,
Aurimas Liutikas13223cc2016-02-16 12:25:19 -080071 jobject /* thiz */,
Wei Hua6b4eebc2012-03-09 10:24:16 -080072 jobjectArray key_array_model,
73 jfloatArray value_array_model,
saberianb019e892012-04-19 11:33:44 -070074 jfloat normalizer_model,
Marcus Oakland55f6e8b2013-03-12 12:49:33 +000075 jlong paPtr) {
Wei Hua6b4eebc2012-03-09 10:24:16 -080076
77 StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
saberianb019e892012-04-19 11:33:44 -070078 if (classifier && key_array_model && value_array_model && normalizer_model) {
Wei Hua6b4eebc2012-03-09 10:24:16 -080079 const int keys_m_len = env->GetArrayLength(key_array_model);
80 jfloat* values_m = env->GetFloatArrayElements(value_array_model, NULL);
81 const int values_m_len = env->GetArrayLength(value_array_model);
Wei Hua6b4eebc2012-03-09 10:24:16 -080082
83 if (values_m && key_array_model && values_m_len == keys_m_len) {
84 SparseWeightVector<string> model;
85 CreateSparseWeightVector(env, key_array_model, values_m, values_m_len, &model);
saberianb019e892012-04-19 11:33:44 -070086 model.SetNormalizer(normalizer_model);
Wei Hua6b4eebc2012-03-09 10:24:16 -080087 classifier->LoadWeights(model);
Wei Hua6b4eebc2012-03-09 10:24:16 -080088 env->ReleaseFloatArrayElements(value_array_model, values_m, JNI_ABORT);
Wei Hua6b4eebc2012-03-09 10:24:16 -080089 return JNI_TRUE;
90 }
91 }
92 return JNI_FALSE;
93}
94
saberianb019e892012-04-19 11:33:44 -070095jboolean Java_android_bordeaux_learning_StochasticLinearRanker_nativeSetParameterClassifier(
96 JNIEnv* env,
Aurimas Liutikas13223cc2016-02-16 12:25:19 -080097 jobject /* thiz */,
saberianb019e892012-04-19 11:33:44 -070098 jstring key,
99 jstring value,
Marcus Oakland55f6e8b2013-03-12 12:49:33 +0000100 jlong paPtr) {
saberianb019e892012-04-19 11:33:44 -0700101
102 StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
103 jboolean iscopy;
104 const char *cKey = env->GetStringUTFChars(key, &iscopy);
105 const char *cValue = env->GetStringUTFChars(value, &iscopy);
106 float v;
107 if (strcmp(cKey, ITR_NUM) == 0){
108 sscanf(cValue, "%f", &v);
109 classifier->SetIterationNumber((uint64) v);
110 return JNI_TRUE;
111 }
112 else if (strcmp(cKey, NORM_CONSTRAINT) == 0){
113 sscanf(cValue, "%f", &v);
114 classifier->SetNormConstraint((double) v);
115 return JNI_TRUE;
116 }
117 else if (strcmp(cKey, REG_TYPE) == 0){
118 if (strcmp(cValue, REG_TYPE_L0 ) == 0)
119 classifier->SetRegularizationType(learning_stochastic_linear::L0);
120 else if (strcmp(cValue, REG_TYPE_L1 ) == 0)
121 classifier->SetRegularizationType(learning_stochastic_linear::L1);
122 else if (strcmp(cValue, REG_TYPE_L2 ) == 0)
123 classifier->SetRegularizationType(learning_stochastic_linear::L2);
124 else if (strcmp(cValue, REG_TYPE_L1L2 ) == 0)
125 classifier->SetRegularizationType(learning_stochastic_linear::L1L2);
126 else if (strcmp(cValue, REG_TYPE_L1LInf ) == 0)
127 classifier->SetRegularizationType(learning_stochastic_linear::L1LInf);
128 else {
129 ALOGE("Error: %s is not a Regularization Type", cValue);
130 return JNI_FALSE;
131 }
132 return JNI_TRUE;
133 }
134 else if (strcmp(cKey, LAMBDA) == 0){
135 sscanf(cValue, "%f", &v);
136 classifier->SetLambda((double) v);
137 return JNI_TRUE;
138 }
139 else if (strcmp(cKey, UPDATE_TYPE) == 0){
140 if (strcmp(cValue, UPDATE_TYPE_FULL_CS) == 0)
141 classifier->SetUpdateType(learning_stochastic_linear::FULL_CS);
142 else if (strcmp(cValue, UPDATE_TYPE_CLIP_CS) == 0)
143 classifier->SetUpdateType(learning_stochastic_linear::CLIP_CS);
144 else if (strcmp(cValue, UPDATE_TYPE_REG_CS ) == 0)
145 classifier->SetUpdateType(learning_stochastic_linear::REG_CS);
146 else if (strcmp(cValue, UPDATE_TYPE_SL) == 0)
147 classifier->SetUpdateType(learning_stochastic_linear::SL);
148 else if (strcmp(cValue, UPDATE_TYPE_ADAPTIVE_REG) == 0)
149 classifier->SetUpdateType(learning_stochastic_linear::ADAPTIVE_REG);
150 else {
151 ALOGE("Error: %s is not an Update Type", cValue);
152 return JNI_FALSE;
153 }
154 return JNI_TRUE;
155 }
156 else if (strcmp(cKey, ADAPT_MODE) == 0){
157 if (strcmp(cValue, ADAPT_MODE_CONST ) == 0)
158 classifier->SetAdaptationMode(learning_stochastic_linear::CONST);
159 else if (strcmp(cValue, ADAPT_MODE_INV_LINEAR ) == 0)
160 classifier->SetAdaptationMode(learning_stochastic_linear::INV_LINEAR);
161 else if (strcmp(cValue, ADAPT_MODE_INV_QUADRATIC ) == 0)
162 classifier->SetAdaptationMode(learning_stochastic_linear::INV_QUADRATIC);
163 else if (strcmp(cValue, ADAPT_MODE_INV_SQRT ) == 0)
164 classifier->SetAdaptationMode(learning_stochastic_linear::INV_SQRT);
165 else {
166 ALOGE("Error: %s is not an Adaptation Mode", cValue);
167 return JNI_FALSE;
168 }
169 return JNI_TRUE;
170 }
171 else if (strcmp(cKey, KERNEL_TYPE) == 0){
172 if (strcmp(cValue, KERNEL_TYPE_LINEAR ) == 0)
173 classifier->SetKernelType(learning_stochastic_linear::LINEAR);
174 else if (strcmp(cValue, KERNEL_TYPE_POLY ) == 0)
175 classifier->SetKernelType(learning_stochastic_linear::POLY);
176 else if (strcmp(cValue, KERNEL_TYPE_RBF ) == 0)
177 classifier->SetKernelType(learning_stochastic_linear::RBF);
178 else {
179 ALOGE("Error: %s is not a Kernel Type", cValue);
180 return JNI_FALSE;
181 }
182 return JNI_TRUE;
183 }
184 else if (strcmp(cKey, KERNEL_PARAM) == 0){
185 sscanf(cValue, "%f", &v);
186 classifier->SetKernelParam((double) v);
187 return JNI_TRUE;
188 }
189 else if (strcmp(cKey, KERNEL_GAIN) == 0){
190 sscanf(cValue, "%f", &v);
191 classifier->SetKernelGain((double) v);
192 return JNI_TRUE;
193 }
194 else if (strcmp(cKey, KERNEL_BIAS) == 0){
195 sscanf(cValue, "%f", &v);
196 classifier->SetKernelBias((double) v);
197 return JNI_TRUE;
198 }
199 else if (strcmp(cKey, LOSS_TYPE) == 0){
200 if (strcmp(cValue, LOSS_TYPE_PAIRWISE ) == 0)
201 classifier->SetRankLossType(learning_stochastic_linear::PAIRWISE);
202 else if (strcmp(cValue, LOSS_TYPE_RECIPROCAL_RANK ) == 0)
203 classifier->SetRankLossType(learning_stochastic_linear::RECIPROCAL_RANK);
204 else {
205 ALOGE("Error: %s is not a Kernel Type", cValue);
206 return JNI_FALSE;
207 }
208 return JNI_TRUE;
209 }
210 else if (strcmp(cKey, ACC_PROB) == 0){
211 sscanf(cValue, "%f", &v);
212 classifier->SetAcceptanceProbability((double) v);
213 return JNI_TRUE;
214 }
215 else if (strcmp(cKey, MIN_BATCH_SIZE) == 0){
216 sscanf(cValue, "%f", &v);
217 classifier->SetMiniBatchSize((uint64) v);
218 return JNI_TRUE;
219 }
220 else if (strcmp(cKey, GRAD_L0_NORM) == 0){
221 sscanf(cValue, "%f", &v);
222 classifier->SetGradientL0Norm((int32) v);
223 return JNI_TRUE;
224 }
225 ALOGE("Error: %s is not a ranker parameter", cKey);
226 return JNI_FALSE;
227}
228
Wei Hua6b4eebc2012-03-09 10:24:16 -0800229jint Java_android_bordeaux_learning_StochasticLinearRanker_nativeGetLengthClassifier(
Aurimas Liutikas13223cc2016-02-16 12:25:19 -0800230 JNIEnv* /* env */,
231 jobject /* thiz */,
Marcus Oakland55f6e8b2013-03-12 12:49:33 +0000232 jlong paPtr) {
Wei Hua6b4eebc2012-03-09 10:24:16 -0800233
234 StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
235 SparseWeightVector<string> M_weights;
236 classifier->SaveWeights(&M_weights);
237
238 SparseWeightVector<string>::Wmap w_map = M_weights.GetMap();
239 int len = w_map.size();
240 return len;
241}
242
saberianb019e892012-04-19 11:33:44 -0700243std::string ConvertFloat2String(float v){
244 std::stringstream converter;
245 converter << v;
246 return converter.str();
247}
248
249void Java_android_bordeaux_learning_StochasticLinearRanker_nativeGetParameterClassifier(
250 JNIEnv* env,
Aurimas Liutikas13223cc2016-02-16 12:25:19 -0800251 jobject /* thiz */,
saberianb019e892012-04-19 11:33:44 -0700252 jobjectArray key_array_param,
253 jobjectArray value_array_param,
Marcus Oakland55f6e8b2013-03-12 12:49:33 +0000254 jlong paPtr){
saberianb019e892012-04-19 11:33:44 -0700255
256 std::string s;
257 StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
258 s = ConvertFloat2String((float) classifier->GetIterationNumber());
259 ConvertParameter2Object(env, &key_array_param, &value_array_param, ITR_NUM, s.c_str(), 0 );
260
261 s = ConvertFloat2String((float) classifier->GetNormContraint());
262 ConvertParameter2Object(env, &key_array_param, &value_array_param, NORM_CONSTRAINT, s.c_str(), 1 );
263
264 float value = (float) classifier->GetRegularizationType();
265 switch ((int) value) {
266 case learning_stochastic_linear::L0 :
267 s = REG_TYPE_L0;
268 break;
269 case learning_stochastic_linear::L1 :
270 s = REG_TYPE_L1;
271 break;
272 case learning_stochastic_linear::L2 :
273 s = REG_TYPE_L2;
274 break;
275 case learning_stochastic_linear::L1L2 :
276 s = REG_TYPE_L1L2;
277 break;
278 case learning_stochastic_linear::L1LInf :
279 s = REG_TYPE_L1LInf;
280 break;
281 }
282 ConvertParameter2Object(env, &key_array_param, &value_array_param, REG_TYPE, s.c_str(), 2 );
283
284 s = ConvertFloat2String((float) classifier->GetLambda());
285 ConvertParameter2Object(env, &key_array_param, &value_array_param, LAMBDA, s.c_str(), 3 );
286
287 value = (float) classifier->GetUpdateType();
288 switch ((int) value) {
289 case learning_stochastic_linear::FULL_CS :
290 s = UPDATE_TYPE_FULL_CS;
291 break;
292 case learning_stochastic_linear::CLIP_CS :
293 s = UPDATE_TYPE_CLIP_CS;
294 break;
295 case learning_stochastic_linear::REG_CS :
296 s = UPDATE_TYPE_REG_CS;
297 break;
298 case learning_stochastic_linear::SL :
299 s = UPDATE_TYPE_SL;
300 break;
301 case learning_stochastic_linear::ADAPTIVE_REG :
302 s = UPDATE_TYPE_ADAPTIVE_REG;
303 break;
304 }
305 ConvertParameter2Object(env, &key_array_param, &value_array_param, UPDATE_TYPE, s.c_str(), 4 );
306
307 value = (float) classifier->GetAdaptationMode();
308 switch ((int) value) {
309 case learning_stochastic_linear::CONST :
310 s = ADAPT_MODE_CONST;
311 break;
312 case learning_stochastic_linear::INV_LINEAR :
313 s = ADAPT_MODE_INV_LINEAR;
314 break;
315 case learning_stochastic_linear::INV_QUADRATIC :
316 s = ADAPT_MODE_INV_QUADRATIC;
317 break;
318 case learning_stochastic_linear::INV_SQRT :
319 s = ADAPT_MODE_INV_SQRT;
320 break;
321 }
322 ConvertParameter2Object(env, &key_array_param, &value_array_param, ADAPT_MODE, s.c_str(), 5 );
323
324 value = (float) classifier->GetKernelType();
325 switch ((int) value) {
326 case learning_stochastic_linear::LINEAR :
327 s = KERNEL_TYPE_LINEAR;
328 break;
329 case learning_stochastic_linear::POLY :
330 s = KERNEL_TYPE_POLY;
331 break;
332 case learning_stochastic_linear::RBF :
333 s = KERNEL_TYPE_RBF;
334 break;
335 }
336 ConvertParameter2Object(env, &key_array_param, &value_array_param, KERNEL_TYPE, s.c_str(), 6 );
337
338 s = ConvertFloat2String((float) classifier->GetKernelParam());
339 ConvertParameter2Object(env, &key_array_param, &value_array_param, KERNEL_PARAM, s.c_str(), 7 );
340
341 s = ConvertFloat2String((float) classifier->GetKernelGain());
342 ConvertParameter2Object(env, &key_array_param, &value_array_param, KERNEL_GAIN, s.c_str(), 8 );
343
344 s = ConvertFloat2String((float)classifier->GetKernelBias());
345 ConvertParameter2Object(env, &key_array_param, &value_array_param, KERNEL_BIAS, s.c_str(), 9 );
346
347 value = (float) classifier->GetRankLossType();
348 switch ((int) value) {
349 case learning_stochastic_linear::PAIRWISE :
350 s = LOSS_TYPE_PAIRWISE;
351 break;
352 case learning_stochastic_linear::RECIPROCAL_RANK :
353 s = LOSS_TYPE_RECIPROCAL_RANK;
354 break;
355 }
356 ConvertParameter2Object(env, &key_array_param, &value_array_param, LOSS_TYPE, s.c_str(), 10 );
357
358 s = ConvertFloat2String((float) classifier->GetAcceptanceProbability());
359 ConvertParameter2Object(env, &key_array_param, &value_array_param, ACC_PROB, s.c_str(), 11 );
360
361 s = ConvertFloat2String((float) classifier->GetMiniBatchSize());
362 ConvertParameter2Object(env, &key_array_param, &value_array_param, MIN_BATCH_SIZE, s.c_str(), 12 );
363
364 s = ConvertFloat2String((float) classifier->GetGradientL0Norm());
365 ConvertParameter2Object(env, &key_array_param, &value_array_param, GRAD_L0_NORM, s.c_str(), 13 );
366}
367
368void Java_android_bordeaux_learning_StochasticLinearRanker_nativeGetWeightClassifier(
Wei Hua6b4eebc2012-03-09 10:24:16 -0800369 JNIEnv* env,
Aurimas Liutikas13223cc2016-02-16 12:25:19 -0800370 jobject /* thiz */,
Wei Hua6b4eebc2012-03-09 10:24:16 -0800371 jobjectArray key_array_model,
372 jfloatArray value_array_model,
saberianb019e892012-04-19 11:33:44 -0700373 jfloat normalizer,
Marcus Oakland55f6e8b2013-03-12 12:49:33 +0000374 jlong paPtr) {
Wei Hua6b4eebc2012-03-09 10:24:16 -0800375
376 StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
Wei Hua6b4eebc2012-03-09 10:24:16 -0800377 SparseWeightVector<string> M_weights;
378 classifier->SaveWeights(&M_weights);
Wei Hua6b4eebc2012-03-09 10:24:16 -0800379 SparseWeightVector<string>::Wmap w_map = M_weights.GetMap();
380 int array_len = w_map.size();
381
saberianb019e892012-04-19 11:33:44 -0700382 normalizer = M_weights.GetNormalizer();
Aurimas Liutikas13223cc2016-02-16 12:25:19 -0800383 DecomposeSparseWeightVector(env, &key_array_model, &value_array_model, &M_weights);
Wei Hua6b4eebc2012-03-09 10:24:16 -0800384}
385
Aurimas Liutikas13223cc2016-02-16 12:25:19 -0800386jlong Java_android_bordeaux_learning_StochasticLinearRanker_initNativeClassifier(
387 JNIEnv* /* env */,
388 jobject /* thiz */) {
Wei Hua6b4eebc2012-03-09 10:24:16 -0800389 StochasticLinearRanker<string>* classifier = new StochasticLinearRanker<string>();
Marcus Oakland55f6e8b2013-03-12 12:49:33 +0000390 return ((jlong) classifier);
Wei Hua6b4eebc2012-03-09 10:24:16 -0800391}
392
Aurimas Liutikas13223cc2016-02-16 12:25:19 -0800393jboolean Java_android_bordeaux_learning_StochasticLinearRanker_deleteNativeClassifier(
394 JNIEnv* /* env */,
395 jobject /* thiz */,
396 jlong paPtr) {
Wei Hua6b4eebc2012-03-09 10:24:16 -0800397 StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
398 delete classifier;
399 return JNI_TRUE;
400}
401
402jboolean Java_android_bordeaux_learning_StochasticLinearRanker_nativeUpdateClassifier(
403 JNIEnv* env,
Aurimas Liutikas13223cc2016-02-16 12:25:19 -0800404 jobject /* thiz */,
Wei Hua6b4eebc2012-03-09 10:24:16 -0800405 jobjectArray key_array_positive,
406 jfloatArray value_array_positive,
407 jobjectArray key_array_negative,
408 jfloatArray value_array_negative,
Marcus Oakland55f6e8b2013-03-12 12:49:33 +0000409 jlong paPtr) {
Wei Hua6b4eebc2012-03-09 10:24:16 -0800410 StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
411
412 if (classifier && key_array_positive && value_array_positive &&
413 key_array_negative && value_array_negative) {
414
415 const int keys_p_len = env->GetArrayLength(key_array_positive);
416 jfloat* values_p = env->GetFloatArrayElements(value_array_positive, NULL);
417 const int values_p_len = env->GetArrayLength(value_array_positive);
418 jfloat* values_n = env->GetFloatArrayElements(value_array_negative, NULL);
419 const int values_n_len = env->GetArrayLength(value_array_negative);
420 const int keys_n_len = env->GetArrayLength(key_array_negative);
421
422 if (values_p && key_array_positive && values_p_len == keys_p_len &&
423 values_n && key_array_negative && values_n_len == keys_n_len) {
424
425 SparseWeightVector<string> sample_pos;
426 SparseWeightVector<string> sample_neg;
427 CreateSparseWeightVector(env, key_array_positive, values_p, values_p_len, &sample_pos);
428 CreateSparseWeightVector(env, key_array_negative, values_n, values_n_len, &sample_neg);
429 classifier->UpdateClassifier(sample_pos, sample_neg);
430 env->ReleaseFloatArrayElements(value_array_negative, values_n, JNI_ABORT);
431 env->ReleaseFloatArrayElements(value_array_positive, values_p, JNI_ABORT);
432
433 return JNI_TRUE;
434 }
435 env->ReleaseFloatArrayElements(value_array_negative, values_n, JNI_ABORT);
436 env->ReleaseFloatArrayElements(value_array_positive, values_p, JNI_ABORT);
437 }
438 return JNI_FALSE;
439}
440
Wei Hua6b4eebc2012-03-09 10:24:16 -0800441jfloat Java_android_bordeaux_learning_StochasticLinearRanker_nativeScoreSample(
442 JNIEnv* env,
Aurimas Liutikas13223cc2016-02-16 12:25:19 -0800443 jobject /* thiz */,
Wei Hua6b4eebc2012-03-09 10:24:16 -0800444 jobjectArray key_array,
445 jfloatArray value_array,
Marcus Oakland55f6e8b2013-03-12 12:49:33 +0000446 jlong paPtr) {
Wei Hua6b4eebc2012-03-09 10:24:16 -0800447
448 StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
449
450 if (classifier && key_array && value_array) {
451
452 jfloat* values = env->GetFloatArrayElements(value_array, NULL);
453 const int values_len = env->GetArrayLength(value_array);
454 const int keys_len = env->GetArrayLength(key_array);
455
456 if (values && key_array && values_len == keys_len) {
457 SparseWeightVector<string> sample;
458 CreateSparseWeightVector(env, key_array, values, values_len, &sample);
459 env->ReleaseFloatArrayElements(value_array, values, JNI_ABORT);
460 return classifier->ScoreSample(sample);
461 }
462 }
463 return -1;
464}