00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <shogun/features/CombinedDotFeatures.h>
00013 #include <shogun/io/SGIO.h>
00014 #include <shogun/mathematics/Math.h>
00015
00016 using namespace shogun;
00017
00018 void
00019 CCombinedDotFeatures::init(void)
00020 {
00021 m_parameters->add(&num_dimensions, "num_dimensions",
00022 "Total number of dimensions.");
00023 m_parameters->add(&num_vectors, "num_vectors",
00024 "Total number of vectors.");
00025 m_parameters->add((CSGObject**) &feature_list,
00026 "feature_list", "Feature list.");
00027 }
00028
00029 CCombinedDotFeatures::CCombinedDotFeatures() : CDotFeatures()
00030 {
00031 init();
00032
00033 feature_list=new CList(true);
00034 update_dim_feature_space_and_num_vec();
00035 }
00036
00037 CCombinedDotFeatures::CCombinedDotFeatures(const CCombinedDotFeatures & orig)
00038 : CDotFeatures(orig), num_vectors(orig.num_vectors),
00039 num_dimensions(orig.num_dimensions)
00040 {
00041 init();
00042
00043 feature_list=new CList(true);
00044 }
00045
00046 CFeatures* CCombinedDotFeatures::duplicate() const
00047 {
00048 return new CCombinedDotFeatures(*this);
00049 }
00050
00051 CCombinedDotFeatures::~CCombinedDotFeatures()
00052 {
00053 delete feature_list;
00054 }
00055
00056 void CCombinedDotFeatures::list_feature_objs()
00057 {
00058 SG_INFO( "BEGIN COMBINED DOTFEATURES LIST (%d, %d) - ", num_vectors, num_dimensions);
00059 this->list_feature_obj();
00060
00061 CListElement* current = NULL ;
00062 CDotFeatures* f=get_first_feature_obj(current);
00063
00064 while (f)
00065 {
00066 f->list_feature_obj();
00067 f=get_next_feature_obj(current);
00068 }
00069
00070 SG_INFO( "END COMBINED DOTFEATURES LIST (%d, %d) - ", num_vectors, num_dimensions);
00071 this->list_feature_obj();
00072 }
00073
00074 void CCombinedDotFeatures::update_dim_feature_space_and_num_vec()
00075 {
00076 CListElement* current = NULL ;
00077 CDotFeatures* f=get_first_feature_obj(current);
00078
00079 int32_t dim=0;
00080 int32_t vec=-1;
00081
00082 while (f)
00083 {
00084 dim+= f->get_dim_feature_space();
00085 if (vec==-1)
00086 vec=f->get_num_vectors();
00087 else if (vec != f->get_num_vectors())
00088 {
00089 f->list_feature_obj();
00090 SG_ERROR("Number of vectors (%d) mismatches in above feature obj (%d)\n", vec, f->get_num_vectors());
00091 }
00092
00093 SG_UNREF(f);
00094
00095 f=get_next_feature_obj(current);
00096 }
00097
00098 num_dimensions=dim;
00099 num_vectors=vec;
00100 SG_DEBUG("vecs=%d, dims=%d\n", num_vectors, num_dimensions);
00101 }
00102
00103 float64_t CCombinedDotFeatures::dot(int32_t vec_idx1, CDotFeatures* df, int32_t vec_idx2)
00104 {
00105 float64_t result=0;
00106
00107 ASSERT(df);
00108 ASSERT(df->get_feature_type() == get_feature_type());
00109 ASSERT(df->get_feature_class() == get_feature_class());
00110 CCombinedDotFeatures* cf = (CCombinedDotFeatures*) df;
00111
00112 CListElement* current1 = NULL;
00113 CDotFeatures* f1=get_first_feature_obj(current1);
00114
00115 CListElement* current2 = NULL;
00116 CDotFeatures* f2=cf->get_first_feature_obj(current2);
00117
00118 while (f1 && f2)
00119 {
00120 result += f1->dot(vec_idx1, f2,vec_idx2) *
00121 f1->get_combined_feature_weight() *
00122 f2->get_combined_feature_weight();
00123
00124 SG_UNREF(f1);
00125 SG_UNREF(f2);
00126 f1=get_next_feature_obj(current1);
00127 f2=cf->get_next_feature_obj(current2);
00128 }
00129
00130
00131 ASSERT(f1 == NULL && f2 == NULL);
00132
00133 return result;
00134 }
00135
00136 float64_t CCombinedDotFeatures::dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
00137 {
00138 float64_t result=0;
00139
00140 CListElement* current = NULL ;
00141 CDotFeatures* f=get_first_feature_obj(current);
00142 uint32_t offs=0;
00143
00144 while (f)
00145 {
00146 int32_t dim = f->get_dim_feature_space();
00147 result += f->dense_dot(vec_idx1, vec2+offs, dim)*f->get_combined_feature_weight();
00148 offs += dim;
00149
00150 SG_UNREF(f);
00151 f=get_next_feature_obj(current);
00152 }
00153
00154 return result;
00155 }
00156
00157 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)
00158 {
00159 if (stop<=start)
00160 return;
00161 ASSERT(dim==num_dimensions);
00162
00163 CListElement* current = NULL;
00164 CDotFeatures* f=get_first_feature_obj(current);
00165 uint32_t offs=0;
00166 bool first=true;
00167 int32_t num=stop-start;
00168 float64_t* tmp=SG_MALLOC(float64_t, num);
00169
00170 while (f)
00171 {
00172 int32_t f_dim = f->get_dim_feature_space();
00173 if (first)
00174 {
00175 f->dense_dot_range(output, start, stop, alphas, vec+offs, f_dim, b);
00176 first=false;
00177 }
00178 else
00179 {
00180 f->dense_dot_range(tmp, start, stop, alphas, vec+offs, f_dim, b);
00181 for (int32_t i=0; i<num; i++)
00182 output[i]+=tmp[i];
00183 }
00184 offs += f_dim;
00185
00186 SG_UNREF(f);
00187 f=get_next_feature_obj(current);
00188 }
00189 SG_FREE(tmp);
00190 }
00191
00192 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)
00193 {
00194 if (num<=0)
00195 return;
00196 ASSERT(dim==num_dimensions);
00197
00198 CListElement* current = NULL;
00199 CDotFeatures* f=get_first_feature_obj(current);
00200 uint32_t offs=0;
00201 bool first=true;
00202 float64_t* tmp=SG_MALLOC(float64_t, num);
00203
00204 while (f)
00205 {
00206 int32_t f_dim = f->get_dim_feature_space();
00207 if (first)
00208 {
00209 f->dense_dot_range_subset(sub_index, num, output, alphas, vec+offs, f_dim, b);
00210 first=false;
00211 }
00212 else
00213 {
00214 f->dense_dot_range_subset(sub_index, num, tmp, alphas, vec+offs, f_dim, b);
00215 for (int32_t i=0; i<num; i++)
00216 output[i]+=tmp[i];
00217 }
00218 offs += f_dim;
00219
00220 SG_UNREF(f);
00221 f=get_next_feature_obj(current);
00222 }
00223 SG_FREE(tmp);
00224 }
00225
00226 void CCombinedDotFeatures::add_to_dense_vec(float64_t alpha, int32_t vec_idx1, float64_t* vec2, int32_t vec2_len, bool abs_val)
00227 {
00228 CListElement* current = NULL ;
00229 CDotFeatures* f=get_first_feature_obj(current);
00230 uint32_t offs=0;
00231
00232 while (f)
00233 {
00234 int32_t dim = f->get_dim_feature_space();
00235 f->add_to_dense_vec(alpha*f->get_combined_feature_weight(), vec_idx1, vec2+offs, dim, abs_val);
00236 offs += dim;
00237
00238 SG_UNREF(f);
00239 f=get_next_feature_obj(current);
00240 }
00241 }
00242
00243
00244 int32_t CCombinedDotFeatures::get_nnz_features_for_vector(int32_t num)
00245 {
00246 CListElement* current = NULL ;
00247 CDotFeatures* f=get_first_feature_obj(current);
00248 int32_t result=0;
00249
00250 while (f)
00251 {
00252 result+=f->get_nnz_features_for_vector(num);
00253
00254 SG_UNREF(f);
00255 f=get_next_feature_obj(current);
00256 }
00257
00258 return result;
00259 }
00260
00261 void CCombinedDotFeatures::get_subfeature_weights(float64_t** weights, int32_t* num_weights)
00262 {
00263 *num_weights = get_num_feature_obj();
00264 ASSERT(*num_weights > 0);
00265
00266 *weights=SG_MALLOC(float64_t, *num_weights);
00267 float64_t* w = *weights;
00268
00269 CListElement* current = NULL;
00270 CDotFeatures* f = get_first_feature_obj(current);
00271
00272 while (f)
00273 {
00274 *w++=f->get_combined_feature_weight();
00275
00276 SG_UNREF(f);
00277 f = get_next_feature_obj(current);
00278 }
00279 }
00280
00281 void CCombinedDotFeatures::set_subfeature_weights(
00282 float64_t* weights, int32_t num_weights)
00283 {
00284 int32_t i=0 ;
00285 CListElement* current = NULL ;
00286 CDotFeatures* f = get_first_feature_obj(current);
00287
00288 ASSERT(num_weights==get_num_feature_obj());
00289
00290 while(f)
00291 {
00292 f->set_combined_feature_weight(weights[i]);
00293
00294 SG_UNREF(f);
00295 f = get_next_feature_obj(current);
00296 i++;
00297 }
00298 }