SHOGUN
v2.0.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) 2009 Alexander Binder 00008 * Copyright (C) 2009 Fraunhofer Institute FIRST and Max-Planck-Society 00009 */ 00010 00011 #include <shogun/classifier/mkl/MKLMulticlassGLPK.h> 00012 #ifdef USE_GLPK 00013 #include <glpk.h> 00014 #endif 00015 00016 00017 using namespace shogun; 00018 00019 MKLMulticlassGLPK::MKLMulticlassGLPK() 00020 { 00021 numkernels = 0; 00022 #ifdef USE_GLPK 00023 //makes glpk quiet 00024 glp_term_out(GLP_OFF); 00025 linearproblem=NULL; 00026 #endif 00027 } 00028 MKLMulticlassGLPK::~MKLMulticlassGLPK() 00029 { 00030 #if defined(USE_GLPK) 00031 if (linearproblem) 00032 { 00033 glp_delete_prob((glp_prob*) linearproblem); 00034 linearproblem=NULL; 00035 } 00036 00037 #endif 00038 } 00039 00040 MKLMulticlassGLPK MKLMulticlassGLPK::operator=(MKLMulticlassGLPK & gl) 00041 { 00042 SG_ERROR( 00043 " MKLMulticlassGLPK MKLMulticlassGLPK::operator=(...): must " 00044 "not be called, glpk structure is currently not copyable"); 00045 return (*this); 00046 00047 } 00048 MKLMulticlassGLPK::MKLMulticlassGLPK(MKLMulticlassGLPK & gl) 00049 { 00050 SG_ERROR( 00051 " MKLMulticlassGLPK::MKLMulticlassGLPK(MKLMulticlassGLPK & gl):" 00052 " must not be called, glpk structure is currently not copyable"); 00053 00054 } 00055 00056 void MKLMulticlassGLPK::setup(const int32_t numkernels2) 00057 { 00058 #if defined(USE_GLPK) 00059 numkernels=numkernels2; 00060 if (numkernels<=1) 00061 { 00062 SG_ERROR("void glpkwrapper::setup(const int32_tnumkernels): input " 00063 "numkernels out of bounds: %d\n",numkernels); 00064 } 00065 00066 if (!linearproblem) 00067 { 00068 linearproblem=glp_create_prob(); 00069 } 00070 00071 glp_set_obj_dir((glp_prob*) linearproblem, GLP_MAX); 00072 00073 glp_add_cols((glp_prob*) linearproblem,1+numkernels); 00074 00075 //set up theta 00076 glp_set_col_bnds((glp_prob*) linearproblem,1,GLP_FR,0.0,0.0); 00077 glp_set_obj_coef((glp_prob*) linearproblem,1,1.0); 00078 00079 //set up betas 00080 int32_t offset=2; 00081 for (int32_t i=0; i<numkernels;++i) 00082 { 00083 glp_set_col_bnds((glp_prob*) linearproblem,offset+i,GLP_DB,0.0,1.0); 00084 glp_set_obj_coef((glp_prob*) linearproblem,offset+i,0.0); 00085 } 00086 00087 //set sumupconstraint32_t/sum_l \beta_l=1 00088 glp_add_rows((glp_prob*) linearproblem,1); 00089 00090 int32_t*betainds(NULL); 00091 betainds=SG_MALLOC(int, 1+numkernels); 00092 for (int32_t i=0; i<numkernels;++i) 00093 { 00094 betainds[1+i]=2+i; // coefficient for theta stays zero, therefore 00095 //start at 2 not at 1 ! 00096 } 00097 00098 float64_t *betacoeffs(NULL); 00099 betacoeffs=SG_MALLOC(float64_t, 1+numkernels); 00100 00101 for (int32_t i=0; i<numkernels;++i) 00102 { 00103 betacoeffs[1+i]=1; 00104 } 00105 00106 glp_set_mat_row((glp_prob*) linearproblem,1,numkernels, betainds,betacoeffs); 00107 glp_set_row_bnds((glp_prob*) linearproblem,1,GLP_FX,1.0,1.0); 00108 00109 SG_FREE(betainds); 00110 betainds=NULL; 00111 00112 SG_FREE(betacoeffs); 00113 betacoeffs=NULL; 00114 #else 00115 SG_ERROR( 00116 "glpk.h from GNU glpk not included at compile time necessary " 00117 "here\n"); 00118 #endif 00119 00120 } 00121 00122 void MKLMulticlassGLPK::addconstraint(const ::std::vector<float64_t> & normw2, 00123 const float64_t sumofpositivealphas) 00124 { 00125 #if defined(USE_GLPK) 00126 00127 ASSERT ((int)normw2.size()==numkernels); 00128 ASSERT (sumofpositivealphas>=0); 00129 00130 glp_add_rows((glp_prob*) linearproblem,1); 00131 00132 int32_t curconstraint=glp_get_num_rows((glp_prob*) linearproblem); 00133 00134 int32_t *betainds(NULL); 00135 betainds=SG_MALLOC(int, 1+1+numkernels); 00136 00137 betainds[1]=1; 00138 for (int32_t i=0; i<numkernels;++i) 00139 { 00140 betainds[2+i]=2+i; // coefficient for theta stays zero, therefore start 00141 //at 2 not at 1 ! 00142 } 00143 00144 float64_t *betacoeffs(NULL); 00145 betacoeffs=SG_MALLOC(float64_t, 1+1+numkernels); 00146 00147 betacoeffs[1]=-1; 00148 00149 for (int32_t i=0; i<numkernels;++i) 00150 { 00151 betacoeffs[2+i]=0.5*normw2[i]; 00152 } 00153 glp_set_mat_row((glp_prob*) linearproblem,curconstraint,1+numkernels, betainds, 00154 betacoeffs); 00155 glp_set_row_bnds((glp_prob*) linearproblem,curconstraint,GLP_LO,sumofpositivealphas, 00156 sumofpositivealphas); 00157 00158 SG_FREE(betainds); 00159 betainds=NULL; 00160 00161 SG_FREE(betacoeffs); 00162 betacoeffs=NULL; 00163 00164 #else 00165 SG_ERROR( 00166 "glpk.h from GNU glpk not included at compile time necessary " 00167 "here\n"); 00168 #endif 00169 } 00170 00171 void MKLMulticlassGLPK::computeweights(std::vector<float64_t> & weights2) 00172 { 00173 #if defined(USE_GLPK) 00174 weights2.resize(numkernels); 00175 00176 glp_simplex((glp_prob*) linearproblem,NULL); 00177 00178 float64_t sum=0; 00179 for (int32_t i=0; i< numkernels;++i) 00180 { 00181 weights2[i]=glp_get_col_prim((glp_prob*) linearproblem, i+2); 00182 weights2[i]= ::std::max(0.0, ::std::min(1.0,weights2[i])); 00183 sum+= weights2[i]; 00184 } 00185 00186 if (sum>0) 00187 { 00188 for (int32_t i=0; i< numkernels;++i) 00189 { 00190 weights2[i]/=sum; 00191 } 00192 } 00193 else 00194 SG_ERROR("void glpkwrapper::computeweights(std::vector<float64_t> & " 00195 "weights2): sum of weights nonpositive %f\n",sum); 00196 #else 00197 SG_ERROR( 00198 "glpk.h from GNU glpk not included at compile time necessary " 00199 "here\n"); 00200 #endif 00201 }