SHOGUN
3.2.1
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_array
=
new
CDynamicObjectArray
();
26
num_vec
=0;
27
}
28
29
CCombinedFeatures::CCombinedFeatures
(
const
CCombinedFeatures
& orig)
30
:
CFeatures
(0)
31
{
32
init();
33
34
feature_array
=
new
CDynamicObjectArray
();
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_array
);
47
}
48
49
CFeatures
*
CCombinedFeatures::get_feature_obj
(int32_t idx)
50
{
51
return
(
CFeatures
*)
feature_array
->
get_element
(idx);
52
}
53
54
void
CCombinedFeatures::list_feature_objs
()
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
69
bool
CCombinedFeatures::check_feature_obj_compatibility
(
CCombinedFeatures
* comb_feat)
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
116
CFeatures
*
CCombinedFeatures::get_first_feature_obj
()
117
{
118
return
get_feature_obj
(0);
119
}
120
121
CFeatures
*
CCombinedFeatures::get_last_feature_obj
()
122
{
123
return
get_feature_obj
(
get_num_feature_obj
()-1);
124
}
125
126
bool
CCombinedFeatures::insert_feature_obj
(
CFeatures
* obj, int32_t idx)
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
141
bool
CCombinedFeatures::append_feature_obj
(
CFeatures
* obj)
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
159
bool
CCombinedFeatures::delete_feature_obj
(int32_t idx)
160
{
161
return
feature_array
->
delete_element
(idx);
162
}
163
164
int32_t
CCombinedFeatures::get_num_feature_obj
()
165
{
166
return
feature_array
->
get_num_elements
();
167
}
168
169
void
CCombinedFeatures::init()
170
{
171
m_parameters
->
add
(&
num_vec
,
"num_vec"
,
172
"Number of vectors."
);
173
m_parameters
->
add
((
CSGObject
**) &
feature_array
,
174
"feature_array"
,
"Feature array."
);
175
}
176
177
CFeatures
*
CCombinedFeatures::create_merged_copy
(
CFeatures
* other)
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
222
void
CCombinedFeatures::add_subset
(
SGVector<index_t>
subset)
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
245
subset_changed_post
();
246
SG_UNREF
(processed);
247
SG_DEBUG
(
"leaving %s::add_subset()\n"
,
get_name
())
248
}
249
250
void
CCombinedFeatures::remove_subset
()
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 */
270
m_subset_stack
->
remove_subset
();
271
272
subset_changed_post
();
273
SG_UNREF
(processed);
274
SG_DEBUG
(
"leaving %s::remove_subset()\n"
,
get_name
())
275
}
276
277
void
CCombinedFeatures::remove_all_subsets
()
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 */
297
m_subset_stack
->
remove_all_subsets
();
298
299
subset_changed_post
();
300
SG_UNREF
(processed);
301
SG_DEBUG
(
"leaving %s::remove_all_subsets()\n"
,
get_name
())
302
}
303
304
CFeatures
*
CCombinedFeatures::copy_subset
(
SGVector<index_t>
indices)
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 */
310
CMap<CFeatures*, CFeatures*>
* processed=
new
CMap<CFeatures*, CFeatures*>
();
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