Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 1 | /* |
| 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> |
| 24 | using std::string; |
| 25 | using std::vector; |
| 26 | using std::hash_map; |
| 27 | using learning_stochastic_linear::StochasticLinearRanker; |
| 28 | using learning_stochastic_linear::SparseWeightVector; |
| 29 | |
| 30 | void CreateSparseWeightVector(JNIEnv* env, const jobjectArray keys, const float* values, |
| 31 | const int length, SparseWeightVector<string> * sample) { |
saberian | b019e89 | 2012-04-19 11:33:44 -0700 | [diff] [blame] | 32 | |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 33 | 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 | |
saberian | b019e89 | 2012-04-19 11:33:44 -0700 | [diff] [blame] | 42 | void 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 Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 51 | void DecomposeSparseWeightVector(JNIEnv* env, jobjectArray *keys, jfloatArray *values, |
| 52 | const int length, SparseWeightVector<string> *sample) { |
| 53 | |
| 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; |
saberian | b019e89 | 2012-04-19 11:33:44 -0700 | [diff] [blame] | 59 | float value = (float) iter->second; |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 60 | jstring jstr = env->NewStringUTF(key.c_str()); |
| 61 | env->SetObjectArrayElement(*keys, i, jstr); |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 62 | jfloat s[1]; |
| 63 | s[0] = value; |
| 64 | env->SetFloatArrayRegion(*values, i, 1, s); |
| 65 | i++; |
| 66 | } |
| 67 | } |
| 68 | |
saberian | b019e89 | 2012-04-19 11:33:44 -0700 | [diff] [blame] | 69 | jboolean Java_android_bordeaux_learning_StochasticLinearRanker_nativeSetWeightClassifier( |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 70 | JNIEnv* env, |
| 71 | jobject thiz, |
| 72 | jobjectArray key_array_model, |
| 73 | jfloatArray value_array_model, |
saberian | b019e89 | 2012-04-19 11:33:44 -0700 | [diff] [blame] | 74 | jfloat normalizer_model, |
Marcus Oakland | 55f6e8b | 2013-03-12 12:49:33 +0000 | [diff] [blame^] | 75 | jlong paPtr) { |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 76 | |
| 77 | StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr; |
saberian | b019e89 | 2012-04-19 11:33:44 -0700 | [diff] [blame] | 78 | if (classifier && key_array_model && value_array_model && normalizer_model) { |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 79 | 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 Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 82 | |
| 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); |
saberian | b019e89 | 2012-04-19 11:33:44 -0700 | [diff] [blame] | 86 | model.SetNormalizer(normalizer_model); |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 87 | classifier->LoadWeights(model); |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 88 | env->ReleaseFloatArrayElements(value_array_model, values_m, JNI_ABORT); |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 89 | return JNI_TRUE; |
| 90 | } |
| 91 | } |
| 92 | return JNI_FALSE; |
| 93 | } |
| 94 | |
saberian | b019e89 | 2012-04-19 11:33:44 -0700 | [diff] [blame] | 95 | jboolean Java_android_bordeaux_learning_StochasticLinearRanker_nativeSetParameterClassifier( |
| 96 | JNIEnv* env, |
| 97 | jobject thiz, |
| 98 | jstring key, |
| 99 | jstring value, |
Marcus Oakland | 55f6e8b | 2013-03-12 12:49:33 +0000 | [diff] [blame^] | 100 | jlong paPtr) { |
saberian | b019e89 | 2012-04-19 11:33:44 -0700 | [diff] [blame] | 101 | |
| 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 Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 229 | jint Java_android_bordeaux_learning_StochasticLinearRanker_nativeGetLengthClassifier( |
| 230 | JNIEnv* env, |
| 231 | jobject thiz, |
Marcus Oakland | 55f6e8b | 2013-03-12 12:49:33 +0000 | [diff] [blame^] | 232 | jlong paPtr) { |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 233 | |
| 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 | |
saberian | b019e89 | 2012-04-19 11:33:44 -0700 | [diff] [blame] | 243 | std::string ConvertFloat2String(float v){ |
| 244 | std::stringstream converter; |
| 245 | converter << v; |
| 246 | return converter.str(); |
| 247 | } |
| 248 | |
| 249 | void Java_android_bordeaux_learning_StochasticLinearRanker_nativeGetParameterClassifier( |
| 250 | JNIEnv* env, |
| 251 | jobject thiz, |
| 252 | jobjectArray key_array_param, |
| 253 | jobjectArray value_array_param, |
Marcus Oakland | 55f6e8b | 2013-03-12 12:49:33 +0000 | [diff] [blame^] | 254 | jlong paPtr){ |
saberian | b019e89 | 2012-04-19 11:33:44 -0700 | [diff] [blame] | 255 | |
| 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 | |
| 368 | void Java_android_bordeaux_learning_StochasticLinearRanker_nativeGetWeightClassifier( |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 369 | JNIEnv* env, |
| 370 | jobject thiz, |
| 371 | jobjectArray key_array_model, |
| 372 | jfloatArray value_array_model, |
saberian | b019e89 | 2012-04-19 11:33:44 -0700 | [diff] [blame] | 373 | jfloat normalizer, |
Marcus Oakland | 55f6e8b | 2013-03-12 12:49:33 +0000 | [diff] [blame^] | 374 | jlong paPtr) { |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 375 | |
| 376 | StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr; |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 377 | SparseWeightVector<string> M_weights; |
| 378 | classifier->SaveWeights(&M_weights); |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 379 | SparseWeightVector<string>::Wmap w_map = M_weights.GetMap(); |
| 380 | int array_len = w_map.size(); |
| 381 | |
saberian | b019e89 | 2012-04-19 11:33:44 -0700 | [diff] [blame] | 382 | normalizer = M_weights.GetNormalizer(); |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 383 | DecomposeSparseWeightVector(env, &key_array_model, &value_array_model, array_len, &M_weights); |
| 384 | } |
| 385 | |
Marcus Oakland | 55f6e8b | 2013-03-12 12:49:33 +0000 | [diff] [blame^] | 386 | jlong Java_android_bordeaux_learning_StochasticLinearRanker_initNativeClassifier(JNIEnv* env, |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 387 | jobject thiz) { |
| 388 | StochasticLinearRanker<string>* classifier = new StochasticLinearRanker<string>(); |
Marcus Oakland | 55f6e8b | 2013-03-12 12:49:33 +0000 | [diff] [blame^] | 389 | return ((jlong) classifier); |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 390 | } |
| 391 | |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 392 | jboolean Java_android_bordeaux_learning_StochasticLinearRanker_deleteNativeClassifier(JNIEnv* env, |
| 393 | jobject thiz, |
Marcus Oakland | 55f6e8b | 2013-03-12 12:49:33 +0000 | [diff] [blame^] | 394 | jlong paPtr) { |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 395 | StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr; |
| 396 | delete classifier; |
| 397 | return JNI_TRUE; |
| 398 | } |
| 399 | |
| 400 | jboolean Java_android_bordeaux_learning_StochasticLinearRanker_nativeUpdateClassifier( |
| 401 | JNIEnv* env, |
| 402 | jobject thiz, |
| 403 | jobjectArray key_array_positive, |
| 404 | jfloatArray value_array_positive, |
| 405 | jobjectArray key_array_negative, |
| 406 | jfloatArray value_array_negative, |
Marcus Oakland | 55f6e8b | 2013-03-12 12:49:33 +0000 | [diff] [blame^] | 407 | jlong paPtr) { |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 408 | StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr; |
| 409 | |
| 410 | if (classifier && key_array_positive && value_array_positive && |
| 411 | key_array_negative && value_array_negative) { |
| 412 | |
| 413 | const int keys_p_len = env->GetArrayLength(key_array_positive); |
| 414 | jfloat* values_p = env->GetFloatArrayElements(value_array_positive, NULL); |
| 415 | const int values_p_len = env->GetArrayLength(value_array_positive); |
| 416 | jfloat* values_n = env->GetFloatArrayElements(value_array_negative, NULL); |
| 417 | const int values_n_len = env->GetArrayLength(value_array_negative); |
| 418 | const int keys_n_len = env->GetArrayLength(key_array_negative); |
| 419 | |
| 420 | if (values_p && key_array_positive && values_p_len == keys_p_len && |
| 421 | values_n && key_array_negative && values_n_len == keys_n_len) { |
| 422 | |
| 423 | SparseWeightVector<string> sample_pos; |
| 424 | SparseWeightVector<string> sample_neg; |
| 425 | CreateSparseWeightVector(env, key_array_positive, values_p, values_p_len, &sample_pos); |
| 426 | CreateSparseWeightVector(env, key_array_negative, values_n, values_n_len, &sample_neg); |
| 427 | classifier->UpdateClassifier(sample_pos, sample_neg); |
| 428 | env->ReleaseFloatArrayElements(value_array_negative, values_n, JNI_ABORT); |
| 429 | env->ReleaseFloatArrayElements(value_array_positive, values_p, JNI_ABORT); |
| 430 | |
| 431 | return JNI_TRUE; |
| 432 | } |
| 433 | env->ReleaseFloatArrayElements(value_array_negative, values_n, JNI_ABORT); |
| 434 | env->ReleaseFloatArrayElements(value_array_positive, values_p, JNI_ABORT); |
| 435 | } |
| 436 | return JNI_FALSE; |
| 437 | } |
| 438 | |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 439 | jfloat Java_android_bordeaux_learning_StochasticLinearRanker_nativeScoreSample( |
| 440 | JNIEnv* env, |
| 441 | jobject thiz, |
| 442 | jobjectArray key_array, |
| 443 | jfloatArray value_array, |
Marcus Oakland | 55f6e8b | 2013-03-12 12:49:33 +0000 | [diff] [blame^] | 444 | jlong paPtr) { |
Wei Hua | 6b4eebc | 2012-03-09 10:24:16 -0800 | [diff] [blame] | 445 | |
| 446 | StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr; |
| 447 | |
| 448 | if (classifier && key_array && value_array) { |
| 449 | |
| 450 | jfloat* values = env->GetFloatArrayElements(value_array, NULL); |
| 451 | const int values_len = env->GetArrayLength(value_array); |
| 452 | const int keys_len = env->GetArrayLength(key_array); |
| 453 | |
| 454 | if (values && key_array && values_len == keys_len) { |
| 455 | SparseWeightVector<string> sample; |
| 456 | CreateSparseWeightVector(env, key_array, values, values_len, &sample); |
| 457 | env->ReleaseFloatArrayElements(value_array, values, JNI_ABORT); |
| 458 | return classifier->ScoreSample(sample); |
| 459 | } |
| 460 | } |
| 461 | return -1; |
| 462 | } |