Exemple #1
0
void
SimulMaskingFft::myProcess(realvec& in, realvec& out)
{
  for (mrs_natural t = 0; t < inSamples_; t++)
  {
    in.getCol(t, processBuff_);

    // normalize spectrum
    processBuff_	*= normFactor_;
    processBuff_	*= processBuff_;

    // weight with outer ear transfer function
    processBuff_	*= outerEar_;

    // compute bark spectrum
    GetBandLevels (freqBounds_, barkSpec_, false);

    // add internal noise
    barkSpec_	+= intNoise_;

    // compute spreading function
    CalcSpreading (barkSpec_, excPattern_);

    // apply  masking threshold
    excPattern_	*= maskingThresh_;

    // normalize input spectrum
    in.getCol(t, processBuff_);
    processBuff_	*= normFactor_;
    processBuff_	*= processBuff_;

    // compute difference
    ComputeDifference (out, processBuff_,  t);

  }
}
void
StereoSpectrumSources::myProcess(realvec& in, realvec& out)
{
  mrs_natural t,o;
  for (t = 0; t < inSamples_; t++)
  {
    //start by sorting in non-descending order the panning values
    //of all spectrum bins of the current frame
    in.getCol(t, orderedPans_);
    orderedPans_.sort();

    //MATLAB_PUT(orderedPans_, "orderedPans");
    //MATLAB_EVAL("plot(orderedPans)");

    //calculate derivative, i.e changes of panning
    panChanges_.create(inObservations_-1);
    for(o=0; o<inObservations_-1; ++o)
      panChanges_(o) = orderedPans_(o+1)-orderedPans_(o);

    //MATLAB_PUT(panChanges_, "panChanges");
    //MATLAB_EVAL("plot(panChanges)");

    //look for peaks in pan changes, i.e. a good estimate of
    //the number of stereo sources in the signal
    panPeaks_.create(inObservations_-1);
    panPeaker_->process(panChanges_, panPeaks_);

    //MATLAB_PUT(panPeaks_, "panPeaks");
    //MATLAB_EVAL("plot(panPeaks)");

    out(0, t) = 0.0;
    for(o=0; o < inObservations_-1; ++o)
      out(0,t) += (panPeaks_(o) != 0.0);//peaks are the non-zero values in panPeaks_

    //cout << out(0,t) << endl;

    // other option for calculating this (pseudo-code):
    // if abs(running-average - current_value) > 0.3 * running_average
  }
}
void 
GMMClassifier::myProcess(realvec& in, realvec& out)
{
	mrs_string mode = ctrl_mode_->to<mrs_string>();
	
	// reset 
	if ((prev_mode_ == "predict") && (mode == "train"))
	{
		//just drop all accumulated feature vectors and
		//copy take the new ones from the input
		trainMatrix_ = in;
	}
	
	if (mode == "train")  
	{
		MRSASSERT(trainMatrix_.getRows() == inObservations_);
		
		//stretch to acommodate input feat Vecs
		mrs_natural storedFeatVecs = trainMatrix_.getCols();
		trainMatrix_.stretch(inObservations_, storedFeatVecs + inSamples_);
		
		//append input data
		for(mrs_natural c=0; c < inSamples_; ++c)
			for(mrs_natural r = 0; r < inObservations_; ++r)
				trainMatrix_(r, c+storedFeatVecs) = in(r,c);
	}
	
	if (mode == "predict")
	{
		mrs_real maxProb = 0.0;
		mrs_natural maxClass = 0;
		mrs_real prob;
		mrs_real dist;
		realvec vec;
		realvec means;
		realvec covars;
		
		MRSASSERT(trainMatrix_.getRows() == inObservations_);
		
		for(mrs_natural t=0; t < inSamples_; ++t)
		{	
			
			in.getCol(t, vec);
			
			for (mrs_natural cl=0; cl < classSize_; cl++)
			{
				for (mrs_natural k=0; k < nMixtures_; k++)
				{
					means_[cl].getCol(k, means);
					covars_[cl].getCol(k, covars);
					dist = NumericLib::mahalanobisDistance(vec, means, covars);					
					likelihoods_(cl,k) = weights_[cl](k) / dist;
				}
				prob = 0.0;
				for (mrs_natural k=0; k < nMixtures_; k++)
				{
					prob += likelihoods_(cl,k);
				}
				if (prob > maxProb) 
				{
					maxProb = prob;
					maxClass = cl;
				}
			}
			out(0,t) = in(labelRow_, t);
			out(1,t) = (mrs_real)maxClass; //FIXME: what about he maxProb (i.e. Confidence)?
		}
	}
	
	prev_mode_ = mode;
}
void
PeakConvert2::myProcess(realvec& in, realvec& out)
{
  mrs_natural o,i;
  out.setval(0);
  peakView pkViewOut(out);

  const mrs_bool useMasking	= getctrl("mrs_bool/useMasking")->to<mrs_bool>();
  const mrs_real probThresh	= getctrl("mrs_real/probabilityTresh")->to<mrs_real>();

  max_->updControl("mrs_natural/nMaximums", frameMaxNumPeaks_);

  max_->setctrl("mrs_natural/inSamples", size_);
  max_->setctrl("mrs_natural/inObservations", 1);
  max_->update();
  tmp_.stretch(frameMaxNumPeaks_*2);

  for(mrs_natural f=0 ; f < inSamples_; ++f)
  {
    //we should avoid the first empty frames,
    //that will contain silence and consequently create
    //discontinuities in the signal, ruining the peak calculation!
    //only process if we have a full data vector (i.e. no zeros)
    if(frame_ >= skip_)
    {
      // get pair of ffts
      in.getCol (f, tmpBuff_);

      // compute magnitude, phase, and instantaneous frequency
      this->ComputeMagnitudeAndPhase (tmpBuff_);

      // compute masking threshold
      if (useMasking && pick_)
        ComputeMasking (tmpBuff_);
      else
        masked_.setval(10.);

      // select bins with local maxima in magnitude (--> peaks)
      peaks_ = mag_;
      if(pick_)
        this->ComputePeaker (mag_, peaks_);
      else
      {
        for (o = 0 ; o < downFrequency_ ; o++)
          peaks_(o)=0.0;
        for (o = upFrequency_ ; o < (mrs_natural)peaks_.getSize() ; o++)
          peaks_(o)=0.0;
      }

      if (lpCoeff_ > 0)
        FreqSmear (lpPeakerRes_);

      //compute the probability of a peak being a peak
      for(o=0 ; o < size_ ; o++)
      {
        if (peaks_(o) <= 0)
        {
          frequency_(o)		= .0;
          //lastmag_(o)		= .0;
          lastfrequency_(o)	= .0;
          // time smearing if no new peak
          lpPeakerRes_(o)	*=lpCoeff_;
          continue;
        }
#ifdef ORIGINAL_VERSION
        // probability of peak being a masker
        peakProb_(0)	= 0;
        // probability of peak being stationary
        peakProb_(1)	= 0;
        // probability of peak being tonal
        peakProb_(2)	= (abs(frequency_(o)/fundamental_-o) > .5)? 0 : 1;
#else
        // probability of peak being a masker
        peakProb_(0)	= max((mrs_real).1, (mrs_real).5 * (mrs_real)(log10(masked_(o)) +1.));
        // probability of peak being stationary
        peakProb_(1)	= max((mrs_real).1, (mrs_real)lpPeakerRes_(o));
        // probability or peak being tonal
        peakProb_(2)	= GaussianPdf (frequency_(o)/fundamental_-o, gaussianStd);
#endif

        // reset lpPeakerRes with peaker results
        lpPeakerRes_(o)	= 1;

        peakProb_ *= peakProbWeight_;
        if ((peakProb_.sum() < probThresh) && pick_)
        {
          peaks_(o)		= .0;
          frequency_(o)	= .0;
          //lastmag_(o)		= .0;
          lastfrequency_(o)	= .0;
        }
      }

      // keep only the frameMaxNumPeaks_ highest amplitude local maxima
      tmp_.setval(0.);
      max_->process(peaks_, tmp_);

      nbPeaks_=tmp_.getSize()/2;
      realvec index_(nbPeaks_); //[!] make member to avoid reallocation at each tick!
      for (i=0 ; i<nbPeaks_ ; i++)
        index_(i) = tmp_(2*i+1);

      // search for bins interval
      realvec interval_(nbPeaks_*2); //[!] make member to avoid reallocation at each tick!
      interval_.setval(0);
      if(pick_)
        getShortBinInterval(interval_, index_, mag_);
      else
      {
        for (i=0 ; i<nbPeaks_ ; i++)
          interval_(2*i+1) = index_(i);
      }

#ifdef LOG2FILE
      for (i=0 ; i<nbPeaks_ ; i++)
      {
        mrs_real value = frequency_((mrs_natural) (index_(i)+.1));
        pFDbgFile << std::scientific << std::setprecision(4) << value << "\t";
      }
      pFDbgFile << std::endl;
#endif
#ifdef MARSYAS_MATLAB
#ifdef MTLB_DBG_LOG
      MATLAB_PUT(mag_, "peaks");
      MATLAB_PUT(peaks_, "k");
      MATLAB_PUT(tmp_, "tmp");
      MATLAB_PUT(interval_, "int");
      MATLAB_PUT(frequency_, "freq");
//			MATLAB_EVAL("figure(1);clf;hold on ;plot(peaks);stem(k);stem(tmp(2:2:end)+1, peaks(tmp(2:2:end)+1), 'r')");
//			MATLAB_EVAL("stem(int+1, peaks(int+1), 'k')");
      MATLAB_EVAL("figure(1);hold on ;stem(freq(tmp(2:2:end)+1), peaks(tmp(2:2:end)+1), 'r');hold off");
#endif
#endif


      // fill output with peaks data
      interval_ /= N_;

      for (i = 0; i < nbPeaks_; i++)
      {
        mrs_natural index = (mrs_natural) (index_(i)+.1);
        pkViewOut(i, peakView::pkFrequency, f) = frequency_(index);
        pkViewOut(i, peakView::pkAmplitude, f) = magCorr_(index);
        pkViewOut(i, peakView::pkPhase, f) = -phase_(index);
        pkViewOut(i, peakView::pkDeltaFrequency, f) = deltafrequency_(index);
        pkViewOut(i, peakView::pkDeltaAmplitude, f) = /*abs*/(deltamag_(index));
        pkViewOut(i, peakView::pkFrame, f) = frame_;
        pkViewOut(i, peakView::pkGroup, f) = 0.;//(pick_)?-1.:0.; //This should be -1!!!! [TODO]
        pkViewOut(i, peakView::pkVolume, f) = 1.0;
        pkViewOut(i, peakView::pkBinLow, f) = interval_(2*i);
        pkViewOut(i, peakView::pkBin, f) = index_(i);
        pkViewOut(i, peakView::pkBinHigh, f) = interval_(2*i+1);
        pkViewOut(i, peakView::pkTrack, f) = -1.0; //null-track ID

        MRSASSERT((index_(i) <= interval_(2*i)) || (interval_(2*i+1) <= index_(i)));

        if(useStereoSpectrum_)
          pkViewOut(i, peakView::pkPan, f) = in((mrs_natural)index_(i)+2*N_, f);
        else
          pkViewOut(i, peakView::pkPan, f) = 0.0;
      }
    }
    else //if not yet reached "skip" number of frames...
    {
      for(mrs_natural i=0; i< frameMaxNumPeaks_; ++i)
      {
        //pkViewOut(i, peakView::pkFrequency, f) = 0;
        //pkViewOut(i, peakView::pkAmplitude, f) = 0;
        //pkViewOut(i, peakView::pkPhase, f) = 0;
        //pkViewOut(i, peakView::pkDeltaFrequency, f) = 0;
        //pkViewOut(i, peakView::pkDeltaAmplitude, f) = 0;
        pkViewOut(i, peakView::pkFrame, f) = frame_;
        //pkViewOut(i, peakView::pkGroup, f) = -1;
        //pkViewOut(i, peakView::pkVolume, f) = 0;
        //pkViewOut(i, peakView::pkPan, f) = 0;
        //pkViewOut(i, peakView::pkBinLow, f) = 0;
        //pkViewOut(i, peakView::pkBin, f) = 0;
        //pkViewOut(i, peakView::pkBinHigh, f) = 0;
      }
    }
    frame_++;
  }

  //count the total number of existing peaks (i.e. peak freq != 0)
  ctrl_totalNumPeaks_->setValue(pkViewOut.getTotalNumPeaks());
}
Exemple #5
0
void
McAulayQuatieri::myProcess(realvec& in, realvec& out)
{
  mrs_natural t,o,c;
  t=0;
  o=0;
  c=0;

  realvec* outPtr;

  out(o,t) = in(o,t);          //    ??????

  //if we want to use memory and we already have data from
  //past inputs (i.e. memory is not empty)...
  if(ctrl_useMemory_->to<mrs_bool>() && memory_.getSize() != 0)
  {
    //concatenate memory column vector with current input
    //so we can continue peak tracking from previous input
    tmp_.stretch(onObservations_, onSamples_+1);
    for(o = 0; o < onObservations_; ++o)
      tmp_(o, 0) = memory_(o);
    for(o = 0; o < onObservations_; ++o)
      for(c = 0; c < onSamples_; ++c)
        tmp_(o,c+1) = in(o,c);
    outPtr = &tmp_;

    //attempt matching of groups between the frame in memory
    //and the first frame from current input
    if(ctrl_useGroups_->to<mrs_bool>())
    {
      peakView inPV(in);
      mrs_realvec inFirstFrame;
      in.getCol(0, inFirstFrame);
      peakView inFirstFramePV(inFirstFrame);
      peakView memPV(memory_);
      peakView tmpPV(tmp_);

      //mrs_natural numInGroups = inPV.getNumGroups();
      mrs_natural numInFirstFrameGroups = inFirstFramePV.getNumGroups();
      mrs_natural numMemGroups = memPV.getNumGroups();

      //we must update the group numbers of the groups
      //in tmp realvec (i.e. [mem|current input])
      //so they do not clash with the previous ones
      if(nextGroup_ > 0)
        for(mrs_natural f=1; f < tmpPV.getNumFrames(); ++f)
          for(mrs_natural p = 0; p < tmpPV.getFrameNumPeaks(f); ++p)
            tmpPV(p, peakView::pkGroup, f) = tmpPV(p, peakView::pkGroup, f) + nextGroup_;

      // Try matching previous groups (in memory from last input)
      // with groups in current input

      // create a tmp copy of the frame in memory and the first frame
      // of current input, so we can do the group matching without
      // destroying the input values
      realvec frames2Match(inObservations_, 2);

      // calculate the matching score for all pairs of groups under matching
      realvec matchScores(numInFirstFrameGroups, numMemGroups);
      for(mrs_natural mg=0; mg < numMemGroups; ++mg)
      {
        for(mrs_natural ig = nextGroup_; ig < nextGroup_ + numInFirstFrameGroups; ++ig)
        {
          //since peakTrack(...) is destructible, we must reset frames2Match everytime... [!]
          for(o=0; o<inObservations_; ++o)
            for(c=0; c < 2; ++c)
              frames2Match(o, c) = tmp_(o, c);

          //use McAulay-Quatieri num of successful peak continuations as a score
          //for the group matching (may be replaced by some other metric in future)
          matchScores(ig-nextGroup_, mg) = peakTrack(frames2Match, 0, ig, mg);
        }
      }

      //Given the matchScores, try to find the optimal assignment
      //of the groups coming from previous input (stored in memory)
      //and the new groups in the current input
      //(using, for e.g. the hungarian method)
      realvec assignedGrp(numInFirstFrameGroups);

      //convert matchScores to costs
      mrs_real maxScore = matchScores.maxval();
      for(o=0; o < matchScores.getRows(); ++o)
        for(c=0; c < matchScores.getCols(); ++ c)
          matchScores(o,c) = maxScore - matchScores(o,c);

      NumericLib::hungarianAssignment(matchScores, assignedGrp); //!!!!!!!!!!!!!!! [TODO][!]

      // given the assignments, try to propagate the group IDs
      // to the groups in the current input
      mrs_natural ig;
      for(mrs_natural f=1; f < tmpPV.getNumFrames(); ++f)
      {
        for(mrs_natural p = 0; p < tmpPV.getFrameNumPeaks(f); ++p)
        {
          //get input group ID (converted to the range [0:...])
          ig = (mrs_natural)(tmpPV(p, peakView::pkGroup, f)) - nextGroup_;

          if(assignedGrp(ig) > -1) //a match was found for this group (ig)
          {
            //check if match is higher than the specified threshold
            if((maxScore - matchScores(ig, (mrs_natural)assignedGrp(ig))) / memPV.getFrameNumPeaks(0,(mrs_natural)assignedGrp(ig)) > ctrl_matchThres_->to<mrs_real>())
            {
              //match confirmed --> propagate group ID
              tmpPV(p, peakView::pkGroup, f) = assignedGrp(ig);
            }
            else //match below threshold --> set as new group
            {
              tmpPV(p, peakView::pkGroup, f) = nextGroup_;
              assignedGrp(ig) = nextGroup_;
              nextGroup_++;
            }
          }
          else //no match found for this group! --> set as new group
          {
            tmpPV(p, peakView::pkGroup, f) = nextGroup_;
            assignedGrp(ig) = nextGroup_;
            nextGroup_++;
          }
        }
      }
    }
  }
  else
  {
    //no need to concatenate memory information with
    //current input. Just do it inplace in the output realvec (avoid extra copy)!
    outPtr = &out;
  }

  peakView tmpPeakView(*outPtr);

  /////////////////////////////////////////////////////////////////////////////
  mrs_natural numGroups;
  mrs_natural g;
  if(ctrl_useGroups_->to<mrs_bool>())
  {
    numGroups = tmpPeakView.getNumGroups();
    g = 0;
  }
  else
  {
    numGroups = 0;
    g = -1;
  }
  //iterate over groups (if any or enabled)
  for(; g < numGroups; ++g)
  {
    //if no memory being used (or no memory stored yet), we must use peaks
    //in first frame to give birth to new tracks
    if(!ctrl_useMemory_->to<mrs_bool>() || memory_.getSize() == 0)
    {
      for(mrs_natural n = 0; n < tmpPeakView.getFrameNumPeaks(0, g); ++n)
        tmpPeakView(n, peakView::pkTrack, 0) = (mrs_real) n;
    }

    //iterate over input frames
    for(mrs_natural f=0; f < tmpPeakView.getNumFrames()-1; ++f)
      peakTrack(*outPtr, f, g, g);
  }

  //if using memory...
  if(ctrl_useMemory_->to<mrs_bool>())
  {
    if(memory_.getSize() != 0)
    {
      //if using a non-empty memory, we should now fill the trackID and GroupID parameters
      //computed above (and stored in the tmp realvec) into the actual output
      peakView outPeakView(out);
      for(mrs_natural f=0; f < outPeakView.getNumFrames(); ++f)
        for(mrs_natural p = 0; p < outPeakView.getFrameNumPeaks(f); ++p)
        {
          outPeakView(p, peakView::pkTrack, f) = tmpPeakView(p, peakView::pkTrack, f+1);
          outPeakView(p, peakView::pkGroup, f) = tmpPeakView(p, peakView::pkGroup, f+1);
        }
    }

    //store the last frame of current output for next time
    memory_.stretch(onObservations_, 1);
    for(o = 0; o < onObservations_; ++o)
      memory_(o, 0) = out(o, onSamples_-1);
  }
}
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
            {
void 
OneRClassifier::myProcess(realvec& in, realvec& out)
{
  cout << "OneRClassifier::myProcess" << endl;
  cout << "in.getCols() = " << in.getCols() << endl;
  cout << "in.getRows() = " << in.getRows() << endl;
  //get the current mode, either train of predict mode
  bool trainMode = (getctrl("mrs_string/mode")->to<mrs_string>() == "train");
  row_.stretch(in.getRows());
  if (trainMode)
    {
      if(lastModePredict_ || instances_.getCols()<=0)
	{
	  mrs_natural nAttributes = getctrl("mrs_natural/inObservations")->to<mrs_natural>();
	  cout << "nAttributes = " << nAttributes << endl;
	  instances_.Create(nAttributes);
	}
      
      lastModePredict_ = false;
      
      //get the incoming data and append it to the data table
      for (mrs_natural ii=0; ii< inSamples_; ++ii)
	{
	  mrs_real label = in(inObservations_-1, ii);
	  instances_.Append(in);
	  out(0,ii) = label;
	  out(1,ii) = label;
	}//for t
    }//if
  else
    {//predict mode

	  cout << "OneRClassifier::predict" << endl;
	  if(!lastModePredict_)
	    {
	      //get the number of class labels and build the classifier
	      mrs_natural nAttributes = getctrl("mrs_natural/inObservations")->to<mrs_natural>();
	      cout << "BUILD nAttributes = " << nAttributes << endl;
	      Build(nAttributes);
	    }//if
	  lastModePredict_ = true;
	  cout << "After lastModePredict" << endl;


      //foreach row of predict data, extract the actual class, then call the
      //classifier predict method. Output the actual and predicted classes.
      for (mrs_natural ii=0; ii<inSamples_; ++ii)
	{
	  //extract the actual class
	  mrs_natural label = (mrs_natural)in(inObservations_-1, ii);
	      
	  //invoke the classifier predict method to predict the class
	  in.getCol(ii,row_);
	  mrs_natural prediction = Predict(row_);
	  cout << "PREDICTION = " << prediction << endl;
	  cout << "row_ " << row_ << endl;

	  //and output actual/predicted classes
	  out(0,ii) = (mrs_real)prediction;
	  out(1,ii) = (mrs_real)label;
	}//for t
    }//if
	
}//myProcess