SHOGUN
v1.1.0
|
00001 /* 00002 * This program is free software; you can redistribute it and/or modify 00003 * it under the terms of the GNU General Public License as published by 00004 * the Free Software Foundation; either version 3 of the License, or 00005 * (at your option) any later version. 00006 * 00007 * Written (W) 2006 Mikio L. Braun 00008 * Written (W) 1999-2009 Soeren Sonnenburg 00009 * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society 00010 */ 00011 00012 #include <shogun/lib/config.h> 00013 00014 #ifdef HAVE_LAPACK 00015 #include <shogun/regression/KRR.h> 00016 #include <shogun/mathematics/lapack.h> 00017 #include <shogun/mathematics/Math.h> 00018 00019 using namespace shogun; 00020 00021 CKRR::CKRR() 00022 : CKernelMachine() 00023 { 00024 alpha=NULL; 00025 tau=1e-6; 00026 } 00027 00028 CKRR::CKRR(float64_t t, CKernel* k, CLabels* lab) 00029 : CKernelMachine() 00030 { 00031 tau=t; 00032 set_labels(lab); 00033 set_kernel(k); 00034 alpha=NULL; 00035 } 00036 00037 00038 CKRR::~CKRR() 00039 { 00040 SG_FREE(alpha); 00041 } 00042 00043 bool CKRR::train_machine(CFeatures* data) 00044 { 00045 SG_FREE(alpha); 00046 00047 ASSERT(labels); 00048 if (data) 00049 { 00050 if (labels->get_num_labels() != data->get_num_vectors()) 00051 SG_ERROR("Number of training vectors does not match number of labels\n"); 00052 kernel->init(data, data); 00053 } 00054 ASSERT(kernel && kernel->has_features()); 00055 00056 // Get kernel matrix 00057 SGMatrix<float64_t> kernel_matrix=kernel->get_kernel_matrix<float64_t>(); 00058 int32_t n = kernel_matrix.num_cols; 00059 int32_t m = kernel_matrix.num_rows; 00060 ASSERT(kernel_matrix.matrix && m>0 && n>0); 00061 00062 for(int32_t i=0; i < n; i++) 00063 kernel_matrix.matrix[i+i*n]+=tau; 00064 00065 // Get labels 00066 if (!labels) 00067 SG_ERROR("No labels set\n"); 00068 00069 SGVector<float64_t> alpha_orig=labels->get_labels(); 00070 00071 alpha=CMath::clone_vector(alpha_orig.vector, alpha_orig.vlen); 00072 00073 if (alpha_orig.vlen!=n) 00074 { 00075 SG_ERROR("Number of labels does not match number of kernel" 00076 " columns (num_labels=%d cols=%d\n", alpha_orig.vlen, n); 00077 } 00078 00079 clapack_dposv(CblasRowMajor,CblasUpper, n, 1, kernel_matrix.matrix, n, alpha, n); 00080 00081 SG_FREE(kernel_matrix.matrix); 00082 return true; 00083 } 00084 00085 bool CKRR::load(FILE* srcfile) 00086 { 00087 SG_SET_LOCALE_C; 00088 SG_RESET_LOCALE; 00089 return false; 00090 } 00091 00092 bool CKRR::save(FILE* dstfile) 00093 { 00094 SG_SET_LOCALE_C; 00095 SG_RESET_LOCALE; 00096 return false; 00097 } 00098 00099 CLabels* CKRR::apply() 00100 { 00101 ASSERT(kernel); 00102 00103 // Get kernel matrix 00104 SGMatrix<float64_t> kernel_matrix=kernel->get_kernel_matrix<float64_t>(); 00105 int32_t n = kernel_matrix.num_cols; 00106 int32_t m = kernel_matrix.num_rows; 00107 ASSERT(kernel_matrix.matrix && m>0 && n>0); 00108 00109 SGVector<float64_t> Yh(n); 00110 00111 // predict 00112 // K is symmetric, CblasColMajor is same as CblasRowMajor 00113 // and used that way in the origin call: 00114 // dgemv('T', m, n, 1.0, K, m, alpha, 1, 0.0, Yh, 1); 00115 int m_int = (int) m; 00116 int n_int = (int) n; 00117 cblas_dgemv(CblasColMajor, CblasTrans, m_int, n_int, 1.0, (double*) kernel_matrix.matrix, 00118 m_int, (double*) alpha, 1, 0.0, (double*) Yh.vector, 1); 00119 00120 SG_FREE(kernel_matrix.matrix); 00121 00122 return new CLabels(Yh); 00123 } 00124 00125 float64_t CKRR::apply(int32_t num) 00126 { 00127 ASSERT(kernel); 00128 00129 // Get kernel matrix 00130 // TODO: use get_kernel_column instead of computing the whole matrix! 00131 SGMatrix<float64_t> kernel_matrix=kernel->get_kernel_matrix<float64_t>(); 00132 int32_t n = kernel_matrix.num_cols; 00133 int32_t m = kernel_matrix.num_rows; 00134 ASSERT(kernel_matrix.matrix && m>0 && n>0); 00135 00136 float64_t Yh; 00137 00138 // predict 00139 Yh = CMath::dot(kernel_matrix.matrix + m*num, alpha, m); 00140 00141 SG_FREE(kernel_matrix.matrix); 00142 return Yh; 00143 } 00144 00145 #endif