00001
00002
00003
00004
00005
00006
00007
00008
00009
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, const 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 }