Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <shogun/features/CombinedFeatures.h>
00014 #include <shogun/io/SGIO.h>
00015 #include <shogun/lib/Set.h>
00016 #include <shogun/lib/Map.h>
00017
00018 using namespace shogun;
00019
00020 CCombinedFeatures::CCombinedFeatures()
00021 : CFeatures(0)
00022 {
00023 init();
00024
00025 feature_list=new CList(true);
00026 num_vec=0;
00027 }
00028
00029 CCombinedFeatures::CCombinedFeatures(const CCombinedFeatures & orig)
00030 : CFeatures(0)
00031 {
00032 init();
00033
00034 feature_list=new CList(true);
00035
00036 num_vec=orig.num_vec;
00037 }
00038
00039 CFeatures* CCombinedFeatures::duplicate() const
00040 {
00041 return new CCombinedFeatures(*this);
00042 }
00043
00044 CCombinedFeatures::~CCombinedFeatures()
00045 {
00046 SG_UNREF(feature_list);
00047 }
00048
00049 int32_t CCombinedFeatures::get_size() const
00050 {
00051 CFeatures* f=(CFeatures*) feature_list
00052 ->get_current_element();
00053 if (f)
00054 {
00055 int32_t s=f->get_size();
00056 SG_UNREF(f)
00057 return s;
00058 }
00059 else
00060 return 0;
00061 }
00062
00063 void CCombinedFeatures::list_feature_objs()
00064 {
00065 SG_INFO( "BEGIN COMBINED FEATURES LIST - ");
00066 this->list_feature_obj();
00067
00068 CListElement* current = NULL ;
00069 CFeatures* f=get_first_feature_obj(current);
00070
00071 while (f)
00072 {
00073 f->list_feature_obj();
00074 SG_UNREF(f);
00075 f=get_next_feature_obj(current);
00076 }
00077
00078 SG_INFO( "END COMBINED FEATURES LIST - ");
00079 }
00080
00081 bool CCombinedFeatures::check_feature_obj_compatibility(CCombinedFeatures* comb_feat)
00082 {
00083 bool result=false;
00084
00085 if (comb_feat && (this->get_num_feature_obj() == comb_feat->get_num_feature_obj()) )
00086 {
00087 CFeatures* f1=this->get_first_feature_obj();
00088 CFeatures* f2=comb_feat->get_first_feature_obj();
00089
00090 if (f1 && f2 && f1->check_feature_compatibility(f2))
00091 {
00092 SG_UNREF(f1);
00093 SG_UNREF(f2);
00094 while( ( (f1=this->get_next_feature_obj()) != NULL ) &&
00095 ( (f2=comb_feat->get_next_feature_obj()) != NULL) )
00096 {
00097 if (!f1->check_feature_compatibility(f2))
00098 {
00099 SG_UNREF(f1);
00100 SG_UNREF(f2);
00101 SG_INFO( "not compatible, combfeat\n");
00102 comb_feat->list_feature_objs();
00103 SG_INFO( "vs this\n");
00104 this->list_feature_objs();
00105 return false;
00106 }
00107 SG_UNREF(f1);
00108 SG_UNREF(f2);
00109 }
00110
00111 SG_DEBUG( "features are compatible\n");
00112 result=true;
00113 }
00114 else
00115 SG_WARNING( "first 2 features not compatible\n");
00116 }
00117 else
00118 {
00119 SG_WARNING( "number of features in combined feature objects differs (%d != %d)\n", this->get_num_feature_obj(), comb_feat->get_num_feature_obj());
00120 SG_INFO( "compare\n");
00121 comb_feat->list_feature_objs();
00122 SG_INFO( "vs this\n");
00123 this->list_feature_objs();
00124 }
00125
00126 return result;
00127 }
00128
00129 CFeatures* CCombinedFeatures::get_first_feature_obj()
00130 {
00131 return (CFeatures*) feature_list->get_first_element();
00132 }
00133
00134 CFeatures* CCombinedFeatures::get_first_feature_obj(CListElement*& current)
00135 {
00136 return (CFeatures*) feature_list->get_first_element(current);
00137 }
00138
00139 CFeatures* CCombinedFeatures::get_next_feature_obj()
00140 {
00141 return (CFeatures*) feature_list->get_next_element();
00142 }
00143
00144 CFeatures* CCombinedFeatures::get_next_feature_obj(CListElement*& current)
00145 {
00146 return (CFeatures*) feature_list->get_next_element(current);
00147 }
00148
00149 CFeatures* CCombinedFeatures::get_last_feature_obj()
00150 {
00151 return (CFeatures*) feature_list->get_last_element();
00152 }
00153
00154 bool CCombinedFeatures::insert_feature_obj(CFeatures* obj)
00155 {
00156 ASSERT(obj);
00157 int32_t n=obj->get_num_vectors();
00158
00159 if (get_num_vectors()>0 && n!=get_num_vectors())
00160 {
00161 SG_ERROR("Number of feature vectors does not match (expected %d, "
00162 "obj has %d)\n", get_num_vectors(), n);
00163 }
00164
00165 num_vec=n;
00166 return feature_list->insert_element(obj);
00167 }
00168
00169 bool CCombinedFeatures::append_feature_obj(CFeatures* obj)
00170 {
00171 ASSERT(obj);
00172 int32_t n=obj->get_num_vectors();
00173
00174 if (get_num_vectors()>0 && n!=get_num_vectors())
00175 {
00176 SG_ERROR("Number of feature vectors does not match (expected %d, "
00177 "obj has %d)\n", get_num_vectors(), n);
00178 }
00179
00180 num_vec=n;
00181 return feature_list->append_element(obj);
00182 }
00183
00184 bool CCombinedFeatures::delete_feature_obj()
00185 {
00186 CFeatures* f=(CFeatures*)feature_list->delete_element();
00187 if (f)
00188 {
00189 SG_UNREF(f);
00190 return true;
00191 }
00192 else
00193 return false;
00194 }
00195
00196 int32_t CCombinedFeatures::get_num_feature_obj()
00197 {
00198 return feature_list->get_num_elements();
00199 }
00200
00201 void CCombinedFeatures::init()
00202 {
00203 m_parameters->add(&num_vec, "num_vec",
00204 "Number of vectors.");
00205 m_parameters->add((CSGObject**) &feature_list,
00206 "feature_list", "Feature list.");
00207 }
00208
00209 CFeatures* CCombinedFeatures::create_merged_copy(CFeatures* other)
00210 {
00211
00212
00213 SG_WARNING("Heiko Strathmann: FIXME, unefficient!\n");
00214
00215 SG_DEBUG("entering %s::create_merged_copy()\n", get_name());
00216 if (get_feature_type()!=other->get_feature_type() ||
00217 get_feature_class()!=other->get_feature_class() ||
00218 strcmp(get_name(), other->get_name()))
00219 {
00220 SG_ERROR("%s::create_merged_copy(): Features are of different type!\n",
00221 get_name());
00222 }
00223
00224 CCombinedFeatures* casted=dynamic_cast<CCombinedFeatures*>(other);
00225
00226 if (!casted)
00227 {
00228 SG_ERROR("%s::create_merged_copy(): Could not cast object of %s to "
00229 "same type as %s\n",get_name(), other->get_name(), get_name());
00230 }
00231
00232 if (get_num_feature_obj()!=casted->get_num_feature_obj())
00233 {
00234 SG_ERROR("%s::create_merged_copy(): Only possible if both instances "
00235 "have the same number of sub-feature-objects\n", get_name());
00236 }
00237
00238 CCombinedFeatures* result=new CCombinedFeatures();
00239 CFeatures* current_this=get_first_feature_obj();
00240 CFeatures* current_other=casted->get_first_feature_obj();
00241 while (current_this)
00242 {
00243 result->append_feature_obj(
00244 current_this->create_merged_copy(current_other));
00245 SG_UNREF(current_this);
00246 SG_UNREF(current_other);
00247 current_this=get_next_feature_obj();
00248 current_other=get_next_feature_obj();
00249 }
00250
00251 SG_DEBUG("leaving %s::create_merged_copy()\n", get_name());
00252 return result;
00253 }
00254
00255 void CCombinedFeatures::add_subset(SGVector<index_t> subset)
00256 {
00257 SG_DEBUG("entering %s::add_subset()\n", get_name());
00258 CSet<CFeatures*>* processed=new CSet<CFeatures*>();
00259
00260 CFeatures* current=get_first_feature_obj();
00261 while (current)
00262 {
00263 if (!processed->contains(current))
00264 {
00265
00266 current->add_subset(subset);
00267 processed->add(current);
00268 SG_DEBUG("adding subset to %s at %p\n",
00269 current->get_name(), current);
00270 }
00271 SG_UNREF(current);
00272 current=get_next_feature_obj();
00273 }
00274
00275
00276 m_subset_stack->add_subset(subset);
00277
00278 subset_changed_post();
00279 SG_UNREF(processed);
00280 SG_DEBUG("leaving %s::add_subset()\n", get_name());
00281 }
00282
00283 void CCombinedFeatures::remove_subset()
00284 {
00285 SG_DEBUG("entering %s::remove_subset()\n", get_name());
00286 CSet<CFeatures*>* processed=new CSet<CFeatures*>();
00287
00288 CFeatures* current=get_first_feature_obj();
00289 while (current)
00290 {
00291 if (!processed->contains(current))
00292 {
00293
00294 current->remove_subset();
00295 processed->add(current);
00296 SG_DEBUG("removing subset from %s at %p\n",
00297 current->get_name(), current);
00298 }
00299 SG_UNREF(current);
00300 current=get_next_feature_obj();
00301 }
00302
00303
00304 m_subset_stack->remove_subset();
00305
00306 subset_changed_post();
00307 SG_UNREF(processed);
00308 SG_DEBUG("leaving %s::remove_subset()\n", get_name());
00309 }
00310
00311 void CCombinedFeatures::remove_all_subsets()
00312 {
00313 SG_DEBUG("entering %s::remove_all_subsets()\n", get_name());
00314 CSet<CFeatures*>* processed=new CSet<CFeatures*>();
00315
00316 CFeatures* current=get_first_feature_obj();
00317 while (current)
00318 {
00319 if (!processed->contains(current))
00320 {
00321
00322 current->remove_all_subsets();
00323 processed->add(current);
00324 SG_DEBUG("removing all subsets from %s at %p\n",
00325 current->get_name(), current);
00326 }
00327 SG_UNREF(current);
00328 current=get_next_feature_obj();
00329 }
00330
00331
00332 m_subset_stack->remove_all_subsets();
00333
00334 subset_changed_post();
00335 SG_UNREF(processed);
00336 SG_DEBUG("leaving %s::remove_all_subsets()\n", get_name());
00337 }
00338
00339 CFeatures* CCombinedFeatures::copy_subset(SGVector<index_t> indices)
00340 {
00341
00342 CCombinedFeatures* result=new CCombinedFeatures();
00343
00344
00345 CMap<CFeatures*, CFeatures*>* processed=new CMap<CFeatures*, CFeatures*>();
00346 CFeatures* current=get_first_feature_obj();
00347 while (current)
00348 {
00349 CFeatures* new_element=NULL;
00350
00351
00352 if (!processed->contains(current))
00353 {
00354 new_element=current->copy_subset(indices);
00355 processed->add(current, new_element);
00356 }
00357 else
00358 {
00359 new_element=processed->get_element(current);
00360
00361
00362 SG_REF(new_element);
00363 }
00364
00365
00366 result->append_feature_obj(new_element);
00367
00368
00369 SG_UNREF(new_element);
00370
00371 SG_UNREF(current);
00372 current=get_next_feature_obj();
00373 }
00374
00375 SG_UNREF(processed);
00376
00377 SG_REF(result);
00378 return result;
00379 }