SHOGUN  v3.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CombinedFeatures.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 1999-2009 Soeren Sonnenburg
8  * Written (W) 1999-2008 Gunnar Raetsch
9  * Written (W) 2012 Heiko Strathmann
10  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
11  */
12 
14 #include <shogun/io/SGIO.h>
15 #include <shogun/lib/Set.h>
16 #include <shogun/lib/Map.h>
17 
18 using namespace shogun;
19 
21 : CFeatures(0)
22 {
23  init();
24 
26  num_vec=0;
27 }
28 
30 : CFeatures(0)
31 {
32  init();
33 
35  //TODO copy features
36  num_vec=orig.num_vec;
37 }
38 
40 {
41  return new CCombinedFeatures(*this);
42 }
43 
45 {
47 }
48 
50 {
51  return (CFeatures*) feature_array->get_element(idx);
52 }
53 
55 {
56  SG_INFO("BEGIN COMBINED FEATURES LIST - ")
57  this->list_feature_obj();
58 
59  for (index_t f_idx=0; f_idx<get_num_feature_obj(); f_idx++)
60  {
61  CFeatures* f = get_feature_obj(f_idx);
62  f->list_feature_obj();
63  SG_UNREF(f);
64  }
65 
66  SG_INFO("END COMBINED FEATURES LIST - ")
67 }
68 
70 {
71  bool result=false;
72 
73  if ( (comb_feat) && (this->get_num_feature_obj() == comb_feat->get_num_feature_obj()) )
74  {
75  for (index_t f_idx=0; f_idx<get_num_feature_obj(); f_idx++)
76  {
77  CFeatures* f1=this->get_feature_obj(f_idx);
78  CFeatures* f2=comb_feat->get_feature_obj(f_idx);
79 
80  if ( ! (f1 && f2 && f1->check_feature_compatibility(f2)) )
81  {
82  SG_UNREF(f1);
83  SG_UNREF(f2);
84  SG_INFO("not compatible, combfeat\n")
85  comb_feat->list_feature_objs();
86  SG_INFO("vs this\n")
87  this->list_feature_objs();
88  return false;
89  }
90 
91  SG_UNREF(f1);
92  SG_UNREF(f2);
93  }
94  SG_DEBUG("features are compatible\n")
95  result=true;
96  }
97  else
98  {
99  SG_WARNING("number of features in combined feature objects differs (%d != %d)\n", this->get_num_feature_obj(), comb_feat->get_num_feature_obj())
100  SG_INFO("compare\n")
101  comb_feat->list_feature_objs();
102  SG_INFO("vs this\n")
103  this->list_feature_objs();
104  }
105 
106  return result;
107 }
108 
110 {
111  return get_feature_obj(0);
112 }
113 
115 {
117 }
118 
120 {
121  ASSERT(obj)
122  int32_t n=obj->get_num_vectors();
123 
124  if (get_num_vectors()>0 && n!=get_num_vectors())
125  {
126  SG_ERROR("Number of feature vectors does not match (expected %d, "
127  "obj has %d)\n", get_num_vectors(), n);
128  }
129 
130  num_vec=n;
131  return feature_array->insert_element(obj, idx);
132 }
133 
135 {
136  ASSERT(obj)
137  int32_t n=obj->get_num_vectors();
138 
139  if (get_num_vectors()>0 && n!=get_num_vectors())
140  {
141  SG_ERROR("Number of feature vectors does not match (expected %d, "
142  "obj has %d)\n", get_num_vectors(), n);
143  }
144 
145  num_vec=n;
146 
147  int num_feature_obj = get_num_feature_obj();
148  feature_array->push_back(obj);
149  return num_feature_obj+1 == feature_array->get_num_elements();
150 }
151 
153 {
154  return feature_array->delete_element(idx);
155 }
156 
158 {
160 }
161 
162 void CCombinedFeatures::init()
163 {
164  m_parameters->add(&num_vec, "num_vec",
165  "Number of vectors.");
167  "feature_array", "Feature array.");
168 }
169 
171 {
172  /* TODO, if all features are the same, only one copy should be created
173  * in memory */
174  SG_WARNING("Heiko Strathmann: FIXME, unefficient!\n")
175 
176  SG_DEBUG("entering %s::create_merged_copy()\n", get_name())
177  if (get_feature_type()!=other->get_feature_type() ||
178  get_feature_class()!=other->get_feature_class() ||
179  strcmp(get_name(), other->get_name()))
180  {
181  SG_ERROR("%s::create_merged_copy(): Features are of different type!\n",
182  get_name());
183  }
184 
185  CCombinedFeatures* casted=dynamic_cast<CCombinedFeatures*>(other);
186 
187  if (!casted)
188  {
189  SG_ERROR("%s::create_merged_copy(): Could not cast object of %s to "
190  "same type as %s\n",get_name(), other->get_name(), get_name());
191  }
192 
193  if (get_num_feature_obj()!=casted->get_num_feature_obj())
194  {
195  SG_ERROR("%s::create_merged_copy(): Only possible if both instances "
196  "have the same number of sub-feature-objects\n", get_name());
197  }
198 
199  CCombinedFeatures* result=new CCombinedFeatures();
200  for (index_t f_idx=0; f_idx<get_num_feature_obj(); f_idx++)
201  {
202  CFeatures* current_this=get_feature_obj(f_idx);
203  CFeatures* current_other=casted->get_feature_obj(f_idx);
204 
205  result->append_feature_obj(
206  current_this->create_merged_copy(current_other));
207  SG_UNREF(current_this);
208  SG_UNREF(current_other);
209  }
210 
211  SG_DEBUG("leaving %s::create_merged_copy()\n", get_name())
212  return result;
213 }
214 
216 {
217  SG_DEBUG("entering %s::add_subset()\n", get_name())
218  CSet<CFeatures*>* processed=new CSet<CFeatures*>();
219 
220  for (index_t f_idx=0; f_idx<get_num_feature_obj(); f_idx++)
221  {
222  CFeatures* current=get_feature_obj(f_idx);
223 
224  if (!processed->contains(current))
225  {
226  /* remember that subset was added here */
227  current->add_subset(subset);
228  processed->add(current);
229  SG_DEBUG("adding subset to %s at %p\n",
230  current->get_name(), current);
231  }
232  SG_UNREF(current);
233  }
234 
235  /* also add subset to local stack to have it for easy access */
236  m_subset_stack->add_subset(subset);
237 
239  SG_UNREF(processed);
240  SG_DEBUG("leaving %s::add_subset()\n", get_name())
241 }
242 
244 {
245  SG_DEBUG("entering %s::remove_subset()\n", get_name())
246  CSet<CFeatures*>* processed=new CSet<CFeatures*>();
247 
248  for (index_t f_idx=0; f_idx<get_num_feature_obj(); f_idx++)
249  {
250  CFeatures* current=get_feature_obj(f_idx);
251  if (!processed->contains(current))
252  {
253  /* remember that subset was added here */
254  current->remove_subset();
255  processed->add(current);
256  SG_DEBUG("removing subset from %s at %p\n",
257  current->get_name(), current);
258  }
259  SG_UNREF(current);
260  }
261 
262  /* also remove subset from local stack to have it for easy access */
264 
266  SG_UNREF(processed);
267  SG_DEBUG("leaving %s::remove_subset()\n", get_name())
268 }
269 
271 {
272  SG_DEBUG("entering %s::remove_all_subsets()\n", get_name())
273  CSet<CFeatures*>* processed=new CSet<CFeatures*>();
274 
275  for (index_t f_idx=0; f_idx<get_num_feature_obj(); f_idx++)
276  {
277  CFeatures* current=get_feature_obj(f_idx);
278  if (!processed->contains(current))
279  {
280  /* remember that subset was added here */
281  current->remove_all_subsets();
282  processed->add(current);
283  SG_DEBUG("removing all subsets from %s at %p\n",
284  current->get_name(), current);
285  }
286  SG_UNREF(current);
287  }
288 
289  /* also remove subsets from local stack to have it for easy access */
291 
293  SG_UNREF(processed);
294  SG_DEBUG("leaving %s::remove_all_subsets()\n", get_name())
295 }
296 
298 {
299  /* this is returned with the results of copy_subset of sub-features */
300  CCombinedFeatures* result=new CCombinedFeatures();
301 
302  /* map to only copy same feature objects once */
304  for (index_t f_idx=0; f_idx<get_num_feature_obj(); f_idx++)
305  {
306  CFeatures* current=get_feature_obj(f_idx);
307 
308  CFeatures* new_element=NULL;
309 
310  /* only copy if not done yet, otherwise, use old copy */
311  if (!processed->contains(current))
312  {
313  new_element=current->copy_subset(indices);
314  processed->add(current, new_element);
315  }
316  else
317  {
318  new_element=processed->get_element(current);
319 
320  /* has to be SG_REF'ed since it will be unrefed afterwards */
321  SG_REF(new_element);
322  }
323 
324  /* add to result */
325  result->append_feature_obj(new_element);
326 
327  /* clean up: copy_subset of SG_REF has to be undone */
328  SG_UNREF(new_element);
329 
330  SG_UNREF(current);
331  }
332 
333  SG_UNREF(processed);
334 
335  SG_REF(result);
336  return result;
337 }

SHOGUN Machine Learning Toolbox - Documentation