SHOGUN
v2.0.0
Main Page
Related Pages
Modules
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Groups
Pages
src
shogun
features
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
13
#include <
shogun/features/CombinedFeatures.h
>
14
#include <
shogun/io/SGIO.h
>
15
#include <
shogun/lib/Set.h
>
16
#include <
shogun/lib/Map.h
>
17
18
using namespace
shogun;
19
20
CCombinedFeatures::CCombinedFeatures
()
21
:
CFeatures
(0)
22
{
23
init();
24
25
feature_list
=
new
CList
(
true
);
26
num_vec
=0;
27
}
28
29
CCombinedFeatures::CCombinedFeatures
(
const
CCombinedFeatures
& orig)
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
39
CFeatures
*
CCombinedFeatures::duplicate
()
const
40
{
41
return
new
CCombinedFeatures
(*
this
);
42
}
43
44
CCombinedFeatures::~CCombinedFeatures
()
45
{
46
SG_UNREF
(
feature_list
);
47
}
48
49
int32_t
CCombinedFeatures::get_size
()
const
50
{
51
CFeatures
* f=(
CFeatures
*)
feature_list
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
63
void
CCombinedFeatures::list_feature_objs
()
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
81
bool
CCombinedFeatures::check_feature_obj_compatibility
(
CCombinedFeatures
* comb_feat)
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
129
CFeatures
*
CCombinedFeatures::get_first_feature_obj
()
130
{
131
return
(
CFeatures
*)
feature_list
->
get_first_element
();
132
}
133
134
CFeatures
*
CCombinedFeatures::get_first_feature_obj
(
CListElement
*& current)
135
{
136
return
(
CFeatures
*)
feature_list
->
get_first_element
(current);
137
}
138
139
CFeatures
*
CCombinedFeatures::get_next_feature_obj
()
140
{
141
return
(
CFeatures
*)
feature_list
->
get_next_element
();
142
}
143
144
CFeatures
*
CCombinedFeatures::get_next_feature_obj
(
CListElement
*& current)
145
{
146
return
(
CFeatures
*)
feature_list
->
get_next_element
(current);
147
}
148
149
CFeatures
*
CCombinedFeatures::get_last_feature_obj
()
150
{
151
return
(
CFeatures
*)
feature_list
->
get_last_element
();
152
}
153
154
bool
CCombinedFeatures::insert_feature_obj
(
CFeatures
* obj)
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
169
bool
CCombinedFeatures::append_feature_obj
(
CFeatures
* obj)
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
184
bool
CCombinedFeatures::delete_feature_obj
()
185
{
186
CFeatures
* f=(
CFeatures
*)
feature_list
->
delete_element
();
187
if
(f)
188
{
189
SG_UNREF
(f);
190
return
true
;
191
}
192
else
193
return
false
;
194
}
195
196
int32_t
CCombinedFeatures::get_num_feature_obj
()
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."
);
205
m_parameters
->
add
((
CSGObject
**) &
feature_list
,
206
"feature_list"
,
"Feature list."
);
207
}
208
209
CFeatures
*
CCombinedFeatures::create_merged_copy
(
CFeatures
* other)
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
255
void
CCombinedFeatures::add_subset
(
SGVector<index_t>
subset)
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
278
subset_changed_post
();
279
SG_UNREF
(processed);
280
SG_DEBUG
(
"leaving %s::add_subset()\n"
,
get_name
());
281
}
282
283
void
CCombinedFeatures::remove_subset
()
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 */
304
m_subset_stack
->
remove_subset
();
305
306
subset_changed_post
();
307
SG_UNREF
(processed);
308
SG_DEBUG
(
"leaving %s::remove_subset()\n"
,
get_name
());
309
}
310
311
void
CCombinedFeatures::remove_all_subsets
()
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 */
332
m_subset_stack
->
remove_all_subsets
();
333
334
subset_changed_post
();
335
SG_UNREF
(processed);
336
SG_DEBUG
(
"leaving %s::remove_all_subsets()\n"
,
get_name
());
337
}
338
339
CFeatures
*
CCombinedFeatures::copy_subset
(
SGVector<index_t>
indices)
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 */
345
CMap<CFeatures*, CFeatures*>
* processed=
new
CMap<CFeatures*, CFeatures*>
();
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