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