Ejemplo n.º 1
0
void
SelfSimilarityMatrix::myProcess(realvec& in, realvec& out)
{
    if(this->getctrl("mrs_natural/mode")->to<mrs_natural>() ==  SelfSimilarityMatrix::outputDistanceMatrix)
    {
        //check if there are any elements to process at the input
        //(in some cases, they may not exist!) - otherwise, do nothing
        //(i.e. output will be zeroed out)
        if(inSamples_ > 0)
        {
            unsigned int child_count = marsystems_.size();
            if(child_count == 1)
            {
                mrs_natural nfeats = in.getRows();

                //normalize input features if necessary
                if(ctrl_normalize_->to<mrs_string>() == "MinMax")
                    in.normObsMinMax(); // (x - min)/(max - min)
                else if(ctrl_normalize_->to<mrs_string>() == "MeanStd")
                    in.normObs(); // (x - mean)/std

                //calculate the Covariance Matrix from the input, if defined
                if(ctrl_calcCovMatrix_->to<mrs_natural>() & SelfSimilarityMatrix::fixedStdDev)
                {
                    //fill covMatrix diagonal with fixed value (remaining values are zero)
                    MarControlAccessor acc(ctrl_covMatrix_);
                    realvec& covMatrix = acc.to<mrs_realvec>();
                    covMatrix.create(inObservations_, inObservations_);
                    mrs_real var = ctrl_stdDev_->to<mrs_real>();
                    var *= var;
                    for(mrs_natural i=0; i< inObservations_; ++i)
                    {
                        covMatrix(i,i) = var;
                    }
                }
                else if(ctrl_calcCovMatrix_->to<mrs_natural>() & SelfSimilarityMatrix::diagCovMatrix)
                {
                    in.varObs(vars_); //FASTER -> only get the vars for each feature
                    mrs_natural dim = vars_.getSize();
                    //fill covMatrix diagonal with var values (remaining values are zero)
                    MarControlAccessor acc(ctrl_covMatrix_);
                    realvec& covMatrix = acc.to<mrs_realvec>();
                    covMatrix.create(dim, dim);
                    for(mrs_natural i=0; i< dim; ++i)
                    {
                        covMatrix(i,i) = vars_(i);
                    }
                }
                else if(ctrl_calcCovMatrix_->to<mrs_natural>() & SelfSimilarityMatrix::fullCovMatrix)
                {
                    MarControlAccessor acc(ctrl_covMatrix_);
                    realvec& covMatrix = acc.to<mrs_realvec>();
                    in.covariance(covMatrix); //SLOWER -> estimate the full cov matrix
                }
                else if(ctrl_calcCovMatrix_->to<mrs_natural>() == SelfSimilarityMatrix::noCovMatrix)
                {
                    ctrl_covMatrix_->setValue(realvec());
                }

                for(mrs_natural i=0; i < in.getCols(); ++i)
                {
                    in.getCol(i, i_featVec_);
                    for(mrs_natural j=0; j <= i; ++j)
                    {
                        in.getCol(j, j_featVec_);

                        //stack i and j feat vecs
                        for(mrs_natural r=0; r < nfeats; ++r)
                        {
                            stackedFeatVecs_(r, 0) = i_featVec_(r);
                            stackedFeatVecs_(r+nfeats, 0) = j_featVec_(r);
                        }
                        //do the metric calculation for these two feat vectors
                        //and store it in the similarity matrix (which is symmetric)
                        marsystems_[0]->process(stackedFeatVecs_, metricResult_);
                        out(i,j) = metricResult_(0,0);
                        //metric should be symmetric!
                        out(j, i) = out(i, j);
                    }
                }
            }
            else
            {
                out.setval(0.0);
                if(child_count == 0)
                {
                    MRSWARN("SelfSimilarityMatrix::myProcess - no Child Metric MarSystem added - outputting zero similarity matrix!");
                }
                else
                {
                    MRSWARN("SelfSimilarityMatrix::myProcess - more than one Child MarSystem exists (i.e. invalid metric) - outputting zero similarity matrix!");
                }
            }
        }

        //MATLAB_PUT(out, "simMatrix");
        //MATLAB_EVAL("figure(1);imagesc(simMatrix);");

        //MATLAB_PUT(out, "simMat");
        //MATLAB_EVAL(name_+"=["+name_+",simMat(:)'];");
    }
    else if(this->getctrl("mrs_natural/mode")->to<mrs_natural>() ==  SelfSimilarityMatrix::outputPairDistance)
    {
        if(inSamples_ == 2) //we always need two column vector instances at input
        {
            unsigned int child_count = marsystems_.size();
            if(child_count == 1)
            {
                MarControlAccessor acc(ctrl_instanceIndexes_);
                realvec& instIdxs = acc.to<mrs_realvec>();
                mrs_natural i = mrs_natural(instIdxs(0));
                mrs_natural j = mrs_natural(instIdxs(1));

                //check for out of bound indexes (which could have been set
                //by someone outside changing the value of the ctrl_instanceIndexes control)
                mrs_natural nInstances = ctrl_nInstances_->to<mrs_natural>();
                if(i >= nInstances || j >= nInstances)
                    ctrl_done_->setValue(true);


                if(!ctrl_done_->isTrue())
                {
                    mrs_natural nfeats = in.getRows();

                    //COMPUTE DISTANCE between the two column vector at input
                    in.getCol(0, i_featVec_);
                    in.getCol(1, j_featVec_);

                    //stack i and j feat vecs
                    for(mrs_natural r=0; r < nfeats; ++r)
                    {
                        stackedFeatVecs_(r, 0) = i_featVec_(r);
                        stackedFeatVecs_(r+nfeats, 0) = j_featVec_(r);
                    }

                    //do the metric calculation for these two feat vectors
                    //and send it to the output
                    marsystems_[0]->process(stackedFeatVecs_, out);
                    //out(0) = metricResult_(0,0);
                }
                else
                {
                    //Self Similarity has completed all pair-wise similarity computations
                    //so, it will just send zero valued values and a warning
                    out(0) = 0.0;
                    MRSWARN("SelfSimilarityMatrix::myProcess - no more pairwise similarity computations to be performed - outputting zero similarity value!")
                }

                //Select indexes for next pair of instances for distance computation
                //Similarity matrix is tringular simetric, so we should just compute
                //half of it (including diagonal). These indexes are to be used by some
                //source MarSystem that has a control linked to ctrl_instanceIndexes (e.g. WekaSource)
                if (i < j)
                    ++i;
                else
                {
                    ++j;
                    i = 0;
                }
                if (j >= nInstances)
                {
                    ctrl_done_->setValue(true);
                    j = -1; //used to signal that there are no more instance pairs to compute
                    i = -1; //used to signal that there are no more instance pairs to compute
                }
                else
                    ctrl_done_->setValue(false);

                //set indexes into the ctrl_instanceIndexes_ control
                instIdxs(0) = i;
                instIdxs(1) = j;
            }
            else
            {