aboutsummaryrefslogtreecommitdiff
path: root/src/gensvm_kernel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gensvm_kernel.c')
-rw-r--r--src/gensvm_kernel.c94
1 files changed, 40 insertions, 54 deletions
diff --git a/src/gensvm_kernel.c b/src/gensvm_kernel.c
index 8f0b6da..a25fcfd 100644
--- a/src/gensvm_kernel.c
+++ b/src/gensvm_kernel.c
@@ -46,29 +46,10 @@
void gensvm_kernel_copy_kernelparam_to_data(struct GenModel *model,
struct GenData *data)
{
- int i;
data->kerneltype = model->kerneltype;
-
- free(data->kernelparam);
- data->kernelparam = NULL;
-
- switch (model->kerneltype) {
- case K_LINEAR:
- break;
- case K_POLY:
- data->kernelparam = Calloc(double, 3);
- for (i=0; i<3; i++)
- data->kernelparam[i] = model->kernelparam[i];
- break;
- case K_RBF:
- data->kernelparam = Calloc(double, 1);
- data->kernelparam[0] = model->kernelparam[0];
- break;
- case K_SIGMOID:
- data->kernelparam = Calloc(double, 2);
- data->kernelparam[0] = model->kernelparam[0];
- data->kernelparam[1] = model->kernelparam[1];
- }
+ data->gamma = model->gamma;
+ data->coef = model->coef;
+ data->degree = model->degree;
}
@@ -188,14 +169,16 @@ void gensvm_kernel_compute(struct GenModel *model, struct GenData *data,
x1 = &data->RAW[i*(data->m+1)+1];
x2 = &data->RAW[j*(data->m+1)+1];
if (model->kerneltype == K_POLY)
- value = gensvm_kernel_dot_poly(x1, x2,
- model->kernelparam, data->m);
+ value = gensvm_kernel_dot_poly(x1, x2, data->m,
+ model->gamma, model->coef,
+ model->degree);
else if (model->kerneltype == K_RBF)
- value = gensvm_kernel_dot_rbf(x1, x2,
- model->kernelparam, data->m);
+ value = gensvm_kernel_dot_rbf(x1, x2, data->m,
+ model-> gamma);
else if (model->kerneltype == K_SIGMOID)
- value = gensvm_kernel_dot_sigmoid(x1, x2,
- model->kernelparam, data->m);
+ value = gensvm_kernel_dot_sigmoid(x1, x2,
+ data->m, model->gamma,
+ model->coef);
else {
// LCOV_EXCL_START
err("[GenSVM Error]: Unknown kernel type in "
@@ -342,14 +325,15 @@ double *gensvm_kernel_cross(struct GenModel *model, struct GenData *data_train,
x1 = &data_test->RAW[i*(m+1)+1];
x2 = &data_train->RAW[j*(m+1)+1];
if (model->kerneltype == K_POLY)
- value = gensvm_kernel_dot_poly(x1, x2,
- model->kernelparam, m);
+ value = gensvm_kernel_dot_poly(x1, x2, m,
+ model->gamma, model->coef,
+ model->degree);
else if (model->kerneltype == K_RBF)
- value = gensvm_kernel_dot_rbf(x1, x2,
- model->kernelparam, m);
+ value = gensvm_kernel_dot_rbf(x1, x2, m,
+ model->gamma);
else if (model->kerneltype == K_SIGMOID)
- value = gensvm_kernel_dot_sigmoid(x1, x2,
- model->kernelparam, m);
+ value = gensvm_kernel_dot_sigmoid(x1, x2, m,
+ model->gamma, model->coef);
else {
// LCOV_EXCL_START
err("[GenSVM Error]: Unknown kernel type in "
@@ -482,20 +466,18 @@ void gensvm_kernel_testfactor(struct GenData *testdata,
*
* @param[in] x1 first vector
* @param[in] x2 second vector
- * @param[in] kernelparam array of kernel parameters (gamma is first
- * element)
* @param[in] n length of the vectors x1 and x2
+ * @param[in] gamma gamma parameter of the kernel
* @returns kernel evaluation
*/
-double gensvm_kernel_dot_rbf(double *x1, double *x2, double *kernelparam,
- long n)
+double gensvm_kernel_dot_rbf(double *x1, double *x2, long n, double gamma)
{
long i;
double value = 0.0;
for (i=0; i<n; i++)
value += (x1[i] - x2[i]) * (x1[i] - x2[i]);
- value *= -kernelparam[0];
+ value *= -gamma;
return exp(value);
}
@@ -506,23 +488,26 @@ double gensvm_kernel_dot_rbf(double *x1, double *x2, double *kernelparam,
* The polynomial kernel is computed between two vectors. This kernel is
* defined as
* @f[
- * k(x_1, x_2) = ( \gamma \langle x_1, x_2 \rangle + c)^d
+ * k(x_1, x_2) = ( \gamma \langle x_1, x_2 \rangle + coef)^{degree}
* @f]
- * where @f$ \gamma @f$, @f$ c @f$ and @f$ d @f$ are kernel parameters.
+ * where @f$ \gamma @f$, @f$ coef @f$ and @f$ degree @f$ are kernel
+ * parameters.
*
* @param[in] x1 first vector
* @param[in] x2 second vector
- * @param[in] kernelparam array of kernel parameters (gamma, c, d)
* @param[in] n length of the vectors x1 and x2
+ * @param[in] gamma gamma parameter of the kernel
+ * @param[in] coef coef parameter of the kernel
+ * @param[in] degree degree parameter of the kernel
* @returns kernel evaluation
*/
-double gensvm_kernel_dot_poly(double *x1, double *x2, double *kernelparam,
- long n)
+double gensvm_kernel_dot_poly(double *x1, double *x2, long n, double gamma,
+ double coef, double degree)
{
double value = cblas_ddot(n, x1, 1, x2, 1);
- value *= kernelparam[0];
- value += kernelparam[1];
- return pow(value, kernelparam[2]);
+ value *= gamma;
+ value += coef;
+ return pow(value, degree);
}
/**
@@ -532,22 +517,23 @@ double gensvm_kernel_dot_poly(double *x1, double *x2, double *kernelparam,
* The sigmoid kernel is computed between two vectors. This kernel is defined
* as
* @f[
- * k(x_1, x_2) = \tanh( \gamma \langle x_1 , x_2 \rangle + c)
+ * k(x_1, x_2) = \tanh( \gamma \langle x_1 , x_2 \rangle + coef)
* @f]
- * where @f$ \gamma @f$ and @f$ c @f$ are kernel parameters.
+ * where @f$ \gamma @f$ and @f$ coef @f$ are kernel parameters.
*
* @param[in] x1 first vector
* @param[in] x2 second vector
- * @param[in] kernelparam array of kernel parameters (gamma, c)
* @param[in] n length of the vectors x1 and x2
+ * @param[in] gamma gamma parameter of the kernel
+ * @param[in] coef coef parameter of the kernel
* @returns kernel evaluation
*/
-double gensvm_kernel_dot_sigmoid(double *x1, double *x2, double *kernelparam,
- long n)
+double gensvm_kernel_dot_sigmoid(double *x1, double *x2, long n, double gamma,
+ double coef)
{
double value = cblas_ddot(n, x1, 1, x2, 1);
- value *= kernelparam[0];
- value += kernelparam[1];
+ value *= gamma;
+ value += coef;
return tanh(value);
}