|
SHOGUN v0.9.3
|
00001 /* 00002 * This program is free software; you can redistribute it and/or modify 00003 * it under the terms of the GNU General Public License as published by 00004 * the Free Software Foundation; either version 3 of the License, or 00005 * (at your option) any later version. 00006 * 00007 * Written (W) 2009-2010 Soeren Sonnenburg 00008 * Copyright (C) 2009 Fraunhofer Institute FIRST and Max-Planck-Society 00009 * Copyright (C) 2010 Berlin Institute of Technology 00010 */ 00011 00012 #include "features/CombinedDotFeatures.h" 00013 #include "lib/io.h" 00014 #include "lib/Mathematics.h" 00015 00016 using namespace shogun; 00017 00018 CCombinedDotFeatures::CCombinedDotFeatures() : CDotFeatures() 00019 { 00020 feature_list=new CList<CDotFeatures*>(true); 00021 update_dim_feature_space_and_num_vec(); 00022 } 00023 00024 CCombinedDotFeatures::CCombinedDotFeatures(const CCombinedDotFeatures & orig) 00025 : CDotFeatures(orig), num_vectors(orig.num_vectors), 00026 num_dimensions(orig.num_dimensions) 00027 { 00028 } 00029 00030 CFeatures* CCombinedDotFeatures::duplicate() const 00031 { 00032 return new CCombinedDotFeatures(*this); 00033 } 00034 00035 CCombinedDotFeatures::~CCombinedDotFeatures() 00036 { 00037 delete feature_list; 00038 } 00039 00040 void CCombinedDotFeatures::list_feature_objs() 00041 { 00042 SG_INFO( "BEGIN COMBINED DOTFEATURES LIST (%d, %d) - ", num_vectors, num_dimensions); 00043 this->list_feature_obj(); 00044 00045 CListElement<CDotFeatures*> * current = NULL ; 00046 CDotFeatures* f=get_first_feature_obj(current); 00047 00048 while (f) 00049 { 00050 f->list_feature_obj(); 00051 f=get_next_feature_obj(current); 00052 } 00053 00054 SG_INFO( "END COMBINED DOTFEATURES LIST (%d, %d) - ", num_vectors, num_dimensions); 00055 this->list_feature_obj(); 00056 } 00057 00058 void CCombinedDotFeatures::update_dim_feature_space_and_num_vec() 00059 { 00060 CListElement<CDotFeatures*> * current = NULL ; 00061 CDotFeatures* f=get_first_feature_obj(current); 00062 00063 int32_t dim=0; 00064 int32_t vec=-1; 00065 00066 while (f) 00067 { 00068 dim+= f->get_dim_feature_space(); 00069 if (vec==-1) 00070 vec=f->get_num_vectors(); 00071 else if (vec != f->get_num_vectors()) 00072 { 00073 f->list_feature_obj(); 00074 SG_ERROR("Number of vectors (%d) mismatches in above feature obj (%d)\n", vec, f->get_num_vectors()); 00075 } 00076 00077 f=get_next_feature_obj(current); 00078 } 00079 00080 num_dimensions=dim; 00081 num_vectors=vec; 00082 SG_DEBUG("vecs=%d, dims=%d\n", num_vectors, num_dimensions); 00083 } 00084 00085 float64_t CCombinedDotFeatures::dot(int32_t vec_idx1, int32_t vec_idx2) 00086 { 00087 float64_t result=0; 00088 00089 CListElement<CDotFeatures*> * current = NULL ; 00090 CDotFeatures* f=get_first_feature_obj(current); 00091 00092 while (f) 00093 { 00094 result += f->dot(vec_idx1, vec_idx2)*CMath::sq(f->get_combined_feature_weight()); 00095 f=get_next_feature_obj(current); 00096 } 00097 00098 return result; 00099 } 00100 00101 float64_t CCombinedDotFeatures::dense_dot(int32_t vec_idx1, float64_t* vec2, int32_t vec2_len) 00102 { 00103 float64_t result=0; 00104 00105 CListElement<CDotFeatures*> * current = NULL ; 00106 CDotFeatures* f=get_first_feature_obj(current); 00107 uint32_t offs=0; 00108 00109 while (f) 00110 { 00111 int32_t dim = f->get_dim_feature_space(); 00112 result += f->dense_dot(vec_idx1, vec2+offs, dim)*f->get_combined_feature_weight(); 00113 offs += dim; 00114 f=get_next_feature_obj(current); 00115 } 00116 00117 return result; 00118 } 00119 00120 void CCombinedDotFeatures::dense_dot_range(float64_t* output, int32_t start, int32_t stop, float64_t* alphas, float64_t* vec, int32_t dim, float64_t b) 00121 { 00122 if (stop<=start) 00123 return; 00124 ASSERT(dim==num_dimensions); 00125 00126 CListElement<CDotFeatures*> * current = NULL; 00127 CDotFeatures* f=get_first_feature_obj(current); 00128 uint32_t offs=0; 00129 bool first=true; 00130 int32_t num=stop-start; 00131 float64_t* tmp=new float64_t[num]; 00132 00133 while (f) 00134 { 00135 int32_t f_dim = f->get_dim_feature_space(); 00136 if (first) 00137 { 00138 f->dense_dot_range(output, start, stop, alphas, vec+offs, f_dim, b); 00139 first=false; 00140 } 00141 else 00142 { 00143 f->dense_dot_range(tmp, start, stop, alphas, vec+offs, f_dim, b); 00144 for (int32_t i=0; i<num; i++) 00145 output[i]+=tmp[i]; 00146 } 00147 offs += f_dim; 00148 f=get_next_feature_obj(current); 00149 } 00150 delete[] tmp; 00151 } 00152 00153 void CCombinedDotFeatures::dense_dot_range_subset(int32_t* sub_index, int32_t num, float64_t* output, float64_t* alphas, float64_t* vec, int32_t dim, float64_t b) 00154 { 00155 if (num<=0) 00156 return; 00157 ASSERT(dim==num_dimensions); 00158 00159 CListElement<CDotFeatures*> * current = NULL; 00160 CDotFeatures* f=get_first_feature_obj(current); 00161 uint32_t offs=0; 00162 bool first=true; 00163 float64_t* tmp=new float64_t[num]; 00164 00165 while (f) 00166 { 00167 int32_t f_dim = f->get_dim_feature_space(); 00168 if (first) 00169 { 00170 f->dense_dot_range_subset(sub_index, num, output, alphas, vec+offs, f_dim, b); 00171 first=false; 00172 } 00173 else 00174 { 00175 f->dense_dot_range_subset(sub_index, num, tmp, alphas, vec+offs, f_dim, b); 00176 for (int32_t i=0; i<num; i++) 00177 output[i]+=tmp[i]; 00178 } 00179 offs += f_dim; 00180 f=get_next_feature_obj(current); 00181 } 00182 delete[] tmp; 00183 } 00184 00185 void CCombinedDotFeatures::add_to_dense_vec(float64_t alpha, int32_t vec_idx1, float64_t* vec2, int32_t vec2_len, bool abs_val) 00186 { 00187 CListElement<CDotFeatures*> * current = NULL ; 00188 CDotFeatures* f=get_first_feature_obj(current); 00189 uint32_t offs=0; 00190 00191 while (f) 00192 { 00193 int32_t dim = f->get_dim_feature_space(); 00194 f->add_to_dense_vec(alpha*f->get_combined_feature_weight(), vec_idx1, vec2+offs, dim, abs_val); 00195 offs += dim; 00196 f=get_next_feature_obj(current); 00197 } 00198 } 00199 00200 00201 int32_t CCombinedDotFeatures::get_nnz_features_for_vector(int32_t num) 00202 { 00203 CListElement<CDotFeatures*> * current = NULL ; 00204 CDotFeatures* f=get_first_feature_obj(current); 00205 int32_t result=0; 00206 00207 while (f) 00208 { 00209 result+=f->get_nnz_features_for_vector(num); 00210 f=get_next_feature_obj(current); 00211 } 00212 00213 return result; 00214 } 00215 00216 void CCombinedDotFeatures::get_subfeature_weights(float64_t** weights, int32_t* num_weights) 00217 { 00218 *num_weights = get_num_feature_obj(); 00219 ASSERT(*num_weights > 0); 00220 00221 *weights=new float64_t[*num_weights]; 00222 float64_t* w = *weights; 00223 00224 CListElement<CDotFeatures*> * current = NULL; 00225 CDotFeatures* f = get_first_feature_obj(current); 00226 00227 while (f) 00228 { 00229 *w++=f->get_combined_feature_weight(); 00230 f = get_next_feature_obj(current); 00231 } 00232 } 00233 00234 void CCombinedDotFeatures::set_subfeature_weights( 00235 float64_t* weights, int32_t num_weights) 00236 { 00237 int32_t i=0 ; 00238 CListElement<CDotFeatures*> * current = NULL ; 00239 CDotFeatures* f = get_first_feature_obj(current); 00240 00241 ASSERT(num_weights==get_num_feature_obj()); 00242 00243 while(f) 00244 { 00245 f->set_combined_feature_weight(weights[i]); 00246 f = get_next_feature_obj(current); 00247 i++; 00248 } 00249 }