diff options
| author | Gertjan van den Burg <burg@ese.eur.nl> | 2016-12-05 19:21:09 +0100 |
|---|---|---|
| committer | Gertjan van den Burg <burg@ese.eur.nl> | 2016-12-05 19:21:09 +0100 |
| commit | dd2cffeceef93ff84ad2d7fe8cea08a1fab5d4e2 (patch) | |
| tree | bde661adfd273becd782b0dc1325d19c48965c76 /src | |
| parent | Tests and documentation kernel module (diff) | |
| download | gensvm-dd2cffeceef93ff84ad2d7fe8cea08a1fab5d4e2.tar.gz gensvm-dd2cffeceef93ff84ad2d7fe8cea08a1fab5d4e2.zip | |
further unit tests for kernel module
Diffstat (limited to 'src')
| -rw-r--r-- | src/gensvm_base.c | 1 | ||||
| -rw-r--r-- | src/gensvm_kernel.c | 80 |
2 files changed, 45 insertions, 36 deletions
diff --git a/src/gensvm_base.c b/src/gensvm_base.c index c9f2c0e..6b979fd 100644 --- a/src/gensvm_base.c +++ b/src/gensvm_base.c @@ -110,6 +110,7 @@ struct GenModel *gensvm_init_model() model->weight_idx = 1; model->kerneltype = K_LINEAR; model->kernelparam = NULL; + model->kernel_eigen_cutoff = 1e-8; model->V = NULL; model->Vbar = NULL; diff --git a/src/gensvm_kernel.c b/src/gensvm_kernel.c index d236553..410ac5f 100644 --- a/src/gensvm_kernel.c +++ b/src/gensvm_kernel.c @@ -32,13 +32,34 @@ #include "gensvm_kernel.h" #include "gensvm_print.h" -#ifndef GENSVM_EIGEN_CUTOFF - /** - * Mimimum ratio between an eigenvalue and the largest eigenvalue for it to - * be included in the reduced eigendecomposition - */ - #define GENSVM_EIGEN_CUTOFF 1e-8 -#endif +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]; + } +} + /** * @brief Do the preprocessing steps needed to perform kernel GenSVM @@ -67,7 +88,6 @@ void gensvm_kernel_preprocess(struct GenModel *model, struct GenData *data) return; } - int i; long r, n = data->n; double *P = NULL, *Sigma = NULL, @@ -78,7 +98,8 @@ void gensvm_kernel_preprocess(struct GenModel *model, struct GenData *data) gensvm_kernel_compute(model, data, K); // generate the eigen decomposition - r = gensvm_kernel_eigendecomp(K, n, &P, &Sigma); + r = gensvm_kernel_eigendecomp(K, n, model->kernel_eigen_cutoff, &P, + &Sigma); // build M and set to data (leave RAW intact) gensvm_kernel_trainfactor(data, P, Sigma, r); @@ -91,28 +112,7 @@ void gensvm_kernel_preprocess(struct GenModel *model, struct GenData *data) data->Sigma = Sigma; // write kernel params to data - 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]; - } + gensvm_kernel_copy_kernelparam_to_data(model, data); free(K); free(P); @@ -186,9 +186,11 @@ void gensvm_kernel_compute(struct GenModel *model, struct GenData *data, value = gensvm_kernel_dot_sigmoid(x1, x2, model->kernelparam, data->m); else { + // LCOV_EXCL_START err("[GenSVM Error]: Unknown kernel type in " "gensvm_make_kernel\n"); exit(EXIT_FAILURE); + // LCOV_EXCL_STOP } matrix_set(K, n, i, j, value); matrix_set(K, n, j, i, value); @@ -203,18 +205,20 @@ void gensvm_kernel_compute(struct GenModel *model, struct GenData *data, * Compute the reduced eigendecomposition of the kernel matrix. This uses the * LAPACK function dsyevx to do the computation. Only those * eigenvalues/eigenvectors are kept for which the ratio between the - * eigenvalue and the largest eigenvalue is larger than GENSVM_EIGEN_CUTOFF. - * This function uses the highest precision eigenvalues, twice the underflow - * threshold (see dsyevx documentation). + * eigenvalue and the largest eigenvalue is larger than cutoff. This function + * uses the highest precision eigenvalues, twice the underflow threshold (see + * dsyevx documentation). * * @param[in] K the kernel matrix * @param[in] n the dimension of the kernel matrix + * @param[in] cutoff mimimum ratio of eigenvalue to largest + * eigenvalue for the eigenvector to be included * @param[out] P on exit contains the eigenvectors * @param[out] Sigma on exit contains the eigenvalues * * @return the number of eigenvalues kept */ -long gensvm_kernel_eigendecomp(double *K, long n, double **P_ret, +long gensvm_kernel_eigendecomp(double *K, long n, double cutoff, double **P_ret, double **Sigma_ret) { int M, status, LWORK, *IWORK = NULL, @@ -246,8 +250,10 @@ long gensvm_kernel_eigendecomp(double *K, long n, double **P_ret, tempSigma, tempP, n, WORK, LWORK, IWORK, IFAIL); if (status != 0) { + // LCOV_EXCL_START err("[GenSVM Error]: Nonzero exit status from dsyevx.\n"); exit(EXIT_FAILURE); + // LCOV_EXCL_STOP } // Select the desired number of eigenvalues, depending on their size. @@ -256,7 +262,7 @@ long gensvm_kernel_eigendecomp(double *K, long n, double **P_ret, cutoff_idx = 0; for (i=0; i<n; i++) { - if (tempSigma[i]/max_eigen > GENSVM_EIGEN_CUTOFF) { + if (tempSigma[i]/max_eigen > cutoff) { cutoff_idx = i; break; } @@ -333,9 +339,11 @@ double *gensvm_kernel_cross(struct GenModel *model, struct GenData *data_train, value = gensvm_kernel_dot_sigmoid(x1, x2, model->kernelparam, m); else { + // LCOV_EXCL_START err("[GenSVM Error]: Unknown kernel type in " "gensvm_make_crosskernel\n"); exit(EXIT_FAILURE); + // LCOV_EXCL_STOP } matrix_set(K2, n_train, i, j, value); } |
