GURLS++  2.0.00
C++ Implementation of GURLS Matlab Toolbox
hodual.h
00001 
00002 
00003 /*
00004  * The GURLS Package in C++
00005  *
00006  * Copyright (C) 2011-1013, IIT@MIT Lab
00007  * All rights reserved.
00008  *
00009  * authors:  M. Santoro
00010  * email:   msantoro@mit.edu
00011  * website: http://cbcl.mit.edu/IIT@MIT/IIT@MIT.html
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions
00015  * are met:
00016  *
00017  *     * Redistributions of source code must retain the above
00018  *       copyright notice, this list of conditions and the following
00019  *       disclaimer.
00020  *     * Redistributions in binary form must reproduce the above
00021  *       copyright notice, this list of conditions and the following
00022  *       disclaimer in the documentation and/or other materials
00023  *       provided with the distribution.
00024  *     * Neither the name(s) of the copyright holders nor the names
00025  *       of its contributors or of the Massacusetts Institute of
00026  *       Technology or of the Italian Institute of Technology may be
00027  *       used to endorse or promote products derived from this software
00028  *       without specific prior written permission.
00029  *
00030  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00031  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00032  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00033  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00034  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00035  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00036  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00037  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00038  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00039  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00040  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00041  * POSSIBILITY OF SUCH DAMAGE.
00042  */
00043 
00044 
00045 #ifndef _GURLS_HODUAL_H_
00046 #define _GURLS_HODUAL_H_
00047 
00048 #include <cstdio>
00049 #include <cstring>
00050 #include <iostream>
00051 #include <cmath>
00052 #include <algorithm>
00053 #include <set>
00054 
00055 #include "gurls++/options.h"
00056 #include "gurls++/optlist.h"
00057 #include "gurls++/gmat2d.h"
00058 #include "gurls++/gvec.h"
00059 #include "gurls++/gmath.h"
00060 
00061 #include "gurls++/paramsel.h"
00062 #include "gurls++/perf.h"
00063 #include "gurls++/dual.h"
00064 
00065 namespace gurls {
00066 
00072 template <typename T>
00073 class ParamSelHoDual: public ParamSelection<T>{
00074 
00075 public:
00094     GurlsOptionsList* execute(const gMat2D<T>& X, const gMat2D<T>& Y, const GurlsOptionsList& opt);
00095 
00096 protected:
00100     virtual void eig_function(T* A, T* L, int A_rows_cols, unsigned long n, const GurlsOptionsList &opt);
00101 
00102     virtual unsigned long getRank(unsigned long last, unsigned long n, unsigned long d, bool linearKernel, const GurlsOptionsList &opt);
00103 };
00104 
00105 
00111 template <typename T>
00112 class ParamSelHoDualr: public ParamSelHoDual<T>{
00113 
00114 protected:
00118     virtual void eig_function(T* A, T* L, int A_rows_cols, unsigned long n, const GurlsOptionsList &opt);
00119 
00120     virtual unsigned long getRank(unsigned long last, unsigned long n, unsigned long d, bool linearKernel, const GurlsOptionsList &opt);
00121 };
00122 
00123 
00124 
00125 
00126 template<typename T>
00127 void ParamSelHoDual<T>::eig_function(T* A, T* L, int A_rows_cols, unsigned long , const GurlsOptionsList &)
00128 {
00129     eig_sm(A, L, A_rows_cols);
00130 }
00131 
00132 template<typename T>
00133 void ParamSelHoDualr<T>::eig_function(T* A, T* L, int A_rows_cols, unsigned long n, const GurlsOptionsList &opt)
00134 {
00135     T* V = NULL;
00136     unsigned long k = static_cast<unsigned long>(gurls::round((opt.getOptAsNumber("eig_percentage")*n)/100.0));
00137     random_svd(A, A_rows_cols, A_rows_cols, A, L, V, k);
00138 }
00139 
00140 template<typename T>
00141 unsigned long ParamSelHoDual<T>::getRank(unsigned long last, unsigned long , unsigned long d, bool linearKernel, const GurlsOptionsList &)
00142 {
00143     if(linearKernel)
00144         return std::min<unsigned long> (last,d);
00145     else
00146         return last;
00147 }
00148 
00149 template<typename T>
00150 unsigned long ParamSelHoDualr<T>::getRank(unsigned long , unsigned long n, unsigned long , bool , const GurlsOptionsList &opt)
00151 {
00152     return static_cast<unsigned long>(gurls::round((opt.getOptAsNumber("eig_percentage")*n)/100.0));
00153 }
00154 
00155 template <typename T>
00156 GurlsOptionsList *ParamSelHoDual<T>::execute(const gMat2D<T>& X, const gMat2D<T>& Y, const GurlsOptionsList &opt)
00157 {
00158     //    [n,T]  = size(y);
00159     const unsigned long n = Y.rows();
00160     const unsigned long t = Y.cols();
00161 
00162     const unsigned long x_rows = X.rows();
00163     const unsigned long d = X.cols();
00164 
00165 
00166     GurlsOptionsList* nestedOpt = new GurlsOptionsList("nested");
00167     nestedOpt->copyOpt("kernel", opt);
00168 
00169     nestedOpt->addOpt("predkernel", new GurlsOptionsList("predkernel"));
00170 
00171 
00172     const GurlsOptionsList* split = opt.getOptAs<GurlsOptionsList>("split");
00173 
00174     const gMat2D< unsigned long > &indices_mat = split->getOptValue<OptMatrix<gMat2D< unsigned long > > >("indices");
00175     const gMat2D< unsigned long > &lasts_mat = split->getOptValue<OptMatrix<gMat2D< unsigned long > > >("lasts");
00176 
00177     const unsigned long *lasts = lasts_mat.getData();
00178     const unsigned long* indices_buffer = indices_mat.getData();
00179 
00180 
00181     const GurlsOptionsList* kernel = opt.getOptAs<GurlsOptionsList>("kernel");
00182     const gMat2D<T> &K = kernel->getOptValue<OptMatrix<gMat2D<T> > >("K");
00183     const bool linearKernel = kernel->getOptAsString("type") == "linear";
00184 
00185     const unsigned long k_rows = K.rows();
00186 
00187     int tot = static_cast<int>(std::ceil( opt.getOptAsNumber("nlambda")));
00188     int nholdouts = static_cast<int>(std::ceil( opt.getOptAsNumber("nholdouts")));
00189 
00190     gMat2D<T> *LAMBDA = new gMat2D<T>(1, t);
00191     T* lambdas = LAMBDA->getData();
00192     set(lambdas, (T)0.0, t);
00193 
00194     gMat2D<T>*  acc_avg_mat = new gMat2D<T>(tot, t);
00195     T* acc_avg = acc_avg_mat->getData();
00196     set(acc_avg, (T)0.0, tot*t);
00197 
00198     //     for nh = 1:opt.nholdouts
00199     GurlsOptionsList* optimizer = new GurlsOptionsList("optimizer");
00200 
00201     Performance<T>* perfClass = Performance<T>::factory(opt.getOptAsString("hoperf"));
00202     PredDual<T> dual;
00203 
00204     nestedOpt->addOpt("optimizer",optimizer);
00205 
00206     gMat2D<T>* perf_mat = new gMat2D<T>(nholdouts, tot*t);
00207     T* perf = perf_mat->getData();
00208 
00209     gMat2D<T>*  guesses_mat = new gMat2D<T>(nholdouts, tot);
00210     T* ret_guesses = guesses_mat->getData();
00211 
00212     gMat2D<T>* lambdas_round_mat = new gMat2D<T>(nholdouts, t);
00213     T* lambdas_round = lambdas_round_mat->getData();
00214 
00215     for(int nh=0; nh<nholdouts; ++nh)
00216     {
00217         unsigned long last = lasts[nh];
00218         unsigned long* tr = new unsigned long[last];
00219         unsigned long* va = new unsigned long[n-last];
00220 
00221         //copy int tr indices_ from n*nh to last
00222         copy<unsigned long>(tr,indices_buffer + n*nh, last);
00223         //copy int va indices_ from n*nh+last to n*nh+n
00224         copy<unsigned long>(va,(indices_buffer+ n*nh+last), n-last);
00225 
00226 
00227         //Get K(tr,tr) from K
00228         T* Q = new T[last*last];
00229         copy_submatrix(Q, K.getData(), k_rows, last, last, tr, tr);
00230 
00231         T *L = new T[last];
00232         eig_function(Q, L, last, n, opt);
00233 
00234         unsigned long r = getRank(last, n, d, linearKernel, opt);
00235 
00236         if(!linearKernel)
00237         {
00238             //  opt.predkernel.K = opt.kernel.K(va,tr);%nva x ntr
00239             gMat2D<T>* predK = new gMat2D<T>(n-last, last);
00240 
00241             copy_submatrix(predK->getData(), K.getData(), k_rows, n-last, last, va, tr);
00242 
00243             GurlsOptionsList* predkernel = nestedOpt->getOptAs<GurlsOptionsList>("predkernel");
00244 
00245             predkernel->removeOpt("K");
00246             predkernel->addOpt("K", new OptMatrix<gMat2D<T> >(*predK));
00247         }
00248 
00249         T* guesses = lambdaguesses(L, last, r, last, tot, (T)(opt.getOptAsNumber("smallnumber")));
00250 
00251         //  ap = zeros(tot,T);
00252         T* ap = new T[tot*t];
00253 
00254         T* Ytr = new T[last*t];
00255         subMatrixFromRows(Y.getData(), n, t, tr, last, Ytr);
00256 
00257         //    QtY = Q'*y(tr,:);
00258         T* Qty = new T[last*t];
00259 
00260         dot(Q, Ytr, Qty, last, last, last, t, last, t, CblasTrans, CblasNoTrans, CblasColMajor);
00261 
00262         delete [] Ytr;
00263 
00264         //    for i = 1:tot
00265         //  opt.rls.X = X(tr,:);
00266 
00267         gMat2D<T>* rlsX = new gMat2D<T>(last, d);
00268         subMatrixFromRows(X.getData(), x_rows, d, tr, last, rlsX->getData());
00269 
00270         delete [] tr;
00271 
00272         optimizer->removeOpt("X");
00273         optimizer->addOpt("X", new OptMatrix<gMat2D<T> >(*rlsX));
00274 
00275 
00276         gMat2D<T>* xx = new gMat2D<T>(n-last, d);
00277         subMatrixFromRows(X.getData(), x_rows, d, va, n-last, xx->getData());
00278 
00279         gMat2D<T>* yy = new gMat2D<T>(n-last, t);
00280         subMatrixFromRows(Y.getData(), n, t, va, n-last, yy->getData());
00281 
00282         delete [] va;
00283 
00284         gMat2D<T>* C = new gMat2D<T>(last, t);
00285         optimizer->removeOpt("C");
00286         optimizer->addOpt("C", new OptMatrix<gMat2D<T> >(*C));
00287 
00288 
00289         gMat2D<T>* W = NULL;
00290 
00291         if(linearKernel)
00292         {
00293             W = new gMat2D<T>(d, t);
00294 
00295             optimizer->removeOpt("W");
00296             optimizer->addOpt("W", new OptMatrix<gMat2D<T> >(*W));
00297         }
00298 
00299         T* work = new T[last*(last+1)];
00300 
00301         for(int i=0; i<tot; ++i)
00302         {
00303             //  opt.rls.C = rls_eigen(Q,L,QtY,guesses(i),ntr);
00304             rls_eigen(Q, L, Qty, C->getData(), guesses[i], last, last, last, last, last, t, work);
00305 
00306             if(linearKernel)
00307             {
00308 //                opt.rls.W = X(tr,:)'*opt.rls.C; % dxT = (ntrxd)'*ntrxT   last*d last*last
00309                 dot(rlsX->getData(), C->getData(), W->getData(), last, d, last, t, d, t, CblasTrans, CblasNoTrans, CblasColMajor);
00310             }
00311 //            else
00312 //            opt.predkernel.K = opt.kernel.K(va,tr);%nva x ntr
00313 //            (see above)
00314 
00315 
00316             OptMatrix<gMat2D<T> >* ret_pred = dual.execute(*xx, *yy, *nestedOpt);
00317 
00318             nestedOpt->addOpt("pred", ret_pred);
00319 
00320             //  opt.perf = opt.hoperf(Xva,yva,opt);
00321             GurlsOptionsList* ret_perf = perfClass->execute(*xx, *yy, *nestedOpt);
00322 
00323             gMat2D<T> &forho_vec = ret_perf->getOptValue<OptMatrix<gMat2D<T> > >("forho");
00324 
00325             //       for t = 1:T
00326             //          ap(i,t) = opt.perf.forho(t);
00327             copy(ap+i, forho_vec.getData(), t, tot, 1);
00328 
00329             nestedOpt->removeOpt("pred");
00330 
00331             delete ret_perf;
00332 
00333         }//for tot
00334 
00335         delete [] Q;
00336         delete [] Qty;
00337         delete [] L;
00338         delete [] work;
00339 
00340         delete xx;
00341         delete yy;
00342 
00343         //[dummy,idx] = max(ap,[],1);
00344         work = NULL;
00345         unsigned long* idx = new unsigned long[t];
00346         indicesOfMax(ap, tot, t, idx, work, 1);
00347 
00348 
00349         //vout.lambdas_round{nh} = guesses(idx);
00350         T* lambdas_nh = new T[t];
00351         copyLocations(idx, guesses, t, tot, lambdas_nh);
00352 
00353         copy(lambdas_round +nh, lambdas_nh, t, nholdouts, 1);
00354 
00355         //add lambdas_nh to lambdas
00356         axpy< T >(t, (T)1, lambdas_nh, 1, lambdas, 1);
00357 
00358         delete [] lambdas_nh;
00359         delete [] idx;
00360 
00361         //  vout.perf{nh} = ap;
00362         copy(perf + nh, ap, tot*t, nholdouts, 1);
00363 
00364         axpy(tot*t, (T)1, ap, 1, acc_avg, 1);
00365 
00366         //  vout.guesses{nh} = guesses;
00367         copy(ret_guesses + nh, guesses, tot, nholdouts, 1);
00368 
00369         delete [] guesses;
00370         delete [] ap;
00371     }//for nholdouts
00372 
00373     delete nestedOpt;
00374     delete perfClass;
00375 
00376 
00377     GurlsOptionsList* paramsel;
00378 
00379     if(opt.hasOpt("paramsel"))
00380     {
00381         GurlsOptionsList* tmp_opt = new GurlsOptionsList("tmp");
00382         tmp_opt->copyOpt("paramsel", opt);
00383 
00384         paramsel = GurlsOptionsList::dynacast(tmp_opt->getOpt("paramsel"));
00385         tmp_opt->removeOpt("paramsel", false);
00386         delete tmp_opt;
00387 
00388         paramsel->removeOpt("perf");
00389         paramsel->removeOpt("guesses");
00390         paramsel->removeOpt("acc_avg");
00391         paramsel->removeOpt("lambdas");
00392         paramsel->removeOpt("lambdas_round");
00393     }
00394     else
00395         paramsel = new GurlsOptionsList("paramsel");
00396 
00397 
00398 
00399     paramsel->addOpt("perf", new OptMatrix<gMat2D<T> >(*perf_mat));
00400     paramsel->addOpt("guesses", new OptMatrix<gMat2D<T> >(*guesses_mat));
00401 
00402     //     if numel(vout.lambdas_round) > 1
00403     //  lambdas = cell2mat(vout.lambdas_round');
00404     //  vout.lambdas = mean(lambdas);
00405     //     else
00406     //  vout.lambdas = vout.lambdas_round{1};
00407     //     end
00408     if(nholdouts>1)
00409     {
00410         scal(t, (T)1.0/nholdouts, lambdas, 1);
00411         scal(t, (T)1.0/nholdouts, acc_avg, 1);
00412     }
00413 
00414     paramsel->addOpt("acc_avg", new OptMatrix<gMat2D<T> >(*acc_avg_mat));
00415 
00416 
00417     paramsel->addOpt("lambdas", new OptMatrix<gMat2D<T> >(*LAMBDA));
00418     paramsel->addOpt("lambdas_round", new OptMatrix<gMat2D<T> >(*lambdas_round_mat));
00419 
00420     return paramsel;
00421 }
00422 
00423 
00424 }
00425 
00426 #endif // _GURLS_HODUAL_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends