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

SHOGUN Machine Learning Toolbox - Documentation