summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-05-07 08:47:18 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-05-07 08:47:18 +0000
commit90b08c696adc1c2a32ea50969f5ec495e369787f (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904
parent00cee902ec6ac3d80f3dab80097dbf13e0a475d9 (diff)
parente40bdc75c869050a62c36532606d8a1bc6fd2b7b (diff)
downloadml-oreo-dr1-release.tar.gz
Change-Id: If0af17c654223a00ac8c4eeadad30b1d0880bee8
-rw-r--r--Android.mk18
-rw-r--r--bordeaux/Android.mk18
-rw-r--r--bordeaux/learning/Android.mk50
-rw-r--r--bordeaux/learning/multiclass_pa/Android.mk33
-rw-r--r--bordeaux/learning/multiclass_pa/java/android/bordeaux/learning/MulticlassPA.java68
-rw-r--r--bordeaux/learning/multiclass_pa/jni/jni_multiclass_pa.cpp116
-rw-r--r--bordeaux/learning/multiclass_pa/jni/jni_multiclass_pa.h59
-rw-r--r--bordeaux/learning/multiclass_pa/native/multiclass_pa.cpp250
-rw-r--r--bordeaux/learning/multiclass_pa/native/multiclass_pa.h117
-rw-r--r--bordeaux/learning/multiclass_pa/native/util.cpp52
-rw-r--r--bordeaux/learning/multiclass_pa/native/util.h33
-rw-r--r--bordeaux/learning/predictor_histogram/Android.mk16
-rw-r--r--bordeaux/learning/predictor_histogram/java/android/bordeaux/learning/HistogramPredictor.java384
-rw-r--r--bordeaux/learning/stochastic_linear_ranker/Android.mk34
-rw-r--r--bordeaux/learning/stochastic_linear_ranker/java/android/bordeaux/learning/StochasticLinearRanker.java193
-rw-r--r--bordeaux/learning/stochastic_linear_ranker/jni/jni_stochastic_linear_ranker.cpp461
-rw-r--r--bordeaux/learning/stochastic_linear_ranker/jni/jni_stochastic_linear_ranker.h182
-rw-r--r--bordeaux/learning/stochastic_linear_ranker/native/common_defs.h46
-rw-r--r--bordeaux/learning/stochastic_linear_ranker/native/learning_rate_controller-inl.h127
-rw-r--r--bordeaux/learning/stochastic_linear_ranker/native/sparse_weight_vector.cpp398
-rw-r--r--bordeaux/learning/stochastic_linear_ranker/native/sparse_weight_vector.h204
-rw-r--r--bordeaux/learning/stochastic_linear_ranker/native/stochastic_linear_ranker.cpp139
-rw-r--r--bordeaux/learning/stochastic_linear_ranker/native/stochastic_linear_ranker.h244
-rw-r--r--bordeaux/service/Android.mk79
-rw-r--r--bordeaux/service/AndroidManifest.xml23
-rw-r--r--bordeaux/service/res/drawable-hdpi/ic_bordeaux.pngbin3774 -> 0 bytes
-rw-r--r--bordeaux/service/res/drawable-mdpi/ic_bordeaux.pngbin2911 -> 0 bytes
-rw-r--r--bordeaux/service/res/drawable-xhdpi/ic_bordeaux.pngbin3904 -> 0 bytes
-rw-r--r--bordeaux/service/res/layout/lava_messenger_service_binding.xml69
-rw-r--r--bordeaux/service/res/layout/lava_service_binding.xml59
-rw-r--r--bordeaux/service/res/layout/lava_service_controller.xml42
-rw-r--r--bordeaux/service/res/values/strings.xml59
-rw-r--r--bordeaux/service/src/android/bordeaux/services/Aggregator.java28
-rw-r--r--bordeaux/service/src/android/bordeaux/services/AggregatorManager.java160
-rw-r--r--bordeaux/service/src/android/bordeaux/services/AggregatorRecordStorage.java120
-rw-r--r--bordeaux/service/src/android/bordeaux/services/AggregatorStorage.java57
-rw-r--r--bordeaux/service/src/android/bordeaux/services/BaseCluster.java213
-rw-r--r--bordeaux/service/src/android/bordeaux/services/BordeauxAggregatorManager.java148
-rw-r--r--bordeaux/service/src/android/bordeaux/services/BordeauxClassifier.java103
-rw-r--r--bordeaux/service/src/android/bordeaux/services/BordeauxManagerService.java152
-rw-r--r--bordeaux/service/src/android/bordeaux/services/BordeauxPredictor.java117
-rw-r--r--bordeaux/service/src/android/bordeaux/services/BordeauxRanker.java139
-rw-r--r--bordeaux/service/src/android/bordeaux/services/BordeauxService.java197
-rw-r--r--bordeaux/service/src/android/bordeaux/services/BordeauxSessionManager.java206
-rw-r--r--bordeaux/service/src/android/bordeaux/services/BordeauxSessionStorage.java152
-rw-r--r--bordeaux/service/src/android/bordeaux/services/ClusterManager.java338
-rw-r--r--bordeaux/service/src/android/bordeaux/services/FeatureAssembly.java112
-rw-r--r--bordeaux/service/src/android/bordeaux/services/IAggregatorManager.aidl38
-rw-r--r--bordeaux/service/src/android/bordeaux/services/IBordeauxLearner.java37
-rw-r--r--bordeaux/service/src/android/bordeaux/services/IBordeauxService.aidl51
-rw-r--r--bordeaux/service/src/android/bordeaux/services/IBordeauxServiceCallback.aidl29
-rw-r--r--bordeaux/service/src/android/bordeaux/services/ILearning_MulticlassPA.aidl29
-rw-r--r--bordeaux/service/src/android/bordeaux/services/ILearning_StochasticLinearRanker.aidl34
-rw-r--r--bordeaux/service/src/android/bordeaux/services/IPredictor.aidl26
-rw-r--r--bordeaux/service/src/android/bordeaux/services/IntFloat.aidl3
-rw-r--r--bordeaux/service/src/android/bordeaux/services/IntFloat.java40
-rw-r--r--bordeaux/service/src/android/bordeaux/services/Learning_MulticlassPA.java89
-rw-r--r--bordeaux/service/src/android/bordeaux/services/Learning_StochasticLinearRanker.java146
-rw-r--r--bordeaux/service/src/android/bordeaux/services/LocationCluster.java149
-rw-r--r--bordeaux/service/src/android/bordeaux/services/LocationStatsAggregator.java239
-rw-r--r--bordeaux/service/src/android/bordeaux/services/MotionStatsAggregator.java39
-rw-r--r--bordeaux/service/src/android/bordeaux/services/Predictor.java174
-rw-r--r--bordeaux/service/src/android/bordeaux/services/StochasticLinearRankerWithPrior.java211
-rw-r--r--bordeaux/service/src/android/bordeaux/services/StringFloat.aidl3
-rw-r--r--bordeaux/service/src/android/bordeaux/services/StringFloat.java46
-rw-r--r--bordeaux/service/src/android/bordeaux/services/StringString.aidl3
-rw-r--r--bordeaux/service/src/android/bordeaux/services/StringString.java41
-rw-r--r--bordeaux/service/src/android/bordeaux/services/TimeStatsAggregator.java199
68 files changed, 0 insertions, 7441 deletions
diff --git a/Android.mk b/Android.mk
deleted file mode 100644
index 0918da517..000000000
--- a/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2012 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.
-#
-
-TOP_LOCAL_PATH:= $(call my-dir)
-
-include $(call all-subdir-makefiles)
diff --git a/bordeaux/Android.mk b/bordeaux/Android.mk
deleted file mode 100644
index 0918da517..000000000
--- a/bordeaux/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (C) 2012 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.
-#
-
-TOP_LOCAL_PATH:= $(call my-dir)
-
-include $(call all-subdir-makefiles)
diff --git a/bordeaux/learning/Android.mk b/bordeaux/learning/Android.mk
deleted file mode 100644
index 562a81def..000000000
--- a/bordeaux/learning/Android.mk
+++ /dev/null
@@ -1,50 +0,0 @@
-# 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.
-#
-
-LEARNING_LOCAL_PATH:= $(call my-dir)
-include $(call all-subdir-makefiles)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := samples tests
-
-LOCAL_MODULE := libbordeaux
-
-LOCAL_WHOLE_STATIC_LIBRARIES := libmulticlass_pa libstochastic_linear
-LOCAL_SHARED_LIBRARIES := libcutils liblog
-
-
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/../native
-
-include $(BUILD_SHARED_LIBRARY)
-
-##
-# Build java lib
-##
-LOCAL_PATH:= $(LEARNING_LOCAL_PATH)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := samples tests
-
-LOCAL_SRC_FILES := $(call all-java-files-under, multiclass_pa stochastic_linear_ranker ) \
- $(call all-java-files-under, predictor_histogram)
-
-LOCAL_MODULE := bordeaux_learners
-
-LOCAL_PROGUARD_ENABLED := disabled
-
-LOCAL_JNI_SHARED_LIBRARIES := libbordeaux
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/bordeaux/learning/multiclass_pa/Android.mk b/bordeaux/learning/multiclass_pa/Android.mk
deleted file mode 100644
index c69f69158..000000000
--- a/bordeaux/learning/multiclass_pa/Android.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-# 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-##
-# Build native code
-##
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := samples tests
-
-LOCAL_MODULE := libmulticlass_pa
-
-LOCAL_SRC_FILES := native/multiclass_pa.cpp \
- jni/jni_multiclass_pa.cpp
-
-
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/../native
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/bordeaux/learning/multiclass_pa/java/android/bordeaux/learning/MulticlassPA.java b/bordeaux/learning/multiclass_pa/java/android/bordeaux/learning/MulticlassPA.java
deleted file mode 100644
index 8a868e1cc..000000000
--- a/bordeaux/learning/multiclass_pa/java/android/bordeaux/learning/MulticlassPA.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.
- */
-
-
-package android.bordeaux.learning;
-
-/**
- * Wrapper for multiclass passive aggressive classifier.
- * version 1 supports indexed sparse feature only.
- */
-public class MulticlassPA {
-
- public MulticlassPA(int numClasses, int numDimensions, float aggressiveness) {
- nativeClassifier = initNativeClassifier(numClasses, numDimensions,
- aggressiveness);
- }
-
- /**
- * Train on one example
- */
- public boolean sparseTrainOneExample(int[] index_array,
- float[] float_array,
- int target) {
- return nativeSparseTrainOneExample(
- index_array, float_array, target, nativeClassifier);
- }
-
- /**
- * Train on one example
- */
- public int sparseGetClass(int[] index_array, float[] float_array) {
- return nativeSparseGetClass(index_array, float_array, nativeClassifier);
- }
-
- static {
- System.loadLibrary("bordeaux");
- }
-
- private long nativeClassifier;
-
- /*
- * Initialize native classifier
- */
- private native long initNativeClassifier(int num_classes, int num_dims, float aggressiveness);
-
- private native void deleteNativeClassifier(long classPtr);
-
- private native boolean nativeSparseTrainOneExample(int[] index_array,
- float[] float_array,
- int target, long classPtr);
-
- private native int nativeSparseGetClass(int[] index_array,
- float[] float_array,
- long classPtr);
-}
diff --git a/bordeaux/learning/multiclass_pa/jni/jni_multiclass_pa.cpp b/bordeaux/learning/multiclass_pa/jni/jni_multiclass_pa.cpp
deleted file mode 100644
index 3825586ed..000000000
--- a/bordeaux/learning/multiclass_pa/jni/jni_multiclass_pa.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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_multiclass_pa.h"
-#include "native/multiclass_pa.h"
-
-#include <vector>
-
-using learningfw::MulticlassPA;
-using std::vector;
-using std::pair;
-
-void CreateIndexValuePairs(const int* indices, const float* values,
- const int length, vector<pair<int, float> >* pairs) {
- pairs->clear();
-
- for (int i = 0; i < length; ++i) {
- pair<int, float> new_pair(indices[i], values[i]);
- pairs->push_back(new_pair);
- }
-}
-
-jlong Java_android_bordeaux_learning_MulticlassPA_initNativeClassifier(JNIEnv* /* env */,
- jobject /* thiz */,
- jint num_classes,
- jint num_dims,
- jfloat aggressiveness) {
- MulticlassPA* classifier = new MulticlassPA(num_classes,
- num_dims,
- aggressiveness);
- return ((jlong) classifier);
-}
-
-
-jboolean Java_android_bordeaux_learning_MulticlassPA_deleteNativeClassifier(JNIEnv* /* env */,
- jobject /* thiz */,
- jlong paPtr) {
- MulticlassPA* classifier = (MulticlassPA*) paPtr;
- delete classifier;
- return JNI_TRUE;
-}
-
-jboolean Java_android_bordeaux_learning_MulticlassPA_nativeSparseTrainOneExample(JNIEnv* env,
- jobject /* thiz */,
- jintArray index_array,
- jfloatArray value_array,
- jint target,
- jlong paPtr) {
- MulticlassPA* classifier = (MulticlassPA*) paPtr;
-
- if (classifier && index_array && value_array) {
-
- jfloat* values = env->GetFloatArrayElements(value_array, NULL);
- jint* indices = env->GetIntArrayElements(index_array, NULL);
- const int value_len = env->GetArrayLength(value_array);
- const int index_len = env->GetArrayLength(index_array);
-
- if (values && indices && value_len == index_len) {
- vector<pair<int, float> > inputs;
-
- CreateIndexValuePairs(indices, values, value_len, &inputs);
- classifier->SparseTrainOneExample(inputs, target);
- env->ReleaseIntArrayElements(index_array, indices, JNI_ABORT);
- env->ReleaseFloatArrayElements(value_array, values, JNI_ABORT);
-
- return JNI_TRUE;
- }
- env->ReleaseIntArrayElements(index_array, indices, JNI_ABORT);
- env->ReleaseFloatArrayElements(value_array, values, JNI_ABORT);
- }
-
- return JNI_FALSE;
-}
-
-
-jint Java_android_bordeaux_learning_MulticlassPA_nativeSparseGetClass(JNIEnv* env,
- jobject /* thiz */,
- jintArray index_array,
- jfloatArray value_array,
- jlong paPtr) {
-
- MulticlassPA* classifier = (MulticlassPA*) paPtr;
-
- if (classifier && index_array && value_array) {
-
- jfloat* values = env->GetFloatArrayElements(value_array, NULL);
- jint* indices = env->GetIntArrayElements(index_array, NULL);
- const int value_len = env->GetArrayLength(value_array);
- const int index_len = env->GetArrayLength(index_array);
-
- if (values && indices && value_len == index_len) {
- vector<pair<int, float> > inputs;
- CreateIndexValuePairs(indices, values, value_len, &inputs);
- env->ReleaseIntArrayElements(index_array, indices, JNI_ABORT);
- env->ReleaseFloatArrayElements(value_array, values, JNI_ABORT);
- return classifier->SparseGetClass(inputs);
- }
- env->ReleaseIntArrayElements(index_array, indices, JNI_ABORT);
- env->ReleaseFloatArrayElements(value_array, values, JNI_ABORT);
- }
-
- return -1;
-}
diff --git a/bordeaux/learning/multiclass_pa/jni/jni_multiclass_pa.h b/bordeaux/learning/multiclass_pa/jni/jni_multiclass_pa.h
deleted file mode 100644
index dd0f43d5c..000000000
--- a/bordeaux/learning/multiclass_pa/jni/jni_multiclass_pa.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef LEARNINGFW_JNI_MULTICLASS_PA_H
-#define LEARNINGFW_JNI_MULTICLASS_PA_H
-
-#include <jni.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-JNIEXPORT jlong JNICALL
-Java_android_bordeaux_learning_MulticlassPA_initNativeClassifier(JNIEnv* env,
- jobject thiz,
- jint num_classes,
- jint num_dims,
- jfloat aggressiveness);
-
-
-JNIEXPORT jboolean JNICALL
-Java_android_bordeaux_learning_MulticlassPA_deleteNativeClassifier(JNIEnv* env,
- jobject thiz,
- jlong paPtr);
-
-JNIEXPORT jboolean JNICALL
-Java_android_bordeaux_learning_MulticlassPA_nativeSparseTrainOneExample(JNIEnv* env,
- jobject thiz,
- jintArray index_array,
- jfloatArray value_array,
- jint target,
- jlong paPtr);
-
-JNIEXPORT jint JNICALL
-Java_android_bordeaux_learning_MulticlassPA_nativeSparseGetClass(JNIEnv* env,
- jobject thiz,
- jintArray index_array,
- jfloatArray value_array,
- jlong paPtr);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ANDROID_LEARNINGFW_JNI_MULTICLASS_PA_H */
diff --git a/bordeaux/learning/multiclass_pa/native/multiclass_pa.cpp b/bordeaux/learning/multiclass_pa/native/multiclass_pa.cpp
deleted file mode 100644
index 9ee12b035..000000000
--- a/bordeaux/learning/multiclass_pa/native/multiclass_pa.cpp
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-//
-// This file contains the MulticlassPA class which implements a simple
-// linear multi-class classifier based on the multi-prototype version of
-// passive aggressive.
-
-#include "native/multiclass_pa.h"
-
-#include <stdlib.h>
-
-using std::vector;
-using std::pair;
-
-namespace learningfw {
-
-float RandFloat() {
- return static_cast<float>(rand()) / RAND_MAX;
-}
-
-MulticlassPA::MulticlassPA(int num_classes,
- int num_dimensions,
- float aggressiveness)
- : num_classes_(num_classes),
- num_dimensions_(num_dimensions),
- aggressiveness_(aggressiveness) {
- InitializeParameters();
-}
-
-MulticlassPA::~MulticlassPA() {
-}
-
-void MulticlassPA::InitializeParameters() {
- parameters_.resize(num_classes_);
- for (int i = 0; i < num_classes_; ++i) {
- parameters_[i].resize(num_dimensions_);
- for (int j = 0; j < num_dimensions_; ++j) {
- parameters_[i][j] = 0.0;
- }
- }
-}
-
-int MulticlassPA::PickAClassExcept(int target) {
- int picked;
- do {
- picked = static_cast<int>(RandFloat() * num_classes_);
- // picked = static_cast<int>(random_.RandFloat() * num_classes_);
- } while (target == picked);
- return picked;
-}
-
-int MulticlassPA::PickAnExample(int num_examples) {
- return static_cast<int>(RandFloat() * num_examples);
-}
-
-float MulticlassPA::Score(const vector<float>& inputs,
- const vector<float>& parameters) const {
- // CHECK_EQ(inputs.size(), parameters.size());
- float result = 0.0;
- for (int i = 0; i < static_cast<int>(inputs.size()); ++i) {
- result += inputs[i] * parameters[i];
- }
- return result;
-}
-
-float MulticlassPA::SparseScore(const vector<pair<int, float> >& inputs,
- const vector<float>& parameters) const {
- float result = 0.0;
- for (int i = 0; i < static_cast<int>(inputs.size()); ++i) {
- //DCHECK_GE(inputs[i].first, 0);
- //DCHECK_LT(inputs[i].first, parameters.size());
- result += inputs[i].second * parameters[inputs[i].first];
- }
- return result;
-}
-
-float MulticlassPA::L2NormSquare(const vector<float>& inputs) const {
- float norm = 0;
- for (int i = 0; i < static_cast<int>(inputs.size()); ++i) {
- norm += inputs[i] * inputs[i];
- }
- return norm;
-}
-
-float MulticlassPA::SparseL2NormSquare(
- const vector<pair<int, float> >& inputs) const {
- float norm = 0;
- for (int i = 0; i < static_cast<int>(inputs.size()); ++i) {
- norm += inputs[i].second * inputs[i].second;
- }
- return norm;
-}
-
-float MulticlassPA::TrainOneExample(const vector<float>& inputs, int target) {
- //CHECK_GE(target, 0);
- //CHECK_LT(target, num_classes_);
- float target_class_score = Score(inputs, parameters_[target]);
- // VLOG(1) << "target class " << target << " score " << target_class_score;
- int other_class = PickAClassExcept(target);
- float other_class_score = Score(inputs, parameters_[other_class]);
- // VLOG(1) << "other class " << other_class << " score " << other_class_score;
- float loss = 1.0 - target_class_score + other_class_score;
- if (loss > 0.0) {
- // Compute the learning rate according to PA-I.
- float twice_norm_square = L2NormSquare(inputs) * 2.0;
- if (twice_norm_square == 0.0) {
- twice_norm_square = kEpsilon;
- }
- float rate = loss / twice_norm_square;
- if (rate > aggressiveness_) {
- rate = aggressiveness_;
- }
- // VLOG(1) << "loss = " << loss << " rate = " << rate;
- // Modify the parameter vectors of the correct and wrong classes
- for (int i = 0; i < static_cast<int>(inputs.size()); ++i) {
- // First modify the parameter value of the correct class
- parameters_[target][i] += rate * inputs[i];
- // Then modify the parameter value of the wrong class
- parameters_[other_class][i] -= rate * inputs[i];
- }
- return loss;
- }
- return 0.0;
-}
-
-float MulticlassPA::SparseTrainOneExample(
- const vector<pair<int, float> >& inputs, int target) {
- // CHECK_GE(target, 0);
- // CHECK_LT(target, num_classes_);
- float target_class_score = SparseScore(inputs, parameters_[target]);
- // VLOG(1) << "target class " << target << " score " << target_class_score;
- int other_class = PickAClassExcept(target);
- float other_class_score = SparseScore(inputs, parameters_[other_class]);
- // VLOG(1) << "other class " << other_class << " score " << other_class_score;
- float loss = 1.0 - target_class_score + other_class_score;
- if (loss > 0.0) {
- // Compute the learning rate according to PA-I.
- float twice_norm_square = SparseL2NormSquare(inputs) * 2.0;
- if (twice_norm_square == 0.0) {
- twice_norm_square = kEpsilon;
- }
- float rate = loss / twice_norm_square;
- if (rate > aggressiveness_) {
- rate = aggressiveness_;
- }
- // VLOG(1) << "loss = " << loss << " rate = " << rate;
- // Modify the parameter vectors of the correct and wrong classes
- for (int i = 0; i < static_cast<int>(inputs.size()); ++i) {
- // First modify the parameter value of the correct class
- parameters_[target][inputs[i].first] += rate * inputs[i].second;
- // Then modify the parameter value of the wrong class
- parameters_[other_class][inputs[i].first] -= rate * inputs[i].second;
- }
- return loss;
- }
- return 0.0;
-}
-
-float MulticlassPA::Train(const vector<pair<vector<float>, int> >& data,
- int num_iterations) {
- int num_examples = data.size();
- float total_loss = 0.0;
- for (int t = 0; t < num_iterations; ++t) {
- int index = PickAnExample(num_examples);
- float loss_t = TrainOneExample(data[index].first, data[index].second);
- total_loss += loss_t;
- }
- return total_loss / static_cast<float>(num_iterations);
-}
-
-float MulticlassPA::SparseTrain(
- const vector<pair<vector<pair<int, float> >, int> >& data,
- int num_iterations) {
- int num_examples = data.size();
- float total_loss = 0.0;
- for (int t = 0; t < num_iterations; ++t) {
- int index = PickAnExample(num_examples);
- float loss_t = SparseTrainOneExample(data[index].first, data[index].second);
- total_loss += loss_t;
- }
- return total_loss / static_cast<float>(num_iterations);
-}
-
-int MulticlassPA::GetClass(const vector<float>& inputs) {
- int best_class = -1;
- float best_score = -10000.0;
- // float best_score = -MathLimits<float>::kMax;
- for (int i = 0; i < num_classes_; ++i) {
- float score_i = Score(inputs, parameters_[i]);
- if (score_i > best_score) {
- best_score = score_i;
- best_class = i;
- }
- }
- return best_class;
-}
-
-int MulticlassPA::SparseGetClass(const vector<pair<int, float> >& inputs) {
- int best_class = -1;
- float best_score = -10000.0;
- //float best_score = -MathLimits<float>::kMax;
- for (int i = 0; i < num_classes_; ++i) {
- float score_i = SparseScore(inputs, parameters_[i]);
- if (score_i > best_score) {
- best_score = score_i;
- best_class = i;
- }
- }
- return best_class;
-}
-
-float MulticlassPA::Test(const vector<pair<vector<float>, int> >& data) {
- int num_examples = data.size();
- float total_error = 0.0;
- for (int t = 0; t < num_examples; ++t) {
- int best_class = GetClass(data[t].first);
- if (best_class != data[t].second) {
- ++total_error;
- }
- }
- return total_error / num_examples;
-}
-
-float MulticlassPA::SparseTest(
- const vector<pair<vector<pair<int, float> >, int> >& data) {
- int num_examples = data.size();
- float total_error = 0.0;
- for (int t = 0; t < num_examples; ++t) {
- int best_class = SparseGetClass(data[t].first);
- if (best_class != data[t].second) {
- ++total_error;
- }
- }
- return total_error / num_examples;
-}
-} // namespace learningfw
diff --git a/bordeaux/learning/multiclass_pa/native/multiclass_pa.h b/bordeaux/learning/multiclass_pa/native/multiclass_pa.h
deleted file mode 100644
index c4d99440a..000000000
--- a/bordeaux/learning/multiclass_pa/native/multiclass_pa.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-// This file contains the MulticlassPA class which implements a simple
-// linear multi-class classifier based on the multi-prototype version of
-// passive aggressive.
-
-#ifndef LEARNINGFW_MULTICLASS_PA_H_
-#define LEARNINGFW_MULTICLASS_PA_H_
-
-#include <vector>
-#include <cmath>
-
-const float kEpsilon = 1.0e-4;
-
-namespace learningfw {
-
-class MulticlassPA {
- public:
- MulticlassPA(int num_classes,
- int num_dimensions,
- float aggressiveness);
- virtual ~MulticlassPA();
-
- // Initialize all parameters to 0.0.
- void InitializeParameters();
-
- // Returns a random class that is different from the target class.
- int PickAClassExcept(int target);
-
- // Returns a random example.
- int PickAnExample(int num_examples);
-
- // Computes the score of a given input vector for a given parameter
- // vector, by computing the dot product between the two.
- float Score(const std::vector<float>& inputs,
- const std::vector<float>& parameters) const;
- float SparseScore(const std::vector<std::pair<int, float> >& inputs,
- const std::vector<float>& parameters) const;
-
- // Returns the square of the L2 norm.
- float L2NormSquare(const std::vector<float>& inputs) const;
- float SparseL2NormSquare(const std::vector<std::pair<int, float> >& inputs) const;
-
- // Verify if the given example is correctly classified with margin with
- // respect to a random class. If not, then modifies the corresponding
- // parameters using passive-aggressive.
- virtual float TrainOneExample(const std::vector<float>& inputs, int target);
- virtual float SparseTrainOneExample(
- const std::vector<std::pair<int, float> >& inputs, int target);
-
- // Iteratively train the model for num_iterations on the given dataset.
- float Train(const std::vector<std::pair<std::vector<float>, int> >& data,
- int num_iterations);
- float SparseTrain(
- const std::vector<std::pair<std::vector<std::pair<int, float> >, int> >& data,
- int num_iterations);
-
- // Returns the best class for a given input vector.
- virtual int GetClass(const std::vector<float>& inputs);
- virtual int SparseGetClass(const std::vector<std::pair<int, float> >& inputs);
-
- // Computes the test error of a given test set on the current model.
- float Test(const std::vector<std::pair<std::vector<float>, int> >& data);
- float SparseTest(
- const std::vector<std::pair<std::vector<std::pair<int, float> >, int> >& data);
-
- // A few accessors used by the sub-classes.
- inline float aggressiveness() const {
- return aggressiveness_;
- }
-
- inline std::vector<std::vector<float> >& parameters() {
- return parameters_;
- }
-
- inline std::vector<std::vector<float> >* mutable_parameters() {
- return &parameters_;
- }
-
- inline int num_classes() const {
- return num_classes_;
- }
-
- inline int num_dimensions() const {
- return num_dimensions_;
- }
-
- private:
- // Keeps the current parameter vector.
- std::vector<std::vector<float> > parameters_;
-
- // The number of classes of the problem.
- int num_classes_;
-
- // The number of dimensions of the input vectors.
- int num_dimensions_;
-
- // Controls how "aggressive" training should be.
- float aggressiveness_;
-
-};
-} // namespace learningfw
-#endif // LEARNINGFW_MULTICLASS_PA_H_
diff --git a/bordeaux/learning/multiclass_pa/native/util.cpp b/bordeaux/learning/multiclass_pa/native/util.cpp
deleted file mode 100644
index fc92fe49a..000000000
--- a/bordeaux/learning/multiclass_pa/native/util.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-// This file contains a few utilities for MulticlassPA
-
-#include "learning/multiclass_pa/util.h"
-
-#include <string>
-
-#include "learning/multiclass_pa/multiclass_pa.h"
-#include "learning/multiclass_pa/multiclass_pa_max.h"
-#include "learning/multiclass_pa/multiclass_pa_opt.h"
-#include "learning/multiclass_pa/multiclass_warp.h"
-#include "strings/strutil.h"
-
-namespace learning_multiclass_pa {
-
-MulticlassPA* CreateMulticlassPA(const string& version,
- int32 num_classes,
- int32 num_dimensions,
- float aggressiveness) {
- MulticlassPA* machine = NULL;
- if (StringCaseEqual(version, "max")) {
- machine = reinterpret_cast<MulticlassPA*>(
- new MulticlassPAMax(num_classes, num_dimensions, aggressiveness));
- } else if (StringCaseEqual(version, "opt")) {
- machine = reinterpret_cast<MulticlassPA*>(
- new MulticlassPAOpt(num_classes, num_dimensions, aggressiveness));
- } else if (StringCaseEqual(version, "random")) {
- machine = new MulticlassPA(num_classes, num_dimensions, aggressiveness);
- } else if (StringCaseEqual(version, "warp")) {
- machine = reinterpret_cast<MulticlassPA*>(
- new MulticlassWarp(num_classes, num_dimensions, aggressiveness));
- } else {
- LOG(ERROR) << "Machine type (" << version << ") unknown";
- }
- return machine;
-}
-} // namespace learning_multiclass_pa
diff --git a/bordeaux/learning/multiclass_pa/native/util.h b/bordeaux/learning/multiclass_pa/native/util.h
deleted file mode 100644
index a3aa4b571..000000000
--- a/bordeaux/learning/multiclass_pa/native/util.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-// This file contains some utilities for MulticlassPA
-
-#ifndef LEARNING_MULTICLASS_PA_UTIL_H_
-#define LEARNING_MULTICLASS_PA_UTIL_H_
-
-#include <string>
-
-#include "learning/multiclass_pa/multiclass_pa.h"
-
-namespace learning_multiclass_pa {
-
-MulticlassPA* CreateMulticlassPA(const string& version,
- int32 num_classes,
- int32 num_dimensions,
- float aggressiveness);
-} // namespace learning_multiclass_pa
-#endif // LEARNING_MULTICLASS_PA_UTIL_H_
diff --git a/bordeaux/learning/predictor_histogram/Android.mk b/bordeaux/learning/predictor_histogram/Android.mk
deleted file mode 100644
index 1c352f1cb..000000000
--- a/bordeaux/learning/predictor_histogram/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-# 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.
-#
-
-LOCAL_PATH := $(call my-dir)
diff --git a/bordeaux/learning/predictor_histogram/java/android/bordeaux/learning/HistogramPredictor.java b/bordeaux/learning/predictor_histogram/java/android/bordeaux/learning/HistogramPredictor.java
deleted file mode 100644
index e63f40dd9..000000000
--- a/bordeaux/learning/predictor_histogram/java/android/bordeaux/learning/HistogramPredictor.java
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * 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.
- */
-
-package android.bordeaux.learning;
-
-import android.util.Log;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.ConcurrentHashMap;
-/**
- * A histogram based predictor which records co-occurrences of applations with a speficic
- * feature, for example, location, * time of day, etc. The histogram is kept in a two level
- * hash table. The first level key is the feature value and the second level key is the app
- * id.
- */
-// TODOS:
-// 1. Use forgetting factor to downweight istances propotional to the time
-// 2. Different features could have different weights on prediction scores.
-// 3. Add function to remove sampleid (i.e. remove apps that are uninstalled).
-
-
-public class HistogramPredictor {
- final static String TAG = "HistogramPredictor";
-
- private HashMap<String, HistogramCounter> mPredictor =
- new HashMap<String, HistogramCounter>();
-
- private HashMap<String, Integer> mClassCounts = new HashMap<String, Integer>();
- private HashSet<String> mBlacklist = new HashSet<String>();
-
- private static final int MINIMAL_FEATURE_VALUE_COUNTS = 5;
- private static final int MINIMAL_APP_APPEARANCE_COUNTS = 5;
-
- // This parameter ranges from 0 to 1 which determines the effect of app prior.
- // When it is set to 0, app prior means completely neglected. When it is set to 1
- // the predictor is a standard naive bayes model.
- private static final int PRIOR_K_VALUE = 1;
-
- private static final String[] APP_BLACKLIST = {
- "com.android.contacts",
- "com.android.chrome",
- "com.android.providers.downloads.ui",
- "com.android.settings",
- "com.android.vending",
- "com.android.mms",
- "com.google.android.gm",
- "com.google.android.gallery3d",
- "com.google.android.apps.googlevoice",
- };
-
- public HistogramPredictor(String[] blackList) {
- for (String appName : blackList) {
- mBlacklist.add(appName);
- }
- }
-
- /*
- * This class keeps the histogram counts for each feature and provide the
- * joint probabilities of <feature, class>.
- */
- private class HistogramCounter {
- private HashMap<String, HashMap<String, Integer> > mCounter =
- new HashMap<String, HashMap<String, Integer> >();
-
- public HistogramCounter() {
- mCounter.clear();
- }
-
- public void setCounter(HashMap<String, HashMap<String, Integer> > counter) {
- resetCounter();
- mCounter.putAll(counter);
- }
-
- public void resetCounter() {
- mCounter.clear();
- }
-
- public void addSample(String className, String featureValue) {
- HashMap<String, Integer> classCounts;
-
- if (!mCounter.containsKey(featureValue)) {
- classCounts = new HashMap<String, Integer>();
- mCounter.put(featureValue, classCounts);
- } else {
- classCounts = mCounter.get(featureValue);
- }
- int count = (classCounts.containsKey(className)) ?
- classCounts.get(className) + 1 : 1;
- classCounts.put(className, count);
- }
-
- public HashMap<String, Double> getClassScores(String featureValue) {
- HashMap<String, Double> classScores = new HashMap<String, Double>();
-
- if (mCounter.containsKey(featureValue)) {
- int totalCount = 0;
- for(Map.Entry<String, Integer> entry :
- mCounter.get(featureValue).entrySet()) {
- String app = entry.getKey();
- int count = entry.getValue();
-
- // For apps with counts less than or equal to one, we treated
- // those as having count one. Hence their score, i.e. log(count)
- // would be zero. classScroes stores only apps with non-zero scores.
- // Note that totalCount also neglect app with single occurrence.
- if (count > 1) {
- double score = Math.log((double) count);
- classScores.put(app, score);
- totalCount += count;
- }
- }
- if (totalCount < MINIMAL_FEATURE_VALUE_COUNTS) {
- classScores.clear();
- }
- }
- return classScores;
- }
-
- public byte[] getModel() {
- try {
- ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
- ObjectOutputStream objStream = new ObjectOutputStream(byteStream);
- synchronized(mCounter) {
- objStream.writeObject(mCounter);
- }
- byte[] bytes = byteStream.toByteArray();
- return bytes;
- } catch (IOException e) {
- throw new RuntimeException("Can't get model");
- }
- }
-
- public boolean setModel(final byte[] modelData) {
- mCounter.clear();
- HashMap<String, HashMap<String, Integer> > model;
-
- try {
- ByteArrayInputStream input = new ByteArrayInputStream(modelData);
- ObjectInputStream objStream = new ObjectInputStream(input);
- model = (HashMap<String, HashMap<String, Integer> >) objStream.readObject();
- } catch (IOException e) {
- throw new RuntimeException("Can't load model");
- } catch (ClassNotFoundException e) {
- throw new RuntimeException("Learning class not found");
- }
-
- synchronized(mCounter) {
- mCounter.putAll(model);
- }
-
- return true;
- }
-
-
- public HashMap<String, HashMap<String, Integer> > getCounter() {
- return mCounter;
- }
-
- public String toString() {
- String result = "";
- for (Map.Entry<String, HashMap<String, Integer> > entry :
- mCounter.entrySet()) {
- result += "{ " + entry.getKey() + " : " +
- entry.getValue().toString() + " }";
- }
- return result;
- }
- }
-
- /*
- * Given a map of feature name -value pairs returns topK mostly likely apps to
- * be launched with corresponding likelihoods. If topK is set zero, it will return
- * the whole list.
- */
- public List<Map.Entry<String, Double> > findTopClasses(Map<String, String> features, int topK) {
- // Most sophisticated function in this class
- HashMap<String, Double> appScores = new HashMap<String, Double>();
- int validFeatureCount = 0;
-
- // compute all app scores
- for (Map.Entry<String, HistogramCounter> entry : mPredictor.entrySet()) {
- String featureName = entry.getKey();
- HistogramCounter counter = entry.getValue();
-
- if (features.containsKey(featureName)) {
- String featureValue = features.get(featureName);
- HashMap<String, Double> scoreMap = counter.getClassScores(featureValue);
-
- if (scoreMap.isEmpty()) {
- continue;
- }
- validFeatureCount++;
-
- for (Map.Entry<String, Double> item : scoreMap.entrySet()) {
- String appName = item.getKey();
- double appScore = item.getValue();
- if (appScores.containsKey(appName)) {
- appScore += appScores.get(appName);
- }
- appScores.put(appName, appScore);
- }
- }
- }
-
- HashMap<String, Double> appCandidates = new HashMap<String, Double>();
- for (Map.Entry<String, Double> entry : appScores.entrySet()) {
- String appName = entry.getKey();
- if (mBlacklist.contains(appName)) {
- Log.i(TAG, appName + " is in blacklist");
- continue;
- }
- if (!mClassCounts.containsKey(appName)) {
- throw new RuntimeException("class count error!");
- }
- int appCount = mClassCounts.get(appName);
- if (appCount < MINIMAL_APP_APPEARANCE_COUNTS) {
- Log.i(TAG, appName + " doesn't have enough counts");
- continue;
- }
-
- double appScore = entry.getValue();
- double appPrior = Math.log((double) appCount);
- appCandidates.put(appName,
- appScore - appPrior * (validFeatureCount - PRIOR_K_VALUE));
- }
-
- // sort app scores
- List<Map.Entry<String, Double> > appList =
- new ArrayList<Map.Entry<String, Double> >(appCandidates.size());
- appList.addAll(appCandidates.entrySet());
- Collections.sort(appList, new Comparator<Map.Entry<String, Double> >() {
- public int compare(Map.Entry<String, Double> o1,
- Map.Entry<String, Double> o2) {
- return o2.getValue().compareTo(o1.getValue());
- }
- });
-
- if (topK == 0) {
- topK = appList.size();
- }
- return appList.subList(0, Math.min(topK, appList.size()));
- }
-
- /*
- * Add a new observation of given sample id and features to the histograms
- */
- public void addSample(String sampleId, Map<String, String> features) {
- for (Map.Entry<String, String> entry : features.entrySet()) {
- String featureName = entry.getKey();
- String featureValue = entry.getValue();
-
- useFeature(featureName);
- HistogramCounter counter = mPredictor.get(featureName);
- counter.addSample(sampleId, featureValue);
- }
-
- int sampleCount = (mClassCounts.containsKey(sampleId)) ?
- mClassCounts.get(sampleId) + 1 : 1;
- mClassCounts.put(sampleId, sampleCount);
- }
-
- /*
- * reset predictor to a empty model
- */
- public void resetPredictor() {
- // TODO: not sure this step would reduce memory waste
- for (HistogramCounter counter : mPredictor.values()) {
- counter.resetCounter();
- }
- mPredictor.clear();
- mClassCounts.clear();
- }
-
- /*
- * convert the prediction model into a byte array
- */
- public byte[] getModel() {
- // TODO: convert model to a more memory efficient data structure.
- HashMap<String, HashMap<String, HashMap<String, Integer > > > model =
- new HashMap<String, HashMap<String, HashMap<String, Integer > > >();
- for(Map.Entry<String, HistogramCounter> entry : mPredictor.entrySet()) {
- model.put(entry.getKey(), entry.getValue().getCounter());
- }
-
- try {
- ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
- ObjectOutputStream objStream = new ObjectOutputStream(byteStream);
- objStream.writeObject(model);
- byte[] bytes = byteStream.toByteArray();
- return bytes;
- } catch (IOException e) {
- throw new RuntimeException("Can't get model");
- }
- }
-
- /*
- * set the prediction model from a model data in the format of byte array
- */
- public boolean setModel(final byte[] modelData) {
- HashMap<String, HashMap<String, HashMap<String, Integer > > > model;
-
- try {
- ByteArrayInputStream input = new ByteArrayInputStream(modelData);
- ObjectInputStream objStream = new ObjectInputStream(input);
- model = (HashMap<String, HashMap<String, HashMap<String, Integer > > >)
- objStream.readObject();
- } catch (IOException e) {
- throw new RuntimeException("Can't load model");
- } catch (ClassNotFoundException e) {
- throw new RuntimeException("Learning class not found");
- }
-
- resetPredictor();
- for (Map.Entry<String, HashMap<String, HashMap<String, Integer> > > entry :
- model.entrySet()) {
- useFeature(entry.getKey());
- mPredictor.get(entry.getKey()).setCounter(entry.getValue());
- }
-
- // TODO: this is a temporary fix for now
- loadClassCounter();
-
- return true;
- }
-
- private void loadClassCounter() {
- String TIME_OF_WEEK = "Time of Week";
-
- if (!mPredictor.containsKey(TIME_OF_WEEK)) {
- throw new RuntimeException("Precition model error: missing Time of Week!");
- }
-
- HashMap<String, HashMap<String, Integer> > counter =
- mPredictor.get(TIME_OF_WEEK).getCounter();
-
- mClassCounts.clear();
- for (HashMap<String, Integer> map : counter.values()) {
- for (Map.Entry<String, Integer> entry : map.entrySet()) {
- int classCount = entry.getValue();
- String className = entry.getKey();
- // mTotalClassCount += classCount;
-
- if (mClassCounts.containsKey(className)) {
- classCount += mClassCounts.get(className);
- }
- mClassCounts.put(className, classCount);
- }
- }
- Log.i(TAG, "class counts: " + mClassCounts);
- }
-
- private void useFeature(String featureName) {
- if (!mPredictor.containsKey(featureName)) {
- mPredictor.put(featureName, new HistogramCounter());
- }
- }
-}
diff --git a/bordeaux/learning/stochastic_linear_ranker/Android.mk b/bordeaux/learning/stochastic_linear_ranker/Android.mk
deleted file mode 100644
index 62f0fd3a0..000000000
--- a/bordeaux/learning/stochastic_linear_ranker/Android.mk
+++ /dev/null
@@ -1,34 +0,0 @@
-# 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-##
-# Build native code
-##
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := samples tests
-
-LOCAL_MODULE := libstochastic_linear
-
-LOCAL_SRC_FILES := native/stochastic_linear_ranker.cpp \
- native/sparse_weight_vector.cpp \
- jni/jni_stochastic_linear_ranker.cpp
-
-
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/../native
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/bordeaux/learning/stochastic_linear_ranker/java/android/bordeaux/learning/StochasticLinearRanker.java b/bordeaux/learning/stochastic_linear_ranker/java/android/bordeaux/learning/StochasticLinearRanker.java
deleted file mode 100644
index 59f32a955..000000000
--- a/bordeaux/learning/stochastic_linear_ranker/java/android/bordeaux/learning/StochasticLinearRanker.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * 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.
- */
-
-
-package android.bordeaux.learning;
-
-import android.util.Log;
-
-import java.io.Serializable;
-import java.util.List;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Stochastic Linear Ranker, learns how to rank a sample. The learned rank score
- * can be used to compare samples.
- * This java class wraps the native StochasticLinearRanker class.
- * To update the ranker, call updateClassifier with two samples, with the first
- * one having higher rank than the second one.
- * To get the rank score of the sample call scoreSample.
- * TODO: adding more interfaces for changing the learning parameters
- */
-public class StochasticLinearRanker {
- String TAG = "StochasticLinearRanker";
- public static int VAR_NUM = 14;
- static public class Model implements Serializable {
- public HashMap<String, Float> weights = new HashMap<String, Float>();
- public float weightNormalizer = 1;
- public HashMap<String, String> parameters = new HashMap<String, String>();
- }
-
- /**
- * Initializing a ranker
- */
- public StochasticLinearRanker() {
- mNativeClassifier = initNativeClassifier();
- }
-
- /**
- * Reset the ranker
- */
- public void resetRanker(){
- deleteNativeClassifier(mNativeClassifier);
- mNativeClassifier = initNativeClassifier();
- }
-
- /**
- * Train the ranker with a pair of samples. A sample, a pair of arrays of
- * keys and values. The first sample should have higher rank than the second
- * one.
- */
- public boolean updateClassifier(String[] keys_positive,
- float[] values_positive,
- String[] keys_negative,
- float[] values_negative) {
- return nativeUpdateClassifier(keys_positive, values_positive,
- keys_negative, values_negative,
- mNativeClassifier);
- }
-
- /**
- * Get the rank score of the sample, a sample is a list of key, value pairs.
- */
- public float scoreSample(String[] keys, float[] values) {
- return nativeScoreSample(keys, values, mNativeClassifier);
- }
-
- /**
- * Get the current model and parameters of ranker
- */
- public Model getUModel(){
- Model slrModel = new Model();
- int len = nativeGetLengthClassifier(mNativeClassifier);
- String[] wKeys = new String[len];
- float[] wValues = new float[len];
- float wNormalizer = 1;
- nativeGetWeightClassifier(wKeys, wValues, wNormalizer, mNativeClassifier);
- slrModel.weightNormalizer = wNormalizer;
- for (int i=0; i< wKeys.length ; i++)
- slrModel.weights.put(wKeys[i], wValues[i]);
-
- String[] paramKeys = new String[VAR_NUM];
- String[] paramValues = new String[VAR_NUM];
- nativeGetParameterClassifier(paramKeys, paramValues, mNativeClassifier);
- for (int i=0; i< paramKeys.length ; i++)
- slrModel.parameters.put(paramKeys[i], paramValues[i]);
- return slrModel;
- }
-
- /**
- * load the given model and parameters to the ranker
- */
- public boolean loadModel(Model model) {
- String[] wKeys = new String[model.weights.size()];
- float[] wValues = new float[model.weights.size()];
- int i = 0 ;
- for (Map.Entry<String, Float> e : model.weights.entrySet()){
- wKeys[i] = e.getKey();
- wValues[i] = e.getValue();
- i++;
- }
- boolean res = setModelWeights(wKeys, wValues, model.weightNormalizer);
- if (!res)
- return false;
-
- for (Map.Entry<String, String> e : model.parameters.entrySet()){
- res = setModelParameter(e.getKey(), e.getValue());
- if (!res)
- return false;
- }
- return res;
- }
-
- public boolean setModelWeights(String[] keys, float [] values, float normalizer){
- return nativeSetWeightClassifier(keys, values, normalizer, mNativeClassifier);
- }
-
- public boolean setModelParameter(String key, String value){
- boolean res = nativeSetParameterClassifier(key, value, mNativeClassifier);
- return res;
- }
-
- /**
- * Print a model for debugging
- */
- public void print(Model model){
- String Sw = "";
- String Sp = "";
- for (Map.Entry<String, Float> e : model.weights.entrySet())
- Sw = Sw + "<" + e.getKey() + "," + e.getValue() + "> ";
- for (Map.Entry<String, String> e : model.parameters.entrySet())
- Sp = Sp + "<" + e.getKey() + "," + e.getValue() + "> ";
- Log.i(TAG, "Weights are " + Sw);
- Log.i(TAG, "Normalizer is " + model.weightNormalizer);
- Log.i(TAG, "Parameters are " + Sp);
- }
-
- @Override
- protected void finalize() throws Throwable {
- deleteNativeClassifier(mNativeClassifier);
- }
-
- static {
- System.loadLibrary("bordeaux");
- }
-
- private long mNativeClassifier;
-
- /*
- * The following methods are the java stubs for the jni implementations.
- */
- private native long initNativeClassifier();
-
- private native void deleteNativeClassifier(long classifierPtr);
-
- private native boolean nativeUpdateClassifier(
- String[] keys_positive,
- float[] values_positive,
- String[] keys_negative,
- float[] values_negative,
- long classifierPtr);
-
- private native float nativeScoreSample(String[] keys, float[] values, long classifierPtr);
-
- private native void nativeGetWeightClassifier(String [] keys, float[] values, float normalizer,
- long classifierPtr);
-
- private native void nativeGetParameterClassifier(String [] keys, String[] values,
- long classifierPtr);
-
- private native int nativeGetLengthClassifier(long classifierPtr);
-
- private native boolean nativeSetWeightClassifier(String [] keys, float[] values,
- float normalizer, long classifierPtr);
-
- private native boolean nativeSetParameterClassifier(String key, String value,
- long classifierPtr);
-}
diff --git a/bordeaux/learning/stochastic_linear_ranker/jni/jni_stochastic_linear_ranker.cpp b/bordeaux/learning/stochastic_linear_ranker/jni/jni_stochastic_linear_ranker.cpp
deleted file mode 100644
index 34709e457..000000000
--- a/bordeaux/learning/stochastic_linear_ranker/jni/jni_stochastic_linear_ranker.cpp
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * 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::unordered_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 ConvertParameter2Object(JNIEnv* env, jobjectArray *keys, jobjectArray *values,
- const char * name , const char * paramValue, int index) {
-
- jstring jstrK = env->NewStringUTF(name);
- jstring jstrV = env->NewStringUTF(paramValue);
- env->SetObjectArrayElement(*keys, index, jstrK);
- env->SetObjectArrayElement(*values, index, jstrV);
-}
-
-void DecomposeSparseWeightVector(JNIEnv* env, jobjectArray *keys, jfloatArray *values,
- 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;
- float value = (float) iter->second;
- jstring jstr = env->NewStringUTF(key.c_str());
- env->SetObjectArrayElement(*keys, i, jstr);
- jfloat s[1];
- s[0] = value;
- env->SetFloatArrayRegion(*values, i, 1, s);
- i++;
- }
-}
-
-jboolean Java_android_bordeaux_learning_StochasticLinearRanker_nativeSetWeightClassifier(
- JNIEnv* env,
- jobject /* thiz */,
- jobjectArray key_array_model,
- jfloatArray value_array_model,
- jfloat normalizer_model,
- jlong paPtr) {
-
- StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
- if (classifier && key_array_model && value_array_model && normalizer_model) {
- 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);
-
- 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(normalizer_model);
- classifier->LoadWeights(model);
- env->ReleaseFloatArrayElements(value_array_model, values_m, JNI_ABORT);
- return JNI_TRUE;
- }
- }
- return JNI_FALSE;
-}
-
-jboolean Java_android_bordeaux_learning_StochasticLinearRanker_nativeSetParameterClassifier(
- JNIEnv* env,
- jobject /* thiz */,
- jstring key,
- jstring value,
- jlong paPtr) {
-
- StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
- jboolean iscopy;
- const char *cKey = env->GetStringUTFChars(key, &iscopy);
- const char *cValue = env->GetStringUTFChars(value, &iscopy);
- float v;
- if (strcmp(cKey, ITR_NUM) == 0){
- sscanf(cValue, "%f", &v);
- classifier->SetIterationNumber((uint64) v);
- return JNI_TRUE;
- }
- else if (strcmp(cKey, NORM_CONSTRAINT) == 0){
- sscanf(cValue, "%f", &v);
- classifier->SetNormConstraint((double) v);
- return JNI_TRUE;
- }
- else if (strcmp(cKey, REG_TYPE) == 0){
- if (strcmp(cValue, REG_TYPE_L0 ) == 0)
- classifier->SetRegularizationType(learning_stochastic_linear::L0);
- else if (strcmp(cValue, REG_TYPE_L1 ) == 0)
- classifier->SetRegularizationType(learning_stochastic_linear::L1);
- else if (strcmp(cValue, REG_TYPE_L2 ) == 0)
- classifier->SetRegularizationType(learning_stochastic_linear::L2);
- else if (strcmp(cValue, REG_TYPE_L1L2 ) == 0)
- classifier->SetRegularizationType(learning_stochastic_linear::L1L2);
- else if (strcmp(cValue, REG_TYPE_L1LInf ) == 0)
- classifier->SetRegularizationType(learning_stochastic_linear::L1LInf);
- else {
- ALOGE("Error: %s is not a Regularization Type", cValue);
- return JNI_FALSE;
- }
- return JNI_TRUE;
- }
- else if (strcmp(cKey, LAMBDA) == 0){
- sscanf(cValue, "%f", &v);
- classifier->SetLambda((double) v);
- return JNI_TRUE;
- }
- else if (strcmp(cKey, UPDATE_TYPE) == 0){
- if (strcmp(cValue, UPDATE_TYPE_FULL_CS) == 0)
- classifier->SetUpdateType(learning_stochastic_linear::FULL_CS);
- else if (strcmp(cValue, UPDATE_TYPE_CLIP_CS) == 0)
- classifier->SetUpdateType(learning_stochastic_linear::CLIP_CS);
- else if (strcmp(cValue, UPDATE_TYPE_REG_CS ) == 0)
- classifier->SetUpdateType(learning_stochastic_linear::REG_CS);
- else if (strcmp(cValue, UPDATE_TYPE_SL) == 0)
- classifier->SetUpdateType(learning_stochastic_linear::SL);
- else if (strcmp(cValue, UPDATE_TYPE_ADAPTIVE_REG) == 0)
- classifier->SetUpdateType(learning_stochastic_linear::ADAPTIVE_REG);
- else {
- ALOGE("Error: %s is not an Update Type", cValue);
- return JNI_FALSE;
- }
- return JNI_TRUE;
- }
- else if (strcmp(cKey, ADAPT_MODE) == 0){
- if (strcmp(cValue, ADAPT_MODE_CONST ) == 0)
- classifier->SetAdaptationMode(learning_stochastic_linear::CONST);
- else if (strcmp(cValue, ADAPT_MODE_INV_LINEAR ) == 0)
- classifier->SetAdaptationMode(learning_stochastic_linear::INV_LINEAR);
- else if (strcmp(cValue, ADAPT_MODE_INV_QUADRATIC ) == 0)
- classifier->SetAdaptationMode(learning_stochastic_linear::INV_QUADRATIC);
- else if (strcmp(cValue, ADAPT_MODE_INV_SQRT ) == 0)
- classifier->SetAdaptationMode(learning_stochastic_linear::INV_SQRT);
- else {
- ALOGE("Error: %s is not an Adaptation Mode", cValue);
- return JNI_FALSE;
- }
- return JNI_TRUE;
- }
- else if (strcmp(cKey, KERNEL_TYPE) == 0){
- if (strcmp(cValue, KERNEL_TYPE_LINEAR ) == 0)
- classifier->SetKernelType(learning_stochastic_linear::LINEAR);
- else if (strcmp(cValue, KERNEL_TYPE_POLY ) == 0)
- classifier->SetKernelType(learning_stochastic_linear::POLY);
- else if (strcmp(cValue, KERNEL_TYPE_RBF ) == 0)
- classifier->SetKernelType(learning_stochastic_linear::RBF);
- else {
- ALOGE("Error: %s is not a Kernel Type", cValue);
- return JNI_FALSE;
- }
- return JNI_TRUE;
- }
- else if (strcmp(cKey, KERNEL_PARAM) == 0){
- sscanf(cValue, "%f", &v);
- classifier->SetKernelParam((double) v);
- return JNI_TRUE;
- }
- else if (strcmp(cKey, KERNEL_GAIN) == 0){
- sscanf(cValue, "%f", &v);
- classifier->SetKernelGain((double) v);
- return JNI_TRUE;
- }
- else if (strcmp(cKey, KERNEL_BIAS) == 0){
- sscanf(cValue, "%f", &v);
- classifier->SetKernelBias((double) v);
- return JNI_TRUE;
- }
- else if (strcmp(cKey, LOSS_TYPE) == 0){
- if (strcmp(cValue, LOSS_TYPE_PAIRWISE ) == 0)
- classifier->SetRankLossType(learning_stochastic_linear::PAIRWISE);
- else if (strcmp(cValue, LOSS_TYPE_RECIPROCAL_RANK ) == 0)
- classifier->SetRankLossType(learning_stochastic_linear::RECIPROCAL_RANK);
- else {
- ALOGE("Error: %s is not a Kernel Type", cValue);
- return JNI_FALSE;
- }
- return JNI_TRUE;
- }
- else if (strcmp(cKey, ACC_PROB) == 0){
- sscanf(cValue, "%f", &v);
- classifier->SetAcceptanceProbability((double) v);
- return JNI_TRUE;
- }
- else if (strcmp(cKey, MIN_BATCH_SIZE) == 0){
- sscanf(cValue, "%f", &v);
- classifier->SetMiniBatchSize((uint64) v);
- return JNI_TRUE;
- }
- else if (strcmp(cKey, GRAD_L0_NORM) == 0){
- sscanf(cValue, "%f", &v);
- classifier->SetGradientL0Norm((int32) v);
- return JNI_TRUE;
- }
- ALOGE("Error: %s is not a ranker parameter", cKey);
- return JNI_FALSE;
-}
-
-jint Java_android_bordeaux_learning_StochasticLinearRanker_nativeGetLengthClassifier(
- JNIEnv* /* env */,
- jobject /* thiz */,
- jlong 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;
-}
-
-std::string ConvertFloat2String(float v){
- std::stringstream converter;
- converter << v;
- return converter.str();
-}
-
-void Java_android_bordeaux_learning_StochasticLinearRanker_nativeGetParameterClassifier(
- JNIEnv* env,
- jobject /* thiz */,
- jobjectArray key_array_param,
- jobjectArray value_array_param,
- jlong paPtr){
-
- std::string s;
- StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
- s = ConvertFloat2String((float) classifier->GetIterationNumber());
- ConvertParameter2Object(env, &key_array_param, &value_array_param, ITR_NUM, s.c_str(), 0 );
-
- s = ConvertFloat2String((float) classifier->GetNormContraint());
- ConvertParameter2Object(env, &key_array_param, &value_array_param, NORM_CONSTRAINT, s.c_str(), 1 );
-
- float value = (float) classifier->GetRegularizationType();
- switch ((int) value) {
- case learning_stochastic_linear::L0 :
- s = REG_TYPE_L0;
- break;
- case learning_stochastic_linear::L1 :
- s = REG_TYPE_L1;
- break;
- case learning_stochastic_linear::L2 :
- s = REG_TYPE_L2;
- break;
- case learning_stochastic_linear::L1L2 :
- s = REG_TYPE_L1L2;
- break;
- case learning_stochastic_linear::L1LInf :
- s = REG_TYPE_L1LInf;
- break;
- }
- ConvertParameter2Object(env, &key_array_param, &value_array_param, REG_TYPE, s.c_str(), 2 );
-
- s = ConvertFloat2String((float) classifier->GetLambda());
- ConvertParameter2Object(env, &key_array_param, &value_array_param, LAMBDA, s.c_str(), 3 );
-
- value = (float) classifier->GetUpdateType();
- switch ((int) value) {
- case learning_stochastic_linear::FULL_CS :
- s = UPDATE_TYPE_FULL_CS;
- break;
- case learning_stochastic_linear::CLIP_CS :
- s = UPDATE_TYPE_CLIP_CS;
- break;
- case learning_stochastic_linear::REG_CS :
- s = UPDATE_TYPE_REG_CS;
- break;
- case learning_stochastic_linear::SL :
- s = UPDATE_TYPE_SL;
- break;
- case learning_stochastic_linear::ADAPTIVE_REG :
- s = UPDATE_TYPE_ADAPTIVE_REG;
- break;
- }
- ConvertParameter2Object(env, &key_array_param, &value_array_param, UPDATE_TYPE, s.c_str(), 4 );
-
- value = (float) classifier->GetAdaptationMode();
- switch ((int) value) {
- case learning_stochastic_linear::CONST :
- s = ADAPT_MODE_CONST;
- break;
- case learning_stochastic_linear::INV_LINEAR :
- s = ADAPT_MODE_INV_LINEAR;
- break;
- case learning_stochastic_linear::INV_QUADRATIC :
- s = ADAPT_MODE_INV_QUADRATIC;
- break;
- case learning_stochastic_linear::INV_SQRT :
- s = ADAPT_MODE_INV_SQRT;
- break;
- }
- ConvertParameter2Object(env, &key_array_param, &value_array_param, ADAPT_MODE, s.c_str(), 5 );
-
- value = (float) classifier->GetKernelType();
- switch ((int) value) {
- case learning_stochastic_linear::LINEAR :
- s = KERNEL_TYPE_LINEAR;
- break;
- case learning_stochastic_linear::POLY :
- s = KERNEL_TYPE_POLY;
- break;
- case learning_stochastic_linear::RBF :
- s = KERNEL_TYPE_RBF;
- break;
- }
- ConvertParameter2Object(env, &key_array_param, &value_array_param, KERNEL_TYPE, s.c_str(), 6 );
-
- s = ConvertFloat2String((float) classifier->GetKernelParam());
- ConvertParameter2Object(env, &key_array_param, &value_array_param, KERNEL_PARAM, s.c_str(), 7 );
-
- s = ConvertFloat2String((float) classifier->GetKernelGain());
- ConvertParameter2Object(env, &key_array_param, &value_array_param, KERNEL_GAIN, s.c_str(), 8 );
-
- s = ConvertFloat2String((float)classifier->GetKernelBias());
- ConvertParameter2Object(env, &key_array_param, &value_array_param, KERNEL_BIAS, s.c_str(), 9 );
-
- value = (float) classifier->GetRankLossType();
- switch ((int) value) {
- case learning_stochastic_linear::PAIRWISE :
- s = LOSS_TYPE_PAIRWISE;
- break;
- case learning_stochastic_linear::RECIPROCAL_RANK :
- s = LOSS_TYPE_RECIPROCAL_RANK;
- break;
- }
- ConvertParameter2Object(env, &key_array_param, &value_array_param, LOSS_TYPE, s.c_str(), 10 );
-
- s = ConvertFloat2String((float) classifier->GetAcceptanceProbability());
- ConvertParameter2Object(env, &key_array_param, &value_array_param, ACC_PROB, s.c_str(), 11 );
-
- s = ConvertFloat2String((float) classifier->GetMiniBatchSize());
- ConvertParameter2Object(env, &key_array_param, &value_array_param, MIN_BATCH_SIZE, s.c_str(), 12 );
-
- s = ConvertFloat2String((float) classifier->GetGradientL0Norm());
- ConvertParameter2Object(env, &key_array_param, &value_array_param, GRAD_L0_NORM, s.c_str(), 13 );
-}
-
-void Java_android_bordeaux_learning_StochasticLinearRanker_nativeGetWeightClassifier(
- JNIEnv* env,
- jobject /* thiz */,
- jobjectArray key_array_model,
- jfloatArray value_array_model,
- jfloat /* normalizer */,
- jlong paPtr) {
-
- StochasticLinearRanker<string>* classifier = (StochasticLinearRanker<string>*) paPtr;
- SparseWeightVector<string> M_weights;
- classifier->SaveWeights(&M_weights);
- SparseWeightVector<string>::Wmap w_map = M_weights.GetMap();
- DecomposeSparseWeightVector(env, &key_array_model, &value_array_model, &M_weights);
-}
-
-jlong Java_android_bordeaux_learning_StochasticLinearRanker_initNativeClassifier(
- JNIEnv* /* env */,
- jobject /* thiz */) {
- StochasticLinearRanker<string>* classifier = new StochasticLinearRanker<string>();
- return ((jlong) classifier);
-}
-
-jboolean Java_android_bordeaux_learning_StochasticLinearRanker_deleteNativeClassifier(
- JNIEnv* /* env */,
- jobject /* thiz */,
- jlong 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,
- jlong 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,
- jlong 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;
-}
diff --git a/bordeaux/learning/stochastic_linear_ranker/jni/jni_stochastic_linear_ranker.h b/bordeaux/learning/stochastic_linear_ranker/jni/jni_stochastic_linear_ranker.h
deleted file mode 100644
index fd187b009..000000000
--- a/bordeaux/learning/stochastic_linear_ranker/jni/jni_stochastic_linear_ranker.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#ifndef LEARNING_JNI_STOCHASTIC_LINEAR_RANKER_H
-#define LEARNING_JNI_STOCHASTIC_LINEAR_RANKER_H
-
-#include <jni.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Counts the number of learning iterations. */
-const char * ITR_NUM = "IterationNumber";
-
-/* The maximum norm of the weight vector. If norm of weights are larger than NormConstraint
- they will be reprojected using RegularizationType to satisfy this constraint. */
-const char * NORM_CONSTRAINT = "NormConstraint";
-
-/* Ddetermines type of the regularization used in learning.
- This regularization can be based on different norms.
- Options: "L0", "L1", "L2", "L1L2", "L1LInf".
- Default : LINEAR */
-const char * REG_TYPE = "RegularizationType";
-
-/* Lambda is a factor that is multiplied with the step size in learning. This can be used
- to change the step size.
- Default : 1.0 */
-const char * LAMBDA = "Lambda";
-
-/* This parameter determines the update type in learning process.
- Options: "FULL_CS" , "CLIP_CS", "REG_CS", "SL", "ADAPTIVE_REG"
- Default : "SL" */
-const char * UPDATE_TYPE = "UpdateType";
-
-/* Options: "CONST", "INV_LINEAR", "INV_QUADRATIC", "INV_SQRT"
- Default: "INV_LINEAR". */
-const char * ADAPT_MODE = "AdaptationMode";
-
-/* Three differnt kernels are supported: Linear "LINEAR", Polynomial "POLY", and RBF "RBF"
- Default : "LINEAR" */
-const char * KERNEL_TYPE = "KernelType";
-
-/* Kernel param is kernel-specific. In case of polynomial kernel, it is the degree of the
- polynomial. In case of RBF kernel, it implies the sigma parameter. In case of linear
- kernel, it is not used. */
-const char * KERNEL_PARAM = "KernelParameter";
-
-/* Kernel gain is typically a multiplicative factor to the dot product while calculating
- the kernel function. In most use cases, gain should be set to 1.0. */
-const char * KERNEL_GAIN = "KernelGain";
-
-/* Kernel bias is typically an additive factors to the dot product while calculating
- the kernel function. In most use cases, bias should be set to 0.0. */
-const char * KERNEL_BIAS = "KernelBias";
-
-/* This parameter determines the type of loss function to minimize.
- Options : "PAIRWISE", "RECIPROCAL_RANK"
- Default : "PAIRWISE" */
-const char * LOSS_TYPE = "LossType";
-
-/* The minimum percent of training pairs that are used in training.
- Default : "0.1" */
-const char * ACC_PROB = "AcceptaceProbability";
-
-/* The code averages out gradient updates for MinimumBatchSize samples
- before performing an iteration of the algorithm. */
-const char * MIN_BATCH_SIZE = "MinimumBatchSize";
-
-/* Specifies the number of non-zero entries allowed in a gradient.
- Default is -1 which means we take the gradient as given by data without
- adding any new constraints. positive number is treated as an L0 constraint */
-const char * GRAD_L0_NORM = "GradientL0Nrom";
-
-const char * REG_TYPE_L0 = "L0";
-const char * REG_TYPE_L1 = "L1";
-const char * REG_TYPE_L2 = "L2";
-const char * REG_TYPE_L1L2 = "L1L2";
-const char * REG_TYPE_L1LInf = "L1LInf";
-const char * UPDATE_TYPE_FULL_CS = "FULL_CS";
-const char * UPDATE_TYPE_CLIP_CS = "CLIP_CS";
-const char * UPDATE_TYPE_REG_CS = "REG_CS";
-const char * UPDATE_TYPE_SL = "SL";
-const char * UPDATE_TYPE_ADAPTIVE_REG = "ADAPTIVE_REG";
-const char * ADAPT_MODE_CONST = "CONST";
-const char * ADAPT_MODE_INV_LINEAR = "INV_LINEAR";
-const char * ADAPT_MODE_INV_QUADRATIC = "INV_QUADRATIC";
-const char * ADAPT_MODE_INV_SQRT = "INV_SQRT";
-const char * KERNEL_TYPE_LINEAR = "LINEAR";
-const char * KERNEL_TYPE_POLY = "POLY";
-const char * KERNEL_TYPE_RBF = "RBF";
-const char * LOSS_TYPE_PAIRWISE = "PAIRWISE";
-const char * LOSS_TYPE_RECIPROCAL_RANK = "RECIPROCAL_RANK";
-
-JNIEXPORT jlong JNICALL
-Java_android_bordeaux_learning_StochasticLinearRanker_initNativeClassifier(
- JNIEnv* env,
- jobject thiz);
-
-
-JNIEXPORT jboolean JNICALL
-Java_android_bordeaux_learning_StochasticLinearRanker_deleteNativeClassifier(
- JNIEnv* env,
- jobject thiz,
- jlong paPtr);
-
-JNIEXPORT jboolean JNICALL
-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,
- jlong paPtr);
-
-JNIEXPORT jfloat JNICALL
-Java_android_bordeaux_learning_StochasticLinearRanker_nativeScoreSample(
- JNIEnv* env,
- jobject thiz,
- jobjectArray key_array,
- jfloatArray value_array,
- jlong paPtr);
-
-JNIEXPORT void JNICALL
-Java_android_bordeaux_learning_StochasticLinearRanker_nativeGetWeightClassifier(
- JNIEnv* env,
- jobject thiz,
- jobjectArray key_array_weight,
- jfloatArray value_array_weight,
- jfloat normalizer,
- jlong paPtr);
-
-JNIEXPORT void JNICALL
-Java_android_bordeaux_learning_StochasticLinearRanker_nativeGetParameterClassifier(
- JNIEnv* env,
- jobject thiz,
- jobjectArray key_array_param,
- jobjectArray value_array_param,
- jlong paPtr);
-
-JNIEXPORT jint JNICALL
-Java_android_bordeaux_learning_StochasticLinearRanker_nativeGetLengthClassifier(
- JNIEnv* env,
- jobject thiz,
- jlong paPtr);
-
-JNIEXPORT jboolean JNICALL
-Java_android_bordeaux_learning_StochasticLinearRanker_nativeSetWeightClassifier(
- JNIEnv* env,
- jobject thiz,
- jobjectArray key_array_model,
- jfloatArray value_array_model,
- jfloat normalizer_model,
- jlong paPtr);
-
-JNIEXPORT jboolean JNICALL
-Java_android_bordeaux_learning_StochasticLinearRanker_nativeSetParameterClassifier(
- JNIEnv* env,
- jobject thiz,
- jstring key,
- jstring value,
- jlong paPtr);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ANDROID_LEARNING_JNI_STOCHASTIC_LINEAR_RANKER_H */
diff --git a/bordeaux/learning/stochastic_linear_ranker/native/common_defs.h b/bordeaux/learning/stochastic_linear_ranker/native/common_defs.h
deleted file mode 100644
index 4df8686c5..000000000
--- a/bordeaux/learning/stochastic_linear_ranker/native/common_defs.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-// Contains definitions commom to all classification and ranking algorithms
-// in this package.
-
-#ifndef LEARNING_STOCHASTIC_LINEAR_COMMON_DEFS_H_
-#define LEARNING_STOCHASTIC_LINEAR_COMMON_DEFS_H_
-
-namespace learning_stochastic_linear {
-// Defines standard types of regulariation methods.
-enum RegularizationType { L0, L1, L2, L1L2, L1LInf };
-
-// Defines standard adaptation modes for which Stochastic Sub-Gradient
-// methods are known to converge.
-enum AdaptationMode { CONST, INV_LINEAR, INV_QUADRATIC, INV_SQRT };
-enum UpdateType { FULL_CS, CLIP_CS, REG_CS, SL, ADAPTIVE_REG };
-enum RankLossType { PAIRWISE, RECIPROCAL_RANK };
-enum KernelType { LINEAR, POLY, RBF };
-enum MulticlassUpdateType { MAX, RANK };
-} // namespace learning_stochastic_linear
-
-#ifdef ANDROID
-#define uint32 uint32_t
-#define int32 int32_t
-#define uint64 uint64_t
-#define int64 int64_t
-#include <cutils/log.h>
-#define CHECK_GT(x,y) if ((x)<(y)) ALOGE("CHECK_GT failed at file %s line %d", \
- __FILE__, __LINE__);
-#endif
-
-#endif // LEARNING_STOCHASTIC_LINEAR_COMMON_DEFS_H_
diff --git a/bordeaux/learning/stochastic_linear_ranker/native/learning_rate_controller-inl.h b/bordeaux/learning/stochastic_linear_ranker/native/learning_rate_controller-inl.h
deleted file mode 100644
index 8aa01f00b..000000000
--- a/bordeaux/learning/stochastic_linear_ranker/native/learning_rate_controller-inl.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-// Implements learning rate adaptations common to most stochastic algorithms.
-
-#ifndef LEARNING_STOCHASTIC_LINEAR_LEARNING_RATE_CONTROLLER_INL_H_
-#define LEARNING_STOCHASTIC_LINEAR_LEARNING_RATE_CONTROLLER_INL_H_
-
-#include <cmath>
-#include "common_defs.h"
-
-namespace learning_stochastic_linear {
-
-class LearningRateController {
- public:
- LearningRateController() {
- iteration_num_ = 1;
- lambda_ = 1.0;
- mini_batch_size_ = 1;
- mini_batch_counter_ = 1;
- sample_num_ = 1;
- mode_ = INV_LINEAR;
- is_first_sample_ = true;
- }
- ~LearningRateController() {}
- // Getters and Setters for learning rate parameter lambda_
- double GetLambda() const {
- return lambda_;
- }
- void SetLambda(double lambda) {
- lambda_ = lambda;
- }
- // Operations on current iteration number
- void SetIterationNumber(uint64 num) {
- iteration_num_ = num;
- }
- void IncrementIteration() {
- ++iteration_num_;
- }
- uint64 GetIterationNumber() const {
- return iteration_num_;
- }
- // Mini batch operations
- uint64 GetMiniBatchSize() const {
- return mini_batch_size_;
- }
- void SetMiniBatchSize(uint64 size) {
- //CHECK_GT(size, 0);
- mini_batch_size_ = size;
- }
- void IncrementSample() {
- // If this is the first sample we've already counted it to prevent NaNs
- // in the learning rate computation
- if (is_first_sample_) {
- is_first_sample_ = false;
- return;
- }
- ++sample_num_;
- if (1 == mini_batch_size_) {
- IncrementIteration();
- mini_batch_counter_ = 0;
- } else {
- ++mini_batch_counter_;
- if ((mini_batch_counter_ % mini_batch_size_ == 0)) {
- IncrementIteration();
- mini_batch_counter_ = 0;
- }
- }
- }
- uint64 GetMiniBatchCounter() const {
- return mini_batch_counter_;
- }
- // Getters and setters for adaptation mode
- AdaptationMode GetAdaptationMode() const {
- return mode_;
- }
- void SetAdaptationMode(AdaptationMode m) {
- mode_ = m;
- }
- double GetLearningRate() const {
- if (mode_ == CONST) {
- return (1.0 / (lambda_ * mini_batch_size_));
- } else if (mode_ == INV_LINEAR) {
- return (1.0 / (lambda_ * iteration_num_ * mini_batch_size_));
- } else if (mode_ == INV_QUADRATIC) {
- return (1.0 / (lambda_ *
- mini_batch_size_ *
- (static_cast<double>(iteration_num_) * iteration_num_)));
- } else if (mode_ == INV_SQRT) {
- return (1.0 / (lambda_ *
- mini_batch_size_ *
- sqrt((double)iteration_num_)));
- }
- return 0;
- }
- void CopyFrom(const LearningRateController &other) {
- iteration_num_ = other.iteration_num_;
- sample_num_ = other.sample_num_;
- mini_batch_size_ = other.mini_batch_size_;
- mini_batch_counter_ = other.mini_batch_counter_;
- mode_ = other.mode_;
- is_first_sample_ = other.is_first_sample_;
- }
- private:
- uint64 iteration_num_;
- uint64 sample_num_;
- uint64 mini_batch_size_;
- uint64 mini_batch_counter_;
- double lambda_;
- AdaptationMode mode_;
- bool is_first_sample_;
-};
-} // namespace learning_stochastic_linear
-#endif // LEARNING_STOCHASTIC_LINEAR_LEARNING_RATE_CONTROLLER_INL_H_
diff --git a/bordeaux/learning/stochastic_linear_ranker/native/sparse_weight_vector.cpp b/bordeaux/learning/stochastic_linear_ranker/native/sparse_weight_vector.cpp
deleted file mode 100644
index 52ce11853..000000000
--- a/bordeaux/learning/stochastic_linear_ranker/native/sparse_weight_vector.cpp
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * Copyright (C) 2012 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 "sparse_weight_vector.h"
-
-#include <algorithm>
-#include <list>
-#include <vector>
-#include <math.h>
-
-using std::vector;
-using std::list;
-using std::max;
-
-namespace learning_stochastic_linear {
-
-// Max/Min permitted values of normalizer_ for preventing under/overflows.
-static double kNormalizerMin = 1e-20;
-static double kNormalizerMax = 1e20;
-
-template<class Key, class Hash>
-bool SparseWeightVector<Key, Hash>::IsValid() const {
- if (isnan(normalizer_) || __isinff(normalizer_))
- return false;
- for (Witer_const iter = w_.begin();
- iter != w_.end();
- ++iter) {
- if (isnanf(iter->second) || __isinff(iter->second))
- return false;
- }
- return true;
-}
-
-template<class Key, class Hash>
-void SparseWeightVector<Key, Hash>::AdditiveWeightUpdate(
- const double multiplier,
- const SparseWeightVector<Key, Hash> &w1,
- const double additive_const) {
- for (Witer_const iter = w1.w_.begin();
- iter != w1.w_.end();
- ++iter) {
- w_[iter->first] += ((multiplier * iter->second) / w1.normalizer_
- + additive_const) * normalizer_;
- }
- return;
-}
-
-template<class Key, class Hash>
-void SparseWeightVector<Key, Hash>::AdditiveSquaredWeightUpdate(
- const double multiplier,
- const SparseWeightVector<Key, Hash> &w1,
- const double additive_const) {
- for (Witer_const iter = w1.w_.begin();
- iter != w1.w_.end();
- ++iter) {
- w_[iter->first] += ((multiplier * iter->second * iter->second) /
- (w1.normalizer_ * w1.normalizer_)
- + additive_const) * normalizer_;
- }
- return;
-}
-
-template<class Key, class Hash>
-void SparseWeightVector<Key, Hash>::AdditiveInvSqrtWeightUpdate(
- const double multiplier,
- const SparseWeightVector<Key, Hash> &w1,
- const double additive_const) {
- for (Witer_const iter = w1.w_.begin();
- iter != w1.w_.end();
- ++iter) {
- if(iter->second > 0.0) {
- w_[iter->first] += ((multiplier * sqrt(w1.normalizer_)) /
- (sqrt(iter->second))
- + additive_const) * normalizer_;
- }
- }
- return;
-}
-
-template<class Key, class Hash>
-void SparseWeightVector<Key, Hash>::AdditiveWeightUpdateBounded(
- const double multiplier,
- const SparseWeightVector<Key, Hash> &w1,
- const double additive_const) {
- double min_bound = 0;
- double max_bound = 0;
- for (Witer_const iter = w1.w_.begin();
- iter != w1.w_.end();
- ++iter) {
- w_[iter->first] += ((multiplier * iter->second) / w1.normalizer_
- + additive_const) * normalizer_;
- bool is_min_bounded = GetValue(wmin_, iter->first, &min_bound);
- if (is_min_bounded) {
- if ((w_[iter->first] / normalizer_) < min_bound) {
- w_[iter->first] = min_bound*normalizer_;
- continue;
- }
- }
- bool is_max_bounded = GetValue(wmax_, iter->first, &max_bound);
- if (is_max_bounded) {
- if ((w_[iter->first] / normalizer_) > max_bound)
- w_[iter->first] = max_bound*normalizer_;
- }
- }
- return;
-}
-
-template<class Key, class Hash>
-void SparseWeightVector<Key, Hash>::MultWeightUpdate(
- const SparseWeightVector<Key, Hash> &w1) {
- for (Witer iter = w_.begin();
- iter != w_.end();
- ++iter) {
- iter->second *= w1.GetElement(iter->first);
- }
- normalizer_ *= w1.normalizer_;
- return;
-}
-
-template<class Key, class Hash>
-void SparseWeightVector<Key, Hash>::MultWeightUpdateBounded(
- const SparseWeightVector<Key, Hash> &w1) {
- double min_bound = 0;
- double max_bound = 0;
-
- normalizer_ *= w1.normalizer_;
- for (Witer iter = w_.begin();
- iter != w_.end();
- ++iter) {
- iter->second *= w1.GetElement(iter->first);
- bool is_min_bounded = GetValue(wmin_, iter->first, &min_bound);
- if (is_min_bounded) {
- if ((iter->second / normalizer_) < min_bound) {
- iter->second = min_bound*normalizer_;
- continue;
- }
- }
- bool is_max_bounded = GetValue(wmax_, iter->first, &max_bound);
- if (is_max_bounded) {
- if ((iter->second / normalizer_) > max_bound)
- iter->second = max_bound*normalizer_;
- }
- }
- return;
-}
-
-template<class Key, class Hash>
-void SparseWeightVector<Key, Hash>::ResetNormalizer() {
- for (Witer iter = w_.begin();
- iter != w_.end();
- ++iter) {
- iter->second /= normalizer_;
- }
- normalizer_ = 1.0;
-}
-
-template<class Key, class Hash>
-void SparseWeightVector<Key, Hash>::ReprojectToBounds() {
- double min_bound = 0;
- double max_bound = 0;
-
- for (Witer iter = w_.begin();
- iter != w_.end();
- ++iter) {
- bool is_min_bounded = GetValue(wmin_, iter->first, &min_bound);
- if (is_min_bounded) {
- if ((iter->second/normalizer_) < min_bound) {
- iter->second = min_bound*normalizer_;
- continue;
- }
- }
- bool is_max_bounded = GetValue(wmax_, iter->first, &max_bound);
- if (is_max_bounded) {
- if ((iter->second/normalizer_) > max_bound)
- iter->second = max_bound*normalizer_;
- }
- }
-}
-
-template<class Key, class Hash>
-double SparseWeightVector<Key, Hash>::DotProduct(
- const SparseWeightVector<Key, Hash> &w1) const {
- double result = 0;
- if (w_.size() > w1.w_.size()) {
- for (Witer_const iter = w1.w_.begin();
- iter != w1.w_.end();
- ++iter) {
- result += iter->second * GetElement(iter->first);
- }
- result /= (this->normalizer_ * w1.normalizer_);
- } else {
- for (Witer_const iter = w_.begin();
- iter != w_.end();
- ++iter) {
- result += iter->second * w1.GetElement(iter->first);
- }
- result /= (this->normalizer_ * w1.normalizer_);
- }
- return result;
-}
-
-template<class Key, class Hash>
-double SparseWeightVector<Key, Hash>::LxNorm(const double x) const {
- double result = 0;
- CHECK_GT(x, 0);
- for (Witer_const iter = w_.begin();
- iter != w_.end();
- ++iter) {
- result += pow(iter->second, x);
- }
- return (pow(result, 1.0 / x) / normalizer_);
-}
-
-template<class Key, class Hash>
-double SparseWeightVector<Key, Hash>::L2Norm() const {
- double result = 0;
- for (Witer_const iter = w_.begin();
- iter != w_.end();
- ++iter) {
- result += iter->second * iter->second;
- }
- return sqrt(result)/normalizer_;
-}
-
-template<class Key, class Hash>
-double SparseWeightVector<Key, Hash>::L1Norm() const {
- double result = 0;
- for (Witer_const iter = w_.begin();
- iter != w_.end();
- ++iter) {
- result += fabs(iter->second);
- }
- return result / normalizer_;
-}
-
-template<class Key, class Hash>
-double SparseWeightVector<Key, Hash>::L0Norm(
- const double epsilon) const {
- double result = 0;
- for (Witer_const iter = w_.begin();
- iter != w_.end();
- ++iter) {
- if (fabs(iter->second / normalizer_) > epsilon)
- ++result;
- }
- return result;
-}
-
-// Algorithm for L0 projection which takes O(n log(n)), where n is
-// the number of non-zero elements in the vector.
-template<class Key, class Hash>
-void SparseWeightVector<Key, Hash>::ReprojectL0(const double l0_norm) {
-// First calculates the order-statistics of the sparse vector
-// and then reprojects to the L0 orthant with the requested norm.
- CHECK_GT(l0_norm, 0);
- uint64 req_l0_norm = static_cast<uint64>(l0_norm);
- // Compute order statistics and the current L0 norm.
- vector<double> abs_val_vec;
- uint64 curr_l0_norm = 0;
- const double epsilone = 1E-05;
- for (Witer iter = w_.begin();
- iter != w_.end();
- ++iter) {
- if (fabs(iter->second/normalizer_) > epsilone) {
- abs_val_vec.push_back(fabs(iter->second/normalizer_));
- ++curr_l0_norm;
- }
- }
- // check if a projection is necessary
- if (curr_l0_norm < req_l0_norm) {
- return;
- }
- std::nth_element(&abs_val_vec[0],
- &abs_val_vec[curr_l0_norm - req_l0_norm],
- &abs_val_vec[curr_l0_norm]);
- const double theta = abs_val_vec[curr_l0_norm - req_l0_norm];
- // compute the final projection.
- for (Witer iter = w_.begin();
- iter != w_.end();
- ++iter) {
- if ((fabs(iter->second/normalizer_) - theta) < 0) {
- iter->second = 0;
- }
- }
-}
-
-// Slow algorithm for accurate L1 projection which takes O(n log(n)), where n is
-// the number of non-zero elements in the vector.
-template<class Key, class Hash>
-void SparseWeightVector<Key, Hash>::ReprojectL1(const double l1_norm) {
-// First calculates the order-statistics of the sparse vector
-// applies a probability simplex projection to the abs(vector)
-// and reprojects back to the original with the appropriate sign.
-// For ref. see "Efficient Projections into the l1-ball for Learning
-// in High Dimensions"
- CHECK_GT(l1_norm, 0);
- // Compute order statistics and the current L1 norm.
- list<double> abs_val_list;
- double curr_l1_norm = 0;
- for (Witer iter = w_.begin();
- iter != w_.end();
- ++iter) {
- abs_val_list.push_back(fabs(iter->second/normalizer_));
- curr_l1_norm += fabs(iter->second/normalizer_);
- }
- // check if a projection is necessary
- if (curr_l1_norm < l1_norm) {
- return;
- }
- abs_val_list.sort();
- abs_val_list.reverse();
- // Compute projection on the probability simplex.
- double curr_index = 1;
- double theta = 0;
- double cum_sum = 0;
- for (list<double>::iterator val_iter = abs_val_list.begin();
- val_iter != abs_val_list.end();
- ++val_iter) {
- cum_sum += *val_iter;
- theta = (cum_sum - l1_norm)/curr_index;
- if (((*val_iter) - theta) <= 0) {
- break;
- }
- ++curr_index;
- }
- // compute the final projection.
- for (Witer iter = w_.begin();
- iter != w_.end();
- ++iter) {
- int sign_mul = iter->second > 0;
- iter->second = max(sign_mul * normalizer_ *
- (fabs(iter->second/normalizer_) - theta),
- 0.0);
- }
-}
-
-template<class Key, class Hash>
-void SparseWeightVector<Key, Hash>::ReprojectL2(const double l2_norm) {
- CHECK_GT(l2_norm, 0);
- double curr_l2_norm = L2Norm();
- // Check if a projection is necessary.
- if (curr_l2_norm > l2_norm) {
- normalizer_ *= curr_l2_norm / l2_norm;
- }
-}
-
-template<class Key, class Hash>
-int32 SparseWeightVector<Key, Hash>::Reproject(const double norm,
- const RegularizationType r) {
- CHECK_GT(norm, 0);
- if (r == L0) {
- ReprojectL0(norm);
- } else if (r == L1) {
- ReprojectL1(norm);
- } else if (r == L2) {
- ReprojectL2(norm);
- } else {
- // This else is just to ensure that if other RegularizationTypes are
- // supported in the enum later which require manipulations not related
- // to SparseWeightVector then we catch the accidental argument here.
- ALOGE("Unsupported regularization type requested");
- return -1;
- }
- // If the normalizer gets dangerously large or small, normalize the
- // entire vector. This stops projections from sending the vector
- // weights and the normalizer simultaneously all very small or
- // large, causing under/over flows. But if you hit this too often
- // it's a sign you've chosen a bad lambda.
- if (normalizer_ < kNormalizerMin) {
- ALOGE("Resetting normalizer to 1.0 to prevent underflow. "
- "Is lambda too large?");
- ResetNormalizer();
- }
- if (normalizer_ > kNormalizerMax) {
- ALOGE("Resetting normalizer to 1.0 to prevent overflow. "
- "Is lambda too small?");
- ResetNormalizer();
- }
- return 0;
-}
-
-template class SparseWeightVector<std::string, std::unordered_map<std::string, double> >;
-template class SparseWeightVector<int, std::unordered_map<int, double> >;
-template class SparseWeightVector<uint64, std::unordered_map<uint64, double> >;
-} // namespace learning_stochastic_linear
diff --git a/bordeaux/learning/stochastic_linear_ranker/native/sparse_weight_vector.h b/bordeaux/learning/stochastic_linear_ranker/native/sparse_weight_vector.h
deleted file mode 100644
index b5f1ff5af..000000000
--- a/bordeaux/learning/stochastic_linear_ranker/native/sparse_weight_vector.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-// Purpose: A container for sparse weight vectors
-// Maintains the sparse vector as a list of (name, value) pairs alongwith
-// a normalizer_. All operations assume that (name, value/normalizer_) is the
-// true value in question.
-
-#ifndef LEARNING_STOCHASTIC_LINEAR_SPARSE_WEIGHT_VECTOR_H_
-#define LEARNING_STOCHASTIC_LINEAR_SPARSE_WEIGHT_VECTOR_H_
-
-#include <math.h>
-
-#include <iosfwd>
-#include <sstream>
-#include <string>
-#include <unordered_map>
-
-#include "common_defs.h"
-
-namespace learning_stochastic_linear {
-
-template<class Key = std::string, class Hash = std::unordered_map<Key, double> >
-class SparseWeightVector {
- public:
- typedef Hash Wmap;
- typedef typename Wmap::iterator Witer;
- typedef typename Wmap::const_iterator Witer_const;
- SparseWeightVector() {
- normalizer_ = 1.0;
- }
- ~SparseWeightVector() {}
- explicit SparseWeightVector(const SparseWeightVector<Key, Hash> &other) {
- CopyFrom(other);
- }
- void operator=(const SparseWeightVector<Key, Hash> &other) {
- CopyFrom(other);
- }
- void CopyFrom(const SparseWeightVector<Key, Hash> &other) {
- w_ = other.w_;
- wmin_ = other.wmin_;
- wmax_ = other.wmax_;
- normalizer_ = other.normalizer_;
- }
-
- // This function implements checks to prevent unbounded vectors. It returns
- // true if the checks succeed and false otherwise. A vector is deemed invalid
- // if any of these conditions are met:
- // 1. it has no values.
- // 2. its normalizer is nan or inf or close to zero.
- // 3. any of its values are nan or inf.
- // 4. its L0 norm is close to zero.
- bool IsValid() const;
-
- // Normalizer getters and setters.
- double GetNormalizer() const {
- return normalizer_;
- }
- void SetNormalizer(const double norm) {
- normalizer_ = norm;
- }
- void NormalizerMultUpdate(const double mul) {
- normalizer_ = normalizer_ * mul;
- }
- void NormalizerAddUpdate(const double add) {
- normalizer_ += add;
- }
-
- // Divides all the values by the normalizer, then it resets it to 1.0
- void ResetNormalizer();
-
- // Bound getters and setters.
- // True if there is a bound with val containing the bound. false otherwise.
- bool GetElementMinBound(const Key &fname, double *val) const {
- return GetValue(wmin_, fname, val);
- }
- bool GetElementMaxBound(const Key &fname, double *val) const {
- return GetValue(wmax_, fname, val);
- }
- void SetElementMinBound(const Key &fname, const double bound) {
- wmin_[fname] = bound;
- }
- void SetElementMaxBound(const Key &fname, const double bound) {
- wmax_[fname] = bound;
- }
- // Element getters and setters.
- double GetElement(const Key &fname) const {
- double val = 0;
- GetValue(w_, fname, &val);
- return val;
- }
- void SetElement(const Key &fname, const double val) {
- //DCHECK(!isnan(val));
- w_[fname] = val;
- }
- void AddUpdateElement(const Key &fname, const double val) {
- w_[fname] += val;
- }
- void MultUpdateElement(const Key &fname, const double val) {
- w_[fname] *= val;
- }
- // Load another weight vectors. Will overwrite the current vector.
- void LoadWeightVector(const SparseWeightVector<Key, Hash> &vec) {
- w_.clear();
- w_.insert(vec.w_.begin(), vec.w_.end());
- wmax_.insert(vec.wmax_.begin(), vec.wmax_.end());
- wmin_.insert(vec.wmin_.begin(), vec.wmin_.end());
- normalizer_ = vec.normalizer_;
- }
- void Clear() {
- w_.clear();
- wmax_.clear();
- wmin_.clear();
- }
- const Wmap& GetMap() const {
- return w_;
- }
- // Vector Operations.
- void AdditiveWeightUpdate(const double multiplier,
- const SparseWeightVector<Key, Hash> &w1,
- const double additive_const);
- void AdditiveSquaredWeightUpdate(const double multiplier,
- const SparseWeightVector<Key, Hash> &w1,
- const double additive_const);
- void AdditiveInvSqrtWeightUpdate(const double multiplier,
- const SparseWeightVector<Key, Hash> &w1,
- const double additive_const);
- void MultWeightUpdate(const SparseWeightVector<Key, Hash> &w1);
- double DotProduct(const SparseWeightVector<Key, Hash> &s) const;
- // L-x norm. eg. L1, L2.
- double LxNorm(const double x) const;
- double L2Norm() const;
- double L1Norm() const;
- double L0Norm(const double epsilon) const;
- // Bound preserving updates.
- void AdditiveWeightUpdateBounded(const double multiplier,
- const SparseWeightVector<Key, Hash> &w1,
- const double additive_const);
- void MultWeightUpdateBounded(const SparseWeightVector<Key, Hash> &w1);
- void ReprojectToBounds();
- void ReprojectL0(const double l0_norm);
- void ReprojectL1(const double l1_norm);
- void ReprojectL2(const double l2_norm);
- // Reproject using the given norm.
- // Will also rescale regularizer_ if it gets too small/large.
- int32 Reproject(const double norm, const RegularizationType r);
- // Convert this vector to a string, simply for debugging.
- std::string DebugString() const {
- std::stringstream stream;
- stream << *this;
- return stream.str();
- }
- private:
- // The weight map.
- Wmap w_;
- // Constraint bounds.
- Wmap wmin_;
- Wmap wmax_;
- // Normalizing constant in magnitude measurement.
- double normalizer_;
- // This function is necessary since by default unordered_map inserts an
- // element if it does not find the key through [] operator. It implements a
- // lookup without the space overhead of an add.
- bool GetValue(const Wmap &w1, const Key &fname, double *val) const {
- Witer_const iter = w1.find(fname);
- if (iter != w1.end()) {
- (*val) = iter->second;
- return true;
- } else {
- (*val) = 0;
- return false;
- }
- }
-};
-
-// Outputs a SparseWeightVector, for debugging.
-template <class Key, class Hash>
-std::ostream& operator<<(std::ostream &stream,
- const SparseWeightVector<Key, Hash> &vector) {
- typename SparseWeightVector<Key, Hash>::Wmap w_map = vector.GetMap();
- stream << "[[ ";
- for (typename SparseWeightVector<Key, Hash>::Witer_const iter = w_map.begin();
- iter != w_map.end();
- ++iter) {
- stream << "<" << iter->first << ", " << iter->second << "> ";
- }
- return stream << " ]]";
-};
-
-} // namespace learning_stochastic_linear
-#endif // LEARNING_STOCHASTIC_LINEAR_SPARSE_WEIGHT_VECTOR_H_
diff --git a/bordeaux/learning/stochastic_linear_ranker/native/stochastic_linear_ranker.cpp b/bordeaux/learning/stochastic_linear_ranker/native/stochastic_linear_ranker.cpp
deleted file mode 100644
index db702ad57..000000000
--- a/bordeaux/learning/stochastic_linear_ranker/native/stochastic_linear_ranker.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2012 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 <algorithm>
-#include <stdlib.h>
-
-#include "stochastic_linear_ranker.h"
-
-namespace learning_stochastic_linear {
-
-template<class Key, class Hash>
-void StochasticLinearRanker<Key, Hash>::UpdateSubGradient(
- const SparseWeightVector<Key, Hash> &positive,
- const SparseWeightVector<Key, Hash> &negative,
- const double learning_rate,
- const double positive_score,
- const double negative_score,
- const int32 gradient_l0_norm) {
- SparseWeightVector<Key, Hash> gradient;
- double final_learning_rate;
- gradient.AdditiveWeightUpdate(1.0, positive, 0.0);
- gradient.AdditiveWeightUpdate(-1.0, negative, 0.0);
- if (update_type_ == FULL_CS || update_type_ == REG_CS) {
- const double loss = std::max(0.0, (1 - positive_score + negative_score));
- const double gradient_norm = gradient.L2Norm();
- const double kMinGradientNorm = 1e-8;
- const double kMaxGradientNorm = 1e8;
- if (gradient_norm < kMinGradientNorm || gradient_norm > kMaxGradientNorm)
- return;
- if (update_type_ == FULL_CS)
- final_learning_rate =
- std::min(lambda_, loss / (gradient_norm * gradient_norm));
- else
- final_learning_rate =
- loss / (gradient_norm * gradient_norm + 1 / (2 * lambda_));
- } else {
- gradient.AdditiveWeightUpdate(-lambda_, weight_, 0.0);
- final_learning_rate = learning_rate;
- }
- if (gradient_l0_norm > 0) {
- gradient.ReprojectL0(gradient_l0_norm);
- }
-
- if (gradient.IsValid())
- weight_.AdditiveWeightUpdate(final_learning_rate, gradient, 0.0);
-}
-
-template<class Key, class Hash>
-int StochasticLinearRanker<Key, Hash>::UpdateClassifier(
- const SparseWeightVector<Key, Hash> &positive,
- const SparseWeightVector<Key, Hash> &negative) {
- // Create a backup of the weight vector in case the iteration results in
- // unbounded weights.
- SparseWeightVector<Key, Hash> weight_backup;
- weight_backup.CopyFrom(weight_);
-
- const double positive_score = ScoreSample(positive);
- const double negative_score = ScoreSample(negative);
- if ((positive_score - negative_score) < 1) {
- ++mini_batch_counter_;
- if ((mini_batch_counter_ % mini_batch_size_ == 0) ||
- (iteration_num_ == 0)) {
- ++iteration_num_;
- mini_batch_counter_ = 0;
- }
- learning_rate_controller_.IncrementSample();
- double learning_rate = learning_rate_controller_.GetLearningRate();
-
- if (rank_loss_type_ == PAIRWISE) {
- UpdateSubGradient(positive, negative, learning_rate,
- positive_score, negative_score,
- gradient_l0_norm_);
- } else if (rank_loss_type_ == RECIPROCAL_RANK) {
- const double current_negative_score = ScoreSample(current_negative_);
- if ((negative_score > current_negative_score) ||
- ((rand()/RAND_MAX) < acceptence_probability_)) {
- UpdateSubGradient(positive, negative, learning_rate,
- positive_score, negative_score,
- gradient_l0_norm_);
- current_negative_.Clear();
- current_negative_.LoadWeightVector(negative);
- } else {
- UpdateSubGradient(positive, current_negative_, learning_rate,
- positive_score, negative_score,
- gradient_l0_norm_);
- }
- } else {
- ALOGE("Unknown rank loss type: %d", rank_loss_type_);
- }
-
- int return_code;
- if ((mini_batch_counter_ == 0) && (update_type_ == SL)) {
- return_code = 1;
- switch (regularization_type_) {
- case L1:
- weight_.ReprojectL1(norm_constraint_);
- break;
- case L2:
- weight_.ReprojectL2(norm_constraint_);
- break;
- case L0:
- weight_.ReprojectL0(norm_constraint_);
- break;
- default:
- ALOGE("Unsupported optimization type specified");
- return_code = -1;
- }
- } else if (update_type_ == SL) {
- return_code = 2;
- } else {
- return_code = 1;
- }
-
- if (!weight_.IsValid())
- weight_.CopyFrom(weight_backup);
- return return_code;
- }
-
- return 0;
-}
-
-template class StochasticLinearRanker<std::string, std::unordered_map<std::string, double> >;
-template class StochasticLinearRanker<int, std::unordered_map<int, double> >;
-template class StochasticLinearRanker<uint64, std::unordered_map<uint64, double> >;
-
-} // namespace learning_stochastic_linear
diff --git a/bordeaux/learning/stochastic_linear_ranker/native/stochastic_linear_ranker.h b/bordeaux/learning/stochastic_linear_ranker/native/stochastic_linear_ranker.h
deleted file mode 100644
index 5419a5a30..000000000
--- a/bordeaux/learning/stochastic_linear_ranker/native/stochastic_linear_ranker.h
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-// Stochastic Linear Ranking algorithms.
-// This class will implement a set of incremental algorithms for ranking tasks
-// They support both L1 and L2 regularizations.
-
-
-#ifndef LEARNING_STOCHASTIC_LINEAR_STOCHASTIC_LINEAR_RANKER_H_
-#define LEARNING_STOCHASTIC_LINEAR_STOCHASTIC_LINEAR_RANKER_H_
-
-#include <sys/types.h>
-
-#include <cmath>
-#include <string>
-#include <unordered_map>
-
-#include "cutils/log.h"
-#include "common_defs.h"
-#include "learning_rate_controller-inl.h"
-#include "sparse_weight_vector.h"
-
-namespace learning_stochastic_linear {
-
-// NOTE: This Stochastic Linear Ranker supports only the following update types:
-// SL: Stochastic Linear
-// CS: Constraint Satisfaction
-template<class Key = std::string, class Hash = std::unordered_map<std::string, double> >
-class StochasticLinearRanker {
- public:
- // initialize lambda_ and constraint to a meaningful default. Will give
- // equal weight to the error and regularizer.
- StochasticLinearRanker() {
- iteration_num_ = 0;
- lambda_ = 1.0;
- learning_rate_controller_.SetLambda(lambda_);
- mini_batch_size_ = 1;
- learning_rate_controller_.SetMiniBatchSize(mini_batch_size_);
- adaptation_mode_ = INV_LINEAR;
- learning_rate_controller_.SetAdaptationMode(adaptation_mode_);
- update_type_ = SL;
- regularization_type_ = L2;
- kernel_type_ = LINEAR;
- kernel_param_ = 1.0;
- kernel_gain_ = 1.0;
- kernel_bias_ = 0.0;
- rank_loss_type_ = PAIRWISE;
- acceptence_probability_ = 0.1;
- mini_batch_counter_ = 0;
- gradient_l0_norm_ = -1;
- norm_constraint_ = 1.0;
- }
-
- ~StochasticLinearRanker() {}
- // Getters and setters
- double GetIterationNumber() const {
- return iteration_num_;
- }
- double GetNormContraint() const {
- return norm_constraint_;
- }
- RegularizationType GetRegularizationType() const {
- return regularization_type_;
- }
- double GetLambda() const {
- return lambda_;
- }
- uint64 GetMiniBatchSize() const {
- return mini_batch_size_;
- }
- int32 GetGradientL0Norm() const {
- return gradient_l0_norm_;
- }
- UpdateType GetUpdateType() const {
- return update_type_;
- }
- AdaptationMode GetAdaptationMode() const {
- return adaptation_mode_;
- }
- KernelType GetKernelType() const {
- return kernel_type_;
- }
- // This function returns the basic kernel parameter. In case of
- // polynomial kernel, it implies the degree of the polynomial. In case of
- // RBF kernel, it implies the sigma parameter. In case of linear kernel,
- // it is not used.
- double GetKernelParam() const {
- return kernel_param_;
- }
- double GetKernelGain() const {
- return kernel_gain_;;
- }
- double GetKernelBias() const {
- return kernel_bias_;
- }
- RankLossType GetRankLossType() const {
- return rank_loss_type_;
- }
- double GetAcceptanceProbability() const {
- return acceptence_probability_;
- }
- void SetIterationNumber(uint64 num) {
- iteration_num_=num;
- }
- void SetNormConstraint(const double norm) {
- norm_constraint_ = norm;
- }
- void SetRegularizationType(const RegularizationType r) {
- regularization_type_ = r;
- }
- void SetLambda(double l) {
- lambda_ = l;
- learning_rate_controller_.SetLambda(l);
- }
- void SetMiniBatchSize(const uint64 msize) {
- mini_batch_size_ = msize;
- learning_rate_controller_.SetMiniBatchSize(msize);
- }
- void SetAdaptationMode(AdaptationMode m) {
- adaptation_mode_ = m;
- learning_rate_controller_.SetAdaptationMode(m);
- }
- void SetKernelType(KernelType k ) {
- kernel_type_ = k;
- }
- // This function sets the basic kernel parameter. In case of
- // polynomial kernel, it implies the degree of the polynomial. In case of
- // RBF kernel, it implies the sigma parameter. In case of linear kernel,
- // it is not used.
- void SetKernelParam(double param) {
- kernel_param_ = param;
- }
- // This function sets the kernel gain. NOTE: in most use cases, gain should
- // be set to 1.0.
- void SetKernelGain(double gain) {
- kernel_gain_ = gain;
- }
- // This function sets the kernel bias. NOTE: in most use cases, bias should
- // be set to 0.0.
- void SetKernelBias(double bias) {
- kernel_bias_ = bias;
- }
- void SetUpdateType(UpdateType u) {
- update_type_ = u;
- }
- void SetRankLossType(RankLossType r) {
- rank_loss_type_ = r;
- }
- void SetAcceptanceProbability(double p) {
- acceptence_probability_ = p;
- }
- void SetGradientL0Norm(const int32 gradient_l0_norm) {
- gradient_l0_norm_ = gradient_l0_norm;
- }
- // Load an existing model
- void LoadWeights(const SparseWeightVector<Key, Hash> &model) {
- weight_.LoadWeightVector(model);
- }
- // Save current model
- void SaveWeights(SparseWeightVector<Key, Hash> *model) {
- model->LoadWeightVector(weight_);
- }
- // Scoring
- double ScoreSample(const SparseWeightVector<Key, Hash> &sample) {
- const double dot = weight_.DotProduct(sample);
- double w_square;
- double s_square;
- switch (kernel_type_) {
- case LINEAR:
- return dot;
- case POLY:
- return pow(kernel_gain_ * dot + kernel_bias_, kernel_param_);
- case RBF:
- w_square = weight_.L2Norm();
- s_square = sample.L2Norm();
- return exp(-1 * kernel_param_ * (w_square + s_square - 2 * dot));
- default:
- ALOGE("unsupported kernel: %d", kernel_type_);
- }
- return -1;
- }
- // Learning Functions
- // Return values:
- // 1 :full update went through
- // 2 :partial update went through (for SL only)
- // 0 :no update necessary.
- // -1:error.
- int UpdateClassifier(const SparseWeightVector<Key, Hash> &positive,
- const SparseWeightVector<Key, Hash> &negative);
-
- private:
- SparseWeightVector<Key, Hash> weight_;
- double norm_constraint_;
- double lambda_;
- RegularizationType regularization_type_;
- AdaptationMode adaptation_mode_;
- UpdateType update_type_;
- RankLossType rank_loss_type_;
- KernelType kernel_type_;
- // Kernel gain and bias are typically multiplicative and additive factors to
- // the dot product while calculating the kernel function. Kernel param is
- // kernel-specific. In case of polynomial kernel, it is the degree of the
- // polynomial.
- double kernel_param_;
- double kernel_gain_;
- double kernel_bias_;
- double acceptence_probability_;
- SparseWeightVector<Key, Hash> current_negative_;
- LearningRateController learning_rate_controller_;
- uint64 iteration_num_;
- // We average out gradient updates for mini_batch_size_ samples
- // before performing an iteration of the algorithm.
- uint64 mini_batch_counter_;
- uint64 mini_batch_size_;
- // Specifies the number of non-zero entries allowed in a gradient.
- // Default is -1 which means we take the gradient as given by data without
- // adding any new constraints. positive number is treated as an L0 constraint
- int32 gradient_l0_norm_;
- // Sub-Gradient Updates
- // Pure Sub-Gradient update without any reprojection
- // Note that a form of L2 regularization is built into this
- void UpdateSubGradient(const SparseWeightVector<Key, Hash> &positive,
- const SparseWeightVector<Key, Hash> &negative,
- const double learning_rate,
- const double positive_score,
- const double negative_score,
- const int32 gradient_l0_norm);
-
-};
-} // namespace learning_stochastic_linear
-#endif // LEARNING_STOCHASTIC_LINEAR_STOCHASTIC_LINEAR_RANKER_H_
diff --git a/bordeaux/service/Android.mk b/bordeaux/service/Android.mk
deleted file mode 100644
index 1d4464b15..000000000
--- a/bordeaux/service/Android.mk
+++ /dev/null
@@ -1,79 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-# Only compile source java files in this apk.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_SRC_FILES += \
- src/android/bordeaux/services/IBordeauxServiceCallback.aidl \
- src/android/bordeaux/services/IAggregatorManager.aidl \
- src/android/bordeaux/services/ILearning_MulticlassPA.aidl \
- src/android/bordeaux/services/IPredictor.aidl \
- src/android/bordeaux/services/ILearning_StochasticLinearRanker.aidl \
- src/android/bordeaux/services/IBordeauxService.aidl \
-
-LOCAL_STATIC_JAVA_LIBRARIES := bordeaux_learners
-LOCAL_JNI_SHARED_LIBRARIES := libbordeaux
-
-LOCAL_PACKAGE_NAME := bordeaux
-
-
-include $(BUILD_PACKAGE)
-
-##
-# Build java lib
-##
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES += \
- src/android/bordeaux/services/IntFloat.java \
- src/android/bordeaux/services/StringFloat.java \
- src/android/bordeaux/services/StringString.java \
- src/android/bordeaux/services/BordeauxClassifier.java \
- src/android/bordeaux/services/BordeauxRanker.java \
- src/android/bordeaux/services/BordeauxPredictor.java \
- src/android/bordeaux/services/BordeauxAggregatorManager.java \
- src/android/bordeaux/services/BordeauxManagerService.java \
- src/android/bordeaux/services/IBordeauxServiceCallback.aidl \
- src/android/bordeaux/services/IAggregatorManager.aidl \
- src/android/bordeaux/services/IPredictor.aidl \
- src/android/bordeaux/services/ILearning_MulticlassPA.aidl \
- src/android/bordeaux/services/ILearning_StochasticLinearRanker.aidl \
- src/android/bordeaux/services/IBordeauxService.aidl \
-
-LOCAL_MODULE := bordeaux_service
-LOCAL_STATIC_JAVA_LIBRARIES := bordeaux_learners
-
-LOCAL_PROGUARD_ENABLED := disabled
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-## Building the whole Bordeaux service
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-# Only compile source java files in this apk.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_SRC_FILES += \
- src/android/bordeaux/services/IBordeauxServiceCallback.aidl \
- src/android/bordeaux/services/IAggregatorManager.aidl \
- src/android/bordeaux/services/ILearning_MulticlassPA.aidl \
- src/android/bordeaux/services/IPredictor.aidl \
- src/android/bordeaux/services/ILearning_StochasticLinearRanker.aidl \
- src/android/bordeaux/services/IBordeauxService.aidl \
-
-LOCAL_STATIC_JAVA_LIBRARIES := bordeaux_learners
-LOCAL_JNI_SHARED_LIBRARIES := libbordeaux
-
-LOCAL_JAVA_RESOURCE_DIRS := res
-LOCAL_MODULE := bordeaux_whole_service
-LOCAL_PROGUARD_ENABLED := disabled
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-# Use the folloing include to make our test apk.
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/bordeaux/service/AndroidManifest.xml b/bordeaux/service/AndroidManifest.xml
deleted file mode 100644
index 5e5ec3f2c..000000000
--- a/bordeaux/service/AndroidManifest.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- android:versionCode="1"
- android:versionName="1.0" package="android.bordeaux">
- <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="14" />
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
- <application android:label="@string/bordeaux_app"
- android:debuggable="true"
- android:hardwareAccelerated="true">
-<!-- BEGIN_INCLUDE(remote_service_declaration) -->
- <service android:name=".services.BordeauxService"
- android:icon="@drawable/ic_bordeaux"
- android:process=":remote" >
- <intent-filter>
- <action android:name="android.bordeaux.services.IBordeauxService" />
- <!-- This is an action code you can use to select the service
- without explicitly supplying the implementation class. -->
- <action android:name="android.bordeaux.services.BORDEAUX_SERVICE" />
- </intent-filter>
- </service>
- </application>
-</manifest>
diff --git a/bordeaux/service/res/drawable-hdpi/ic_bordeaux.png b/bordeaux/service/res/drawable-hdpi/ic_bordeaux.png
deleted file mode 100644
index b191d46d2..000000000
--- a/bordeaux/service/res/drawable-hdpi/ic_bordeaux.png
+++ /dev/null
Binary files differ
diff --git a/bordeaux/service/res/drawable-mdpi/ic_bordeaux.png b/bordeaux/service/res/drawable-mdpi/ic_bordeaux.png
deleted file mode 100644
index 8975f9bf4..000000000
--- a/bordeaux/service/res/drawable-mdpi/ic_bordeaux.png
+++ /dev/null
Binary files differ
diff --git a/bordeaux/service/res/drawable-xhdpi/ic_bordeaux.png b/bordeaux/service/res/drawable-xhdpi/ic_bordeaux.png
deleted file mode 100644
index ac7513d3e..000000000
--- a/bordeaux/service/res/drawable-xhdpi/ic_bordeaux.png
+++ /dev/null
Binary files differ
diff --git a/bordeaux/service/res/layout/lava_messenger_service_binding.xml b/bordeaux/service/res/layout/lava_messenger_service_binding.xml
deleted file mode 100644
index 4fa314c05..000000000
--- a/bordeaux/service/res/layout/lava_messenger_service_binding.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<!-- Demonstrates starting and stopping a local service.
- See corresponding Java code com.android.sdk.app.LocalSerice.java. -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
- android:gravity="center_horizontal"
- android:layout_width="match_parent" android:layout_height="match_parent">
-
- <TextView
- android:layout_width="match_parent" android:layout_height="wrap_content"
- android:layout_weight="0"
- android:paddingBottom="4dip"
- android:text="@string/lava_service_binding"/>
-
- <Button android:id="@+id/startService"
- android:layout_width="wrap_content" android:layout_height="wrap_content"
- android:text="@string/start_service">
- <requestFocus />
- </Button>
-
- <Button android:id="@+id/stopService"
- android:layout_width="wrap_content" android:layout_height="wrap_content"
- android:text="@string/stop_service">
- <requestFocus />
- </Button>
-
- <Button android:id="@+id/bind"
- android:layout_width="wrap_content" android:layout_height="wrap_content"
- android:text="@string/bind_service">
- <requestFocus />
- </Button>
-
- <Button android:id="@+id/unbind"
- android:layout_width="wrap_content" android:layout_height="wrap_content"
- android:text="@string/unbind_service">
- </Button>
-
- <Button android:id="@+id/sendData"
- android:layout_width="wrap_content" android:layout_height="wrap_content"
- android:text="@string/send_data">
- </Button>
-
- <Button android:id="@+id/kill"
- android:layout_width="wrap_content" android:layout_height="wrap_content"
- android:text="@string/kill_process">
- </Button>
-
- <TextView android:id="@+id/callback"
- android:layout_width="match_parent" android:layout_height="wrap_content"
- android:layout_weight="0"
- android:gravity="center_horizontal" android:paddingTop="4dip"/>
-
-</LinearLayout>
-
diff --git a/bordeaux/service/res/layout/lava_service_binding.xml b/bordeaux/service/res/layout/lava_service_binding.xml
deleted file mode 100644
index c41980c4e..000000000
--- a/bordeaux/service/res/layout/lava_service_binding.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 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.
--->
-
-<!-- Demonstrates starting and stopping a local service.
- See corresponding Java code com.android.sdk.app.LocalSerice.java. -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
- android:gravity="center_horizontal"
- android:layout_width="match_parent" android:layout_height="match_parent">
-
- <TextView
- android:layout_width="match_parent" android:layout_height="wrap_content"
- android:layout_weight="0"
- android:paddingBottom="4dip"
- android:text="@string/lava_service_binding"/>
-
- <Button android:id="@+id/startService"
- android:layout_width="wrap_content" android:layout_height="wrap_content"
- android:text="@string/start_service">
- <requestFocus />
- </Button>
-
- <Button android:id="@+id/stopService"
- android:layout_width="wrap_content" android:layout_height="wrap_content"
- android:text="@string/stop_service">
- <requestFocus />
- </Button>
-
- <Button android:id="@+id/bind"
- android:layout_width="wrap_content" android:layout_height="wrap_content"
- android:text="@string/bind_service">
- <requestFocus />
- </Button>
-
- <Button android:id="@+id/unbind"
- android:layout_width="wrap_content" android:layout_height="wrap_content"
- android:text="@string/unbind_service">
- </Button>
-
- <TextView android:id="@+id/callback"
- android:layout_width="match_parent" android:layout_height="wrap_content"
- android:layout_weight="0"
- android:gravity="center_horizontal" android:paddingTop="4dip"/>
-
-</LinearLayout>
-
diff --git a/bordeaux/service/res/layout/lava_service_controller.xml b/bordeaux/service/res/layout/lava_service_controller.xml
deleted file mode 100644
index 804589aba..000000000
--- a/bordeaux/service/res/layout/lava_service_controller.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 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.
--->
-
-<!-- Demonstrates starting and stopping a local service.
- See corresponding Java code com.android.sdk.app.LocalSerice.java. -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
- android:gravity="center_horizontal"
- android:layout_width="match_parent" android:layout_height="match_parent">
-
- <TextView
- android:layout_width="match_parent" android:layout_height="wrap_content"
- android:layout_weight="0"
- android:paddingBottom="4dip"
- android:text="@string/lava_service_controller"/>
-
- <Button android:id="@+id/start"
- android:layout_width="wrap_content" android:layout_height="wrap_content"
- android:text="@string/start_service">
- <requestFocus />
- </Button>
-
- <Button android:id="@+id/stop"
- android:layout_width="wrap_content" android:layout_height="wrap_content"
- android:text="@string/stop_service">
- </Button>
-
-</LinearLayout>
-
diff --git a/bordeaux/service/res/values/strings.xml b/bordeaux/service/res/values/strings.xml
deleted file mode 100644
index f49d1a090..000000000
--- a/bordeaux/service/res/values/strings.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 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.
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bordeaux_app">Bordeaux Apps</string>
- <string name="send_data">Send Learning Data</string>
-
- <string name="local_service_started">Local service has started</string>
- <string name="local_service_stopped">Local service has stopped</string>
- <string name="local_service_label">Sample Local Service</string>
-
- <string name="activity_local_service_controller">App/Service/Local Service Controller</string>
- <string name="local_service_controller">This demonstrates how you can implement persistent services that
- may be started and stopped as desired.</string>
- <string name="start_service">Start Service</string>
- <string name="stop_service">Stop Service</string>
-
- <string name="activity_local_service_binding">App/Service/Local Service Binding</string>
- <string name="local_service_binding">This demonstrates how you can connect with a persistent
- service. Notice how it automatically starts for you, and play around with the
- interaction between this and Local Service Controller.</string>
- <string name="bind_service">Bind Service</string>
- <string name="unbind_service">Unbind Service</string>
- <string name="local_service_connected">Connected to local service</string>
- <string name="local_service_disconnected">Disconnected from local service</string>
-
- <string name="remote_service_started">Remote service has started</string>
- <string name="remote_service_stopped">Remote service has stopped</string>
- <string name="remote_service_label">Sample Remote Service</string>
-
- <string name="activity_lava_service_controller">Bordeaux Service Controller</string>
- <string name="lava_service_controller">This demonstrates how you can implement persistent services
- running in a separate process that may be started and stopped as desired.</string>
-
- <string name="activity_lava_service_binding">Bordeaux Service</string>
- <string name="lava_service_binding">This demonstrates how you can connect with a persistent
- service running in another process. Use the kill button to see what happens when
- the process crashes.</string>
- <string name="kill_process">Kill Process</string>
- <string name="remote_service_connected">Connected to remote service</string>
- <string name="remote_service_disconnected">Disconnected from remote service</string>
- <string name="remote_service_unbind_disconn">Unbinding due to disconnect</string>
- <string name="remote_call_failed">Failure calling remote service</string>
-
-
- </resources>
diff --git a/bordeaux/service/src/android/bordeaux/services/Aggregator.java b/bordeaux/service/src/android/bordeaux/services/Aggregator.java
deleted file mode 100644
index a5aced04a..000000000
--- a/bordeaux/service/src/android/bordeaux/services/Aggregator.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-
-import java.util.Map;
-
-abstract class Aggregator {
- protected AggregatorManager mAggregatorManager;
- public void setManager(AggregatorManager m) {
- mAggregatorManager = m;
- }
- abstract public String[] getListOfFeatures();
- abstract public Map<String,String> getFeatureValue(String featureName);
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/AggregatorManager.java b/bordeaux/service/src/android/bordeaux/services/AggregatorManager.java
deleted file mode 100644
index 0fea228a7..000000000
--- a/bordeaux/service/src/android/bordeaux/services/AggregatorManager.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-
-
-import android.bordeaux.services.StringString;
-import android.content.Context;
-import android.util.Log;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-class AggregatorManager extends IAggregatorManager.Stub {
- private final String TAG = "AggregatorMnager";
- // this maps from the aggregator name to the registered aggregator instance
- private static HashMap<String, Aggregator> mAggregators = new HashMap<String, Aggregator>();
- // this maps from the feature names to the aggregator that generates the feature
- private static HashMap<String, Aggregator> sFeatureMap = new HashMap<String, Aggregator>();
- private static AggregatorManager mManager = null;
-
- private String mFakeLocation = null;
- private String mFakeTimeOfDay = null;
- private String mFakeDayOfWeek = null;
-
- private AggregatorManager() {
- sFeatureMap = new HashMap<String, Aggregator>();
- }
-
- public static AggregatorManager getInstance() {
- if (mManager == null )
- mManager = new AggregatorManager();
- return mManager;
- }
-
- public String[] getListOfFeatures() {
- String[] s = new String[sFeatureMap.size()];
- int i = 0;
- for (Map.Entry<String, Aggregator> x : sFeatureMap.entrySet()) {
- s[i] = x.getKey();
- i++;
- }
- return s;
- }
-
- public void registerAggregator(Aggregator agg, AggregatorManager m) {
- if (mAggregators.get(agg.getClass().getName()) != null) {
- // only one instance
- // throw new RuntimeException("Can't register more than one instance");
- }
- mAggregators.put(agg.getClass().getName(), agg);
- agg.setManager(m);
- String[] fl = agg.getListOfFeatures();
- for ( int i = 0; i< fl.length; i ++)
- sFeatureMap.put(fl[i], agg);
- }
-
- // Start of IAggregatorManager interface
- public ArrayList<StringString> getData(String dataName) {
- return getList(getDataMap(dataName));
- }
-
- public List<String> getLocationClusters() {
- LocationStatsAggregator agg = (LocationStatsAggregator)
- mAggregators.get(LocationStatsAggregator.class.getName());
- if (agg == null) return new ArrayList<String> ();
- return agg.getClusterNames();
- }
-
- public List<String> getTimeOfDayValues() {
- TimeStatsAggregator agg = (TimeStatsAggregator)
- mAggregators.get(TimeStatsAggregator.class.getName());
- if (agg == null) return new ArrayList<String>();
- return agg.getTimeOfDayValues();
- }
-
- public List<String> getDayOfWeekValues() {
- TimeStatsAggregator agg = (TimeStatsAggregator)
- mAggregators.get(TimeStatsAggregator.class.getName());
- if (agg == null) return new ArrayList<String>();
- return agg.getDayOfWeekValues();
- }
-
- // Set an empty string "" to disable the fake location
- public boolean setFakeLocation(String location) {
- LocationStatsAggregator agg = (LocationStatsAggregator)
- mAggregators.get(LocationStatsAggregator.class.getName());
- if (agg == null) return false;
- agg.setFakeLocation(location);
- mFakeLocation = location;
- return true;
- }
-
- // Set an empty string "" to disable the fake time of day
- public boolean setFakeTimeOfDay(String time_of_day) {
- TimeStatsAggregator agg = (TimeStatsAggregator)
- mAggregators.get(TimeStatsAggregator.class.getName());
- if (agg == null) return false;
- agg.setFakeTimeOfDay(time_of_day);
- mFakeTimeOfDay = time_of_day;
- return true;
- }
-
- // Set an empty string "" to disable the fake day of week
- public boolean setFakeDayOfWeek(String day_of_week) {
- TimeStatsAggregator agg = (TimeStatsAggregator)
- mAggregators.get(TimeStatsAggregator.class.getName());
- if (agg == null) return false;
- agg.setFakeDayOfWeek(day_of_week);
- mFakeDayOfWeek = day_of_week;
- return true;
- }
-
- // Get the current mode, if fake mode return true
- public boolean getFakeMode() {
- boolean fakeMode = false;
- // checking any features that are in the fake mode
- if (mFakeLocation != null && mFakeLocation.length() != 0)
- fakeMode = true;
- if (mFakeTimeOfDay != null && mFakeTimeOfDay.length() != 0)
- fakeMode = true;
- if (mFakeDayOfWeek != null && mFakeDayOfWeek.length() != 0)
- fakeMode = true;
- return fakeMode;
- }
- // End of IAggregatorManger interface
-
- public Map<String, String> getDataMap(String dataName) {
- if (sFeatureMap.get(dataName) != null)
- return sFeatureMap.get(dataName).getFeatureValue(dataName);
- else
- Log.e(TAG, "There is no feature called " + dataName);
- return null;
- }
-
- private ArrayList<StringString> getList(final Map<String, String> sample) {
- ArrayList<StringString> StringString_sample = new ArrayList<StringString>();
- for (Map.Entry<String, String> x : sample.entrySet()) {
- StringString v = new StringString();
- v.key = x.getKey();
- v.value = x.getValue();
- StringString_sample.add(v);
- }
- return StringString_sample;
- }
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/AggregatorRecordStorage.java b/bordeaux/service/src/android/bordeaux/services/AggregatorRecordStorage.java
deleted file mode 100644
index 4bf677f59..000000000
--- a/bordeaux/service/src/android/bordeaux/services/AggregatorRecordStorage.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.SQLException;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/* This class implements record like data storage for aggregator.
- * The data is stored in the sqlite database row by row without primary key, all
- * columns are assume having string value.
- * Sample usage:
- * AggregatorRecordStorage db = new AggregatorRecordStorage(this, "TestTable",
- * new String[]{"clusterid", "long", "lat"});
- * db.removeAllData();
- * HashMap<String, String> row = new HashMap<String, String>();
- * row.put("clusterid", "home");
- * row.put("long", "110.203");
- * row.put("lat", "-13.787");
- * db.addData(row);
- * row.put("clusterid", "office");
- * row.put("long", "1.203");
- * row.put("lat", "33.787");
- * db.addData(row);
- * List<Map<String,String> > allData = db.getAllData();
- * Log.i(TAG,"Total data in database: " + allData.size());
- */
-class AggregatorRecordStorage extends AggregatorStorage {
- private static final String TAG = "AggregatorRecordStorage";
- private String mTableName;
- private List<String> mColumnNames;
-
- public AggregatorRecordStorage(Context context, String tableName, String [] columnNames) {
- if (columnNames.length < 1) {
- throw new RuntimeException("No column keys");
- }
- mColumnNames = Arrays.asList(columnNames);
- mTableName = tableName;
-
- String tableCmd = "create table " + tableName + "( " + columnNames[0] +
- " TEXT";
- for (int i = 1; i < columnNames.length; ++i)
- tableCmd = tableCmd + ", " + columnNames[i] + " TEXT";
- tableCmd = tableCmd + ");";
- Log.i(TAG, tableCmd);
- try {
- mDbHelper = new DBHelper(context, tableName, tableCmd);
- mDatabase = mDbHelper.getWritableDatabase();
- } catch (SQLException e) {
- throw new RuntimeException("Can't open table: " + tableName);
- }
- }
-
- // Adding one more row to the table.
- // the data is a map of <column_name, value> pair.
- public boolean addData(Map<String, String> data) {
- ContentValues content = new ContentValues();
- for (Map.Entry<String, String> item : data.entrySet()) {
- content.put(item.getKey(), item.getValue());
- }
- long rowID =
- mDatabase.insert(mTableName, null, content);
- return rowID >= 0;
- }
-
- // Return all data as a list of Map.
- // Notice that the column names are repeated for each row.
- public List<Map<String, String>> getAllData() {
- ArrayList<Map<String, String> > allData = new ArrayList<Map<String, String> >();
-
- Cursor cursor = mDatabase.rawQuery("select * from " + mTableName + ";", null);
- if (cursor.getCount() == 0) {
- return allData;
- }
- cursor.moveToFirst();
- do {
- HashMap<String, String> oneRow = new HashMap<String, String>();
- for (String column : mColumnNames) {
- int columnIndex = cursor.getColumnIndex(column);
- if (!cursor.isNull(columnIndex)) {
- String value = cursor.getString(columnIndex);
- oneRow.put(column, value);
- }
- }
- allData.add(oneRow);
- } while (cursor.moveToNext());
- return allData;
- }
-
- // Empty the storage.
- public int removeAllData() {
- int nDeleteRows = mDatabase.delete(mTableName, "1", null);
- Log.i(TAG, "Number of rows in table deleted: " + nDeleteRows);
- return nDeleteRows;
- }
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/AggregatorStorage.java b/bordeaux/service/src/android/bordeaux/services/AggregatorStorage.java
deleted file mode 100644
index 1d8886e66..000000000
--- a/bordeaux/service/src/android/bordeaux/services/AggregatorStorage.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-
-import android.content.Context;
-import android.database.SQLException;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.util.Log;
-
-// Base Helper class for aggregator storage database
-class AggregatorStorage {
- private static final String TAG = "AggregatorStorage";
- private static final String DATABASE_NAME = "aggregator";
- private static final int DATABASE_VERSION = 1;
-
- protected DBHelper mDbHelper;
- protected SQLiteDatabase mDatabase;
-
- class DBHelper extends SQLiteOpenHelper {
- private String mTableCmd;
- private String mTableName;
- DBHelper(Context context, String tableName, String tableCmd) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
- mTableName = tableName;
- mTableCmd = tableCmd;
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- db.execSQL(mTableCmd);
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
- + newVersion + ", which will destroy all old data");
-
- db.execSQL("DROP TABLE IF EXISTS " + mTableName);
- onCreate(db);
- }
- }
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/BaseCluster.java b/bordeaux/service/src/android/bordeaux/services/BaseCluster.java
deleted file mode 100644
index 03574a9fa..000000000
--- a/bordeaux/service/src/android/bordeaux/services/BaseCluster.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-package android.bordeaux.services;
-import android.location.Location;
-import android.text.format.Time;
-import android.util.Log;
-
-import java.lang.Math;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
-public class BaseCluster {
-
- public static String TAG = "BaseCluster";
-
- public double[] mCenter;
- // protected double[] mCenter;
-
- protected static final int VECTOR_LENGTH = 3;
-
- private static final long FORGETTING_ENUMERATOR = 95;
- private static final long FORGETTING_DENOMINATOR = 100;
-
- // Histogram illustrates the pattern of visit during time of day,
- protected HashMap<String, Long> mHistogram = new HashMap<String, Long>();
-
- protected long mDuration;
-
- protected String mSemanticId;
-
- protected static final double EARTH_RADIUS = 6378100f;
-
- public BaseCluster(Location location) {
- mCenter = getLocationVector(location);
- mDuration = 0;
- }
-
- public BaseCluster(String semanticId, double longitude, double latitude,
- long duration) {
- mSemanticId = semanticId;
- mCenter = getLocationVector(longitude, latitude);
- mDuration = duration;
- }
-
- public String getSemanticId() {
- return mSemanticId;
- }
-
- public void generateSemanticId(long index) {
- mSemanticId = "cluser: " + String.valueOf(index);
- }
-
- public long getDuration() {
- return mDuration;
- }
-
- public boolean hasSemanticId() {
- return mSemanticId != null;
- }
-
- protected double[] getLocationVector(Location location) {
- return getLocationVector(location.getLongitude(), location.getLatitude());
- }
-
- protected double[] getLocationVector(double longitude, double latitude) {
- double vector[] = new double[VECTOR_LENGTH];
- double lambda = Math.toRadians(longitude);
- double phi = Math.toRadians(latitude);
-
- vector[0] = Math.cos(lambda) * Math.cos(phi);
- vector[1] = Math.sin(lambda) * Math.cos(phi);
- vector[2] = Math.sin(phi);
- return vector;
- }
-
- protected double getCenterLongitude() {
- // Because latitude ranges from -90 to 90 degrees, cosPhi >= 0.
- double cosPhi = Math.cos(Math.asin(mCenter[2]));
- double longitude = Math.toDegrees(Math.asin(mCenter[1] / cosPhi));
- if (mCenter[0] < 0) {
- longitude = (longitude > 0) ? 180f - longitude : -180 - longitude;
- }
- return longitude;
- }
-
- protected double getCenterLatitude() {
- return Math.toDegrees(Math.asin(mCenter[2]));
- }
-
- private double computeDistance(double[] vector1, double[] vector2) {
- double product = 0f;
- for (int i = 0; i < VECTOR_LENGTH; ++i) {
- product += vector1[i] * vector2[i];
- }
- double radian = Math.acos(Math.min(product, 1f));
- return radian * EARTH_RADIUS;
- }
-
- /*
- * This computes the distance from loation to the cluster center in meter.
- */
- public float distanceToCenter(Location location) {
- return (float) computeDistance(mCenter, getLocationVector(location));
- }
-
- public float distanceToCluster(BaseCluster cluster) {
- return (float) computeDistance(mCenter, cluster.mCenter);
- }
-
- public void absorbCluster(BaseCluster cluster) {
- averageCenter(cluster.mCenter, cluster.mDuration);
- absorbHistogram(cluster);
- }
-
- public void setCluster(BaseCluster cluster) {
- for (int i = 0; i < VECTOR_LENGTH; ++i) {
- mCenter[i] = cluster.mCenter[i];
- }
- mHistogram.clear();
- mHistogram.putAll(cluster.mHistogram);
- mDuration = cluster.mDuration;
- }
-
- private void absorbHistogram(BaseCluster cluster) {
- for (Map.Entry<String, Long> entry : cluster.mHistogram.entrySet()) {
- String timeLabel = entry.getKey();
- long duration = entry.getValue();
-
- if (mHistogram.containsKey(timeLabel)) {
- duration += mHistogram.get(timeLabel);
- }
- mHistogram.put(timeLabel, duration);
- }
- mDuration += cluster.mDuration;
- }
-
- public boolean passThreshold(long durationThreshold) {
- // TODO: might want to keep semantic cluster
- return mDuration > durationThreshold;
- }
-
- public final HashMap<String, Long> getHistogram() {
- return mHistogram;
- }
-
- public void setHistogram(Map<String, Long> histogram) {
- mHistogram.clear();
- mHistogram.putAll(histogram);
-
- mDuration = 0;
- if (mHistogram.containsKey(TimeStatsAggregator.WEEKEND)) {
- mDuration += mHistogram.get(TimeStatsAggregator.WEEKEND);
- }
- if (mHistogram.containsKey(TimeStatsAggregator.WEEKDAY)) {
- mDuration += mHistogram.get(TimeStatsAggregator.WEEKDAY);
- }
- }
-
- public void forgetPastHistory() {
- mDuration *= FORGETTING_ENUMERATOR;
- mDuration /= FORGETTING_DENOMINATOR;
-
- for (Map.Entry<String, Long> entry : mHistogram.entrySet()) {
- String key = entry.getKey();
- long value = entry.getValue();
-
- value *= FORGETTING_ENUMERATOR;
- value /= FORGETTING_DENOMINATOR;
-
- mHistogram.put(key, value);
- }
- }
-
- protected void normalizeCenter() {
- double norm = 0;
- for (int i = 0; i < VECTOR_LENGTH; ++i) {
- norm += mCenter[i] * mCenter[i];
- }
- norm = Math.sqrt(norm);
- for (int i = 0; i < VECTOR_LENGTH; ++i) {
- mCenter[i] /= norm;
- }
- }
-
- protected void averageCenter(double[] newCenter, long newDuration) {
- double weight = ((double) mDuration) / (mDuration + newDuration);
- double newWeight = 1f - weight;
-
- double norm = 0;
- for (int i = 0; i < VECTOR_LENGTH; ++i) {
- mCenter[i] = weight * mCenter[i] + newWeight * newCenter[i];
- norm += mCenter[i] * mCenter[i];
- }
- norm = Math.sqrt(norm);
- for (int i = 0; i < VECTOR_LENGTH; ++i) {
- mCenter[i] /= norm;
- }
- }
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/BordeauxAggregatorManager.java b/bordeaux/service/src/android/bordeaux/services/BordeauxAggregatorManager.java
deleted file mode 100644
index 7a01233ab..000000000
--- a/bordeaux/service/src/android/bordeaux/services/BordeauxAggregatorManager.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-
-import android.bordeaux.services.IAggregatorManager;
-import android.bordeaux.services.StringString;
-import android.content.Context;
-import android.os.RemoteException;
-import android.util.Log;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
-/** AggregatorManger for Learning framework.
- */
-public class BordeauxAggregatorManager {
- static final String TAG = "BordeauxAggregatorManager";
- static final String AggregatorManager_NOTAVAILABLE = "AggregatorManager not Available";
- private Context mContext;
- private IAggregatorManager mAggregatorManager;
-
- public boolean retrieveAggregatorManager() {
- if (mAggregatorManager == null) {
- mAggregatorManager = BordeauxManagerService.getAggregatorManager(mContext);
- if (mAggregatorManager == null) {
- Log.e(TAG, AggregatorManager_NOTAVAILABLE);
- return false;
- }
- }
- return true;
- }
-
- public BordeauxAggregatorManager (Context context) {
- mContext = context;
- mAggregatorManager = BordeauxManagerService.getAggregatorManager(mContext);
- }
-
- public Map<String, String> GetData(final String dataName) {
- if (!retrieveAggregatorManager())
- throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
- try {
- return getMap(mAggregatorManager.getData(dataName));
- } catch (RemoteException e) {
- Log.e(TAG,"Exception in Getting " + dataName);
- throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
- }
- }
-
- public List<String> getLocationClusters() {
- if (!retrieveAggregatorManager())
- throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
- try {
- return mAggregatorManager.getLocationClusters();
- } catch (RemoteException e) {
- Log.e(TAG,"Error getting location clusters");
- throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
- }
- }
-
- public List<String> getTimeOfDayValues() {
- if (!retrieveAggregatorManager())
- throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
- try {
- return mAggregatorManager.getTimeOfDayValues();
- } catch (RemoteException e) {
- Log.e(TAG,"Error getting time of day values");
- throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
- }
- }
-
- public List<String> getDayOfWeekValues() {
- if (!retrieveAggregatorManager())
- throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
- try {
- return mAggregatorManager.getDayOfWeekValues();
- } catch (RemoteException e) {
- Log.e(TAG,"Error getting day of week values");
- throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
- }
- }
-
- public boolean setFakeLocation(final String name) {
- if (!retrieveAggregatorManager())
- throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
- try {
- return mAggregatorManager.setFakeLocation(name);
- } catch (RemoteException e) {
- Log.e(TAG,"Error setting fake location:" + name);
- throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
- }
- }
-
- public boolean setFakeTimeOfDay(final String time_of_day) {
- if (!retrieveAggregatorManager())
- throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
- try {
- return mAggregatorManager.setFakeTimeOfDay(time_of_day);
- } catch (RemoteException e) {
- Log.e(TAG,"Error setting fake time of day:" + time_of_day);
- throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
- }
- }
-
- public boolean setFakeDayOfWeek(final String day_of_week) {
- if (!retrieveAggregatorManager())
- throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
- try {
- return mAggregatorManager.setFakeDayOfWeek(day_of_week);
- } catch (RemoteException e) {
- Log.e(TAG,"Error setting fake day of week:" + day_of_week);
- throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
- }
- }
-
- public boolean getFakeMode() {
- if (!retrieveAggregatorManager())
- throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
- try {
- return mAggregatorManager.getFakeMode();
- } catch (RemoteException e) {
- Log.e(TAG,"Error getting fake mode");
- throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
- }
- }
-
- private Map<String, String> getMap(final List<StringString> sample) {
- HashMap<String, String> map = new HashMap<String, String>();
- for (int i =0; i < sample.size(); i++) {
- map.put(sample.get(i).key, sample.get(i).value);
- }
- return (Map) map;
- }
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/BordeauxClassifier.java b/bordeaux/service/src/android/bordeaux/services/BordeauxClassifier.java
deleted file mode 100644
index 348cd0cb8..000000000
--- a/bordeaux/service/src/android/bordeaux/services/BordeauxClassifier.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-
-import android.bordeaux.services.ILearning_MulticlassPA;
-import android.bordeaux.services.IntFloat;
-import android.content.Context;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.HashMap;
-import java.util.Map;
-
-/** Classifier for the Learning framework.
- * For training: call trainOneSample
- * For classifying: call classify
- * Data is represented as sparse key, value pair. And key is an integer, value
- * is a float. Class label(target) for the training data is an integer.
- * Note: since the actual classifier is running in a remote the service.
- * Sometimes the connection may be lost or not established.
- *
- */
-public class BordeauxClassifier {
- static final String TAG = "BordeauxClassifier";
- private Context mContext;
- private String mName;
- private ILearning_MulticlassPA mClassifier;
- private ArrayList<IntFloat> getArrayList(final HashMap<Integer, Float> sample) {
- ArrayList<IntFloat> intfloat_sample = new ArrayList<IntFloat>();
- for (Map.Entry<Integer, Float> x : sample.entrySet()) {
- IntFloat v = new IntFloat();
- v.index = x.getKey();
- v.value = x.getValue();
- intfloat_sample.add(v);
- }
- return intfloat_sample;
- }
-
- private boolean retrieveClassifier() {
- if (mClassifier == null)
- mClassifier = BordeauxManagerService.getClassifier(mContext, mName);
- // if classifier is not available, return false
- if (mClassifier == null) {
- Log.i(TAG,"Classifier not available.");
- return false;
- }
- return true;
- }
-
- public BordeauxClassifier(Context context) {
- mContext = context;
- mName = "defaultClassifier";
- mClassifier = BordeauxManagerService.getClassifier(context, mName);
- }
-
- public BordeauxClassifier(Context context, String name) {
- mContext = context;
- mName = name;
- mClassifier = BordeauxManagerService.getClassifier(context, mName);
- }
-
- public boolean update(final HashMap<Integer, Float> sample, int target) {
- if (!retrieveClassifier())
- return false;
- try {
- mClassifier.TrainOneSample(getArrayList(sample), target);
- } catch (RemoteException e) {
- Log.e(TAG,"Exception: training one sample.");
- return false;
- }
- return true;
- }
-
- public int classify(final HashMap<Integer, Float> sample) {
- // if classifier is not available return -1 as an indication of fail.
- if (!retrieveClassifier())
- return -1;
- try {
- return mClassifier.Classify(getArrayList(sample));
- } catch (RemoteException e) {
- Log.e(TAG,"Exception: classify the sample.");
- // return an invalid number.
- // TODO: throw exception.
- return -1;
- }
- }
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/BordeauxManagerService.java b/bordeaux/service/src/android/bordeaux/services/BordeauxManagerService.java
deleted file mode 100644
index 00fbb30f8..000000000
--- a/bordeaux/service/src/android/bordeaux/services/BordeauxManagerService.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PointF;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Process;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * {@hide}
- * This is used to provide a convenience to access the actual remote running
- * service.
- * TODO: Eventally the remote service will be running in the system server, and
- * this will need to be served as a stub for the remote running service. And
- * extends from IBordeauxManager.stub
- */
-public class BordeauxManagerService {
-
- static private final String TAG = "BordeauxMangerService";
- static private IBordeauxService mService = null;
- static private ILearning_StochasticLinearRanker mRanker = null;
- static private IAggregatorManager mAggregatorManager = null;
- static private IPredictor mPredictor = null;
- static private ILearning_MulticlassPA mClassifier = null;
- static private boolean mStarted = false;
-
- public BordeauxManagerService() {
- }
-
- static private synchronized void bindServices(Context context) {
- if (mStarted) return;
- context.bindService(new Intent(IBordeauxService.class.getName()),
- mConnection, Context.BIND_AUTO_CREATE);
- mStarted = true;
- }
-
- // Call the release, before the Context gets destroyed.
- static public synchronized void release(Context context) {
- if (mStarted && mConnection != null) {
- context.unbindService(mConnection);
- mService = null;
- mStarted = false;
- }
- }
-
- static public synchronized IBordeauxService getService(Context context) {
- if (mService == null) bindServices(context);
- return mService;
- }
-
- static public synchronized IAggregatorManager getAggregatorManager(Context context) {
- if (mService == null) {
- bindServices(context);
- return null;
- }
- try {
- mAggregatorManager = IAggregatorManager.Stub.asInterface(
- mService.getAggregatorManager());
- } catch (RemoteException e) {
- mAggregatorManager = null;
- }
- return mAggregatorManager;
- }
-
- static public synchronized IPredictor getPredictor(Context context, String name) {
- if (mService == null) {
- bindServices(context);
- return null;
- }
- try {
- mPredictor = IPredictor.Stub.asInterface(mService.getPredictor(name));
- } catch (RemoteException e) {
- mPredictor = null;
- }
- return mPredictor;
- }
-
- static public synchronized ILearning_StochasticLinearRanker
- getRanker(Context context, String name) {
- if (mService == null) {
- bindServices(context);
- return null;
- }
- try {
- mRanker =
- ILearning_StochasticLinearRanker.Stub.asInterface(
- mService.getRanker(name));
- } catch (RemoteException e) {
- mRanker = null;
- }
- return mRanker;
- }
-
- static public synchronized ILearning_MulticlassPA
- getClassifier(Context context, String name) {
- if (mService == null) {
- bindServices(context);
- return null;
- }
- try {
- mClassifier =
- ILearning_MulticlassPA.Stub.asInterface(mService.getClassifier(name));
- } catch (RemoteException e) {
- mClassifier = null;
- }
- return mClassifier;
- }
-
- /**
- * Class for interacting with the main interface of the service.
- */
- static private ServiceConnection mConnection = new ServiceConnection() {
- public void onServiceConnected(ComponentName className,
- IBinder service) {
- // This is called when the connection with the service has been
- // established.
- mService = IBordeauxService.Stub.asInterface(service);
- }
-
- public void onServiceDisconnected(ComponentName className) {
- // This is called when the connection with the service has been
- // unexpectedly disconnected -- that is, its process crashed.
- mService = null;
- mStarted = false; // needs to bind again
- }
- };
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/BordeauxPredictor.java b/bordeaux/service/src/android/bordeaux/services/BordeauxPredictor.java
deleted file mode 100644
index ac46af11f..000000000
--- a/bordeaux/service/src/android/bordeaux/services/BordeauxPredictor.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-
-import android.bordeaux.services.IPredictor;
-import android.content.Context;
-import android.os.RemoteException;
-import android.util.Log;
-import android.util.Pair;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.HashMap;
-import java.util.Map;
-
-/** Predictor for the Learning framework.
- */
-public class BordeauxPredictor {
- static final String TAG = "BordeauxPredictor";
- static final String PREDICTOR_NOTAVAILABLE = "Predictor is not available.";
- private Context mContext;
- private String mName;
- private IPredictor mPredictor;
-
- public BordeauxPredictor(Context context) {
- mContext = context;
- mName = "defaultPredictor";
- mPredictor = BordeauxManagerService.getPredictor(context, mName);
- }
-
- public BordeauxPredictor(Context context, String name) {
- mContext = context;
- mName = name;
- mPredictor = BordeauxManagerService.getPredictor(context, mName);
- }
-
- public boolean reset() {
- if (!retrievePredictor()){
- Log.e(TAG, "reset: " + PREDICTOR_NOTAVAILABLE);
- return false;
- }
- try {
- mPredictor.resetPredictor();
- return true;
- } catch (RemoteException e) {
- }
- return false;
- }
-
- public boolean retrievePredictor() {
- if (mPredictor == null) {
- mPredictor = BordeauxManagerService.getPredictor(mContext, mName);
- }
- if (mPredictor == null) {
- Log.e(TAG, "retrievePredictor: " + PREDICTOR_NOTAVAILABLE);
- return false;
- }
- return true;
- }
-
- public void addSample(String sampleName) {
- if (!retrievePredictor())
- throw new RuntimeException(PREDICTOR_NOTAVAILABLE);
- try {
- mPredictor.pushNewSample(sampleName);
- } catch (RemoteException e) {
- Log.e(TAG,"Exception: pushing a new example");
- throw new RuntimeException(PREDICTOR_NOTAVAILABLE);
- }
- }
-
- public ArrayList<Pair<String, Float> > getTopSamples() {
- return getTopSamples(0);
- }
-
- public ArrayList<Pair<String, Float> > getTopSamples(int topK) {
- try {
- ArrayList<StringFloat> topList =
- (ArrayList<StringFloat>) mPredictor.getTopCandidates(topK);
-
- ArrayList<Pair<String, Float> > topSamples =
- new ArrayList<Pair<String, Float> >(topList.size());
- for (int i = 0; i < topList.size(); ++i) {
- topSamples.add(new Pair<String, Float>(topList.get(i).key, topList.get(i).value));
- }
- return topSamples;
- } catch(RemoteException e) {
- Log.e(TAG,"Exception: getTopSamples");
- throw new RuntimeException(PREDICTOR_NOTAVAILABLE);
- }
- }
-
- public boolean setParameter(String key, String value) {
- if (!retrievePredictor())
- throw new RuntimeException(PREDICTOR_NOTAVAILABLE);
- try {
- return mPredictor.setPredictorParameter(key, value);
- } catch (RemoteException e) {
- Log.e(TAG,"Exception: setting predictor parameter");
- throw new RuntimeException(PREDICTOR_NOTAVAILABLE);
- }
- }
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/BordeauxRanker.java b/bordeaux/service/src/android/bordeaux/services/BordeauxRanker.java
deleted file mode 100644
index 1ae5fcb62..000000000
--- a/bordeaux/service/src/android/bordeaux/services/BordeauxRanker.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-
-import android.bordeaux.services.ILearning_StochasticLinearRanker;
-import android.bordeaux.services.StringFloat;
-import android.content.Context;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.HashMap;
-import java.util.Map;
-
-/** Ranker for the Learning framework.
- * For training: call updateClassifier with a pair of samples.
- * For ranking: call scoreSample to the score of the rank
- * Data is represented as sparse key, value pair. And key is a String, value
- * is a float.
- * Note: since the actual ranker is running in a remote the service.
- * Sometimes the connection may be lost or not established.
- *
- */
-public class BordeauxRanker {
- static final String TAG = "BordeauxRanker";
- static final String RANKER_NOTAVAILABLE = "Ranker not Available";
- private Context mContext;
- private String mName;
- private ILearning_StochasticLinearRanker mRanker;
- private ArrayList<StringFloat> getArrayList(final HashMap<String, Float> sample) {
- ArrayList<StringFloat> stringfloat_sample = new ArrayList<StringFloat>();
- for (Map.Entry<String, Float> x : sample.entrySet()) {
- StringFloat v = new StringFloat();
- v.key = x.getKey();
- v.value = x.getValue();
- stringfloat_sample.add(v);
- }
- return stringfloat_sample;
- }
-
- public boolean retrieveRanker() {
- if (mRanker == null)
- mRanker = BordeauxManagerService.getRanker(mContext, mName);
- // if classifier is not available, return false
- if (mRanker == null) {
- Log.e(TAG,"Ranker not available.");
- return false;
- }
- return true;
- }
-
- public BordeauxRanker(Context context) {
- mContext = context;
- mName = "defaultRanker";
- mRanker = BordeauxManagerService.getRanker(context, mName);
- }
-
- public BordeauxRanker(Context context, String name) {
- mContext = context;
- mName = name;
- mRanker = BordeauxManagerService.getRanker(context, mName);
- }
-
- // Update the ranker with two samples, sample1 has higher rank than
- // sample2.
- public boolean update(final HashMap<String, Float> sample1,
- final HashMap<String, Float> sample2) {
- if (!retrieveRanker())
- return false;
- try {
- mRanker.UpdateClassifier(getArrayList(sample1), getArrayList(sample2));
- } catch (RemoteException e) {
- Log.e(TAG,"Exception: updateClassifier.");
- return false;
- }
- return true;
- }
-
- public boolean reset() {
- if (!retrieveRanker()){
- Log.e(TAG,"Exception: Ranker is not availible");
- return false;
- }
- try {
- mRanker.ResetRanker();
- return true;
- } catch (RemoteException e) {
- }
- return false;
- }
-
- public float scoreSample(final HashMap<String, Float> sample) {
- if (!retrieveRanker())
- throw new RuntimeException(RANKER_NOTAVAILABLE);
- try {
- return mRanker.ScoreSample(getArrayList(sample));
- } catch (RemoteException e) {
- Log.e(TAG,"Exception: scoring the sample.");
- throw new RuntimeException(RANKER_NOTAVAILABLE);
- }
- }
-
- public boolean setPriorWeight(final HashMap<String, Float> sample) {
- if (!retrieveRanker())
- throw new RuntimeException(RANKER_NOTAVAILABLE);
- try {
- return mRanker.SetModelPriorWeight(getArrayList(sample));
- } catch (RemoteException e) {
- Log.e(TAG,"Exception: set prior Weights");
- throw new RuntimeException(RANKER_NOTAVAILABLE);
- }
- }
-
- public boolean setParameter(String key, String value) {
- if (!retrieveRanker())
- throw new RuntimeException(RANKER_NOTAVAILABLE);
- try {
- return mRanker.SetModelParameter(key, value);
- } catch (RemoteException e) {
- Log.e(TAG,"Exception: Setting Parameter");
- throw new RuntimeException(RANKER_NOTAVAILABLE);
- }
- }
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/BordeauxService.java b/bordeaux/service/src/android/bordeaux/services/BordeauxService.java
deleted file mode 100644
index 48d41d942..000000000
--- a/bordeaux/service/src/android/bordeaux/services/BordeauxService.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-
-import android.app.Activity;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.Service;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.ServiceConnection;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Process;
-import android.os.RemoteCallbackList;
-import android.os.RemoteException;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.TextView;
-import android.widget.Toast;
-
-//import android.bordeaux.R;
-import android.util.Log;
-
-import java.io.*;
-
-/**
- * Machine Learning service that runs in a remote process.
- * The application doesn't use this class directly.
- *
- */
-public class BordeauxService extends Service {
- private final String TAG = "BordeauxService";
- /**
- * This is a list of callbacks that have been registered with the
- * service.
- * It's a place holder for future communications with all registered
- * clients.
- */
- final RemoteCallbackList<IBordeauxServiceCallback> mCallbacks =
- new RemoteCallbackList<IBordeauxServiceCallback>();
-
- int mValue = 0;
- NotificationManager mNotificationManager;
-
- BordeauxSessionManager mSessionManager;
- AggregatorManager mAggregatorManager;
- TimeStatsAggregator mTimeStatsAggregator;
- LocationStatsAggregator mLocationStatsAggregator;
- MotionStatsAggregator mMotionStatsAggregator;
-
- @Override
- public void onCreate() {
- Log.i(TAG, "Bordeaux service created.");
- //mNotificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
- mSessionManager = new BordeauxSessionManager(this);
- mMotionStatsAggregator = new MotionStatsAggregator();
- mLocationStatsAggregator = new LocationStatsAggregator(this);
- mTimeStatsAggregator = new TimeStatsAggregator();
- mAggregatorManager = AggregatorManager.getInstance();
- mAggregatorManager.registerAggregator(mMotionStatsAggregator, mAggregatorManager);
- mAggregatorManager.registerAggregator(mLocationStatsAggregator, mAggregatorManager);
- mAggregatorManager.registerAggregator(mTimeStatsAggregator, mAggregatorManager);
-
- // Display a notification about us starting.
- // TODO: don't display the notification after the service is
- // automatically started by the system, currently it's useful for
- // debugging.
- showNotification();
- }
-
- @Override
- public void onDestroy() {
- // Save the sessions
- mSessionManager.saveSessions();
-
- // Cancel the persistent notification.
- //mNotificationManager.cancel(R.string.remote_service_started);
-
- // Tell the user we stopped.
- //Toast.makeText(this, R.string.remote_service_stopped, Toast.LENGTH_SHORT).show();
-
- // Unregister all callbacks.
- mCallbacks.kill();
-
- mLocationStatsAggregator.release();
-
- Log.i(TAG, "Bordeaux service stopped.");
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- // Return the requested interface.
- if (IBordeauxService.class.getName().equals(intent.getAction())) {
- return mBinder;
- }
- return null;
- }
-
-
- // The main interface implemented by the service.
- private final IBordeauxService.Stub mBinder = new IBordeauxService.Stub() {
- private IBinder getLearningSession(Class learnerClass, String name) {
- PackageManager pm = getPackageManager();
- String uidname = pm.getNameForUid(getCallingUid());
- Log.i(TAG,"Name for uid: " + uidname);
- BordeauxSessionManager.SessionKey key =
- mSessionManager.getSessionKey(uidname, learnerClass, name);
- Log.i(TAG, "request learning session: " + key.value);
- try {
- IBinder iLearner = mSessionManager.getSessionBinder(learnerClass, key);
- return iLearner;
- } catch (RuntimeException e) {
- Log.e(TAG, "Error getting learning interface" + e);
- return null;
- }
- }
-
- public IBinder getClassifier(String name) {
- return getLearningSession(Learning_MulticlassPA.class, name);
- }
-
- public IBinder getRanker(String name) {
- return getLearningSession(Learning_StochasticLinearRanker.class, name);
- }
-
- public IBinder getPredictor(String name) {
- return getLearningSession(Predictor.class, name);
- }
-
- public IBinder getAggregatorManager() {
- return (IBinder) mAggregatorManager;
- }
-
- public void registerCallback(IBordeauxServiceCallback cb) {
- if (cb != null) mCallbacks.register(cb);
- }
-
- public void unregisterCallback(IBordeauxServiceCallback cb) {
- if (cb != null) mCallbacks.unregister(cb);
- }
- };
-
- @Override
- public void onTaskRemoved(Intent rootIntent) {
- Toast.makeText(this, "Task removed: " + rootIntent, Toast.LENGTH_LONG).show();
- }
-
- /**
- * Show a notification while this service is running.
- * TODO: remove the code after production (when service is loaded
- * automatically by the system).
- */
- private void showNotification() {
- /*// In this sample, we'll use the same text for the ticker and the expanded notification
- CharSequence text = getText(R.string.remote_service_started);
-
- // The PendingIntent to launch our activity if the user selects this notification
- PendingIntent contentIntent =
- PendingIntent.getActivity(this, 0,
- new Intent("android.bordeaux.DEBUG_CONTROLLER"), 0);
-
- // // Set the info for the views that show in the notification panel.
-
- Notification.Builder builder = new Notification.Builder(this);
- builder.setSmallIcon(R.drawable.ic_bordeaux);
- builder.setWhen(System.currentTimeMillis());
- builder.setTicker(text);
- builder.setContentTitle(text);
- builder.setContentIntent(contentIntent);
- Notification notification = builder.getNotification();
- // Send the notification.
- // We use a string id because it is a unique number. We use it later to cancel.
- mNotificationManager.notify(R.string.remote_service_started, notification); */
- }
-
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/BordeauxSessionManager.java b/bordeaux/service/src/android/bordeaux/services/BordeauxSessionManager.java
deleted file mode 100644
index 89fcac29e..000000000
--- a/bordeaux/service/src/android/bordeaux/services/BordeauxSessionManager.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-
-import android.bordeaux.services.IBordeauxLearner.ModelChangeCallback;
-import android.content.Context;
-import android.os.IBinder;
-import android.util.Log;
-
-import java.lang.NoSuchMethodException;
-import java.lang.InstantiationException;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.HashMap;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-// This class manages the learning sessions from multiple applications.
-// The learning sessions are automatically backed up to the storage.
-//
-class BordeauxSessionManager {
-
- static private final String TAG = "BordeauxSessionManager";
- private BordeauxSessionStorage mSessionStorage;
-
- static class Session {
- Class learnerClass;
- IBordeauxLearner learner;
- boolean modified = false;
- };
-
- static class SessionKey {
- String value;
- };
-
- // Thread to periodically save the sessions to storage
- class PeriodicSave extends Thread implements Runnable {
- long mSavingInterval = 60000; // 60 seconds
- boolean mQuit = false;
- PeriodicSave() {}
- public void run() {
- while (!mQuit) {
- try {
- sleep(mSavingInterval);
- } catch (InterruptedException e) {
- // thread waked up.
- // ignore
- }
- saveSessions();
- }
- }
- }
-
- PeriodicSave mSavingThread = new PeriodicSave();
-
- private ConcurrentHashMap<String, Session> mSessions =
- new ConcurrentHashMap<String, Session>();
-
- public BordeauxSessionManager(final Context context) {
- mSessionStorage = new BordeauxSessionStorage(context);
- mSavingThread.start();
- }
-
- class LearningUpdateCallback implements ModelChangeCallback {
- private String mKey;
-
- public LearningUpdateCallback(String key) {
- mKey = key;
- }
-
- public void modelChanged(IBordeauxLearner learner) {
- // Save the session
- Session session = mSessions.get(mKey);
- if (session != null) {
- synchronized(session) {
- if (session.learner != learner) {
- throw new RuntimeException("Session data corrupted!");
- }
- session.modified = true;
- }
- }
- }
- }
-
- // internal unique key that identifies the learning instance.
- // Composed by the package id of the calling process, learning class name
- // and user specified name.
- public SessionKey getSessionKey(String callingUid, Class learnerClass, String name) {
- SessionKey key = new SessionKey();
- key.value = callingUid + "#" + "_" + name + "_" + learnerClass.getName();
- return key;
- }
-
- public IBinder getSessionBinder(Class learnerClass, SessionKey key) {
- if (mSessions.containsKey(key.value)) {
- return mSessions.get(key.value).learner.getBinder();
- }
- // not in memory cache
- try {
- // try to find it in the database
- Session stored = mSessionStorage.getSession(key.value);
- if (stored != null) {
- // set the callback, so that we can save the state
- stored.learner.setModelChangeCallback(new LearningUpdateCallback(key.value));
- // found session in the storage, put in the cache
- mSessions.put(key.value, stored);
- return stored.learner.getBinder();
- }
-
- // if session is not already stored, create a new one.
- Log.i(TAG, "create a new learning session: " + key.value);
- IBordeauxLearner learner =
- (IBordeauxLearner) learnerClass.getConstructor().newInstance();
- // set the callback, so that we can save the state
- learner.setModelChangeCallback(new LearningUpdateCallback(key.value));
- Session session = new Session();
- session.learnerClass = learnerClass;
- session.learner = learner;
- mSessions.put(key.value, session);
- return learner.getBinder();
- } catch (Exception e) {
- throw new RuntimeException("Can't instantiate class: " +
- learnerClass.getName());
- }
- }
-
- public void saveSessions() {
- for (Map.Entry<String, Session> session : mSessions.entrySet()) {
- synchronized(session) {
- // Save the session if it's modified.
- if (session.getValue().modified) {
- SessionKey skey = new SessionKey();
- skey.value = session.getKey();
- saveSession(skey);
- }
- }
- }
- }
-
- public boolean saveSession(SessionKey key) {
- Session session = mSessions.get(key.value);
- if (session != null) {
- synchronized(session) {
- byte[] model = session.learner.getModel();
-
- // write to database
- boolean res = mSessionStorage.saveSession(key.value, session.learnerClass, model);
- if (res)
- session.modified = false;
- else {
- Log.e(TAG, "Can't save session: " + key.value);
- }
- return res;
- }
- }
- Log.e(TAG, "Session not found: " + key.value);
- return false;
- }
-
- // Load all session data into memory.
- // The session data will be loaded into the memory from the database, even
- // if this method is not called.
- public void loadSessions() {
- synchronized(mSessions) {
- mSessionStorage.getAllSessions(mSessions);
- for (Map.Entry<String, Session> session : mSessions.entrySet()) {
- // set the callback, so that we can save the state
- session.getValue().learner.setModelChangeCallback(
- new LearningUpdateCallback(session.getKey()));
- }
- }
- }
-
- public void removeAllSessionsFromCaller(String callingUid) {
- // remove in the hash table
- ArrayList<String> remove_keys = new ArrayList<String>();
- for (Map.Entry<String, Session> session : mSessions.entrySet()) {
- if (session.getKey().startsWith(callingUid + "#")) {
- remove_keys.add(session.getKey());
- }
- }
- for (String key : remove_keys) {
- mSessions.remove(key);
- }
- // remove all session data from the callingUid in database
- // % is used as wild match for the rest of the string in sql
- int nDeleted = mSessionStorage.removeSessions(callingUid + "#%");
- if (nDeleted > 0)
- Log.i(TAG, "Successfully deleted " + nDeleted + "sessions");
- }
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/BordeauxSessionStorage.java b/bordeaux/service/src/android/bordeaux/services/BordeauxSessionStorage.java
deleted file mode 100644
index 89c347204..000000000
--- a/bordeaux/service/src/android/bordeaux/services/BordeauxSessionStorage.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.SQLException;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.util.Log;
-
-import java.lang.System;
-import java.util.concurrent.ConcurrentHashMap;
-
-// This class manages the database for storing the session data.
-//
-class BordeauxSessionStorage {
-
- private static final String TAG = "BordeauxSessionStorage";
- // unique key for the session
- public static final String COLUMN_KEY = "key";
- // name of the learning class
- public static final String COLUMN_CLASS = "class";
- // data of the learning model
- public static final String COLUMN_MODEL = "model";
- // last update time
- public static final String COLUMN_TIME = "time";
-
- private static final String DATABASE_NAME = "bordeaux";
- private static final String SESSION_TABLE = "sessions";
- private static final int DATABASE_VERSION = 1;
- private static final String DATABASE_CREATE =
- "create table " + SESSION_TABLE + "( " + COLUMN_KEY +
- " TEXT primary key, " + COLUMN_CLASS + " TEXT, " +
- COLUMN_MODEL + " BLOB, " + COLUMN_TIME + " INTEGER);";
-
- private SessionDBHelper mDbHelper;
- private SQLiteDatabase mDbSessions;
-
- BordeauxSessionStorage(final Context context) {
- try {
- mDbHelper = new SessionDBHelper(context);
- mDbSessions = mDbHelper.getWritableDatabase();
- } catch (SQLException e) {
- throw new RuntimeException("Can't open session database");
- }
- }
-
- private class SessionDBHelper extends SQLiteOpenHelper {
- SessionDBHelper(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- db.execSQL(DATABASE_CREATE);
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
- + newVersion + ", which will destroy all old data");
-
- db.execSQL("DROP TABLE IF EXISTS " + SESSION_TABLE);
- onCreate(db);
- }
- }
-
- private ContentValues createSessionEntry(String key, Class learner, byte[] model) {
- ContentValues entry = new ContentValues();
- entry.put(COLUMN_KEY, key);
- entry.put(COLUMN_TIME, System.currentTimeMillis());
- entry.put(COLUMN_MODEL, model);
- entry.put(COLUMN_CLASS, learner.getName());
- return entry;
- }
-
- boolean saveSession(String key, Class learner, byte[] model) {
- ContentValues content = createSessionEntry(key, learner, model);
- long rowID =
- mDbSessions.insertWithOnConflict(SESSION_TABLE, null, content,
- SQLiteDatabase.CONFLICT_REPLACE);
- return rowID >= 0;
- }
-
- private BordeauxSessionManager.Session getSessionFromCursor(Cursor cursor) {
- BordeauxSessionManager.Session session = new BordeauxSessionManager.Session();
- String className = cursor.getString(cursor.getColumnIndex(COLUMN_CLASS));
- try {
- session.learnerClass = Class.forName(className);
- session.learner = (IBordeauxLearner) session.learnerClass.getConstructor().newInstance();
- } catch (Exception e) {
- throw new RuntimeException("Can't instantiate class: " + className);
- }
- byte[] model = cursor.getBlob(cursor.getColumnIndex(COLUMN_MODEL));
- session.learner.setModel(model);
- return session;
- }
-
- BordeauxSessionManager.Session getSession(String key) {
- Cursor cursor = mDbSessions.query(true, SESSION_TABLE,
- new String[]{COLUMN_KEY, COLUMN_CLASS, COLUMN_MODEL, COLUMN_TIME},
- COLUMN_KEY + "=\"" + key + "\"", null, null, null, null, null);
- if ((cursor == null) | (cursor.getCount() == 0)) {
- cursor.close();
- return null;
- }
- if (cursor.getCount() > 1) {
- cursor.close();
- throw new RuntimeException("Unexpected duplication in session table for key:" + key);
- }
- cursor.moveToFirst();
- BordeauxSessionManager.Session s = getSessionFromCursor(cursor);
- cursor.close();
- return s;
- }
-
- void getAllSessions(ConcurrentHashMap<String, BordeauxSessionManager.Session> sessions) {
- Cursor cursor = mDbSessions.rawQuery("select * from ?;", new String[]{SESSION_TABLE});
- if (cursor == null) return;
- cursor.moveToFirst();
- do {
- String key = cursor.getString(cursor.getColumnIndex(COLUMN_KEY));
- BordeauxSessionManager.Session session = getSessionFromCursor(cursor);
- sessions.put(key, session);
- } while (cursor.moveToNext());
- }
-
- // remove all sessions that have the key that matches the given sql regular
- // expression.
- int removeSessions(String reKey) {
- int nDeleteRows = mDbSessions.delete(SESSION_TABLE, "? like \"?\"",
- new String[]{COLUMN_KEY, reKey});
- Log.i(TAG, "Number of rows in session table deleted: " + nDeleteRows);
- return nDeleteRows;
- }
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/ClusterManager.java b/bordeaux/service/src/android/bordeaux/services/ClusterManager.java
deleted file mode 100644
index 71e77a34e..000000000
--- a/bordeaux/service/src/android/bordeaux/services/ClusterManager.java
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-
-import android.content.Context;
-import android.location.Location;
-import android.text.format.Time;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-
-/**
- * ClusterManager incrementally indentify representitve clusters from the input location
- * stream. Clusters are updated online using leader based clustering algorithm. The input
- * locations initially are kept by the clusters. Periodially, a cluster consolidating
- * procedure is carried out to refine the cluster centers. After consolidation, the
- * location data are released.
- */
-public class ClusterManager {
-
- private static String TAG = "ClusterManager";
-
- private static float LOCATION_CLUSTER_RADIUS = 25; // meter
-
- private static float SEMANTIC_CLUSTER_RADIUS = 75; // meter
-
- // Consoliate location clusters (and check for new semantic clusters)
- // every 10 minutes (600 seconds).
- private static final long CONSOLIDATE_INTERVAL = 600;
-
- // A location cluster can be labeled as a semantic cluster if it has been
- // stayed for at least 10 minutes (600 seconds) within a day.
- private static final long SEMANTIC_CLUSTER_THRESHOLD = 600; // seconds
-
- // Reset location cluters every 24 hours (86400 seconds).
- private static final long LOCATION_REFRESH_PERIOD = 86400; // seconds
-
- private static String UNKNOWN_LOCATION = "Unknown Location";
-
- private Location mLastLocation = null;
-
- private long mClusterDuration;
-
- private long mConsolidateRef = 0;
-
- private long mRefreshRef = 0;
-
- private long mSemanticClusterCount = 0;
-
- private ArrayList<LocationCluster> mLocationClusters = new ArrayList<LocationCluster>();
-
- private ArrayList<BaseCluster> mSemanticClusters = new ArrayList<BaseCluster>();
-
- private AggregatorRecordStorage mStorage;
-
- private static String SEMANTIC_TABLE = "SemanticTable";
-
- private static String SEMANTIC_ID = "ID";
-
- private static final String SEMANTIC_LONGITUDE = "Longitude";
-
- private static final String SEMANTIC_LATITUDE = "Latitude";
-
- private static final String SEMANTIC_DURATION = "Duration";
-
- private static final String[] SEMANTIC_COLUMNS =
- new String[]{ SEMANTIC_ID,
- SEMANTIC_LONGITUDE,
- SEMANTIC_LATITUDE,
- SEMANTIC_DURATION,
- TimeStatsAggregator.WEEKEND,
- TimeStatsAggregator.WEEKDAY,
- TimeStatsAggregator.MORNING,
- TimeStatsAggregator.NOON,
- TimeStatsAggregator.AFTERNOON,
- TimeStatsAggregator.EVENING,
- TimeStatsAggregator.NIGHT,
- TimeStatsAggregator.LATENIGHT };
-
- private static final int mFeatureValueStart = 4;
- private static final int mFeatureValueEnd = 11;
-
- public ClusterManager(Context context) {
- mStorage = new AggregatorRecordStorage(context, SEMANTIC_TABLE, SEMANTIC_COLUMNS);
-
- loadSemanticClusters();
- }
-
- public void addSample(Location location) {
- float bestClusterDistance = Float.MAX_VALUE;
- int bestClusterIndex = -1;
- long lastDuration;
- long currentTime = location.getTime() / 1000; // measure time in seconds
-
- if (mLastLocation != null) {
- if (location.getTime() == mLastLocation.getTime()) {
- return;
- }
- // get the duration spent in the last location
- long duration = (location.getTime() - mLastLocation.getTime()) / 1000;
- mClusterDuration += duration;
-
- Log.v(TAG, "sample duration: " + duration +
- ", number of clusters: " + mLocationClusters.size());
-
- synchronized (mLocationClusters) {
- // add the last location to cluster.
- // first find the cluster it belongs to.
- for (int i = 0; i < mLocationClusters.size(); ++i) {
- float distance = mLocationClusters.get(i).distanceToCenter(mLastLocation);
- Log.v(TAG, "clulster " + i + " is within " + distance + " meters");
- if (distance < bestClusterDistance) {
- bestClusterDistance = distance;
- bestClusterIndex = i;
- }
- }
-
- // add the location to the selected cluster
- if (bestClusterDistance < LOCATION_CLUSTER_RADIUS) {
- mLocationClusters.get(bestClusterIndex).addSample(mLastLocation, duration);
- } else {
- // if it is far away from all existing clusters, create a new cluster.
- LocationCluster cluster = new LocationCluster(mLastLocation, duration);
- mLocationClusters.add(cluster);
- }
- }
- } else {
- mConsolidateRef = currentTime;
- mRefreshRef = currentTime;
-
- if (mLocationClusters.isEmpty()) {
- mClusterDuration = 0;
- }
- }
-
- long collectDuration = currentTime - mConsolidateRef;
- Log.v(TAG, "collect duration: " + collectDuration);
- if (collectDuration > CONSOLIDATE_INTERVAL) {
- // TODO : conslidation takes time. move this to a separate thread later.
- consolidateClusters();
- mConsolidateRef = currentTime;
-
- long refreshDuration = currentTime - mRefreshRef;
- Log.v(TAG, "refresh duration: " + refreshDuration);
- if (refreshDuration > LOCATION_REFRESH_PERIOD) {
- updateSemanticClusters();
- mRefreshRef = currentTime;
- }
- saveSemanticClusters();
- }
-
- mLastLocation = location;
- }
-
- private void consolidateClusters() {
- synchronized (mSemanticClusters) {
- LocationCluster locationCluster;
- for (int i = mLocationClusters.size() - 1; i >= 0; --i) {
- locationCluster = mLocationClusters.get(i);
- locationCluster.consolidate();
- }
-
- // merge clusters whose regions are overlapped. note that after merge
- // cluster center changes but cluster size remains unchanged.
- for (int i = mLocationClusters.size() - 1; i >= 0; --i) {
- locationCluster = mLocationClusters.get(i);
- for (int j = i - 1; j >= 0; --j) {
- float distance =
- mLocationClusters.get(j).distanceToCluster(locationCluster);
- if (distance < LOCATION_CLUSTER_RADIUS) {
- mLocationClusters.get(j).absorbCluster(locationCluster);
- mLocationClusters.remove(locationCluster);
- }
- }
- }
- Log.v(TAG, mLocationClusters.size() + " location clusters after consolidate");
-
- // assign each candidate to a semantic cluster and check if new semantic
- // clusters are found
- for (LocationCluster candidate : mLocationClusters) {
- if (candidate.hasSemanticId() ||
- candidate.hasSemanticClusterId() ||
- !candidate.passThreshold(SEMANTIC_CLUSTER_THRESHOLD)) {
- continue;
- }
-
- // find the closest semantic cluster
- float bestClusterDistance = Float.MAX_VALUE;
- String bestClusterId = "Unused Id";
- for (BaseCluster cluster : mSemanticClusters) {
- float distance = cluster.distanceToCluster(candidate);
- Log.v(TAG, distance + "distance to semantic cluster: " +
- cluster.getSemanticId());
-
- if (distance < bestClusterDistance) {
- bestClusterDistance = distance;
- bestClusterId = cluster.getSemanticId();
- }
- }
-
- // if candidate doesn't belong to any semantic cluster, create a new
- // semantic cluster
- if (bestClusterDistance > SEMANTIC_CLUSTER_RADIUS) {
- candidate.generateSemanticId(mSemanticClusterCount++);
- mSemanticClusters.add(candidate);
- } else {
- candidate.setSemanticClusterId(bestClusterId);
- }
- }
- Log.v(TAG, mSemanticClusters.size() + " semantic clusters after consolidate");
- }
- }
-
- private void updateSemanticClusters() {
- synchronized (mSemanticClusters) {
- // create index to cluster map
- HashMap<String, BaseCluster> semanticIdMap =
- new HashMap<String, BaseCluster>();
- for (BaseCluster cluster : mSemanticClusters) {
- // TODO: apply forgetting factor on existing semantic cluster stats,
- // duration, histogram, etc.
- cluster.forgetPastHistory();
- semanticIdMap.put(cluster.getSemanticId(), cluster);
- }
-
- // assign each candidate to a semantic cluster
- for (LocationCluster cluster : mLocationClusters) {
- if (cluster.hasSemanticClusterId()) {
- BaseCluster semanticCluster =
- semanticIdMap.get(cluster.getSemanticClusterId());
- semanticCluster.absorbCluster(cluster);
- }
- }
- // reset location clusters.
- mLocationClusters.clear();
- }
- }
-
- private void loadSemanticClusters() {
- List<Map<String, String> > allData = mStorage.getAllData();
- HashMap<String, Long> histogram = new HashMap<String, Long>();
-
- synchronized (mSemanticClusters) {
- mSemanticClusters.clear();
- for (Map<String, String> map : allData) {
- String semanticId = map.get(SEMANTIC_ID);
- double longitude = Double.parseDouble(map.get(SEMANTIC_LONGITUDE));
- double latitude = Double.parseDouble(map.get(SEMANTIC_LATITUDE));
- long duration = Long.parseLong(map.get(SEMANTIC_DURATION));
- BaseCluster cluster =
- new BaseCluster(semanticId, longitude, latitude, duration);
-
- histogram.clear();
- for (int i = mFeatureValueStart; i <= mFeatureValueEnd; i++) {
- String featureValue = SEMANTIC_COLUMNS[i];
- if (map.containsKey(featureValue)) {
- histogram.put(featureValue, Long.valueOf(map.get(featureValue)));
- }
- }
- cluster.setHistogram(histogram);
- mSemanticClusters.add(cluster);
- }
- mSemanticClusterCount = mSemanticClusters.size();
- Log.e(TAG, "load " + mSemanticClusterCount + " semantic clusters.");
- }
- }
-
- private void saveSemanticClusters() {
- HashMap<String, String> rowFeatures = new HashMap<String, String>();
-
- mStorage.removeAllData();
- synchronized (mSemanticClusters) {
- for (BaseCluster cluster : mSemanticClusters) {
- rowFeatures.clear();
- rowFeatures.put(SEMANTIC_ID, cluster.getSemanticId());
-
- rowFeatures.put(SEMANTIC_LONGITUDE,
- String.valueOf(cluster.getCenterLongitude()));
- rowFeatures.put(SEMANTIC_LATITUDE,
- String.valueOf(cluster.getCenterLatitude()));
- rowFeatures.put(SEMANTIC_DURATION,
- String.valueOf(cluster.getDuration()));
-
- HashMap<String, Long> histogram = cluster.getHistogram();
- for (Map.Entry<String, Long> entry : histogram.entrySet()) {
- rowFeatures.put(entry.getKey(), String.valueOf(entry.getValue()));
- }
- mStorage.addData(rowFeatures);
- Log.e(TAG, "saving semantic cluster: " + rowFeatures);
- }
- }
- }
-
- public String getSemanticLocation() {
- String label = LocationStatsAggregator.UNKNOWN_LOCATION;
-
- // instead of using the last location, try acquiring the latest location.
- if (mLastLocation != null) {
- // TODO: use fast neatest neighbor search speed up location search
- synchronized (mSemanticClusters) {
- for (BaseCluster cluster: mSemanticClusters) {
- if (cluster.distanceToCenter(mLastLocation) < SEMANTIC_CLUSTER_RADIUS) {
- return cluster.getSemanticId();
- }
- }
- }
- }
- return label;
- }
-
- public List<String> getClusterNames() {
- ArrayList<String> clusters = new ArrayList<String>();
- synchronized (mSemanticClusters) {
- for (BaseCluster cluster: mSemanticClusters) {
- clusters.add(cluster.getSemanticId());
- }
- }
- return clusters;
- }
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/FeatureAssembly.java b/bordeaux/service/src/android/bordeaux/services/FeatureAssembly.java
deleted file mode 100644
index 75a4a9f28..000000000
--- a/bordeaux/service/src/android/bordeaux/services/FeatureAssembly.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-
-import android.os.IBinder;
-import android.util.Log;
-import android.util.Pair;
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.List;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Iterator;
-
-class FeatureAssembly {
- private static final String TAG = "FeatureAssembly";
- private List<String> mPossibleFeatures;
- private HashSet<String> mUseFeatures;
- private HashSet<Pair<String, String> > mUsePairedFeatures;
- private AggregatorManager mAggregatorManager;
-
- public FeatureAssembly() {
- mAggregatorManager = AggregatorManager.getInstance();
- mPossibleFeatures = Arrays.asList(mAggregatorManager.getListOfFeatures());
- mUseFeatures = new HashSet<String>();
- mUsePairedFeatures = new HashSet<Pair<String, String> >();
- }
-
- public boolean registerFeature(String s) {
- if (mPossibleFeatures.contains(s)) {
- mUseFeatures.add(s);
- return true;
- } else {
- return false;
- }
- }
-
- public boolean registerFeaturePair(String[] features) {
- if (features.length != 2 ||
- !mPossibleFeatures.contains(features[0]) ||
- !mPossibleFeatures.contains(features[1])) {
- return false;
- } else {
- mUseFeatures.add(features[0]);
- mUseFeatures.add(features[1]);
- mUsePairedFeatures.add(Pair.create(features[0], features[1]));
- return true;
- }
- }
-
- public Set<String> getUsedFeatures() {
- return (Set) mUseFeatures;
- }
-
- public Map<String, String> getFeatureMap() {
- HashMap<String, String> featureMap = new HashMap<String, String>();
-
- Iterator itr = mUseFeatures.iterator();
- while(itr.hasNext()) {
- String f = (String) itr.next();
- Map<String, String> features = mAggregatorManager.getDataMap(f);
-
- // TODO: sanity check for now.
- if (features.size() > 1) {
- throw new RuntimeException("Incorrect feature format extracted from aggregator.");
- }
- featureMap.putAll(features);
- }
-
- if (!mUsePairedFeatures.isEmpty()) {
- itr = mUsePairedFeatures.iterator();
- while(itr.hasNext()) {
- Pair<String, String> pair = (Pair<String, String>) itr.next();
- if (featureMap.containsKey(pair.first) &&
- featureMap.containsKey(pair.second)) {
- String key = pair.first + Predictor.FEATURE_SEPARATOR + pair.second;
- String value = featureMap.get(pair.first) + Predictor.FEATURE_SEPARATOR +
- featureMap.get(pair.second);
- featureMap.put(key, value);
- }
- }
- }
- return (Map)featureMap;
- }
-
-
- public String augmentFeatureInputString(String s) {
- String fs = s;
- Iterator itr = mUseFeatures.iterator();
- while(itr.hasNext()) {
- String f = (String) itr.next();
- fs = fs + "+" + mAggregatorManager.getDataMap(f).get(f);
- }
- return fs;
- }
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/IAggregatorManager.aidl b/bordeaux/service/src/android/bordeaux/services/IAggregatorManager.aidl
deleted file mode 100644
index 06afb401f..000000000
--- a/bordeaux/service/src/android/bordeaux/services/IAggregatorManager.aidl
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2007 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.
- */
-
-package android.bordeaux.services;
-
-import android.bordeaux.services.StringString;
-
-interface IAggregatorManager {
- List<StringString> getData(in String dataName);
-
- // TODO: remove the following interfaces in production
- // they are only used for demo purpose
- List<String> getLocationClusters();
- List<String> getTimeOfDayValues();
- List<String> getDayOfWeekValues();
- // use "" to disable the fake location
- boolean setFakeLocation(in String cluster);
- // use "" to disable the fake time
- boolean setFakeTimeOfDay(in String time_of_day);
- // use "" to disable the fake day
- boolean setFakeDayOfWeek(in String day_of_week);
- // return whether the service is in fake mode
- // it's in fake mode, if any of the location, time and day is fake
- boolean getFakeMode();
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/IBordeauxLearner.java b/bordeaux/service/src/android/bordeaux/services/IBordeauxLearner.java
deleted file mode 100644
index 114d29410..000000000
--- a/bordeaux/service/src/android/bordeaux/services/IBordeauxLearner.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-
-import android.os.IBinder;
-
-interface IBordeauxLearner {
-
- interface ModelChangeCallback {
-
- public void modelChanged(IBordeauxLearner learner);
-
- }
-
- public byte [] getModel();
-
- public boolean setModel(final byte [] modelData);
-
- public IBinder getBinder();
-
- // call back for the learner model change
- public void setModelChangeCallback(ModelChangeCallback callback);
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/IBordeauxService.aidl b/bordeaux/service/src/android/bordeaux/services/IBordeauxService.aidl
deleted file mode 100644
index 4aa4f08de..000000000
--- a/bordeaux/service/src/android/bordeaux/services/IBordeauxService.aidl
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-
-import android.bordeaux.services.IBordeauxServiceCallback;
-
-/**
- * Main learning interface of bordeaux service
- * (running in another process).
- */
-interface IBordeauxService {
- /* Request a Ranker
- */
- IBinder getRanker(String name);
-
- /* Request a MulticlassPA
- */
- IBinder getClassifier(String name);
-
- /* Request to access AggregatorManager
- */
- IBinder getAggregatorManager();
- /* Request a Predictor
- */
- IBinder getPredictor(String name);
- /**
- * Often you want to allow a service to call back to its clients.
- * This shows how to do so, by registering a callback interface with
- * the service.
- */
- void registerCallback(IBordeauxServiceCallback cb);
-
- /**
- * Remove a previously registered callback interface.
- */
- void unregisterCallback(IBordeauxServiceCallback cb);
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/IBordeauxServiceCallback.aidl b/bordeaux/service/src/android/bordeaux/services/IBordeauxServiceCallback.aidl
deleted file mode 100644
index ad87ceeda..000000000
--- a/bordeaux/service/src/android/bordeaux/services/IBordeauxServiceCallback.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2007 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.
- */
-
-package android.bordeaux.services;
-
-/**
- * Example of a callback interface used by IRemoteService to send
- * synchronous notifications back to its clients. Note that this is a
- * one-way interface so the server does not block waiting for the client.
- */
-oneway interface IBordeauxServiceCallback {
- /**
- * Called when the service has a new value for you.
- */
- void valueChanged(int value);
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/ILearning_MulticlassPA.aidl b/bordeaux/service/src/android/bordeaux/services/ILearning_MulticlassPA.aidl
deleted file mode 100644
index a62eb788b..000000000
--- a/bordeaux/service/src/android/bordeaux/services/ILearning_MulticlassPA.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2007 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.
- */
-
-package android.bordeaux.services;
-
-/**
- * Example of a secondary interface associated with a service. (Note that
- * the interface itself doesn't impact, it is just a matter of how you
- * retrieve it from the service.)
- */
-import android.bordeaux.services.IntFloat;
-
-interface ILearning_MulticlassPA {
- void TrainOneSample(in List<IntFloat> sample, int target);
- int Classify(in List<IntFloat> sample);
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/ILearning_StochasticLinearRanker.aidl b/bordeaux/service/src/android/bordeaux/services/ILearning_StochasticLinearRanker.aidl
deleted file mode 100644
index f89ce0aef..000000000
--- a/bordeaux/service/src/android/bordeaux/services/ILearning_StochasticLinearRanker.aidl
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2007 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.
- */
-
-package android.bordeaux.services;
-
-/**
- * Example of a secondary interface associated with a service. (Note that
- * the interface itself doesn't impact, it is just a matter of how you
- * retrieve it from the service.)
- */
-import android.bordeaux.services.StringFloat;
-
-
-interface ILearning_StochasticLinearRanker {
-
- boolean UpdateClassifier(in List<StringFloat> sample_1, in List<StringFloat> sample_2);
- float ScoreSample(in List<StringFloat> sample);
- void ResetRanker();
- boolean SetModelPriorWeight(in List<StringFloat> weight);
- boolean SetModelParameter(in String key, in String value);
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/IPredictor.aidl b/bordeaux/service/src/android/bordeaux/services/IPredictor.aidl
deleted file mode 100644
index 0986cd0a7..000000000
--- a/bordeaux/service/src/android/bordeaux/services/IPredictor.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2007 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.
- */
-
-package android.bordeaux.services;
-
-import android.bordeaux.services.StringFloat;
-
-interface IPredictor {
- boolean setPredictorParameter(in String key, in String value);
- void pushNewSample(in String sampleName);
- void resetPredictor();
- List<StringFloat> getTopCandidates(in int topK);
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/IntFloat.aidl b/bordeaux/service/src/android/bordeaux/services/IntFloat.aidl
deleted file mode 100644
index 3b561aecb..000000000
--- a/bordeaux/service/src/android/bordeaux/services/IntFloat.aidl
+++ /dev/null
@@ -1,3 +0,0 @@
-package android.bordeaux.services;
-
-parcelable IntFloat;
diff --git a/bordeaux/service/src/android/bordeaux/services/IntFloat.java b/bordeaux/service/src/android/bordeaux/services/IntFloat.java
deleted file mode 100644
index b9803264c..000000000
--- a/bordeaux/service/src/android/bordeaux/services/IntFloat.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package android.bordeaux.services;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public final class IntFloat implements Parcelable {
- public int index;
- public float value;
-
- public static final Parcelable.Creator<IntFloat> CREATOR = new Parcelable.Creator<IntFloat>() {
- public IntFloat createFromParcel(Parcel in) {
- return new IntFloat(in);
- }
-
- public IntFloat[] newArray(int size) {
- return new IntFloat[size];
- }
- };
-
- public IntFloat() {
- }
-
- private IntFloat(Parcel in) {
- readFromParcel(in);
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(index);
- out.writeFloat(value);
- }
-
- public void readFromParcel(Parcel in) {
- index = in.readInt();
- value = in.readFloat();
- }
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/Learning_MulticlassPA.java b/bordeaux/service/src/android/bordeaux/services/Learning_MulticlassPA.java
deleted file mode 100644
index 438398d0f..000000000
--- a/bordeaux/service/src/android/bordeaux/services/Learning_MulticlassPA.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-
-import android.bordeaux.learning.MulticlassPA;
-import android.os.IBinder;
-
-import java.util.List;
-import java.util.ArrayList;
-
-public class Learning_MulticlassPA extends ILearning_MulticlassPA.Stub
- implements IBordeauxLearner {
- private MulticlassPA mMulticlassPA_learner;
- private ModelChangeCallback modelChangeCallback = null;
-
- class IntFloatArray {
- int[] indexArray;
- float[] floatArray;
- };
-
- private IntFloatArray splitIntFloatArray(List<IntFloat> sample) {
- IntFloatArray splited = new IntFloatArray();
- ArrayList<IntFloat> s = (ArrayList<IntFloat>)sample;
- splited.indexArray = new int[s.size()];
- splited.floatArray = new float[s.size()];
- for (int i = 0; i < s.size(); i++) {
- splited.indexArray[i] = s.get(i).index;
- splited.floatArray[i] = s.get(i).value;
- }
- return splited;
- }
-
- public Learning_MulticlassPA() {
- mMulticlassPA_learner = new MulticlassPA(2, 2, 0.001f);
- }
-
- // Beginning of the IBordeauxLearner Interface implementation
- public byte [] getModel() {
- return null;
- }
-
- public boolean setModel(final byte [] modelData) {
- return false;
- }
-
- public IBinder getBinder() {
- return this;
- }
-
- public void setModelChangeCallback(ModelChangeCallback callback) {
- modelChangeCallback = callback;
- }
- // End of IBordeauxLearner Interface implemenation
-
- // This implementation, combines training and prediction in one step.
- // The return value is the prediction value for the supplied sample. It
- // also update the model with the current sample.
- public void TrainOneSample(List<IntFloat> sample, int target) {
- IntFloatArray splited = splitIntFloatArray(sample);
- mMulticlassPA_learner.sparseTrainOneExample(splited.indexArray,
- splited.floatArray,
- target);
- if (modelChangeCallback != null) {
- modelChangeCallback.modelChanged(this);
- }
- }
-
- public int Classify(List<IntFloat> sample) {
- IntFloatArray splited = splitIntFloatArray(sample);
- int prediction = mMulticlassPA_learner.sparseGetClass(splited.indexArray,
- splited.floatArray);
- return prediction;
- }
-
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/Learning_StochasticLinearRanker.java b/bordeaux/service/src/android/bordeaux/services/Learning_StochasticLinearRanker.java
deleted file mode 100644
index c648bd2d1..000000000
--- a/bordeaux/service/src/android/bordeaux/services/Learning_StochasticLinearRanker.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-
-import android.bordeaux.learning.StochasticLinearRanker;
-import android.bordeaux.services.IBordeauxLearner.ModelChangeCallback;
-import android.os.IBinder;
-import android.util.Log;
-import java.util.List;
-import java.util.ArrayList;
-import java.io.*;
-import java.lang.ClassNotFoundException;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Scanner;
-import java.io.ByteArrayOutputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-public class Learning_StochasticLinearRanker extends ILearning_StochasticLinearRanker.Stub
- implements IBordeauxLearner {
-
- private final String TAG = "ILearning_StochasticLinearRanker";
- private StochasticLinearRankerWithPrior mLearningSlRanker = null;
- private ModelChangeCallback modelChangeCallback = null;
-
- public Learning_StochasticLinearRanker(){
- }
-
- public void ResetRanker(){
- if (mLearningSlRanker == null)
- mLearningSlRanker = new StochasticLinearRankerWithPrior();
- mLearningSlRanker.resetRanker();
- }
-
- public boolean UpdateClassifier(List<StringFloat> sample_1, List<StringFloat> sample_2){
- ArrayList<StringFloat> temp_1 = (ArrayList<StringFloat>)sample_1;
- String[] keys_1 = new String[temp_1.size()];
- float[] values_1 = new float[temp_1.size()];
- for (int i = 0; i < temp_1.size(); i++){
- keys_1[i] = temp_1.get(i).key;
- values_1[i] = temp_1.get(i).value;
- }
- ArrayList<StringFloat> temp_2 = (ArrayList<StringFloat>)sample_2;
- String[] keys_2 = new String[temp_2.size()];
- float[] values_2 = new float[temp_2.size()];
- for (int i = 0; i < temp_2.size(); i++){
- keys_2[i] = temp_2.get(i).key;
- values_2[i] = temp_2.get(i).value;
- }
- if (mLearningSlRanker == null)
- mLearningSlRanker = new StochasticLinearRankerWithPrior();
- boolean res = mLearningSlRanker.updateClassifier(keys_1,values_1,keys_2,values_2);
- if (res && modelChangeCallback != null) {
- modelChangeCallback.modelChanged(this);
- }
- return res;
- }
-
- public float ScoreSample(List<StringFloat> sample) {
- ArrayList<StringFloat> temp = (ArrayList<StringFloat>)sample;
- String[] keys = new String[temp.size()];
- float[] values = new float[temp.size()];
- for (int i = 0; i < temp.size(); i++){
- keys[i] = temp.get(i).key;
- values[i] = temp.get(i).value;
- }
- if (mLearningSlRanker == null)
- mLearningSlRanker = new StochasticLinearRankerWithPrior();
- return mLearningSlRanker.scoreSample(keys,values);
- }
-
- public boolean SetModelPriorWeight(List<StringFloat> sample) {
- ArrayList<StringFloat> temp = (ArrayList<StringFloat>)sample;
- HashMap<String, Float> weights = new HashMap<String, Float>();
- for (int i = 0; i < temp.size(); i++)
- weights.put(temp.get(i).key, temp.get(i).value);
- if (mLearningSlRanker == null)
- mLearningSlRanker = new StochasticLinearRankerWithPrior();
- return mLearningSlRanker.setModelPriorWeights(weights);
- }
-
- public boolean SetModelParameter(String key, String value) {
- if (mLearningSlRanker == null)
- mLearningSlRanker = new StochasticLinearRankerWithPrior();
- return mLearningSlRanker.setModelParameter(key,value);
- }
-
- // Beginning of the IBordeauxLearner Interface implementation
- public byte [] getModel() {
- if (mLearningSlRanker == null)
- mLearningSlRanker = new StochasticLinearRankerWithPrior();
- StochasticLinearRankerWithPrior.Model model = mLearningSlRanker.getModel();
- try {
- ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
- ObjectOutputStream objStream = new ObjectOutputStream(byteStream);
- objStream.writeObject(model);
- //return byteStream.toByteArray();
- byte[] bytes = byteStream.toByteArray();
- return bytes;
- } catch (IOException e) {
- throw new RuntimeException("Can't get model");
- }
- }
-
- public boolean setModel(final byte [] modelData) {
- try {
- ByteArrayInputStream input = new ByteArrayInputStream(modelData);
- ObjectInputStream objStream = new ObjectInputStream(input);
- StochasticLinearRankerWithPrior.Model model =
- (StochasticLinearRankerWithPrior.Model) objStream.readObject();
- if (mLearningSlRanker == null)
- mLearningSlRanker = new StochasticLinearRankerWithPrior();
- boolean res = mLearningSlRanker.loadModel(model);
- return res;
- } catch (IOException e) {
- throw new RuntimeException("Can't load model");
- } catch (ClassNotFoundException e) {
- throw new RuntimeException("Learning class not found");
- }
- }
-
- public IBinder getBinder() {
- return this;
- }
-
- public void setModelChangeCallback(ModelChangeCallback callback) {
- modelChangeCallback = callback;
- }
- // End of IBordeauxLearner Interface implemenation
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/LocationCluster.java b/bordeaux/service/src/android/bordeaux/services/LocationCluster.java
deleted file mode 100644
index c9f753f76..000000000
--- a/bordeaux/service/src/android/bordeaux/services/LocationCluster.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-package android.bordeaux.services;
-
-import android.location.Location;
-import android.text.format.Time;
-import android.util.Log;
-
-import java.lang.Math;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
-public class LocationCluster extends BaseCluster {
- public static String TAG = "LocationCluster";
-
- private ArrayList<Location> mLocations = new ArrayList<Location>();
- private HashMap<String, Long> mNewHistogram = new HashMap<String, Long>();
-
- private String mSemanticClusterId = null;
-
- public void setSemanticClusterId(String semanticClusterId) {
- mSemanticClusterId = semanticClusterId;
- }
-
- public String getSemanticClusterId() {
- return mSemanticClusterId;
- }
-
- public boolean hasSemanticClusterId() {
- return mSemanticClusterId != null;
- }
-
- // TODO: make it a singleton class
- public LocationCluster(Location location, long duration) {
- super(location);
- addSample(location, duration);
- }
-
- public void addSample(Location location, long duration) {
- updateTemporalHistogram(location.getTime(), duration);
-
- // use time field to store duation of this location
- // TODO: extend Location class with additional field for this.
- location.setTime(duration);
- mLocations.add(location);
- }
-
- public void consolidate() {
- // If there is no new location added during this period, do nothing.
- if (mLocations.size() == 0) {
- return;
- }
-
- double[] newCenter = {0f, 0f, 0f};
- long newDuration = 0l;
- // update cluster center
- for (Location location : mLocations) {
- double[] vector = getLocationVector(location);
- long duration = location.getTime(); // in seconds
-
- if (duration == 0) {
- throw new RuntimeException("location duration is zero");
- }
-
- newDuration += duration;
- for (int i = 0; i < VECTOR_LENGTH; ++i) {
- newCenter[i] += vector[i] * duration;
- }
- }
- if (newDuration == 0l) {
- throw new RuntimeException("new duration is zero!");
- }
- for (int i = 0; i < VECTOR_LENGTH; ++i) {
- newCenter[i] /= newDuration;
- }
- // remove location data
- mLocations.clear();
-
- // The updated center is the weighted average of the existing and the new
- // centers. Note that if the cluster is consolidated for the first time,
- // the weight for the existing cluster would be zero.
- averageCenter(newCenter, newDuration);
-
- // update histogram
- for (Map.Entry<String, Long> entry : mNewHistogram.entrySet()) {
- String timeLabel = entry.getKey();
- long duration = entry.getValue();
- if (mHistogram.containsKey(timeLabel)) {
- duration += mHistogram.get(timeLabel);
- }
- mHistogram.put(timeLabel, duration);
- }
- mDuration += newDuration;
- mNewHistogram.clear();
- }
-
- /*
- * if the new created cluster whose covered area overlaps with any existing
- * cluster move the center away from that cluster till there is no overlap.
- */
- public void moveAwayCluster(LocationCluster cluster, float distance) {
- double[] vector = new double[VECTOR_LENGTH];
-
- double dot = 0f;
- for (int i = 0; i < VECTOR_LENGTH; ++i) {
- dot += mCenter[i] * cluster.mCenter[i];
- }
- double norm = 0f;
- for (int i = 0; i < VECTOR_LENGTH; ++i) {
- vector[i] = mCenter[i] - dot * cluster.mCenter[i];
- norm += vector[i] * vector[i];
- }
- norm = Math.sqrt(norm);
-
- double radian = distance / EARTH_RADIUS;
- for (int i = 0; i < VECTOR_LENGTH; ++i) {
- mCenter[i] = cluster.mCenter[i] * Math.cos(radian) +
- (vector[i] / norm) * Math.sin(radian);
- }
- }
-
- private void updateTemporalHistogram(long time, long duration) {
- HashMap<String, String> timeFeatures = TimeStatsAggregator.getAllTimeFeatures(time);
-
- String timeOfWeek = timeFeatures.get(TimeStatsAggregator.TIME_OF_WEEK);
- long totalDuration = (mNewHistogram.containsKey(timeOfWeek)) ?
- mNewHistogram.get(timeOfWeek) + duration : duration;
- mNewHistogram.put(timeOfWeek, totalDuration);
-
- String timeOfDay = timeFeatures.get(TimeStatsAggregator.TIME_OF_DAY);
- totalDuration = (mNewHistogram.containsKey(timeOfDay)) ?
- mNewHistogram.get(timeOfDay) + duration : duration;
- mNewHistogram.put(timeOfDay, totalDuration);
- }
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/LocationStatsAggregator.java b/bordeaux/service/src/android/bordeaux/services/LocationStatsAggregator.java
deleted file mode 100644
index 6f792be77..000000000
--- a/bordeaux/service/src/android/bordeaux/services/LocationStatsAggregator.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.location.Criteria;
-import android.location.Location;
-import android.location.LocationListener;
-import android.location.LocationManager;
-import android.location.LocationProvider;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Message;
-import android.os.Process;
-import android.os.SystemClock;
-import android.text.format.Time;
-import android.util.Log;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-// TODO: add functionality to detect speed (use GPS) when needed
-// withouth draining the battery quickly
-public class LocationStatsAggregator extends Aggregator {
- final String TAG = "LocationStatsAggregator";
- public static final String CURRENT_LOCATION = "Current Location";
- public static final String CURRENT_SPEED = "Current Speed";
- public static final String UNKNOWN_LOCATION = "Unknown Location";
-
- private static final long REPEAT_INTERVAL = 120000;
-
- private static final long FRESH_THRESHOLD = 90000;
-
- private static final int LOCATION_CHANGE = 1;
-
- // record time when the location provider is set
- private long mProviderSetTime;
-
- private Handler mHandler;
- private HandlerThread mHandlerThread;
- private AlarmManager mAlarmManager;
- private LocationManager mLocationManager;
-
- private ClusterManager mClusterManager;
-
- private Criteria mCriteria = new Criteria();
-
- private LocationUpdater mLocationUpdater;
-
- private Context mContext;
- private PendingIntent mPendingIntent;
-
- // Fake location, used for testing.
- private String mFakeLocation = null;
-
- public LocationStatsAggregator(final Context context) {
- mLocationManager =
- (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
- mAlarmManager =
- (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
-
- setClusteringThread(context);
-
- mCriteria.setAccuracy(Criteria.ACCURACY_COARSE);
- mCriteria.setPowerRequirement(Criteria.POWER_LOW);
- /*
- mCriteria.setAltitudeRequired(false);
- mCriteria.setBearingRequired(false);
- mCriteria.setSpeedRequired(true);
- */
- mCriteria.setCostAllowed(true);
-
-
- IntentFilter filter = new IntentFilter(LocationUpdater.LOCATION_UPDATE);
- mLocationUpdater = new LocationUpdater();
- context.registerReceiver(mLocationUpdater, filter);
-
- Intent intent = new Intent(LocationUpdater.LOCATION_UPDATE);
-
- mContext = context;
- mPendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
-
- mAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- SystemClock.elapsedRealtime() + 30000, //
- REPEAT_INTERVAL,
- mPendingIntent);
- }
-
- public void release() {
- mContext.unregisterReceiver(mLocationUpdater);
- mAlarmManager.cancel(mPendingIntent);
- }
-
- public String[] getListOfFeatures(){
- String[] list = { CURRENT_LOCATION } ;
- return list;
- }
-
- public Map<String,String> getFeatureValue(String featureName) {
- HashMap<String,String> feature = new HashMap<String,String>();
-
- if (featureName.equals(CURRENT_LOCATION)) {
- // TODO: check last known location first before sending out location request.
- /*
- Location location =
- mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
- */
- String location = mClusterManager.getSemanticLocation();
- if (!location.equals(UNKNOWN_LOCATION)) {
- if (mFakeLocation != null) {
- feature.put(CURRENT_LOCATION, mFakeLocation);
- } else {
- feature.put(CURRENT_LOCATION, location);
- }
- }
- }
- return (Map) feature;
- }
-
- public List<String> getClusterNames() {
- return mClusterManager.getClusterNames();
- }
-
- // set a fake location using cluster name.
- // Set an empty string "" to disable the fake location
- public void setFakeLocation(String name) {
- if (name != null && name.length() != 0)
- mFakeLocation = name;
- else mFakeLocation = null;
- }
-
- private Location getLastKnownLocation() {
- List<String> providers = mLocationManager.getAllProviders();
- Location bestResult = null;
- float bestAccuracy = Float.MAX_VALUE;
- long bestTime;
-
- // get the latest location data
- long currTime = System.currentTimeMillis();
- for (String provider : providers) {
- Location location = mLocationManager.getLastKnownLocation(provider);
-
- if (location != null) {
- float accuracy = location.getAccuracy();
- long time = location.getTime();
-
- if (currTime - time < FRESH_THRESHOLD && accuracy < bestAccuracy) {
- bestResult = location;
- bestAccuracy = accuracy;
- bestTime = time;
- }
- }
- }
- if (bestResult != null) {
- Log.i(TAG, "found location for free: " + bestResult);
- }
- return bestResult;
- }
-
- private class LocationUpdater extends BroadcastReceiver {
- String TAG = "LocationUpdater";
-
- public static final String LOCATION_UPDATE = "android.bordeaux.services.LOCATION_UPDATE";
-
- @Override
- public void onReceive(Context context, Intent intent) {
- Location location = getLastKnownLocation();
-
- if (location == null) {
- String provider = mLocationManager.getBestProvider(mCriteria, true);
- Log.i(TAG, "Best Available Location Provider: " + provider);
- mLocationManager.requestSingleUpdate(provider, mLocationListener,
- mHandlerThread.getLooper());
- } else {
- mHandler.sendMessage(mHandler.obtainMessage(LOCATION_CHANGE, location));
- }
- }
- }
-
- private void setClusteringThread(Context context) {
- mClusterManager = new ClusterManager(context);
-
- mHandlerThread = new HandlerThread("Location Handler",
- Process.THREAD_PRIORITY_BACKGROUND);
- mHandlerThread.start();
- mHandler = new Handler(mHandlerThread.getLooper()) {
-
- @Override
- public void handleMessage(Message msg) {
- if (!(msg.obj instanceof Location)) {
- return;
- }
- Location location = (Location) msg.obj;
- switch(msg.what) {
- case LOCATION_CHANGE:
- mClusterManager.addSample(location);
- break;
- default:
- super.handleMessage(msg);
- }
- }
- };
- }
-
- private final LocationListener mLocationListener = new LocationListener() {
- private static final String TAG = "LocationListener";
-
- public void onLocationChanged(Location location) {
- mHandler.sendMessage(mHandler.obtainMessage(LOCATION_CHANGE, location));
- mLocationManager.removeUpdates(this);
- }
-
- public void onStatusChanged(String provider, int status, Bundle extras) { }
-
- public void onProviderEnabled(String provider) { }
-
- public void onProviderDisabled(String provider) { }
- };
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/MotionStatsAggregator.java b/bordeaux/service/src/android/bordeaux/services/MotionStatsAggregator.java
deleted file mode 100644
index c34779e5e..000000000
--- a/bordeaux/service/src/android/bordeaux/services/MotionStatsAggregator.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-
-import android.util.Log;
-import java.util.HashMap;
-import java.util.Map;
-
-public class MotionStatsAggregator extends Aggregator {
- final String TAG = "MotionStatsAggregator";
- public static final String CURRENT_MOTION = "Current Motion";
- public String[] getListOfFeatures(){
- String [] list = new String[1];
- list[0] = CURRENT_MOTION;
- return list;
- }
- public Map<String,String> getFeatureValue(String featureName) {
- HashMap<String,String> m = new HashMap<String,String>();
- if (featureName.equals(CURRENT_MOTION))
- m.put(CURRENT_MOTION,"Running"); //TODO maybe use clustering for user motion
- else
- Log.e(TAG, "There is no motion feature called " + featureName);
- return (Map) m;
- }
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/Predictor.java b/bordeaux/service/src/android/bordeaux/services/Predictor.java
deleted file mode 100644
index 9d9047a86..000000000
--- a/bordeaux/service/src/android/bordeaux/services/Predictor.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you my 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.
- */
-
-package android.bordeaux.services;
-
-import android.os.IBinder;
-import android.util.Log;
-import java.util.HashMap;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.io.Serializable;
-import java.io.*;
-import java.lang.Boolean;
-import android.bordeaux.services.FeatureAssembly;
-import android.bordeaux.learning.HistogramPredictor;
-
-/**
- * This is interface to implement Prediction based on histogram that
- * uses predictor_histogram from learnerning section
- */
-public class Predictor extends IPredictor.Stub
- implements IBordeauxLearner {
- private final String TAG = "Predictor";
- private ModelChangeCallback modelChangeCallback = null;
-
- private FeatureAssembly mFeatureAssembly = new FeatureAssembly();
-
- public static final String SET_FEATURE = "SetFeature";
- public static final String SET_PAIRED_FEATURES = "SetPairedFeatures";
- public static final String FEATURE_SEPARATOR = ":";
- public static final String USE_HISTORY = "UseHistory";
- public static final String PREVIOUS_SAMPLE = "PreviousSample";
-
- private boolean mUseHistory = false;
- private long mHistorySpan = 0;
- private String mPrevSample;
- private long mPrevSampleTime;
-
- // TODO: blacklist should be set outside Bordeaux service!
- private static final String[] APP_BLACKLIST = {
- "com.android.contacts",
- "com.android.chrome",
- "com.android.providers.downloads.ui",
- "com.android.settings",
- "com.android.vending",
- "com.android.mms",
- "com.google.android.gm",
- "com.google.android.gallery3d",
- "com.google.android.apps.googlevoice",
- };
-
- private HistogramPredictor mPredictor = new HistogramPredictor(APP_BLACKLIST);
-
-
- /**
- * Reset the Predictor
- */
- public void resetPredictor(){
- mPredictor.resetPredictor();
-
- if (modelChangeCallback != null) {
- modelChangeCallback.modelChanged(this);
- }
- }
-
- /**
- * Input is a sampleName e.g.action name. This input is then augmented with requested build-in
- * features such as time and location to create sampleFeatures. The sampleFeatures is then
- * pushed to the histogram
- */
- public void pushNewSample(String sampleName) {
- Map<String, String> sampleFeatures = getSampleFeatures();
- Log.i(TAG, "pushNewSample " + sampleName + ": " + sampleFeatures);
-
- // TODO: move to the end of the function?
- mPrevSample = sampleName;
- mPrevSampleTime = System.currentTimeMillis();
-
- mPredictor.addSample(sampleName, sampleFeatures);
- if (modelChangeCallback != null) {
- modelChangeCallback.modelChanged(this);
- }
- }
-
- private Map<String, String> getSampleFeatures() {
- Map<String, String> sampleFeatures = mFeatureAssembly.getFeatureMap();
- long currTime = System.currentTimeMillis();
-
- if (mUseHistory && mPrevSample != null &&
- ((currTime - mPrevSampleTime) < mHistorySpan)) {
- sampleFeatures.put(PREVIOUS_SAMPLE, mPrevSample);
- }
-
- return sampleFeatures;
- }
-
- // TODO: getTopK samples instead get scord for debugging only
- /**
- * return probabilty of an exmple using the histogram
- */
- public List<StringFloat> getTopCandidates(int topK) {
- Map<String, String> features = getSampleFeatures();
- List<Map.Entry<String, Double> > topApps = mPredictor.findTopClasses(features, topK);
-
- int listSize = topApps.size();
- ArrayList<StringFloat> result = new ArrayList<StringFloat>(listSize);
- for (int i = 0; i < listSize; ++i) {
- Map.Entry<String, Double> entry = topApps.get(i);
- result.add(new StringFloat(entry.getKey(), entry.getValue().floatValue()));
- }
- return result;
- }
-
- /**
- * Set parameters for 1) using History in probability estimations e.g. consider the last event
- * and 2) featureAssembly e.g. time and location.
- */
- public boolean setPredictorParameter(String key, String value) {
- Log.i(TAG, "setParameter : " + key + ", " + value);
- boolean result = true;
- if (key.equals(SET_FEATURE)) {
- result = mFeatureAssembly.registerFeature(value);
- if (!result) {
- Log.e(TAG,"Setting on feauture: " + value + " which is not available");
- }
- } else if (key.equals(SET_PAIRED_FEATURES)) {
- String[] features = value.split(FEATURE_SEPARATOR);
- result = mFeatureAssembly.registerFeaturePair(features);
- if (!result) {
- Log.e(TAG,"Setting feauture pair: " + value + " is not valid");
- }
- } else if (key.equals(USE_HISTORY)) {
- mUseHistory = true;
- mHistorySpan = Long.parseLong(value);
- } else {
- Log.e(TAG,"Setting parameter " + key + " with " + value + " is not valid");
- }
- return result;
- }
-
- // Beginning of the IBordeauxLearner Interface implementation
- public byte [] getModel() {
- return mPredictor.getModel();
- }
-
- public boolean setModel(final byte [] modelData) {
- return mPredictor.setModel(modelData);
- }
-
- public IBinder getBinder() {
- return this;
- }
-
- public void setModelChangeCallback(ModelChangeCallback callback) {
- modelChangeCallback = callback;
- }
- // End of IBordeauxLearner Interface implemenation
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/StochasticLinearRankerWithPrior.java b/bordeaux/service/src/android/bordeaux/services/StochasticLinearRankerWithPrior.java
deleted file mode 100644
index fd56a2fd6..000000000
--- a/bordeaux/service/src/android/bordeaux/services/StochasticLinearRankerWithPrior.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-import android.util.Log;
-
-import android.bordeaux.learning.StochasticLinearRanker;
-import java.util.HashMap;
-import java.util.Map;
-import java.io.Serializable;
-
-public class StochasticLinearRankerWithPrior extends StochasticLinearRanker {
- private final String TAG = "StochasticLinearRankerWithPrior";
- private final float EPSILON = 0.0001f;
-
- /* If the is parameter is true, the final score would be a
- linear combination of user model and prior model */
- private final String USE_PRIOR = "usePriorInformation";
-
- /* When prior model is used, this parmaeter will set the mixing factor, alpha. */
- private final String SET_ALPHA = "setAlpha";
-
- /* When prior model is used, If this parameter is true then algorithm will use
- the automatic cross validated alpha for mixing user model and prior model */
- private final String USE_AUTO_ALPHA = "useAutoAlpha";
-
- /* When automatic cross validation is active, this parameter will
- set the forget rate in cross validation. */
- private final String SET_FORGET_RATE = "setForgetRate";
-
- /* When automatic cross validation is active, this parameter will
- set the minium number of required training pairs before using the user model */
- private final String SET_MIN_TRAIN_PAIR = "setMinTrainingPair";
-
- private final String SET_USER_PERF = "setUserPerformance";
- private final String SET_PRIOR_PERF = "setPriorPerformance";
- private final String SET_NUM_TRAIN_PAIR = "setNumberTrainingPairs";
- private final String SET_AUTO_ALPHA = "setAutoAlpha";
-
-
-
- private HashMap<String, Float> mPriorWeights = new HashMap<String, Float>();
- private float mAlpha = 0;
- private float mAutoAlpha = 0;
- private float mForgetRate = 0;
- private float mUserRankerPerf = 0;
- private float mPriorRankerPerf = 0;
- private int mMinReqTrainingPair = 0;
- private int mNumTrainPair = 0;
- private boolean mUsePrior = false;
- private boolean mUseAutoAlpha = false;
-
- static public class Model implements Serializable {
- public StochasticLinearRanker.Model uModel = new StochasticLinearRanker.Model();
- public HashMap<String, Float> priorWeights = new HashMap<String, Float>();
- public HashMap<String, String> priorParameters = new HashMap<String, String>();
- }
-
- @Override
- public void resetRanker(){
- super.resetRanker();
- mPriorWeights.clear();
- mAlpha = 0;
- mAutoAlpha = 0;
- mForgetRate = 0;
- mMinReqTrainingPair = 0;
- mUserRankerPerf = 0;
- mPriorRankerPerf = 0;
- mNumTrainPair = 0;
- mUsePrior = false;
- mUseAutoAlpha = false;
- }
-
- @Override
- public float scoreSample(String[] keys, float[] values) {
- if (!mUsePrior){
- return super.scoreSample(keys, values);
- } else {
- if (mUseAutoAlpha) {
- if (mNumTrainPair > mMinReqTrainingPair)
- return (1 - mAutoAlpha) * super.scoreSample(keys,values) +
- mAutoAlpha * priorScoreSample(keys,values);
- else
- return priorScoreSample(keys,values);
- } else
- return (1 - mAlpha) * super.scoreSample(keys,values) +
- mAlpha * priorScoreSample(keys,values);
- }
- }
-
- public float priorScoreSample(String[] keys, float[] values) {
- float score = 0;
- for (int i=0; i< keys.length; i++){
- if (mPriorWeights.get(keys[i]) != null )
- score = score + mPriorWeights.get(keys[i]) * values[i];
- }
- return score;
- }
-
- @Override
- public boolean updateClassifier(String[] keys_positive,
- float[] values_positive,
- String[] keys_negative,
- float[] values_negative){
- if (mUsePrior && mUseAutoAlpha && (mNumTrainPair > mMinReqTrainingPair))
- updateAutoAlpha(keys_positive, values_positive, keys_negative, values_negative);
- mNumTrainPair ++;
- return super.updateClassifier(keys_positive, values_positive,
- keys_negative, values_negative);
- }
-
- void updateAutoAlpha(String[] keys_positive,
- float[] values_positive,
- String[] keys_negative,
- float[] values_negative) {
- float positiveUserScore = super.scoreSample(keys_positive, values_positive);
- float negativeUserScore = super.scoreSample(keys_negative, values_negative);
- float positivePriorScore = priorScoreSample(keys_positive, values_positive);
- float negativePriorScore = priorScoreSample(keys_negative, values_negative);
- float userDecision = 0;
- float priorDecision = 0;
- if (positiveUserScore > negativeUserScore)
- userDecision = 1;
- if (positivePriorScore > negativePriorScore)
- priorDecision = 1;
- mUserRankerPerf = (1 - mForgetRate) * mUserRankerPerf + userDecision;
- mPriorRankerPerf = (1 - mForgetRate) * mPriorRankerPerf + priorDecision;
- mAutoAlpha = (mPriorRankerPerf + EPSILON) / (mUserRankerPerf + mPriorRankerPerf + EPSILON);
- }
-
- public Model getModel(){
- Model m = new Model();
- m.uModel = super.getUModel();
- m.priorWeights.putAll(mPriorWeights);
- m.priorParameters.put(SET_ALPHA, String.valueOf(mAlpha));
- m.priorParameters.put(SET_AUTO_ALPHA, String.valueOf(mAutoAlpha));
- m.priorParameters.put(SET_FORGET_RATE, String.valueOf(mForgetRate));
- m.priorParameters.put(SET_MIN_TRAIN_PAIR, String.valueOf(mMinReqTrainingPair));
- m.priorParameters.put(SET_USER_PERF, String.valueOf(mUserRankerPerf));
- m.priorParameters.put(SET_PRIOR_PERF, String.valueOf(mPriorRankerPerf));
- m.priorParameters.put(SET_NUM_TRAIN_PAIR, String.valueOf(mNumTrainPair));
- m.priorParameters.put(USE_AUTO_ALPHA, String.valueOf(mUseAutoAlpha));
- m.priorParameters.put(USE_PRIOR, String.valueOf(mUsePrior));
- return m;
- }
-
- public boolean loadModel(Model m) {
- mPriorWeights.clear();
- mPriorWeights.putAll(m.priorWeights);
- for (Map.Entry<String, String> e : m.priorParameters.entrySet()) {
- boolean res = setModelParameter(e.getKey(), e.getValue());
- if (!res) return false;
- }
- return super.loadModel(m.uModel);
- }
-
- public boolean setModelPriorWeights(HashMap<String, Float> pw){
- mPriorWeights.clear();
- mPriorWeights.putAll(pw);
- return true;
- }
-
- public boolean setModelParameter(String key, String value){
- if (key.equals(USE_AUTO_ALPHA)){
- mUseAutoAlpha = Boolean.parseBoolean(value);
- } else if (key.equals(USE_PRIOR)){
- mUsePrior = Boolean.parseBoolean(value);
- } else if (key.equals(SET_ALPHA)){
- mAlpha = Float.valueOf(value.trim()).floatValue();
- }else if (key.equals(SET_AUTO_ALPHA)){
- mAutoAlpha = Float.valueOf(value.trim()).floatValue();
- }else if (key.equals(SET_FORGET_RATE)){
- mForgetRate = Float.valueOf(value.trim()).floatValue();
- }else if (key.equals(SET_MIN_TRAIN_PAIR)){
- mMinReqTrainingPair = (int) Float.valueOf(value.trim()).floatValue();
- }else if (key.equals(SET_USER_PERF)){
- mUserRankerPerf = Float.valueOf(value.trim()).floatValue();
- }else if (key.equals(SET_PRIOR_PERF)){
- mPriorRankerPerf = Float.valueOf(value.trim()).floatValue();
- }else if (key.equals(SET_NUM_TRAIN_PAIR)){
- mNumTrainPair = (int) Float.valueOf(value.trim()).floatValue();
- }else
- return super.setModelParameter(key, value);
- return true;
- }
-
- public void print(Model m){
- super.print(m.uModel);
- String Spw = "";
- for (Map.Entry<String, Float> e : m.priorWeights.entrySet())
- Spw = Spw + "<" + e.getKey() + "," + e.getValue() + "> ";
- Log.i(TAG, "Prior model is " + Spw);
- String Spp = "";
- for (Map.Entry<String, String> e : m.priorParameters.entrySet())
- Spp = Spp + "<" + e.getKey() + "," + e.getValue() + "> ";
- Log.i(TAG, "Prior parameters are " + Spp);
- }
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/StringFloat.aidl b/bordeaux/service/src/android/bordeaux/services/StringFloat.aidl
deleted file mode 100644
index f01f166eb..000000000
--- a/bordeaux/service/src/android/bordeaux/services/StringFloat.aidl
+++ /dev/null
@@ -1,3 +0,0 @@
-package android.bordeaux.services;
-
-parcelable StringFloat;
diff --git a/bordeaux/service/src/android/bordeaux/services/StringFloat.java b/bordeaux/service/src/android/bordeaux/services/StringFloat.java
deleted file mode 100644
index c95ccd29c..000000000
--- a/bordeaux/service/src/android/bordeaux/services/StringFloat.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package android.bordeaux.services;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public final class StringFloat implements Parcelable {
- public String key;
- public float value;
-
- public static final Parcelable.Creator<StringFloat>
- CREATOR = new Parcelable.Creator<StringFloat>() {
- public StringFloat createFromParcel(Parcel in) {
- return new StringFloat(in);
- }
-
- public StringFloat[] newArray(int size) {
- return new StringFloat[size];
- }
- };
-
- public StringFloat() {
- }
-
- public StringFloat(String newKey, float newValue) {
- key = newKey;
- value = newValue;
- }
-
- private StringFloat(Parcel in) {
- readFromParcel(in);
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel out, int flags) {
- out.writeString(key);
- out.writeFloat(value);
- }
-
- public void readFromParcel(Parcel in) {
- key = in.readString();
- value = in.readFloat();
- }
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/StringString.aidl b/bordeaux/service/src/android/bordeaux/services/StringString.aidl
deleted file mode 100644
index 3cb89b9cf..000000000
--- a/bordeaux/service/src/android/bordeaux/services/StringString.aidl
+++ /dev/null
@@ -1,3 +0,0 @@
-package android.bordeaux.services;
-
-parcelable StringString;
diff --git a/bordeaux/service/src/android/bordeaux/services/StringString.java b/bordeaux/service/src/android/bordeaux/services/StringString.java
deleted file mode 100644
index 109462e9f..000000000
--- a/bordeaux/service/src/android/bordeaux/services/StringString.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package android.bordeaux.services;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-public final class StringString implements Parcelable {
- public String key;
- public String value;
-
- public static final Parcelable.Creator<StringString>
- CREATOR = new Parcelable.Creator<StringString>() {
- public StringString createFromParcel(Parcel in) {
- return new StringString(in);
- }
-
- public StringString[] newArray(int size) {
- return new StringString[size];
- }
- };
-
- public StringString() {
- }
-
- private StringString(Parcel in) {
- readFromParcel(in);
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel out, int flags) {
- out.writeString(key);
- out.writeString(value);
- }
-
- public void readFromParcel(Parcel in) {
- key = in.readString();
- value = in.readString();
- }
-}
diff --git a/bordeaux/service/src/android/bordeaux/services/TimeStatsAggregator.java b/bordeaux/service/src/android/bordeaux/services/TimeStatsAggregator.java
deleted file mode 100644
index a3e123c74..000000000
--- a/bordeaux/service/src/android/bordeaux/services/TimeStatsAggregator.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-package android.bordeaux.services;
-
-import android.text.format.Time;
-import android.util.Log;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-// import java.util.Date;
-
-// TODO: use build in functions in
-// import android.text.format.Time;
-public class TimeStatsAggregator extends Aggregator {
- final String TAG = "TimeStatsAggregator";
-
- public static final String TIME_OF_WEEK = "Time of Week";
- public static final String DAY_OF_WEEK = "Day of Week";
- public static final String TIME_OF_DAY = "Time of Day";
- public static final String PERIOD_OF_DAY = "Period of Day";
-
- static final String WEEKEND = "Weekend";
- static final String WEEKDAY = "Weekday";
- static final String MONDAY = "Monday";
- static final String TUESDAY = "Tuesday";
- static final String WEDNESDAY = "Wednesday";
- static final String THURSDAY = "Thursday";
- static final String FRIDAY = "Friday";
- static final String SATURDAY = "Saturday";
- static final String SUNDAY = "Sunday";
- static final String MORNING = "Morning";
- static final String NOON = "Noon";
- static final String AFTERNOON = "AfterNoon";
- static final String EVENING = "Evening";
- static final String NIGHT = "Night";
- static final String LATENIGHT = "LateNight";
- static final String DAYTIME = "Daytime";
- static final String NIGHTTIME = "Nighttime";
-
- static String mFakeTimeOfDay = null;
- static String mFakeDayOfWeek = null;
-
- static final String[] TIME_OF_DAY_VALUES =
- {MORNING, NOON, AFTERNOON, EVENING, NIGHT, LATENIGHT};
-
- static final String[] DAY_OF_WEEK_VALUES =
- {SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY};
-
- static final String[] DAYTIME_VALUES = {MORNING, NOON, AFTERNOON, EVENING};
-
- public String[] getListOfFeatures(){
- String [] list = new String[4];
- list[0] = TIME_OF_WEEK;
- list[1] = DAY_OF_WEEK;
- list[2] = TIME_OF_DAY;
- list[3] = PERIOD_OF_DAY;
- return list;
- }
-
- public Map<String,String> getFeatureValue(String featureName) {
- HashMap<String,String> feature = new HashMap<String,String>();
-
- HashMap<String, String> features =
- getAllTimeFeatures(System.currentTimeMillis());
- if (features.containsKey(featureName)) {
- feature.put(featureName, features.get(featureName));
- } else {
- Log.e(TAG, "There is no Time feature called " + featureName);
- }
- return (Map)feature;
- }
-
- private static String getTimeOfDay(int hour) {
- if (hour >= 5 && hour < 11) {
- return MORNING;
- } else if (hour >= 11 && hour < 14) {
- return NOON;
- } else if (hour >= 14 && hour < 18) {
- return AFTERNOON;
- } else if (hour >= 18 && hour < 21) {
- return EVENING;
- } else if ((hour >= 21 && hour < 24) ||
- (hour >= 0 && hour < 1)) {
- return NIGHT;
- } else {
- return LATENIGHT;
- }
- }
-
- private static String getDayOfWeek(int day) {
- switch (day) {
- case Time.SATURDAY:
- return SATURDAY;
- case Time.SUNDAY:
- return SUNDAY;
- case Time.MONDAY:
- return MONDAY;
- case Time.TUESDAY:
- return TUESDAY;
- case Time.WEDNESDAY:
- return WEDNESDAY;
- case Time.THURSDAY:
- return THURSDAY;
- default:
- return FRIDAY;
- }
- }
-
- private static String getPeriodOfDay(int hour) {
- if (hour > 6 && hour < 19) {
- return DAYTIME;
- } else {
- return NIGHTTIME;
- }
- }
-
- static HashMap<String, String> getAllTimeFeatures(long utcTime) {
- HashMap<String, String> features = new HashMap<String, String>();
- Time time = new Time();
- time.set(utcTime);
-
- if (mFakeTimeOfDay != null && mFakeTimeOfDay.length() != 0) {
- List<String> day_list = Arrays.asList(DAYTIME_VALUES);
-
- if (day_list.contains(mFakeTimeOfDay)) {
- features.put(PERIOD_OF_DAY, DAYTIME);
- } else {
- features.put(PERIOD_OF_DAY, NIGHTTIME);
- }
- features.put(TIME_OF_DAY, mFakeTimeOfDay);
- } else {
- features.put(PERIOD_OF_DAY, getPeriodOfDay(time.hour));
- features.put(TIME_OF_DAY, getTimeOfDay(time.hour));
- }
-
- if (mFakeDayOfWeek != null && mFakeDayOfWeek.length() != 0) {
- features.put(DAY_OF_WEEK, mFakeDayOfWeek);
- if (mFakeDayOfWeek.equals(SUNDAY) ||
- mFakeDayOfWeek.equals(SATURDAY) ||
- mFakeDayOfWeek.equals(FRIDAY) &&
- features.get(PERIOD_OF_DAY).equals(NIGHTTIME)) {
- features.put(TIME_OF_WEEK, WEEKEND);
- } else {
- features.put(TIME_OF_WEEK, WEEKDAY);
- }
- }
- else {
- features.put(DAY_OF_WEEK, getDayOfWeek(time.weekDay));
- if (time.weekDay == Time.SUNDAY || time.weekDay == Time.SATURDAY ||
- (time.weekDay == Time.FRIDAY &&
- features.get(PERIOD_OF_DAY).equals(NIGHTTIME))) {
- features.put(TIME_OF_WEEK, WEEKEND);
- } else {
- features.put(TIME_OF_WEEK, WEEKDAY);
- }
- }
-
- return features;
- }
-
- // get all possible time_of_day values
- public static List<String> getTimeOfDayValues() {
- return Arrays.asList(TIME_OF_DAY_VALUES);
- }
-
- // get all possible day values
- public static List<String> getDayOfWeekValues() {
- return Arrays.asList(DAY_OF_WEEK_VALUES);
- }
-
- // set the fake time of day
- // set to "" to disable the fake time
- public static void setFakeTimeOfDay(String time_of_day) {
- mFakeTimeOfDay = time_of_day;
- }
-
- // set the fake day of week
- // set to "" to disable the fake day
- public static void setFakeDayOfWeek(String day_of_week) {
- mFakeDayOfWeek = day_of_week;
- }
-}