SHOGUN  6.1.3
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  REQUIRE(
52  idx < get_num_feature_obj() && idx>=0, "Feature index (%d) must be within [%d, %d]",
53  idx, 0, get_num_feature_obj()-1);
54  return (CFeatures*) feature_array->get_element(idx);
55 }
56 
58 {
59  SG_INFO("BEGIN COMBINED FEATURES LIST - ")
60  this->list_feature_obj();
61 
62  for (index_t f_idx=0; f_idx<get_num_feature_obj(); f_idx++)
63  {
64  CFeatures* f = get_feature_obj(f_idx);
65  f->list_feature_obj();
66  SG_UNREF(f);
67  }
68 
69  SG_INFO("END COMBINED FEATURES LIST - ")
70 }
71 
73 {
74  bool result=false;
75 
76  if ( (comb_feat) && (this->get_num_feature_obj() == comb_feat->get_num_feature_obj()) )
77  {
78  for (index_t f_idx=0; f_idx<get_num_feature_obj(); f_idx++)
79  {
80  CFeatures* f1=this->get_feature_obj(f_idx);
81  CFeatures* f2=comb_feat->get_feature_obj(f_idx);
82 
83  if ( ! (f1 && f2 && f1->check_feature_compatibility(f2)) )
84  {
85  SG_UNREF(f1);
86  SG_UNREF(f2);
87  SG_INFO("not compatible, combfeat\n")
88  comb_feat->list_feature_objs();
89  SG_INFO("vs this\n")
90  this->list_feature_objs();
91  return false;
92  }
93 
94  SG_UNREF(f1);
95  SG_UNREF(f2);
96  }
97  SG_DEBUG("features are compatible\n")
98  result=true;
99  }
100  else
101  {
102  if (!comb_feat)
103  {
104  SG_WARNING("comb_feat is NULL \n");
105  }
106  else
107  {
108  SG_WARNING("number of features in combined feature objects differs (%d != %d)\n", this->get_num_feature_obj(), comb_feat->get_num_feature_obj())
109  SG_INFO("compare\n")
110  comb_feat->list_feature_objs();
111  SG_INFO("vs this\n")
112  this->list_feature_objs();
113  }
114  }
115 
116  return result;
117 }
118 
120 {
121  return get_feature_obj(0);
122 }
123 
125 {
127 }
128 
130 {
131  ASSERT(obj)
132  int32_t n=obj->get_num_vectors();
133 
134  if (get_num_vectors()>0 && n!=get_num_vectors())
135  {
136  SG_ERROR("Number of feature vectors does not match (expected %d, "
137  "obj has %d)\n", get_num_vectors(), n);
138  }
139 
140  num_vec=n;
141  return feature_array->insert_element(obj, idx);
142 }
143 
145 {
146  ASSERT(obj)
147  int32_t n=obj->get_num_vectors();
148 
149  if (get_num_vectors()>0 && n!=get_num_vectors())
150  {
151  SG_ERROR("Number of feature vectors does not match (expected %d, "
152  "obj has %d)\n", get_num_vectors(), n);
153  }
154 
155  num_vec=n;
156 
157  int num_feature_obj = get_num_feature_obj();
158  feature_array->push_back(obj);
159  return num_feature_obj+1 == feature_array->get_num_elements();
160 }
161 
163 {
164  return feature_array->delete_element(idx);
165 }
166 
168 {
170 }
171 
172 void CCombinedFeatures::init()
173 {
174  m_parameters->add(&num_vec, "num_vec",
175  "Number of vectors.");
177  "feature_array", "Feature array.");
178 }
179 
181 {
182  /* TODO, if all features are the same, only one copy should be created
183  * in memory */
184  SG_WARNING("Heiko Strathmann: FIXME, unefficient!\n")
185 
186  SG_DEBUG("entering %s::create_merged_copy()\n", get_name())
187  if (get_feature_type()!=other->get_feature_type() ||
188  get_feature_class()!=other->get_feature_class() ||
189  strcmp(get_name(), other->get_name()))
190  {
191  SG_ERROR("%s::create_merged_copy(): Features are of different type!\n",
192  get_name());
193  }
194 
195  CCombinedFeatures* casted=dynamic_cast<CCombinedFeatures*>(other);
196 
197  if (!casted)
198  {
199  SG_ERROR("%s::create_merged_copy(): Could not cast object of %s to "
200  "same type as %s\n",get_name(), other->get_name(), get_name());
201  }
202 
203  if (get_num_feature_obj()!=casted->get_num_feature_obj())
204  {
205  SG_ERROR("%s::create_merged_copy(): Only possible if both instances "
206  "have the same number of sub-feature-objects\n", get_name());
207  }
208 
209  CCombinedFeatures* result=new CCombinedFeatures();
210  for (index_t f_idx=0; f_idx<get_num_feature_obj(); f_idx++)
211  {
212  CFeatures* current_this=get_feature_obj(f_idx);
213  CFeatures* current_other=casted->get_feature_obj(f_idx);
214 
215  result->append_feature_obj(
216  current_this->create_merged_copy(current_other));
217  SG_UNREF(current_this);
218  SG_UNREF(current_other);
219  }
220 
221  SG_DEBUG("leaving %s::create_merged_copy()\n", get_name())
222  return result;
223 }
224 
226 {
227  SG_DEBUG("entering %s::add_subset()\n", get_name())
228  CSet<CFeatures*>* processed=new CSet<CFeatures*>();
229 
230  for (index_t f_idx=0; f_idx<get_num_feature_obj(); f_idx++)
231  {
232  CFeatures* current=get_feature_obj(f_idx);
233 
234  if (!processed->contains(current))
235  {
236  /* remember that subset was added here */
237  current->add_subset(subset);
238  processed->add(current);
239  SG_DEBUG("adding subset to %s at %p\n",
240  current->get_name(), current);
241  }
242  SG_UNREF(current);
243  }
244 
245  /* also add subset to local stack to have it for easy access */
246  m_subset_stack->add_subset(subset);
247 
249  SG_UNREF(processed);
250  SG_DEBUG("leaving %s::add_subset()\n", get_name())
251 }
252 
254 {
255  SG_DEBUG("entering %s::remove_subset()\n", get_name())
256  CSet<CFeatures*>* processed=new CSet<CFeatures*>();
257 
258  for (index_t f_idx=0; f_idx<get_num_feature_obj(); f_idx++)
259  {
260  CFeatures* current=get_feature_obj(f_idx);
261  if (!processed->contains(current))
262  {
263  /* remember that subset was added here */
264  current->remove_subset();
265  processed->add(current);
266  SG_DEBUG("removing subset from %s at %p\n",
267  current->get_name(), current);
268  }
269  SG_UNREF(current);
270  }
271 
272  /* also remove subset from local stack to have it for easy access */
274 
276  SG_UNREF(processed);
277  SG_DEBUG("leaving %s::remove_subset()\n", get_name())
278 }
279 
281 {
282  SG_DEBUG("entering %s::remove_all_subsets()\n", get_name())
283  CSet<CFeatures*>* processed=new CSet<CFeatures*>();
284 
285  for (index_t f_idx=0; f_idx<get_num_feature_obj(); f_idx++)
286  {
287  CFeatures* current=get_feature_obj(f_idx);
288  if (!processed->contains(current))
289  {
290  /* remember that subset was added here */
291  current->remove_all_subsets();
292  processed->add(current);
293  SG_DEBUG("removing all subsets from %s at %p\n",
294  current->get_name(), current);
295  }
296  SG_UNREF(current);
297  }
298 
299  /* also remove subsets from local stack to have it for easy access */
301 
303  SG_UNREF(processed);
304  SG_DEBUG("leaving %s::remove_all_subsets()\n", get_name())
305 }
306 
308 {
309  /* this is returned with the results of copy_subset of sub-features */
310  CCombinedFeatures* result=new CCombinedFeatures();
311 
312  /* map to only copy same feature objects once */
314  for (index_t f_idx=0; f_idx<get_num_feature_obj(); f_idx++)
315  {
316  CFeatures* current=get_feature_obj(f_idx);
317 
318  CFeatures* new_element=NULL;
319 
320  /* only copy if not done yet, otherwise, use old copy */
321  if (!processed->contains(current))
322  {
323  new_element=current->copy_subset(indices);
324  processed->add(current, new_element);
325  }
326  else
327  {
328  new_element=processed->get_element(current);
329 
330  /* has to be SG_REF'ed since it will be unrefed afterwards */
331  SG_REF(new_element);
332  }
333 
334  /* add to result */
335  result->append_feature_obj(new_element);
336 
337  /* clean up: copy_subset of SG_REF has to be undone */
338  SG_UNREF(new_element);
339 
340  SG_UNREF(current);
341  }
342 
343  SG_UNREF(processed);
344 
345  SG_REF(result);
346  return result;
347 }
virtual const char * get_name() const =0
bool contains(const T &element)
Definition: Set.h:123
CSubsetStack * m_subset_stack
Definition: Features.h:378
#define SG_INFO(...)
Definition: SGIO.h:117
virtual EFeatureType get_feature_type() const
virtual void add_subset(SGVector< index_t > subset)
int32_t index_t
Definition: common.h:72
bool insert_element(CSGObject *e, int32_t index)
virtual int32_t get_num_vectors() const =0
bool contains(const K &key)
Definition: Map.h:122
#define SG_ERROR(...)
Definition: SGIO.h:128
#define REQUIRE(x,...)
Definition: SGIO.h:181
CDynamicObjectArray * feature_array
Parameter * m_parameters
Definition: SGObject.h:609
#define SG_REF(x)
Definition: SGObject.h:52
virtual CFeatures * copy_subset(SGVector< index_t > indices)
T get_element(const K &key)
Definition: Map.h:171
virtual CFeatures * create_merged_copy(CList *others)
Definition: Features.h:252
virtual void subset_changed_post()
Definition: Features.h:310
void add(bool *param, const char *name, const char *description="")
Definition: Parameter.cpp:38
bool check_feature_compatibility(CFeatures *f) const
Definition: Features.cpp:283
void list_feature_obj() const
Definition: Features.cpp:171
virtual void add_subset(SGVector< index_t > subset)
Definition: SubsetStack.cpp:84
#define ASSERT(x)
Definition: SGIO.h:176
Class SGObject is the base class of all shogun objects.
Definition: SGObject.h:124
the class CSet, a set based on the hash-table. w: http://en.wikipedia.org/wiki/Hash_table ...
Definition: Set.h:51
virtual void remove_all_subsets()
Definition: SubsetStack.cpp:62
virtual int32_t get_num_vectors() const
virtual EFeatureClass get_feature_class() const
virtual CFeatures * duplicate() const
the class CMap, a map based on the hash-table. w: http://en.wikipedia.org/wiki/Hash_table ...
Definition: SGObject.h:42
CFeatures * get_feature_obj(int32_t idx)
virtual EFeatureClass get_feature_class() const =0
Dynamic array class for CSGObject pointers that creates an array that can be used like a list or an a...
CFeatures * create_merged_copy(CFeatures *other)
bool check_feature_obj_compatibility(CCombinedFeatures *comb_feat)
bool insert_feature_obj(CFeatures *obj, int32_t idx)
#define SG_UNREF(x)
Definition: SGObject.h:53
#define SG_DEBUG(...)
Definition: SGIO.h:106
all of classes and functions are contained in the shogun namespace
Definition: class_list.h:18
int32_t add(const K &key, const T &data)
Definition: Map.h:101
virtual void remove_subset()
Definition: Features.cpp:322
virtual CFeatures * copy_subset(SGVector< index_t > indices)
Definition: Features.cpp:340
The class Features is the base class of all feature objects.
Definition: Features.h:69
void add(const T &element)
Definition: Set.h:109
CSGObject * get_element(int32_t index) const
virtual const char * get_name() const
virtual void remove_subset()
#define SG_WARNING(...)
Definition: SGIO.h:127
The class CombinedFeatures is used to combine a number of of feature objects into a single CombinedFe...
virtual void remove_all_subsets()
Definition: Features.cpp:328
bool delete_feature_obj(int32_t idx)
virtual void add_subset(SGVector< index_t > subset)
Definition: Features.cpp:310
virtual EFeatureType get_feature_type() const =0
bool append_feature_obj(CFeatures *obj)

SHOGUN Machine Learning Toolbox - Documentation