GURLS++  2.0.00
C++ Implementation of GURLS Matlab Toolbox
gurls::ICholWrapper< T > Class Template Reference
Inheritance diagram for gurls::ICholWrapper< T >:
Collaboration diagram for gurls::ICholWrapper< T >:

List of all members.

Public Types

enum  ProblemType { CLASSIFICATION, REGRESSION }

Public Member Functions

gMat2D< T > * eval (const gMat2D< T > &X)
 Estimates label for an input matrix.
virtual T eval (const gVec< T > &X, unsigned long *index=NULL)
 Estimates label for a new input point.
gMat2D< T > * eval_ls (const gMat2D< T > &X)
virtual const GurlsOptionsListgetOpt () const
 Returns a const reference to the options structure.
 ICholWrapper (const std::string &name)
 Constructor.
virtual void loadModel (const std::string &fileName)
 Loads a computed model from a file.
virtual void saveModel (const std::string &fileName)
 Saves the computed model to file.
virtual void setNparams (unsigned long value)
void setNRank (unsigned long n_rank)
virtual void setParam (double value)
virtual void setProblemType (ProblemType value)
void setRankMax (unsigned long rank)
void setSigma (double sigma)
virtual void setSplitProportion (double value)
void setXva (const gMat2D< T > &Xva)
void setyva (const gMat2D< T > &yva)
void train (const gMat2D< T > &X, const gMat2D< T > &y)
 Initial parameter selection and training.
void update (const gVec< T > &X, const gVec< T > &y)
 Estimator update.

Protected Member Functions

T * computeNewKcol (const T *Xtr, const unsigned long xr, const unsigned long xc, const double sigma, const unsigned long *pVec, const unsigned long start, const unsigned long n)
virtual bool trainedModel ()
 Checks if model has already been trained.

Protected Attributes

std::string name
 Name of the options structure.
GurlsOptionsListopt
 Options structure where information about initial training is stored.
ProblemType probType
 Problem type.

Detailed Description

template<typename T>
class gurls::ICholWrapper< T >

Definition at line 51 of file icholwrapper.h.


Constructor & Destructor Documentation

template<typename T >
gurls::ICholWrapper< T >::ICholWrapper ( const std::string &  name)
Parameters:
nameName of the option's structure that will be initialized

Definition at line 19 of file icholwrapper.hpp.

                                                  :GurlsWrapper<T>(name)
{
    this->opt = new GurlsOptionsList(name, true);

    GurlsOptionsList *paramsel = new GurlsOptionsList("paramsel");
    this->opt->addOpt("paramsel", paramsel);

    GurlsOptionsList *split = new GurlsOptionsList("split");
    this->opt->addOpt("split", split);
}

Member Function Documentation

template<typename T >
gMat2D< T > * gurls::ICholWrapper< T >::eval ( const gMat2D< T > &  X) [virtual]
Parameters:
[in]XInput matrix
Returns:
Matrix of predicted labels

Implements gurls::GurlsWrapper< T >.

Definition at line 440 of file icholwrapper.hpp.

{
    GurlsOptionsList *opt = this->opt;

    const gMat2D<T> &alpha_mat = opt->getOptValue<OptMatrix<gMat2D<T> > >("paramsel.alpha");
    const T *const alpha = alpha_mat.getData();

    const unsigned long n = X.rows();
    const unsigned long nt = alpha_mat.rows();
    const unsigned long t = alpha_mat.cols();

    PredKernelTrainTest<T> predKernelTask;

    gMat2D<T> empty;


    GurlsOptionsList* opt_tmp = new GurlsOptionsList("tmp");
    GurlsOptionsList* tmp_kernel = new GurlsOptionsList("kernel");
    GurlsOptionsList* tmp_paramsel = new GurlsOptionsList("paramsel");

    opt_tmp->addOpt("kernel", tmp_kernel);
    opt_tmp->addOpt("paramsel", tmp_paramsel);
    opt_tmp->addOpt("optimizer", opt->getOpt("optimizer"));

    tmp_kernel->addOpt("type", "rbf");
    tmp_paramsel->addOpt("sigma", new OptNumber(opt->getOptAsNumber("paramsel.sigma")));


    gMat2D<T> *y = new gMat2D<T>(n, t);

    GurlsOptionsList *predKernel = predKernelTask.execute(X, empty, *opt_tmp);
    const gMat2D<T> &predKernel_K = predKernel->getOptValue<OptMatrix<gMat2D<T> > >("K");

    dot(predKernel_K.getData(), alpha, y->getData(), n, nt, nt, t, n, t, CblasNoTrans, CblasNoTrans, CblasColMajor);

    opt_tmp->removeOpt("optimizer", false);
    delete opt_tmp;
    delete predKernel;

    return y;
}
template<typename T >
T gurls::GurlsWrapper< T >::eval ( const gVec< T > &  X,
unsigned long *  index = NULL 
) [virtual, inherited]
Parameters:
[in]XInput point
[out]indexIndex of the estimated label
Returns:
Estimated label

Definition at line 26 of file wrapper.hpp.

{
    if(!trainedModel())
        throw gException("Error, Train Model First");

    gMat2D<T>X_mat(1, X.getSize());
    copy(X_mat.getData(), X.getData(), X.getSize());

    gMat2D<T>* pred_mat = eval(X_mat);

    const T* pred = pred_mat->getData();
    const unsigned long size = pred_mat->getSize();

    const T* max = std::max_element(pred, pred+size);
    T ret = *max;
    if(index != NULL)
        *index = max-pred;

    delete pred_mat;
    return ret;
}
template<typename T >
void gurls::GurlsWrapper< T >::loadModel ( const std::string &  fileName) [virtual, inherited]
Parameters:
fileNamename of the file containing the data to load

Definition at line 61 of file wrapper.hpp.

{
    opt->load(fileName);
}
template<typename T >
void gurls::GurlsWrapper< T >::saveModel ( const std::string &  fileName) [virtual, inherited]
Parameters:
fileNamename of the file where data will be saved

Definition at line 55 of file wrapper.hpp.

{
    opt->save(fileName);
}
template<typename T >
void gurls::GurlsWrapper< T >::setNparams ( unsigned long  value) [virtual, inherited]
Parameters:
[in]value

Definition at line 67 of file wrapper.hpp.

{
    opt->getOptValue<OptNumber>("nlambda") = value;

    if(opt->hasOpt("paramsel.lambdas") && value > 1.0)
    {
        std::cout << "Warning: ignoring previous values of the regularization parameter" << std::endl;
        opt->getOptAs<GurlsOptionsList>("paramsel")->removeOpt("lambdas");
    }
}
template<typename T >
void gurls::GurlsWrapper< T >::setParam ( double  value) [virtual, inherited]
Parameters:
[in]value

Reimplemented in gurls::NystromWrapper< T >.

Definition at line 79 of file wrapper.hpp.

{
    if(!opt->hasOpt("paramsel"))
        opt->addOpt("paramsel", new GurlsOptionsList("paramsel"));

    if(opt->hasOpt("paramsel.lambdas"))
        opt->getOptValue<OptMatrix<gMat2D<T> > >("paramsel.lambdas").getData()[0] = (T)value;
    else
    {
        gMat2D<T> * lambdas = new gMat2D<T>(1,1);
        lambdas->getData()[0] = (T)value;
        opt->getOptAs<GurlsOptionsList>("paramsel")->addOpt("lambdas", new OptMatrix<gMat2D<T> >(*lambdas));
    }

    setNparams(1);
}
template<typename T >
void gurls::GurlsWrapper< T >::setProblemType ( typename GurlsWrapper< T >::ProblemType  value) [virtual, inherited]
Parameters:
[in]value

Definition at line 103 of file wrapper.hpp.

{
    probType = value;

    opt->getOptValue<OptString>("hoperf") = (value == CLASSIFICATION)? "macroavg": "rmse";
}
template<typename T >
void gurls::GurlsWrapper< T >::setSplitProportion ( double  value) [virtual, inherited]
Parameters:
[in]value

Definition at line 97 of file wrapper.hpp.

{
    opt->getOptValue<OptNumber>("hoproportion") = value;
}
template<typename T >
void gurls::ICholWrapper< T >::train ( const gMat2D< T > &  X,
const gMat2D< T > &  y 
) [virtual]
Parameters:
XInput data matrix
YLabels matrix

Implements gurls::GurlsWrapper< T >.

Definition at line 31 of file icholwrapper.hpp.

{
    GurlsOptionsList*opt = this->opt;

    const unsigned long m = static_cast<unsigned long>(opt->getOptAsNumber("paramsel.rank_max"));
    const unsigned long n_rank = static_cast<unsigned long>(opt->getOptAsNumber("paramsel.n_rank"));

    const double sigma = opt->getOptAsNumber("paramsel.sigma");

    const unsigned long n = X.rows();
    const unsigned long d = X.cols();
    const unsigned long t = y.cols();

    Performance<T> * perfTask = Performance<T>::factory(opt->getOptAsString("hoperf"));

    bool computePred = (opt->hasOpt("split.Xva") && opt->hasOpt("split.yva"));


    GurlsOptionsList* tmp_optimizer = new GurlsOptionsList("optimizer");
    OptMatrix<const gMat2D<T> > *X_opt = new OptMatrix<const gMat2D<T> >(X, false);
    tmp_optimizer->addOpt("X", X_opt);

    const gMat2D<T>* Xva = NULL;
    const gMat2D<T>* yva = NULL;
    gMat2D<T>* predKernel_K = NULL;
    const gMat2D<T> empty;

    if(computePred)
    {
        Xva = &(opt->getOptValue<OptMatrix<gMat2D<T> > >("split.Xva"));
        yva = &(opt->getOptValue<OptMatrix<gMat2D<T> > >("split.yva"));


        GurlsOptionsList* opt_tmp = new GurlsOptionsList("tmp");
        GurlsOptionsList* tmp_kernel = new GurlsOptionsList("kernel");
        GurlsOptionsList* tmp_paramsel = new GurlsOptionsList("paramsel");

        opt_tmp->addOpt("kernel", tmp_kernel);
        opt_tmp->addOpt("paramsel", tmp_paramsel);
        opt_tmp->addOpt("optimizer", tmp_optimizer);

        tmp_kernel->addOpt("type", "rbf");
        tmp_paramsel->addOpt("sigma", new OptNumber(sigma));


        PredKernelTrainTest<T> predKernelTask;
        GurlsOptionsList* predKernel = predKernelTask.execute(*Xva, empty, *opt_tmp);

        OptMatrix<gMat2D<T> > *k_opt = predKernel->getOptAs<OptMatrix<gMat2D<T> > >("K");
        k_opt->detachValue();
        predKernel_K = &(k_opt->getValue());

        delete predKernel;
        opt_tmp->removeOpt("optimizer", false);
        delete opt_tmp;
    }

    opt->addOpt("optimizer", tmp_optimizer);


    std::set<unsigned long> ireg;
//    for(unsigned long i=0; i<n_rank; ++i)
//        ireg.insert( static_cast<unsigned long>(gurls::round(std::pow(m, (i+1.0)/n_rank)))-1);

    unsigned long step = static_cast<unsigned long>(floor(m/n_rank));
    for(unsigned long i = m-1, count = 0; count < n_rank; i-=step, ++count)
        ireg.insert(i);


    GurlsOptionsList* perf_opt = new GurlsOptionsList("perf_opt");
    gMat2D<T>* alpha = new gMat2D<T>();
    T maxPerf = -std::numeric_limits<T>::max();
    unsigned long maxRank = 0;
    gMat2D<T> *perfs_mat = new gMat2D<T>(1, ireg.size());
    T *perfs = perfs_mat->getData();
    set(perfs, (T)-1, ireg.size());

    gMat2D<T> *times_mat = new gMat2D<T>(1, ireg.size());
    T *times = times_mat->getData();
    set(times, (T)0, ireg.size());


    gMat2D<T> *guesses_mat = new gMat2D<T>(1, ireg.size());
    T *guesses_mat_it = guesses_mat->getData();
    set(guesses_mat_it, (T)-1, ireg.size());


    T* G = new T[n*m];  //Cholesky factor
    set(G, (T)0.0, n*m);

    T* Q = new T[n*m];  //Q part of the QR decomposition
    set(Q, (T)0.0, n*m);

    T* RR = new T[m*m];  //inverse of R*R'
    set(RR, (T)0.0, m*m);

    T* yPvec = new T[n*t];
    copy(yPvec, y.getData(), n*t);


    boost::posix_time::ptime begin, end;
    boost::posix_time::time_duration diff;

    T prevPerf = 0;

    // ---- Cholesky decomposition ----
    T* diagG;
    T* newKcol;
    unsigned long* pVec;
    T normG;

    begin = boost::posix_time::microsec_clock::local_time();
    for(unsigned long i=0; i<m; ++i)
    {

        if(i==0)
        {
            //First iteration
            diagG = new T[n];
            set(diagG, (T)1.0, n);

            pVec = new unsigned long[n];
            for(unsigned long *it = pVec, *const end = pVec+n, i=0; it != end; ++it, ++i)
                *it = i;

            G[0] = 1.0;


        //     newKcol = exp(-1/sigma^2*square_distance(X(Pvec(2:n),:)',X(1,:)'));
            newKcol = computeNewKcol(X.getData(), n, d, sigma, pVec, 1, n);

        //    G(2:n,1) = newKcol;
            copy(G + 1, newKcol, n-1);

        //    diagG(2:n)=ones(n-1,1)-sum(G(2:n,1).^2,2);
            mult(newKcol, newKcol, newKcol, n-1);
            axpy(n-1, (T)-1.0, newKcol, 1, diagG+1, 1); // assumes diagG has been previously initialized to 1

        //    normG = norm(G(:,1));
            normG = sqrt(sumv(newKcol, n-1) + (G[0]*G[0]));
            delete [] newKcol;

        //    Q(:,1) = G(:,1) / normG;
            copy(Q, G, n);
            scal(n, (T)1.0/normG, Q, 1);

        //    RR(1,1) = 1/(normG^2);
            RR[0] = 1.0/ (normG*normG);
        }
        else // all other iterations
        {
            // find best new element
            unsigned long jast = std::max_element(diagG+i, diagG+n)-diagG;

            // updates permutation
    //        Pvec( [i jast] ) = Pvec( [jast i] );
            std::swap(*(pVec+i), *(pVec+jast));

            // swap y
            gurls::swap(t, yPvec+i, n, yPvec+jast, n);

            // updates all elements of G due to new permutation
    //        G([i jast],1:i)=G([ jast i],1:i);
            gurls::swap(i+1, G+i, n, G+jast, n);


            // updates all elements of Q due to new permutation
    //        Q([i jast],1:i-1) = Q([ jast i],1:i-1);
            gurls::swap(i, Q+i, n, Q+jast, n);


            // do the cholesky update
    //        G(i,i)=diagG(jast);
    //        G(i,i)=sqrt(G(i,i));
            const T G_ii = sqrt(diagG[jast]);
            G[(n*i)+i] = G_ii;


    //        newKcol = exp(-1/sigma^2*square_distance(X(Pvec((i+1):n),:)',X(Pvec(i),:)'));
            newKcol = computeNewKcol(X.getData(), n, d, sigma, pVec, i+1, n);

    //        G((i+1):n,i)=1/G(i,i)*( newKcol - G((i+1):n,1:(i-1))*(G(i,1:(i-1)))');
            const int rows = (n-(i+1));
            const unsigned long cols = i;

            T* G_ip1_n = new T[rows*(cols+1)]; // extracting +1 cols for future use

            for(T *G_it = G+(i+1), *Gi_it = G_ip1_n, *const Gi_end = Gi_it+rows*cols; Gi_it != Gi_end; G_it+=n, Gi_it+=rows)
                copy(Gi_it, G_it, rows);

            T* G_i= new T[cols];
            copy(G_i, G+i, cols, 1, n);

            const T beta = 1.0/G_ii;

            gemv(CblasNoTrans, rows, cols, -beta, G_ip1_n, rows, G_i, 1, beta, newKcol, 1);
            copy(G+(i+1)+(n*i), newKcol, rows);

            delete [] G_i;

            // updates diagonal elements
    //        diagG((i+1):n)=ones(n-i,1)-sum(G((i+1):n,1:i).^2,2  );
            copy(G_ip1_n+(rows*cols), newKcol, rows);
            mult(G_ip1_n, G_ip1_n, G_ip1_n, rows*(cols+1));

            delete [] newKcol;

            T* sums = new T[rows];
            sum_col(G_ip1_n, sums, rows, cols+1);
            set(diagG+(i+1), (T)1.0, rows);
            axpy(rows, (T)-1.0, sums, 1, diagG+(i+1), 1);

            delete [] sums;
            delete [] G_ip1_n;


            // performs QR decomposition
    //        Gcol = G(:,i);
            T* Gcol = new T[n];
            copy(Gcol, G+(n*i), n);

    //        Rcol = Q(:,1:(i-1))' * Gcol;
            T* Rcol = new T[cols];
            T* Q_sub = new T[n*cols];
            copy(Q_sub, Q, n*cols);
            gemv(CblasTrans, n, cols, (T)1.0, Q_sub, n, Gcol, 1, (T)0.0, Rcol, 1);


    //        Q(:,i) = Gcol - Q(:,1:(i-1)) * Rcol;
            T* Q_i = Q+(n*i);
            copy(Q_i, Gcol, n);
            gemv(CblasNoTrans, n, cols, (T)-1.0, Q_sub, n, Rcol, 1, (T)1.0, Q_i, 1);

            delete [] Gcol;
            delete [] Q_sub;

    //        Rii = norm(Q(:,i));
    //        Q(:,i) = Q(:,i) / Rii;
            normG = nrm2(n, Q_i, 1);
            scal(n, (T)1.0/normG, Q_i, 1);


            // updates
    //        RR(1:(i-1),i) = -(RR(1:(i-1),1:(i-1))*Rcol)./Rii;
            T* RR_sub = new T[cols*cols];
            for(T *R_it = RR, *Rs_it = RR_sub, *const R_end = R_it+(i*m); R_it != R_end; R_it+=m, Rs_it+=cols)
                copy(Rs_it, R_it, cols);

            T* RR_i = RR+(m*i);
            T* RR_Rcol = new T[cols];

            gemv(CblasNoTrans, cols, cols, (T)1.0, RR_sub, cols, Rcol, 1, (T)0.0, RR_Rcol, 1);
            copy(RR_i, RR_Rcol, cols);
            scal(cols, (T)-1.0/normG, RR_i, 1);

            delete[] RR_sub;

    //        RR(i,1:(i-1)) = RR(1:(i-1),i)';
            copy(RR+i, RR_i, cols, m, 1);

    //        RR(i,i) = (Rcol'*RR(1:(i-1),1:(i-1))*Rcol + 1)./(Rii^2);
            normG *= normG;
            RR[i+(i*m)] = (dot(cols, Rcol, 1, RR_Rcol, 1)+1) / normG;

            delete [] Rcol;
            delete [] RR_Rcol;
        }


        if(ireg.find(i) != ireg.end())
        {
            *guesses_mat_it++ = i+1;

//            vout.alpha = Q(:,1:i)*RR(1:i,1:i)*(Q(:,1:i)'*y(Pvec,:));

            const unsigned long ii = i+1;


            T* QtYp = new T[ii*t];
            dot(Q, yPvec, QtYp, n, ii, n, t, ii, t, CblasTrans, CblasNoTrans, CblasColMajor);

            T* RR_sub = new T[ii*ii];
            for(T *R_it = RR, *Rs_it = RR_sub, *const R_end = R_it+(ii*m); R_it != R_end; R_it+=m, Rs_it+=ii)
                copy(Rs_it, R_it, ii);

            T* RRQtYp = new T[ii*t];
            dot(RR_sub, QtYp, RRQtYp, ii, ii, ii, t, ii, t, CblasNoTrans, CblasNoTrans, CblasColMajor);

            delete [] RR_sub;
            delete [] QtYp;

            T* alpha_i = new T[n*t];
            dot(Q, RRQtYp, alpha_i, n, ii, ii, t, n, t, CblasNoTrans, CblasNoTrans, CblasColMajor);

            delete [] RRQtYp;



        //    permute indices of alpha
        //    vout.alpha(Pvec, :) = vout.alpha;
            gMat2D<T>* alphaMat = new gMat2D<T>(n,t);

            T *const alphaMat_it = alphaMat->getData();
            for (unsigned long j=0; j<n; ++j)
                copy(alphaMat_it+pVec[j], alpha_i+j, t, n, n);

            delete [] alpha_i;

            if(computePred)
            {
                // pred_primal
                gMat2D<T> * pred = new gMat2D<T>(Xva->rows(), t);
                dot(predKernel_K->getData(), alphaMat_it, pred->getData(), Xva->rows(), n, n, t, Xva->rows(), t, CblasNoTrans, CblasNoTrans, CblasColMajor);

                // perf_macroavg

                perf_opt->addOpt("pred", new OptMatrix<gMat2D<T> >(*pred));
                GurlsOptionsList* perf = perfTask->execute(empty, *yva, *perf_opt);

                gMat2D<T>& acc = perf->getOptValue<OptMatrix<gMat2D<T> > >("acc");
                T perf_i = sumv(acc.getData(), acc.getSize())/acc.getSize();
                *perfs = perf_i;
//                ++perfs;

                perf_opt->removeOpt("pred");
                delete perf;

                if(perf_i > maxPerf)
                {
                    maxPerf = perf_i;
                    maxRank = i;

                    delete alpha;
                    alpha = alphaMat;
                }
                else
                    delete alphaMat;


                if(le(*perfs, prevPerf) && i > 10)
                    break;
                else
                {
                    prevPerf = *perfs;
                    ++perfs;
                }
            }
            else
            {
                if(i == m-1)
                {
                    delete alpha;
                    alpha = alphaMat;
                    maxPerf = 1;
                    maxRank = i;

                    set(perfs, (T)0.0, ireg.size());
                    set(times, (T)0.0, ireg.size());
                }
            }

            end = boost::posix_time::microsec_clock::local_time();
            diff = end-begin;

            *times = diff.total_milliseconds();
            ++times;

        }

    }

    delete perf_opt;
    delete perfTask;

    delete [] G;
    delete [] diagG;


    delete [] yPvec;
    delete [] RR;
    delete [] Q;

    delete [] pVec;

    delete predKernel_K;

    GurlsOptionsList* paramsel = opt->getOptAs<GurlsOptionsList>("paramsel");
    paramsel->removeOpt("alpha");
    paramsel->removeOpt("acc");
    paramsel->removeOpt("maxRank");
    paramsel->removeOpt("maxPerf");
    paramsel->removeOpt("times");
    paramsel->removeOpt("guesses");

    paramsel->addOpt("alpha", new OptMatrix<gMat2D<T> >(*alpha));
    paramsel->addOpt("acc", new OptMatrix<gMat2D<T> >(*perfs_mat));
    paramsel->addOpt("maxRank", new OptNumber(maxRank));
    paramsel->addOpt("maxPerf", new OptNumber(maxPerf));
    paramsel->addOpt("times", new OptMatrix<gMat2D<T> >(*times_mat));
    paramsel->addOpt("guesses", new OptMatrix<gMat2D<T> >(*guesses_mat));

}
template<typename T >
bool gurls::GurlsWrapper< T >::trainedModel ( ) [protected, virtual, inherited]
Parameters:
value
value

Definition at line 111 of file wrapper.hpp.

{
    return opt->hasOpt("optimizer");
}
template<typename T >
void gurls::ICholWrapper< T >::update ( const gVec< T > &  X,
const gVec< T > &  y 
)
Parameters:
XInput data vector
YLabels vector

Definition at line 435 of file icholwrapper.hpp.

{
}

The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends