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
kernel
ProductKernel.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
* Copyright (C) 2012 Jacob Walker
8
*
9
* Code adapted from CCombinedKernel
10
*/
11
12
#include <
shogun/kernel/ProductKernel.h
>
13
#include <
shogun/kernel/CustomKernel.h
>
14
15
using namespace
shogun;
16
17
CProductKernel::CProductKernel
(int32_t size) :
CKernel
(size)
18
{
19
init
();
20
21
SG_INFO
(
"Product kernel created (%p)\n"
,
this
)
22
}
23
24
CProductKernel::~CProductKernel
()
25
{
26
cleanup
();
27
SG_UNREF
(
kernel_array
);
28
29
SG_INFO
(
"Product kernel deleted (%p).\n"
,
this
)
30
}
31
32
//Adapted from CCombinedKernel
33
bool
CProductKernel::init(
CFeatures
* l,
CFeatures
* r)
34
{
35
CKernel::init(l,r);
36
ASSERT
(l->
get_feature_class
()==
C_COMBINED
)
37
ASSERT
(r->
get_feature_class
()==
C_COMBINED
)
38
ASSERT
(l->
get_feature_type
()==
F_UNKNOWN
)
39
ASSERT
(r->
get_feature_type
()==
F_UNKNOWN
)
40
41
CFeatures
* lf=NULL;
42
CFeatures
* rf=NULL;
43
CKernel
* k=NULL;
44
45
bool
result=
true
;
46
47
index_t
f_idx=0;
48
for
(
index_t
k_idx=0; k_idx<
get_num_subkernels
() && result; k_idx++)
49
{
50
k=
get_kernel
(k_idx);
51
if
(!k)
52
SG_ERROR
(
"Kernel at position %d is NULL\n"
, k_idx);
53
54
// skip over features - the custom kernel does not need any
55
if
(k->
get_kernel_type
() !=
K_CUSTOM
)
56
{
57
lf=((
CCombinedFeatures
*) l)->get_feature_obj(f_idx);
58
rf=((
CCombinedFeatures
*) r)->get_feature_obj(f_idx);
59
f_idx++;
60
if
(!lf || !rf)
61
{
62
SG_UNREF
(lf);
63
SG_UNREF
(rf);
64
SG_UNREF
(k);
65
SG_ERROR
(
"ProductKernel: Number of features/kernels does not match - bailing out\n"
)
66
}
67
68
SG_DEBUG
(
"Initializing 0x%p - \"%s\"\n"
,
this
, k->
get_name
())
69
result=k->
init
(lf,rf);
70
71
SG_UNREF
(lf);
72
SG_UNREF
(rf);
73
74
if
(!result)
75
break
;
76
}
77
else
78
{
79
SG_DEBUG
(
"Initializing 0x%p - \"%s\" (skipping init, this is a CUSTOM kernel)\n"
,
this
, k->
get_name
())
80
if
(!k->
has_features
())
81
SG_ERROR
(
"No kernel matrix was assigned to this Custom kernel\n"
)
82
if
(k->
get_num_vec_lhs
() !=
num_lhs
)
83
SG_ERROR
(
"Number of lhs-feature vectors (%d) not match with number of rows (%d) of custom kernel\n"
,
num_lhs
, k->
get_num_vec_lhs
())
84
if
(k->
get_num_vec_rhs
() !=
num_rhs
)
85
SG_ERROR
(
"Number of rhs-feature vectors (%d) not match with number of cols (%d) of custom kernel\n"
,
num_rhs
, k->
get_num_vec_rhs
())
86
}
87
88
SG_UNREF
(k);
89
}
90
91
if
(!result)
92
{
93
SG_INFO
(
"ProductKernel: Initialising the following kernel failed\n"
)
94
if
(k)
95
{
96
k->
list_kernel
();
97
SG_UNREF
(k);
98
}
99
else
100
SG_INFO
(
"<NULL>\n"
)
101
return
false
;
102
}
103
104
if
( (f_idx!=((
CCombinedFeatures
*) l)->get_num_feature_obj()) ||
105
(f_idx!=((
CCombinedFeatures
*) r)->get_num_feature_obj()) )
106
SG_ERROR
(
"ProductKernel: Number of features/kernels does not match - bailing out\n"
)
107
108
initialized
=
true
;
109
return
true
;
110
}
111
112
//Adapted from CCombinedKernel
113
void
CProductKernel::remove_lhs
()
114
{
115
for
(
index_t
k_idx=0; k_idx<
get_num_subkernels
(); k_idx++)
116
{
117
CKernel
* k=
get_kernel
(k_idx);
118
if
(k->
get_kernel_type
() !=
K_CUSTOM
)
119
k->
remove_lhs
();
120
121
SG_UNREF
(k);
122
}
123
CKernel::remove_lhs
();
124
125
num_lhs
=0;
126
}
127
128
//Adapted from CCombinedKernel
129
void
CProductKernel::remove_rhs
()
130
{
131
for
(
index_t
k_idx=0; k_idx<
get_num_subkernels
(); k_idx++)
132
{
133
CKernel
* k=
get_kernel
(k_idx);
134
if
(k->
get_kernel_type
() !=
K_CUSTOM
)
135
k->
remove_rhs
();
136
SG_UNREF
(k);
137
}
138
CKernel::remove_rhs
();
139
140
num_rhs
=0;
141
}
142
143
//Adapted from CCombinedKernel
144
void
CProductKernel::remove_lhs_and_rhs
()
145
{
146
for
(
index_t
k_idx=0; k_idx<
get_num_subkernels
(); k_idx++)
147
{
148
CKernel
* k=
get_kernel
(k_idx);
149
if
(k->
get_kernel_type
() !=
K_CUSTOM
)
150
k->
remove_lhs_and_rhs
();
151
SG_UNREF
(k);
152
}
153
154
CKernel::remove_lhs_and_rhs
();
155
156
num_lhs
=0;
157
num_rhs
=0;
158
}
159
160
//Adapted from CCombinedKernel
161
void
CProductKernel::cleanup
()
162
{
163
for
(
index_t
k_idx=0; k_idx<
get_num_subkernels
(); k_idx++)
164
{
165
CKernel
* k=
get_kernel
(k_idx);
166
k->
cleanup
();
167
SG_UNREF
(k);
168
}
169
170
CKernel::cleanup
();
171
172
num_lhs
=0;
173
num_rhs
=0;
174
}
175
176
//Adapted from CCombinedKernel
177
void
CProductKernel::list_kernels
()
178
{
179
SG_INFO
(
"BEGIN PRODUCT KERNEL LIST - "
)
180
this->
list_kernel
();
181
182
for
(
index_t
k_idx=0; k_idx<
get_num_subkernels
(); k_idx++)
183
{
184
CKernel
* k=
get_kernel
(k_idx);
185
k->
list_kernel
();
186
SG_UNREF
(k);
187
}
188
SG_INFO
(
"END PRODUCT KERNEL LIST - "
)
189
}
190
191
//Adapted from CCombinedKernel
192
float64_t
CProductKernel::compute
(int32_t x, int32_t y)
193
{
194
float64_t
result=1;
195
for
(
index_t
k_idx=0; k_idx<
get_num_subkernels
(); k_idx++)
196
{
197
CKernel
* k=
get_kernel
(k_idx);
198
result *= k->
get_combined_kernel_weight
() * k->
kernel
(x,y);
199
SG_UNREF
(k);
200
}
201
202
return
result;
203
}
204
205
//Adapted from CCombinedKernel
206
bool
CProductKernel::precompute_subkernels
()
207
{
208
if
(
get_num_subkernels
()==0)
209
return
false
;
210
211
CDynamicObjectArray
* new_kernel_array=
new
CDynamicObjectArray
();
212
213
for
(
index_t
k_idx=0; k_idx<
get_num_subkernels
(); k_idx++)
214
{
215
CKernel
* k=
get_kernel
(k_idx);
216
new_kernel_array->
append_element
(
new
CCustomKernel
(k));
217
SG_UNREF
(k);
218
}
219
220
SG_UNREF
(
kernel_array
);
221
kernel_array
=new_kernel_array;
222
SG_REF
(
kernel_array
);
223
224
return
true
;
225
}
226
227
void
CProductKernel::init()
228
{
229
initialized
=
false
;
230
231
properties
=
KP_NONE
;
232
kernel_array
=
new
CDynamicObjectArray
();
233
SG_REF
(
kernel_array
);
234
235
SG_ADD
((
CSGObject
**) &
kernel_array
,
"kernel_array"
,
"Array of kernels"
,
236
MS_AVAILABLE
);
237
SG_ADD
(&
initialized
,
"initialized"
,
"Whether kernel is ready to be used"
,
238
MS_NOT_AVAILABLE
);
239
}
240
241
SGMatrix<float64_t>
CProductKernel::get_parameter_gradient
(
242
const
TParameter
* param,
index_t
index)
243
{
244
CKernel
* k=
get_kernel
(0);
245
SGMatrix<float64_t>
temp_kernel=k->
get_kernel_matrix
();
246
SG_UNREF
(k);
247
248
bool
found_derivative=
false
;
249
250
for
(
index_t
g=0; g<temp_kernel.
num_rows
; g++)
251
{
252
for
(
int
h=0; h<temp_kernel.
num_cols
; h++)
253
temp_kernel(g,h)=1.0;
254
}
255
256
for
(
index_t
k_idx=0; k_idx<
get_num_subkernels
(); k_idx++)
257
{
258
k=
get_kernel
(k_idx);
259
SGMatrix<float64_t>
cur_matrix=k->
get_kernel_matrix
();
260
SGMatrix<float64_t>
derivative=
261
k->
get_parameter_gradient
(param, index);
262
263
if
(derivative.
num_cols
*derivative.
num_rows
> 0)
264
{
265
found_derivative=
true
;
266
for
(
index_t
g=0; g<derivative.
num_rows
; g++)
267
{
268
for
(
index_t
h=0; h<derivative.
num_cols
; h++)
269
temp_kernel(g,h)*=derivative(g,h);
270
}
271
}
272
else
273
{
274
for
(
index_t
g=0; g<cur_matrix.
num_rows
; g++)
275
{
276
for
(
index_t
h=0; h<cur_matrix.
num_cols
; h++)
277
temp_kernel(g,h)*=cur_matrix(g,h);
278
}
279
}
280
281
SG_UNREF
(k);
282
}
283
284
if
(found_derivative)
285
return
temp_kernel;
286
else
287
return
SGMatrix<float64_t>
();
288
}
SHOGUN
Machine Learning Toolbox - Documentation