SHOGUN  3.2.1
 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  if (!comb_feat)
100  {
101  SG_WARNING("comb_feat is NULL \n");
102  }
103  else
104  {
105  SG_WARNING("number of features in combined feature objects differs (%d != %d)\n", this->get_num_feature_obj(), comb_feat->get_num_feature_obj())
106  SG_INFO("compare\n")
107  comb_feat->list_feature_objs();
108  SG_INFO("vs this\n")
109  this->list_feature_objs();
110  }
111  }
112 
113  return result;
114 }
115 
117 {
118  return get_feature_obj(0);
119 }
120 
122 {
124 }
125 
127 {
128  ASSERT(obj)
129  int32_t n=obj->get_num_vectors();
130 
131  if (get_num_vectors()>0 && n!=get_num_vectors())
132  {
133  SG_ERROR("Number of feature vectors does not match (expected %d, "
134  "obj has %d)\n", get_num_vectors(), n);
135  }
136 
137  num_vec=n;
138  return feature_array->insert_element(obj, idx);
139 }
140 
142 {
143  ASSERT(obj)
144  int32_t n=obj->get_num_vectors();
145 
146  if (get_num_vectors()>0 && n!=get_num_vectors())
147  {
148  SG_ERROR("Number of feature vectors does not match (expected %d, "
149  "obj has %d)\n", get_num_vectors(), n);
150  }
151 
152  num_vec=n;
153 
154  int num_feature_obj = get_num_feature_obj();
155  feature_array->push_back(obj);
156  return num_feature_obj+1 == feature_array->get_num_elements();
157 }
158 
160 {
161  return feature_array->delete_element(idx);
162 }
163 
165 {
167 }
168 
169 void CCombinedFeatures::init()
170 {
171  m_parameters->add(&num_vec, "num_vec",
172  "Number of vectors.");
174  "feature_array", "Feature array.");
175 }
176 
178 {
179  /* TODO, if all features are the same, only one copy should be created
180  * in memory */
181  SG_WARNING("Heiko Strathmann: FIXME, unefficient!\n")
182 
183  SG_DEBUG("entering %s::create_merged_copy()\n", get_name())
184  if (get_feature_type()!=other->get_feature_type() ||
185  get_feature_class()!=other->get_feature_class() ||
186  strcmp(get_name(), other->get_name()))
187  {
188  SG_ERROR("%s::create_merged_copy(): Features are of different type!\n",
189  get_name());
190  }
191 
192  CCombinedFeatures* casted=dynamic_cast<CCombinedFeatures*>(other);
193 
194  if (!casted)
195  {
196  SG_ERROR("%s::create_merged_copy(): Could not cast object of %s to "
197  "same type as %s\n",get_name(), other->get_name(), get_name());
198  }
199 
200  if (get_num_feature_obj()!=casted->get_num_feature_obj())
201  {
202  SG_ERROR("%s::create_merged_copy(): Only possible if both instances "
203  "have the same number of sub-feature-objects\n", get_name());
204  }
205 
206  CCombinedFeatures* result=new CCombinedFeatures();
207  for (index_t f_idx=0; f_idx<get_num_feature_obj(); f_idx++)
208  {
209  CFeatures* current_this=get_feature_obj(f_idx);
210  CFeatures* current_other=casted->get_feature_obj(f_idx);
211 
212  result->append_feature_obj(
213  current_this->create_merged_copy(current_other));
214  SG_UNREF(current_this);
215  SG_UNREF(current_other);
216  }
217 
218  SG_DEBUG("leaving %s::create_merged_copy()\n", get_name())
219  return result;
220 }
221 
223 {
224  SG_DEBUG("entering %s::add_subset()\n", get_name())
225  CSet<CFeatures*>* processed=new CSet<CFeatures*>();
226 
227  for (index_t f_idx=0; f_idx<get_num_feature_obj(); f_idx++)
228  {
229  CFeatures* current=get_feature_obj(f_idx);
230 
231  if (!processed->contains(current))
232  {
233  /* remember that subset was added here */
234  current->add_subset(subset);
235  processed->add(current);
236  SG_DEBUG("adding subset to %s at %p\n",
237  current->get_name(), current);
238  }
239  SG_UNREF(current);
240  }
241 
242  /* also add subset to local stack to have it for easy access */
243  m_subset_stack->add_subset(subset);
244 
246  SG_UNREF(processed);
247  SG_DEBUG("leaving %s::add_subset()\n", get_name())
248 }
249 
251 {
252  SG_DEBUG("entering %s::remove_subset()\n", get_name())
253  CSet<CFeatures*>* processed=new CSet<CFeatures*>();
254 
255  for (index_t f_idx=0; f_idx<get_num_feature_obj(); f_idx++)
256  {
257  CFeatures* current=get_feature_obj(f_idx);
258  if (!processed->contains(current))
259  {
260  /* remember that subset was added here */
261  current->remove_subset();
262  processed->add(current);
263  SG_DEBUG("removing subset from %s at %p\n",
264  current->get_name(), current);
265  }
266  SG_UNREF(current);
267  }
268 
269  /* also remove subset from local stack to have it for easy access */
271 
273  SG_UNREF(processed);
274  SG_DEBUG("leaving %s::remove_subset()\n", get_name())
275 }
276 
278 {
279  SG_DEBUG("entering %s::remove_all_subsets()\n", get_name())
280  CSet<CFeatures*>* processed=new CSet<CFeatures*>();
281 
282  for (index_t f_idx=0; f_idx<get_num_feature_obj(); f_idx++)
283  {
284  CFeatures* current=get_feature_obj(f_idx);
285  if (!processed->contains(current))
286  {
287  /* remember that subset was added here */
288  current->remove_all_subsets();
289  processed->add(current);
290  SG_DEBUG("removing all subsets from %s at %p\n",
291  current->get_name(), current);
292  }
293  SG_UNREF(current);
294  }
295 
296  /* also remove subsets from local stack to have it for easy access */
298 
300  SG_UNREF(processed);
301  SG_DEBUG("leaving %s::remove_all_subsets()\n", get_name())
302 }
303 
305 {
306  /* this is returned with the results of copy_subset of sub-features */
307  CCombinedFeatures* result=new CCombinedFeatures();
308 
309  /* map to only copy same feature objects once */
311  for (index_t f_idx=0; f_idx<get_num_feature_obj(); f_idx++)
312  {
313  CFeatures* current=get_feature_obj(f_idx);
314 
315  CFeatures* new_element=NULL;
316 
317  /* only copy if not done yet, otherwise, use old copy */
318  if (!processed->contains(current))
319  {
320  new_element=current->copy_subset(indices);
321  processed->add(current, new_element);
322  }
323  else
324  {
325  new_element=processed->get_element(current);
326 
327  /* has to be SG_REF'ed since it will be unrefed afterwards */
328  SG_REF(new_element);
329  }
330 
331  /* add to result */
332  result->append_feature_obj(new_element);
333 
334  /* clean up: copy_subset of SG_REF has to be undone */
335  SG_UNREF(new_element);
336 
337  SG_UNREF(current);
338  }
339 
340  SG_UNREF(processed);
341 
342  SG_REF(result);
343  return result;
344 }

SHOGUN Machine Learning Toolbox - Documentation