00001
00002
00003
00004
00005
00006
00007
00008
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
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
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
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
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;
00095
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;
00141
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 }