16b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua/*
26b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * Copyright (C) 2012 The Android Open Source Project
36b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *
46b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * Licensed under the Apache License, Version 2.0 (the "License");
56b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * you may not use this file except in compliance with the License.
66b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * You may obtain a copy of the License at
76b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *
86b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *      http://www.apache.org/licenses/LICENSE-2.0
96b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *
106b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * Unless required by applicable law or agreed to in writing, software
116b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * distributed under the License is distributed on an "AS IS" BASIS,
126b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * See the License for the specific language governing permissions and
146b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua * limitations under the License.
156b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua */
166b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
176b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huapackage android.bordeaux.services;
186b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
196b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huaimport android.bordeaux.services.ILearning_StochasticLinearRanker;
206b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huaimport android.bordeaux.services.StringFloat;
216b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huaimport android.content.Context;
226b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huaimport android.os.RemoteException;
236b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huaimport android.util.Log;
246b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
256b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huaimport java.util.ArrayList;
266b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huaimport java.util.List;
276b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huaimport java.util.HashMap;
286b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huaimport java.util.Map;
296b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
306b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua/** Ranker for the Learning framework.
316b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *  For training: call updateClassifier with a pair of samples.
326b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *  For ranking: call scoreSample to the score of the rank
336b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *  Data is represented as sparse key, value pair. And key is a String, value
346b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *  is a float.
356b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *  Note: since the actual ranker is running in a remote the service.
366b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *  Sometimes the connection may be lost or not established.
376b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua *
386b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua */
396b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Huapublic class BordeauxRanker {
406b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    static final String TAG = "BordeauxRanker";
416b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    static final String RANKER_NOTAVAILABLE = "Ranker not Available";
426b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    private Context mContext;
436b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    private String mName;
446b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    private ILearning_StochasticLinearRanker mRanker;
456b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    private ArrayList<StringFloat> getArrayList(final HashMap<String, Float> sample) {
466b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        ArrayList<StringFloat> stringfloat_sample = new ArrayList<StringFloat>();
476b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        for (Map.Entry<String, Float> x : sample.entrySet()) {
486b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua           StringFloat v = new StringFloat();
496b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua           v.key = x.getKey();
506b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua           v.value = x.getValue();
516b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua           stringfloat_sample.add(v);
526b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        }
536b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        return stringfloat_sample;
546b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    }
556b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
56b019e89cbea221598c482b05ab68b7660b41aa23saberian    public boolean retrieveRanker() {
576b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        if (mRanker == null)
586b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            mRanker = BordeauxManagerService.getRanker(mContext, mName);
596b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        // if classifier is not available, return false
606b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        if (mRanker == null) {
616b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            Log.e(TAG,"Ranker not available.");
626b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            return false;
636b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        }
646b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        return true;
656b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    }
666b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
676b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    public BordeauxRanker(Context context) {
686b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        mContext = context;
696b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        mName = "defaultRanker";
706b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        mRanker = BordeauxManagerService.getRanker(context, mName);
716b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    }
726b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
736b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    public BordeauxRanker(Context context, String name) {
746b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        mContext = context;
756b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        mName = name;
766b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        mRanker = BordeauxManagerService.getRanker(context, mName);
776b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    }
786b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
796b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    // Update the ranker with two samples, sample1 has higher rank than
806b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    // sample2.
816b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    public boolean update(final HashMap<String, Float> sample1,
826b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua                          final HashMap<String, Float> sample2) {
836b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        if (!retrieveRanker())
846b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            return false;
856b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        try {
866b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            mRanker.UpdateClassifier(getArrayList(sample1), getArrayList(sample2));
876b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        } catch (RemoteException e) {
886b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            Log.e(TAG,"Exception: updateClassifier.");
896b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            return false;
906b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        }
916b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        return true;
926b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    }
936b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
94b019e89cbea221598c482b05ab68b7660b41aa23saberian    public boolean reset() {
95b019e89cbea221598c482b05ab68b7660b41aa23saberian        if (!retrieveRanker()){
96b019e89cbea221598c482b05ab68b7660b41aa23saberian            Log.e(TAG,"Exception: Ranker is not availible");
97b019e89cbea221598c482b05ab68b7660b41aa23saberian            return false;
98b019e89cbea221598c482b05ab68b7660b41aa23saberian        }
99b019e89cbea221598c482b05ab68b7660b41aa23saberian        try {
100b019e89cbea221598c482b05ab68b7660b41aa23saberian            mRanker.ResetRanker();
101b019e89cbea221598c482b05ab68b7660b41aa23saberian            return true;
102b019e89cbea221598c482b05ab68b7660b41aa23saberian        } catch (RemoteException e) {
103b019e89cbea221598c482b05ab68b7660b41aa23saberian        }
104b019e89cbea221598c482b05ab68b7660b41aa23saberian        return false;
105b019e89cbea221598c482b05ab68b7660b41aa23saberian    }
106b019e89cbea221598c482b05ab68b7660b41aa23saberian
1076b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    public float scoreSample(final HashMap<String, Float> sample) {
1086b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        if (!retrieveRanker())
1096b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            throw new RuntimeException(RANKER_NOTAVAILABLE);
1106b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        try {
1116b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            return mRanker.ScoreSample(getArrayList(sample));
1126b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        } catch (RemoteException e) {
1136b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            Log.e(TAG,"Exception: scoring the sample.");
1146b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua            throw new RuntimeException(RANKER_NOTAVAILABLE);
1156b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua        }
1166b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    }
1176b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
118b019e89cbea221598c482b05ab68b7660b41aa23saberian    public boolean setPriorWeight(final HashMap<String, Float> sample) {
119b019e89cbea221598c482b05ab68b7660b41aa23saberian        if (!retrieveRanker())
120b019e89cbea221598c482b05ab68b7660b41aa23saberian            throw new RuntimeException(RANKER_NOTAVAILABLE);
121b019e89cbea221598c482b05ab68b7660b41aa23saberian        try {
122b019e89cbea221598c482b05ab68b7660b41aa23saberian            return mRanker.SetModelPriorWeight(getArrayList(sample));
123b019e89cbea221598c482b05ab68b7660b41aa23saberian        } catch (RemoteException e) {
124b019e89cbea221598c482b05ab68b7660b41aa23saberian            Log.e(TAG,"Exception: set prior Weights");
125b019e89cbea221598c482b05ab68b7660b41aa23saberian            throw new RuntimeException(RANKER_NOTAVAILABLE);
126b019e89cbea221598c482b05ab68b7660b41aa23saberian        }
1276b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    }
1286b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua
129b019e89cbea221598c482b05ab68b7660b41aa23saberian    public boolean setParameter(String key, String value) {
130b019e89cbea221598c482b05ab68b7660b41aa23saberian        if (!retrieveRanker())
131b019e89cbea221598c482b05ab68b7660b41aa23saberian            throw new RuntimeException(RANKER_NOTAVAILABLE);
132b019e89cbea221598c482b05ab68b7660b41aa23saberian        try {
133b019e89cbea221598c482b05ab68b7660b41aa23saberian            return mRanker.SetModelParameter(key, value);
134b019e89cbea221598c482b05ab68b7660b41aa23saberian        } catch (RemoteException e) {
135984e52f31d596840cfa51b1238e1c43d2e1918f8saberian            Log.e(TAG,"Exception: Setting Parameter");
136b019e89cbea221598c482b05ab68b7660b41aa23saberian            throw new RuntimeException(RANKER_NOTAVAILABLE);
137b019e89cbea221598c482b05ab68b7660b41aa23saberian        }
1386b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua    }
1396b4eebc73439cbc3ddfb547444a341d1f9be7996Wei Hua}
140