00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "lib/common.h"
00012 #include "lib/io.h"
00013 #include "features/Features.h"
00014 #include "features/SparseFeatures.h"
00015 #include "kernel/SparseLinearKernel.h"
00016 #include "kernel/SparseKernel.h"
00017
00018 CSparseLinearKernel::CSparseLinearKernel(INT size, DREAL s)
00019 : CSparseKernel<DREAL>(size), scale(s), initialized(false), normal(NULL),
00020 normal_length(0)
00021 {
00022 properties |= KP_LINADD;
00023 }
00024
00025 CSparseLinearKernel::CSparseLinearKernel(
00026 CSparseFeatures<DREAL>* l, CSparseFeatures<DREAL>* r, DREAL s, INT size)
00027 : CSparseKernel<DREAL>(size), scale(s), initialized(false), normal(NULL),
00028 normal_length(0)
00029 {
00030 properties |= KP_LINADD;
00031 init(l,r);
00032 }
00033
00034 CSparseLinearKernel::~CSparseLinearKernel()
00035 {
00036 cleanup();
00037 }
00038
00039 bool CSparseLinearKernel::init(CFeatures* l, CFeatures* r)
00040 {
00041 CSparseKernel<DREAL>::init(l, r);
00042
00043 if (!initialized)
00044 init_rescale();
00045
00046 SG_INFO( "rescaling kernel by %g (num:%d)\n",scale, CMath::min(l->get_num_vectors(), r->get_num_vectors()));
00047
00048 return true;
00049 }
00050
00051 void CSparseLinearKernel::init_rescale()
00052 {
00053 if (scale!=0.0)
00054 return;
00055 double sum=0;
00056 scale=1.0;
00057 for (INT i=0; (i<lhs->get_num_vectors() && i<rhs->get_num_vectors()); i++)
00058 sum+=compute(i, i);
00059
00060 scale=sum/CMath::min(lhs->get_num_vectors(), rhs->get_num_vectors());
00061 initialized=true;
00062 }
00063
00064 void CSparseLinearKernel::cleanup()
00065 {
00066 delete_optimization();
00067
00068 CKernel::cleanup();
00069 }
00070
00071 bool CSparseLinearKernel::load_init(FILE* src)
00072 {
00073 return false;
00074 }
00075
00076 bool CSparseLinearKernel::save_init(FILE* dest)
00077 {
00078 return false;
00079 }
00080
00081 void CSparseLinearKernel::clear_normal()
00082 {
00083 int num = ((CSparseFeatures<DREAL>*) lhs)->get_num_features();
00084 if (normal==NULL)
00085 {
00086 normal = new DREAL[num];
00087 normal_length=num;
00088 }
00089
00090 memset(normal, 0, sizeof(DREAL)*normal_length);
00091
00092 set_is_initialized(true);
00093 }
00094
00095 void CSparseLinearKernel::add_to_normal(INT idx, DREAL weight)
00096 {
00097 ((CSparseFeatures<DREAL>*) rhs)->add_to_dense_vec(weight, idx, normal, normal_length);
00098 set_is_initialized(true);
00099 }
00100
00101 DREAL CSparseLinearKernel::compute(INT idx_a, INT idx_b)
00102 {
00103 INT alen=0;
00104 INT blen=0;
00105 bool afree=false;
00106 bool bfree=false;
00107
00108 TSparseEntry<DREAL>* avec=((CSparseFeatures<DREAL>*) lhs)->get_sparse_feature_vector(idx_a, alen, afree);
00109 TSparseEntry<DREAL>* bvec=((CSparseFeatures<DREAL>*) rhs)->get_sparse_feature_vector(idx_b, blen, bfree);
00110
00111 DREAL result=((CSparseFeatures<DREAL>*) lhs)->sparse_dot(1.0/scale, avec,alen, bvec,blen);
00112
00113 ((CSparseFeatures<DREAL>*) lhs)->free_feature_vector(avec, idx_a, afree);
00114 ((CSparseFeatures<DREAL>*) rhs)->free_feature_vector(bvec, idx_b, bfree);
00115
00116 return result;
00117 }
00118
00119 bool CSparseLinearKernel::init_optimization(INT num_suppvec, INT* sv_idx, DREAL* alphas)
00120 {
00121 clear_normal();
00122
00123 for (int i=0; i<num_suppvec; i++)
00124 add_to_normal(sv_idx[i], alphas[i]);
00125
00126 set_is_initialized(true);
00127 return true;
00128 }
00129
00130 bool CSparseLinearKernel::delete_optimization()
00131 {
00132 delete[] normal;
00133 normal_length=0;
00134 normal=NULL;
00135 set_is_initialized(false);
00136
00137 return true;
00138 }
00139
00140 DREAL CSparseLinearKernel::compute_optimized(INT idx)
00141 {
00142 ASSERT(get_is_initialized());
00143 return ((CSparseFeatures<DREAL>*) rhs)->dense_dot(1.0/scale, idx, normal, normal_length, 0.0);
00144 }