00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <shogun/classifier/mkl/MKLMultiClassGLPK.h>
00012
00013 using namespace shogun;
00014
00015 MKLMultiClassGLPK::MKLMultiClassGLPK()
00016 {
00017 numkernels = 0;
00018 #ifdef USE_GLPK
00019
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
00072 glp_set_col_bnds(linearproblem,1,GLP_FR,0.0,0.0);
00073 glp_set_obj_coef(linearproblem,1,1.0);
00074
00075
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
00084 glp_add_rows(linearproblem,1);
00085
00086 int32_t*betainds(NULL);
00087 betainds=SG_MALLOC(int, 1+numkernels);
00088 for (int32_t i=0; i<numkernels;++i)
00089 {
00090 betainds[1+i]=2+i;
00091
00092 }
00093
00094 float64_t *betacoeffs(NULL);
00095 betacoeffs=SG_MALLOC(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 SG_FREE(betainds);
00106 betainds=NULL;
00107
00108 SG_FREE(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=SG_MALLOC(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;
00137
00138 }
00139
00140 float64_t *betacoeffs(NULL);
00141 betacoeffs=SG_MALLOC(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 SG_FREE(betainds);
00155 betainds=NULL;
00156
00157 SG_FREE(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 }