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