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