MKLMulticlassGLPK.cpp

Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation