SHOGUN  v2.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 
25  feature_list=new CList(true);
26  num_vec=0;
27 }
28 
30 : CFeatures(0)
31 {
32  init();
33 
34  feature_list=new CList(true);
35  //todo copy features
36  num_vec=orig.num_vec;
37 }
38 
40 {
41  return new CCombinedFeatures(*this);
42 }
43 
45 {
47 }
48 
50 {
52  ->get_current_element();
53  if (f)
54  {
55  int32_t s=f->get_size();
56  SG_UNREF(f)
57  return s;
58  }
59  else
60  return 0;
61 }
62 
64 {
65  SG_INFO( "BEGIN COMBINED FEATURES LIST - ");
66  this->list_feature_obj();
67 
68  CListElement* current = NULL ;
69  CFeatures* f=get_first_feature_obj(current);
70 
71  while (f)
72  {
73  f->list_feature_obj();
74  SG_UNREF(f);
75  f=get_next_feature_obj(current);
76  }
77 
78  SG_INFO( "END COMBINED FEATURES LIST - ");
79 }
80 
82 {
83  bool result=false;
84 
85  if (comb_feat && (this->get_num_feature_obj() == comb_feat->get_num_feature_obj()) )
86  {
87  CFeatures* f1=this->get_first_feature_obj();
88  CFeatures* f2=comb_feat->get_first_feature_obj();
89 
90  if (f1 && f2 && f1->check_feature_compatibility(f2))
91  {
92  SG_UNREF(f1);
93  SG_UNREF(f2);
94  while( ( (f1=this->get_next_feature_obj()) != NULL ) &&
95  ( (f2=comb_feat->get_next_feature_obj()) != NULL) )
96  {
97  if (!f1->check_feature_compatibility(f2))
98  {
99  SG_UNREF(f1);
100  SG_UNREF(f2);
101  SG_INFO( "not compatible, combfeat\n");
102  comb_feat->list_feature_objs();
103  SG_INFO( "vs this\n");
104  this->list_feature_objs();
105  return false;
106  }
107  SG_UNREF(f1);
108  SG_UNREF(f2);
109  }
110 
111  SG_DEBUG( "features are compatible\n");
112  result=true;
113  }
114  else
115  SG_WARNING( "first 2 features not compatible\n");
116  }
117  else
118  {
119  SG_WARNING( "number of features in combined feature objects differs (%d != %d)\n", this->get_num_feature_obj(), comb_feat->get_num_feature_obj());
120  SG_INFO( "compare\n");
121  comb_feat->list_feature_objs();
122  SG_INFO( "vs this\n");
123  this->list_feature_objs();
124  }
125 
126  return result;
127 }
128 
130 {
132 }
133 
135 {
136  return (CFeatures*) feature_list->get_first_element(current);
137 }
138 
140 {
142 }
143 
145 {
146  return (CFeatures*) feature_list->get_next_element(current);
147 }
148 
150 {
152 }
153 
155 {
156  ASSERT(obj);
157  int32_t n=obj->get_num_vectors();
158 
159  if (get_num_vectors()>0 && n!=get_num_vectors())
160  {
161  SG_ERROR("Number of feature vectors does not match (expected %d, "
162  "obj has %d)\n", get_num_vectors(), n);
163  }
164 
165  num_vec=n;
166  return feature_list->insert_element(obj);
167 }
168 
170 {
171  ASSERT(obj);
172  int32_t n=obj->get_num_vectors();
173 
174  if (get_num_vectors()>0 && n!=get_num_vectors())
175  {
176  SG_ERROR("Number of feature vectors does not match (expected %d, "
177  "obj has %d)\n", get_num_vectors(), n);
178  }
179 
180  num_vec=n;
181  return feature_list->append_element(obj);
182 }
183 
185 {
187  if (f)
188  {
189  SG_UNREF(f);
190  return true;
191  }
192  else
193  return false;
194 }
195 
197 {
198  return feature_list->get_num_elements();
199 }
200 
201 void CCombinedFeatures::init()
202 {
203  m_parameters->add(&num_vec, "num_vec",
204  "Number of vectors.");
206  "feature_list", "Feature list.");
207 }
208 
210 {
211  /* TODO, if all features are the same, only one copy should be created
212  * in memory */
213  SG_WARNING("Heiko Strathmann: FIXME, unefficient!\n");
214 
215  SG_DEBUG("entering %s::create_merged_copy()\n", get_name());
216  if (get_feature_type()!=other->get_feature_type() ||
217  get_feature_class()!=other->get_feature_class() ||
218  strcmp(get_name(), other->get_name()))
219  {
220  SG_ERROR("%s::create_merged_copy(): Features are of different type!\n",
221  get_name());
222  }
223 
224  CCombinedFeatures* casted=dynamic_cast<CCombinedFeatures*>(other);
225 
226  if (!casted)
227  {
228  SG_ERROR("%s::create_merged_copy(): Could not cast object of %s to "
229  "same type as %s\n",get_name(), other->get_name(), get_name());
230  }
231 
232  if (get_num_feature_obj()!=casted->get_num_feature_obj())
233  {
234  SG_ERROR("%s::create_merged_copy(): Only possible if both instances "
235  "have the same number of sub-feature-objects\n", get_name());
236  }
237 
238  CCombinedFeatures* result=new CCombinedFeatures();
239  CFeatures* current_this=get_first_feature_obj();
240  CFeatures* current_other=casted->get_first_feature_obj();
241  while (current_this)
242  {
243  result->append_feature_obj(
244  current_this->create_merged_copy(current_other));
245  SG_UNREF(current_this);
246  SG_UNREF(current_other);
247  current_this=get_next_feature_obj();
248  current_other=get_next_feature_obj();
249  }
250 
251  SG_DEBUG("leaving %s::create_merged_copy()\n", get_name());
252  return result;
253 }
254 
256 {
257  SG_DEBUG("entering %s::add_subset()\n", get_name());
258  CSet<CFeatures*>* processed=new CSet<CFeatures*>();
259 
260  CFeatures* current=get_first_feature_obj();
261  while (current)
262  {
263  if (!processed->contains(current))
264  {
265  /* remember that subset was added here */
266  current->add_subset(subset);
267  processed->add(current);
268  SG_DEBUG("adding subset to %s at %p\n",
269  current->get_name(), current);
270  }
271  SG_UNREF(current);
272  current=get_next_feature_obj();
273  }
274 
275  /* also add subset to local stack to have it for easy access */
276  m_subset_stack->add_subset(subset);
277 
279  SG_UNREF(processed);
280  SG_DEBUG("leaving %s::add_subset()\n", get_name());
281 }
282 
284 {
285  SG_DEBUG("entering %s::remove_subset()\n", get_name());
286  CSet<CFeatures*>* processed=new CSet<CFeatures*>();
287 
288  CFeatures* current=get_first_feature_obj();
289  while (current)
290  {
291  if (!processed->contains(current))
292  {
293  /* remember that subset was added here */
294  current->remove_subset();
295  processed->add(current);
296  SG_DEBUG("removing subset from %s at %p\n",
297  current->get_name(), current);
298  }
299  SG_UNREF(current);
300  current=get_next_feature_obj();
301  }
302 
303  /* also remove subset from local stack to have it for easy access */
305 
307  SG_UNREF(processed);
308  SG_DEBUG("leaving %s::remove_subset()\n", get_name());
309 }
310 
312 {
313  SG_DEBUG("entering %s::remove_all_subsets()\n", get_name());
314  CSet<CFeatures*>* processed=new CSet<CFeatures*>();
315 
316  CFeatures* current=get_first_feature_obj();
317  while (current)
318  {
319  if (!processed->contains(current))
320  {
321  /* remember that subset was added here */
322  current->remove_all_subsets();
323  processed->add(current);
324  SG_DEBUG("removing all subsets from %s at %p\n",
325  current->get_name(), current);
326  }
327  SG_UNREF(current);
328  current=get_next_feature_obj();
329  }
330 
331  /* also remove subsets from local stack to have it for easy access */
333 
335  SG_UNREF(processed);
336  SG_DEBUG("leaving %s::remove_all_subsets()\n", get_name());
337 }
338 
340 {
341  /* this is returned with the results of copy_subset of sub-features */
342  CCombinedFeatures* result=new CCombinedFeatures();
343 
344  /* map to only copy same feature objects once */
346  CFeatures* current=get_first_feature_obj();
347  while (current)
348  {
349  CFeatures* new_element=NULL;
350 
351  /* only copy if not done yet, otherwise, use old copy */
352  if (!processed->contains(current))
353  {
354  new_element=current->copy_subset(indices);
355  processed->add(current, new_element);
356  }
357  else
358  {
359  new_element=processed->get_element(current);
360 
361  /* has to be SG_REF'ed since it will be unrefed afterwards */
362  SG_REF(new_element);
363  }
364 
365  /* add to result */
366  result->append_feature_obj(new_element);
367 
368  /* clean up: copy_subset of SG_REF has to be undone */
369  SG_UNREF(new_element);
370 
371  SG_UNREF(current);
372  current=get_next_feature_obj();
373  }
374 
375  SG_UNREF(processed);
376 
377  SG_REF(result);
378  return result;
379 }

SHOGUN Machine Learning Toolbox - Documentation