void AlgebraManager::matchingOperators(const int algId,
                                       const ListExpr arguments,
                       vector< pair< pair<int,int>, ListExpr> >& result){
  assert( (algId>0) && (algId<(int)algebra.size()) ); // 0 is an invalid algId!
  ListExpr typeError = nl->SymbolAtom(Symbol::TYPEERROR());
  Algebra* alg = algebra[algId];
  if(alg!=0){
    for(int o=0 ; o<alg->GetNumOps() ; o++){
      Operator* op = alg->GetOperator(o);
      try{
          ListExpr res = op->CallTypeMapping(arguments);
         // cout << "Check finished" << endl << endl;
          if(!nl->Equal(res,typeError)){
            pair<int, int> p1(algId,o);
            pair<pair<int, int>, ListExpr> p(p1, res);
            result.push_back(p);
          }
      } catch (...){
          cerr << "Problem in Typemapping of operator " << op->GetName()
               << " in Algebra" << GetAlgebraName(algId) << endl;
          cerr << "Throws an exception when called with "
               << nl->ToString(arguments) << endl;
      }
    }
  }
}
Operator*
AlgebraManager::GetOP( int algebraId, int opId )
{
  if(algebraId < 0 || algebraId >= (int)algebra.size()){
    return 0;
  }
  Algebra* alg = algebra[algebraId];
  if(!alg){
    return 0;
  }
  return  alg->GetOperator(opId);
}
void testMultiplicationSquares(std::size_t noBits, DynamicElementStorageType lhsStorage, DynamicElementStorageType rhsStorage)
{
    Bitset activeBits;
    for(std::size_t i = 0; i < noBits; ++i)
        activeBits[std::rand() & MAX_K_VALUE] = true;

    Element lhs(activeBits, lhsStorage);

    // get a non-zero value
    Z2k value;
    while(value.getValue() == 0)
        value = Z2k( rand() & activeBits.to_ulong() );

    // get a coeff
    GaloisField coeff( rand() & 255 );

    lhs.setCoefficient(value, coeff);
    lhs.setCoefficient(Z2k(), coeff);


    Element rhs(lhs, rhsStorage);

    Element prod;
    algebra.multiply(lhs, rhs, prod);

    BOOST_CHECK_EQUAL(prod.isZero(), true);
}
 void operator()( Algebra &algebra , const StateIn &in , StateOut &out , const StepStorage &steps , const Coefficients &coef , Time dt ) const
 {
     typedef typename Coefficients::value_type value_type;
     algebra.for_each7( out , in , steps[0].m_v , steps[1].m_v , steps[2].m_v , steps[3].m_v , steps[4].m_v ,
             typename Operations::template scale_sum6< value_type , Time , Time , Time , Time >(
                     1.0 , dt * coef[0] , dt * coef[1] , dt * coef[2] , dt * coef[3] , dt * coef[4] ) );
 }
Exemple #5
0
std::pair<Algebra, Algebra> Algebra::algDiv(const Algebra &D) const
/**
  Divide by D algebrically
  @param D :: Divisor
  @return Quotian + Remainder
 */
{
  Algebra Q;
  Algebra R;
  Acomp Tf = F;
  // std::cerr<<"AlgDiv:"<<std::endl;
  std::pair<Acomp, Acomp> QR = Tf.algDiv(D.F);
  if (!QR.first.isNull() && !QR.second.isNull()) {
    Q.setFunction(QR.first);
    R.setFunction(QR.second);
  }
  return std::pair<Algebra, Algebra>(Q, R);
}
Exemple #6
0
R PPForest<L>::maxScore(const Algebra<R,L> &alg, size_type i, size_type j) const
{
	R down, over;

	if(j==0)
		return 0;

	if(isLeave(i))
	{
		over=maxScore(alg,rb(i),j-1);
		return alg.replace(label(i),0,label(i),over);
	}
	else
	{
		down=maxScore(alg,i+1,noc(i));
		over=maxScore(alg,rb(i),j-1);
		return alg.replace(label(i),down,label(i),over);
	}
}  
Exemple #7
0
            static Size Search3D (const System::Collection::Array<1,Vector<3,T> > &p, Size a, Size b)
            {
                Size c;
                for (c = 0; c == a || c == b; c++)
                    ;

                Hyperplane<3,T> h(CrossProduct(p[b]-p[a],p[c]-p[a]), p[a]);

                for (Size i = c + 1; i < p.Elements(); i++) 
                {
                    if (i != a && i != b && h.IsAbove(p[i]))
                    {
                        c = i;
                        h.Set(CrossProduct(p[b]-p[a],p[c]-p[a]), p[a]);
                    }
                }

                return c;
            }
void testMultiplicationSameBitset(std::size_t noBits, std::size_t noElements, DynamicElementStorageType lhsStorage, DynamicElementStorageType rhsStorage)
{
    std::size_t k2 = (1 << noBits);

    Bitset activeBits = k2 - 1;

    Element lhs(activeBits, lhsStorage);
    Element rhs(activeBits, rhsStorage);

    initializeElement(lhs, activeBits, noElements);
    initializeElement(rhs, activeBits, noElements);

    Element prod;
    algebra.multiply(lhs, rhs, prod);

    checkMultiplicationResult(lhs, rhs, prod);
}
void AlgebraManager::findTMExceptions(const string& algName,
                                      const ListExpr argList,
                                      queue<pair<string,string> >& q,
                                      const bool print) {

   if(algName.size()==0){
     for(unsigned int a=1 ; a<algebra.size() ; a++){ // algId=0 is prohibited
       Algebra* alg = algebra[a];
       if(alg!=0){
          if(print){
              cout << "process algebra" << GetAlgebraName(a) << endl;
          }
          for(int o=0;o<alg->GetNumOps(); o++){
             Operator* op = alg->GetOperator(o);
             if(print){
               cout << "process operator " << op->GetName() << endl; 
             }  
             try{
               op->CallTypeMapping(argList);
             } catch(...){
               pair<string,string> p(GetAlgebraName(a), op->GetName());
               q.push(p);  
             }
          }
       }    
     }
   } else {
     int a = GetAlgebraId(algName);
     if(a<1){
        if(print){
          cout << "Algebra " << algName << " not found" << endl;
        }
        return;
     }
     if(print){
         cout << "process algebra" << GetAlgebraName(a) << endl;
     }
     Algebra* alg = algebra[a];
     for(int o=0;o<alg->GetNumOps(); o++){
        Operator* op = alg->GetOperator(o);
        if(print){
          cout << "process operator " << op->GetName() << endl; 
        }  
        try{
          op->CallTypeMapping(argList);
        } catch(...){
          pair<string,string> p(GetAlgebraName(a), op->GetName());
          q.push(p);  
        }
     }
   }
}
void testMultiplicationDifferentBitset(std::size_t noBits, std::size_t noElements, DynamicElementStorageType lhsStorage, DynamicElementStorageType rhsStorage)
{
    Bitset lr, nr;

    for(std::size_t i = 0; i < noBits; ++i)
    {
        lr[i] = (std::rand() % 2 == 0);
        nr[i] = (std::rand() % 2 == 0);
    }

    Element lhs(lr, lhsStorage);
    Element rhs(nr, rhsStorage);

    initializeElement(lhs, lr, noElements);
    initializeElement(rhs, nr, noElements);

    Element prod;
    algebra.multiply(lhs, rhs, prod);

    checkMultiplicationResult(lhs, rhs, prod);
}
 void process(Algebra &algebra) const
 {
     Type a00 = algebra.getInput(0,0);
     Type result = (a00 & Type((uint16_t)0x00FF)) << 4;
     algebra.putOutput(0,0,result);
 }
    void for_each3( Iterator1 first1 , Iterator1 last1 , Iterator2 first2 , Iterator3 first3, Operation op , Algebra &algebra )
{
    for( ; first1 != last1 ; )
        algebra.for_each3( *first1++ , *first2++ , *first3++ , op );
}
Exemple #13
0
void Alignment<R,L,AL>::calculateGlobal(const PPForest<L> *ppfx, const PPForest<L> *ppfy, const Algebra<R,L> &alg, bool noSpeedup)
{
	assert(ppfx != NULL);
	assert(ppfy != NULL);

	Ulong m,n,h,cols;
	long i,k;
	Uint j,l,r;

	R score,h_score;

	// alloc space for the score matrix, backtrack structure  and , if wanted, for the calculation-order-matrix
	m_mtrxSize=ppfx->getNumCSFs()*ppfy->getNumCSFs();

	m_mtrx=new R[m_mtrxSize];
	m_rowStart=new Ulong[ppfx->getNumCSFs()];
	m_ppfx = new PPForest<L>(*ppfx);				// copy the ppforests
	m_ppfy = new PPForest<L>(*ppfy);
	m_alg=&alg;
	m_rnaAlg=NULL;
	m_localOptimum=alg.worst_score();


	// initialize variables
	m=ppfx->size();
	n=ppfy->size();
	cols=ppfy->getNumCSFs();

	m_rowStart[0]=0;
	for(h=1;h<ppfx->getNumCSFs();h++)
		m_rowStart[h]=m_rowStart[h-1]+cols;

	// align forests fx and fy

	// the easiest case .. 
	setMtrxVal(0,0,alg.empty());

	// align fx to the empty forest (fill first row of array)
	for(i=m-1;i>=0;i--)  // for all nodes in fx
	{
		for(j=1;j<=ppfx->getMaxLength(i);j++)  // for all non empty csfs induced by i
		{
			score = alg.del(ppfx->label(i),
				            getMtrxVal(ppfx->down(i),0),
				            getMtrxVal(ppfx->over(i,j),0));	  

			setMtrxVal(ppfx->indexpos(i,j),0,score);
		}
	}

	// align fy to the empty forest (fill first column of array)
	for(k=n-1;k>=0;k--)  // for all nodes in fx
	{
		for(l=1;l<=ppfy->getMaxLength(k);l++)  // for all non empty csfs induced by k
		{
			score = alg.insert(getMtrxVal(0,ppfy->down(k)),
					            ppfy->label(k),
					            getMtrxVal(0,ppfy->over(k,l)));

			setMtrxVal(0,ppfy->indexpos(k,l),score);
		}
	}

	// align the rest
	for(i=m-1;i>=0;i--)  // for all nodes in fx  
		for(k=n-1;k>=0;k--)  // for all nodes in fx
		        {
			        j=ppfx->getMaxLength(i);
				for(l=1;l<=ppfy->getMaxLength(k);l++)  // for all non empty csfs induced by k
				{
					// replace
		  
					score = alg.replace(ppfx->label(i),
							            getMtrxVal(ppfx->down(i),ppfy->down(k)),
							            ppfy->label(k),
							            getMtrxVal(ppfx->over(i,j),ppfy->over(k,l)));
					
					// delete				       
					if(ppfx->noc(i)==0 && !noSpeedup)  // no child
					  {
					    h_score = alg.del(ppfx->label(i),0,
							              getMtrxVal(ppfx->over(i,j),ppfy->indexpos(k,l)));

						score=alg.choice(score,h_score);
					  }
					else					  
					  {	
					    if(ppfx->rb(i)==0 && !noSpeedup) // no right brother
					      {
						h_score = alg.del(ppfx->label(i),
								  getMtrxVal(ppfx->down(i),ppfy->indexpos(k,l)),
								  0);
						
						score=alg.choice(score,h_score);
					      }
					    else
					      {
						h=k;               // h is the node where the suffix of the split begins		   					
						for(r=0;r<=l;r++)  // for all splits of fy
						  {
						    h_score = alg.del(ppfx->label(i),
							              getMtrxVal(ppfx->down(i),ppfy->indexpos(k,r)),
							              getMtrxVal(ppfx->over(i,j),ppfy->indexpos(h,l-r)));
						    
						    score=alg.choice(score,h_score);
						    h=ppfy->rb(h);
						  }
					      }
					  }

					// insert
					if(ppfy->noc(k)==0 && !noSpeedup) // no child
					  {
					    h_score = alg.insert(0,
							                 ppfy->label(k),
							                 getMtrxVal(ppfx->indexpos(i,j),ppfy->over(k,l)));

						score=alg.choice(score,h_score);
					  }
					else
					  {
					    if(ppfy->rb(k)==0 && !noSpeedup) // no right brother
					      {
						h_score = alg.insert(getMtrxVal(ppfx->indexpos(i,j),ppfy->down(k)),
								     ppfy->label(k),
								     0);
						
						score=alg.choice(score,h_score);
					      }					 
					    else
					      {
						h=i;
						for(r=0;r<=j;r++) // for all splits of fx
						  {
						    h_score = alg.insert(getMtrxVal(ppfx->indexpos(i,r),ppfy->down(k)),
							                 ppfy->label(k),
									 getMtrxVal(ppfx->indexpos(h,j-r),ppfy->over(k,l)));
						    
						    score=alg.choice(score,h_score);
						    h=ppfx->rb(h);
						  }
					      }
					  }

					// set value
					setMtrxVal(ppfx->indexpos(i,j),ppfy->indexpos(k,l),score);
				}

				l=ppfy->getMaxLength(k);
				for(j=1;j<=ppfx->getMaxLength(i);j++)    // for all non empty csfs induced by i
				{
					// replace
					score = alg.replace(ppfx->label(i),
							            getMtrxVal(ppfx->down(i),ppfy->down(k)),
							            ppfy->label(k),
							            getMtrxVal(ppfx->over(i,j),ppfy->over(k,l)));

					// delete				       
					if(ppfx->noc(i)==0 && !noSpeedup)  // no child
					  {
					    h_score = alg.del(ppfx->label(i),0,
							              getMtrxVal(ppfx->over(i,j),ppfy->indexpos(k,l)));

						score=alg.choice(score,h_score);
					  }
					else					  
					  {	
					    if(ppfx->rb(i)==0 && !noSpeedup) // no right brother
					      {
						h_score = alg.del(ppfx->label(i),
								  getMtrxVal(ppfx->down(i),ppfy->indexpos(k,l)),
								  0);
						
						score=alg.choice(score,h_score);
					      }
					    else
					      {
						h=k;               // h is the node where the suffix of the split begins		   					
						for(r=0;r<=l;r++)  // for all splits of fy
						  {
						    h_score = alg.del(ppfx->label(i),
							              getMtrxVal(ppfx->down(i),ppfy->indexpos(k,r)),
							              getMtrxVal(ppfx->over(i,j),ppfy->indexpos(h,l-r)));
						    
						    score=alg.choice(score,h_score);
						    h=ppfy->rb(h);
						  }
					      }
					  }

					// insert
					if(ppfy->noc(k)==0 && !noSpeedup) // no child
					  {
					    h_score = alg.insert(0,
							                 ppfy->label(k),
							                 getMtrxVal(ppfx->indexpos(i,j),ppfy->over(k,l)));

						score=alg.choice(score,h_score);
					  }
					else
					  {
					    if(ppfy->rb(k)==0 && !noSpeedup) // no right brother
					      {
						h_score = alg.insert(getMtrxVal(ppfx->indexpos(i,j),ppfy->down(k)),
								     ppfy->label(k),
								     0);
						
						score=alg.choice(score,h_score);
					      }					 
					    else
					      {
						h=i;
						for(r=0;r<=j;r++) // for all splits of fx
						  {
						    h_score = alg.insert(getMtrxVal(ppfx->indexpos(i,r),ppfy->down(k)),
							                 ppfy->label(k),
									 getMtrxVal(ppfx->indexpos(h,j-r),ppfy->over(k,l)));
						    
						    score=alg.choice(score,h_score);
						    h=ppfx->rb(h);
						  }
					      }
					  }

					// set value
					setMtrxVal(ppfx->indexpos(i,j),ppfy->indexpos(k,l),score);
				}
			}

	//      showArray(m_mtrx,ppfx->getNumCSFs(),ppfy->getNumCSFs());
	resetOptLocalAlignment(100);
}
 void operator()( Algebra &algebra , const StateIn &in , StateOut &out , const DerivIn &dxdt , const StepStorage &steps , const Coefficients &coef , Time dt ) const
 {
     typedef typename Coefficients::value_type value_type;
     algebra.for_each3( out , in , dxdt , typename Operations::template scale_sum2< value_type , Time >( 1.0 , dt * coef[0] ) );
 }
bool AlgebraManager::findOperator(const string& name,
                                  const ListExpr argList,
                                  ListExpr& resultList,
                                  int& algId,
                                  int& opId,
                                  int& funId){

   ListExpr typeError = nl->SymbolAtom(Symbol::TYPEERROR());

   NestedList* nl_orig = NList::getNLRef();
   NList::setNLRef(nl);

   int mode = 0;  // normal mode, search for matching arglist
   string algName ="";
   if(nl->HasLength(argList,2)){
     if(nl->IsEqual(nl->First(argList),"algebra")
        && nl->AtomType(nl->Second(argList)==SymbolType)){
        mode = 1; // search within a specific algebra
        algName = nl->SymbolValue(nl->Second(argList));
        stringutils::toLower(algName);
        if(algName=="all"){
           mode = 2; // search all algebras, return first hit
        }
     } 
   }
   for(unsigned int a=0;a<algebra.size();a++){
     Algebra* alg = algebra[a];
     if(alg!=0){
       string an = algebraNames[a];
       stringutils::toLower(an);
       if(mode==0 || mode==2 || an==algName){
         for(int o=0; o< alg->GetNumOps(); o++){
           Operator* op = alg->GetOperator(o);
           if(op->GetName() == name){
             if(mode==0){
               try{
                  ListExpr res = op->CallTypeMapping(argList);
                  if(!nl->Equal(res,typeError)){ //  appropriate operator found
                     algId = a;
                     opId = o;
                     funId = op->Select(argList);
                     resultList = res;
                     NList::setNLRef(nl_orig);
                     return true;
                  }
               } catch (...){
                  cerr << "Problem in Typemapping of operator " << op->GetName()
                       << " in Algebra" << GetAlgebraName(a) << endl;
                  cerr << "Throws an exception when called with "
                       << nl->ToString(argList) << endl;
               }
            } else { // mode <>0
                algId = a;
                opId = o;
                funId = 0;
                resultList = nl->TheEmptyList();
                NList::setNLRef(nl_orig);
                return true;
            }
          }
        }
      } // fitting algebra name
    }
  }
  algId = 0;
  opId = 0;
  resultList = nl->TheEmptyList();
  NList::setNLRef(nl_orig);
  return false;
}
 void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S3 &s3 , S4 s4_array[7] , Op op ) const
 {
     algebra.for_each10( s1 , s2 , s3 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , s4_array[3].m_v , s4_array[4].m_v ,
             s4_array[5].m_v , s4_array[6].m_v , op );
 }
void progressiveAlign(std::vector<RNAProfileAlignment*> &inputList, 
											std::vector<std::pair<double,RNAProfileAlignment*> > &resultList, const Score& score, const Options &options, bool anchored) {

		Algebra<double,RNA_Alphabet_Profile> *alg = NULL;
		AlgebraAffine<double,RNA_Alphabet_Profile> *alg_affine = NULL;

    if (options.has(Options::Affine)) {
			if (options.has(Options::CalculateDistance)) {
        alg_affine = new AffineDoubleDistProfileAlgebra(score);
			}
			else {
        alg_affine = new AffineDoubleSimiProfileAlgebra(score);
			}
		}
		else {
			// distance or similarity
			if (options.has(Options::CalculateDistance))
        alg = new DoubleDistProfileAlgebra(score);
			else
        alg = new DoubleSimiProfileAlgebra(score);
		}

    std::cout << "*** Calculation ***" << std::endl << std::endl;

    // create inputMapProfile to access a profile by an index value
    RNAProfileAliMapType inputMapProfile;
    std::vector<RNAProfileAlignment*>::const_iterator inpIt;
    long i = 1;
    for (inpIt=inputList.begin(); inpIt!=inputList.end(); inpIt++) {
        inputMapProfile[i]=*inpIt;
        i++;
    }
    inputList.clear();

    // create matrix for all against all comparison
		double bestScore;
		if (options.has(Options::Affine))
			bestScore = alg_affine->worst_score();
		else
			bestScore = alg->worst_score();
    Matrix<double> *score_mtrx = new Matrix<double>(inputMapProfile.size(),inputMapProfile.size());

    // set threshold for the clustering algorithm
    double threshold = 0; 
    if (options.has(Options::CalculateDistance))
        options.get(Options::ClusterThreshold, threshold, 20.0);
    else
        options.get(Options::ClusterThreshold, threshold, 0.7);
    std::cout << "clustering threshold is: " << threshold << std::endl;

    // set cutoff value for clustering
		double cutoff = 0;
    if (options.has(Options::CalculateDistance))
        options.get(Options::ClusterJoinCutoff, cutoff, 100.0);
    else
        options.get(Options::ClusterJoinCutoff, cutoff, 0.0);
    std::cout << "join clusters cutoff is: " << cutoff << std::endl << std::endl;

		bool topdown = options.has(Options::Topdown);
		//bool anchored = options.has(Options::Anchoring);
    bool local = options.has(Options::LocalSimilarity);
		bool printBT = options.has(Options::Backtrace);

    // generate dot file
		std::string clusterfilename = options.generateFilename(Options::Help,"_cluster.dot", "cluster.dot");  // use Help as dummy
    std::ofstream s;
    s.open(clusterfilename.c_str());
    s << "digraph forest" << std::endl << "{" << std::endl;

		// generate nodes for the input forests
	  RNAProfileAliMapType::iterator it;
    for (it = inputMapProfile.begin(); it!=inputMapProfile.end(); it++) {
        RNAProfileAlignment * f = it->second;

        s << "\"" << f->getName() << "\"" << "[label=\"" << f->getName() << "\"]" << std::endl;
        s << "\"" << f->getName() << "\"" << "[label=\"" << f->getName() << "\"]" << std::endl;
    }

		// compute all pairwise alignment scores
    // !! NOTE !! iterating through the map is ordered by key number
    // as i only calculate a triangle matrix this is a prerequisite
		long x = 0, y = 0;
		RNAProfileAlignment *f1 = NULL, *f2 = NULL;
    std::cout << "Computing all pairwise similarities" << std::endl;

    RNAProfileAliMapType::iterator it2;
    for (it=inputMapProfile.begin(); it!=inputMapProfile.end(); it++) {
        x = it->first;
        f1 = it->second;
        for (it2=inputMapProfile.begin(); it2->first<it->first; it2++) {
            y = it2->first;
            f2 = it2->second;

						if (options.has(Options::Affine)) {
							AlignmentAffine<double,RNA_Alphabet_Profile,RNA_Alphabet_Profile> * ali = new AlignmentAffine<double,RNA_Alphabet_Profile,RNA_Alphabet_Profile>(f1,f2,*alg_affine,topdown,anchored,local,printBT);
	            if (local)
		              score_mtrx->setAt(x-1,y-1,ali->getLocalOptimum());
			        else
				          score_mtrx->setAt(x-1,y-1,ali->getGlobalOptimumRelative());

					    std::cout << x << "," << y << ": " << score_mtrx->getAt(x-1,y-1) << std::endl;
							delete ali;
						}
						else {
							AlignmentLinear<double,RNA_Alphabet_Profile,RNA_Alphabet_Profile> * ali = new AlignmentLinear<double,RNA_Alphabet_Profile,RNA_Alphabet_Profile>(f1,f2,*alg,topdown,anchored,local,printBT);
							if (local)
								  score_mtrx->setAt(x-1,y-1,ali->getLocalOptimum());
							else
								  score_mtrx->setAt(x-1,y-1,ali->getGlobalOptimumRelative());

							std::cout << x << "," << y << ": " << score_mtrx->getAt(x-1,y-1) << std::endl;
							delete ali;
						}
        }
    }
    std::cout << std::endl;

    std::vector<RNAProfileAliKeyPairType> inputListMult;
    long bestx = 0, besty = 0;  // keys of stuctures in inputMapProfile
    RNAProfileAlignment *f = NULL;
    int level = 1;


    while (inputMapProfile.size()>1) {
        // find the best score of all pairwise alignments
				if (options.has(Options::Affine))
					bestScore = alg_affine->worst_score();
				else
					bestScore = alg->worst_score();
        for (it=inputMapProfile.begin(); it!=inputMapProfile.end(); it++) {
            x = it->first;
            for (it2=inputMapProfile.begin(); it2->first < it->first; it2++) {
                double old_bestScore = bestScore;

                y = it2->first;

								if (options.has(Options::Affine))
									bestScore = alg_affine->choice(bestScore,score_mtrx->getAt(x-1,y-1));
								else
									bestScore = alg->choice(bestScore,score_mtrx->getAt(x-1,y-1));

                if (bestScore != old_bestScore) {
                    bestx = it->first;
                    besty = it2->first;
                    old_bestScore = bestScore;
                }
            }
        }

        std::cout << "joining alignments:" << std::endl;

        // test, if score is better than the threshold value
        // if threshold is set generate a vector of best pairs within threshold
				bool scoreBetterThanThreshold = false;
				if (options.has(Options::Affine))
					scoreBetterThanThreshold = (alg_affine->choice(bestScore,threshold)!= threshold);
				else
					scoreBetterThanThreshold = (alg->choice(bestScore,threshold)!= threshold);
        if (scoreBetterThanThreshold) {

            int maximize;

            Graph graph;
						if (options.has(Options::Affine))
							graph = makePairsGraph(inputMapProfile,alg_affine,score_mtrx,threshold);
						else
							graph = makePairsGraph(inputMapProfile,alg,score_mtrx,threshold);
            if (options.has(Options::CalculateDistance))
                maximize = 0;
            else
                maximize = 1;

            int *mate;
            mate = Weighted_Match(graph, 1, maximize);
            for (x=1; x<=score_mtrx->xDim(); x++) { // !! begins at 1 !!
                if (x<mate[x]) {
                    // if it is a best pair put it in the align vector
                    f1 = inputMapProfile[x];
                    inputMapProfile.erase(x);
                    inputListMult.push_back(std::make_pair(x,f1));
                    f2 = inputMapProfile[mate[x]];
                    inputMapProfile.erase(mate[x]);
                    inputListMult.push_back(std::make_pair(mate[x],f2));
                }
            }
            free(mate);
            free(graph);
        } else {
            // if there us no pair below the threshold
            // combine those two profile forests, that produced the best score
            f1 = inputMapProfile[bestx];
            f2 = inputMapProfile[besty];
            inputMapProfile.erase(bestx);
            inputMapProfile.erase(besty);
            inputListMult.push_back(std::make_pair(bestx,f1));
            inputListMult.push_back(std::make_pair(besty,f2));
        }

        // align all forests in the align vector.
        while (inputListMult.size()>1) {
            std::string aliName;

            x = inputListMult.front().first;
            f1 = inputListMult.front().second;
            inputListMult.erase(inputListMult.begin());
            y = inputListMult.front().first;
            f2 = inputListMult.front().second;
            inputListMult.erase(inputListMult.begin());

            // compute alignment again
            Alignment<double,RNA_Alphabet_Profile,RNA_Alphabet_Profile> * bestali = NULL;
						if (options.has(Options::Affine))
							bestali = new AlignmentAffine<double,RNA_Alphabet_Profile,RNA_Alphabet_Profile>(f1,f2,*alg_affine,topdown,anchored,local,printBT);
						else
							bestali = new AlignmentLinear<double,RNA_Alphabet_Profile,RNA_Alphabet_Profile>(f1,f2,*alg,topdown,anchored,local,printBT);
            if (local)
                bestScore = bestali->getLocalOptimum();
            else
                bestScore = bestali->getGlobalOptimumRelative();

            // test, if score is worse than the cutoff value
						bool scoreWorseThanCutoff = false;
						if (options.has(Options::Affine))
							scoreWorseThanCutoff = (alg_affine->choice(bestScore,cutoff) == cutoff);
						else
							scoreWorseThanCutoff = (alg->choice(bestScore,cutoff) == cutoff);

            if (scoreWorseThanCutoff) {
                // copy involved forests to the result vector
                std::cout << x << "," << y << ": alignment is below cutoff." << std::endl;
								std::cout << f1->getNumStructures() << "  " << f2->getNumStructures() << std::endl;
								std::cout << resultList.size() << std::endl;
								if (options.has(Options::Affine)) {
									if (f1->getNumStructures()>1)
                    resultList.push_back(std::make_pair(f1->maxScore(*alg_affine),f1));
									if (f2->getNumStructures()>1)
                    resultList.push_back(std::make_pair(f2->maxScore(*alg_affine),f2));
								}
								else {
									if (f1->getNumStructures()>1)
                    resultList.push_back(std::make_pair(f1->maxScore(*alg),f1));
									if (f2->getNumStructures()>1)
                    resultList.push_back(std::make_pair(f2->maxScore(*alg),f2));
								}
            } 
						else {
                // calculate optimal alignment and add it to inputMapProfile

								// the anchors are part of the profile alignment
                f = new RNAProfileAlignment(f1->getNumStructures(),f2->getNumStructures());

                if (local) {
                    unsigned int xbasepos,ybasepos;
                    bestali->getOptLocalAlignment(*f,xbasepos,ybasepos);
                } else {
                    bestali->getOptGlobalAlignment(*f);
                }

                f->addStrNames(f1->getStrNames());
                f->addStrNames(f2->getStrNames());
                aliName = f1->getName() + "." +f2->getName();
                f->setName(aliName);

                // for debug purposes
                //std::string dotfilename;
                //dotfilename=f->getName() + std::string(".dot");
                //				std::ofstream s("test.dot");
                //				f->printDot(s);

                // generate nodes in cluster file (dot format)
                s << "\"" << f->getName() << "\"" << "[shape=\"diamond\" label=\"" << bestScore << "\"]" << std::endl;
                s << "\"" << f->getName() << "\"" << "-> {\"" <<  f1->getName() << "\" \"" << f2->getName() << "\"}";

								long joinedClusterNumber = std::min(x, y);
                std::cout << x << "," << y << ": " << bestScore << " -> " << joinedClusterNumber << std::endl;

								// TODO problem when deleting (the anchors?)
                //delete f1;
                //delete f2;

                // calculate distance to all forests in the vector
                std::cout << "Calculate similarities to other clusters" << std::endl;
                f1 = f;
                // x remains x !!
								x = joinedClusterNumber;
                for (it=inputMapProfile.begin(); it!=inputMapProfile.end(); it++) {
                    y = it->first;
                    f2 = it->second;

										Alignment<double,RNA_Alphabet_Profile,RNA_Alphabet_Profile> * ali = NULL;
										if (options.has(Options::Affine))
											ali = new AlignmentAffine<double,RNA_Alphabet_Profile,RNA_Alphabet_Profile>(f1,f2,*alg_affine,topdown,anchored,local,printBT);
										else
											ali = new AlignmentLinear<double,RNA_Alphabet_Profile,RNA_Alphabet_Profile>(f1,f2,*alg,topdown,anchored,local,printBT);
                    if (local) {
                        score_mtrx->setAt(std::min(x-1,y-1),std::max(x-1,y-1),ali->getLocalOptimum());  // min - max = fill the upper triangle
                        std::cout << std::min(x,y) << "," << std::max(x,y) << ": " << ali->getLocalOptimum() <<  std::endl;
                    } 
										else {
                        score_mtrx->setAt(std::min(x-1,y-1),std::max(x-1,y-1),ali->getGlobalOptimumRelative());  // min - max = fill the upper triangle
                        std::cout << std::min(x,y) << "," << std::max(x,y) << ": " << ali->getGlobalOptimumRelative() <<  std::endl;
                    }
										delete ali;
                }
                std::cout << std::endl;

                // ... and append it to the vector
                inputMapProfile.insert(std::make_pair(x,f));
            }
						delete bestali;
        }

        level++;
    }

    assert(inputMapProfile.size()<2);

    // copy last profile to resultList
    if (inputMapProfile.size()==1) {
        f=inputMapProfile.begin()->second;
				if (options.has(Options::Affine))
					resultList.push_back(std::make_pair(f->maxScore(*alg_affine),f));
				else
					resultList.push_back(std::make_pair(f->maxScore(*alg),f));
        inputMapProfile.clear();
    }

    // end of dot file
    s << "}" << std::endl;

    // sort result vector
    //	std::sort(resultList.begin(),resultList.end());

		if (options.has(Options::Affine)) 
			delete alg_affine;
		else 
			delete alg;

    delete score_mtrx;
}
 void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S4 s4_array[3] , Op op ) const
 {
     algebra.for_each5( s1 , s2 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , op );
 }
 void operator()( Algebra &algebra , S1 &s1 , S2 &s2 ,  S3 &s3 , S4 s4_array[1] , Op op ) const
 {
     algebra.for_each4( s1 , s2 , s3 , s4_array[0].m_v , op );
 }
 void operator()( Algebra &algebra , S1 &s1 , S2 &s2 , S4 s4_array[12] , Op op ) const
 {
     algebra.for_each14( s1 , s2 , s4_array[0].m_v , s4_array[1].m_v , s4_array[2].m_v , s4_array[3].m_v , s4_array[4].m_v ,
             s4_array[5].m_v , s4_array[6].m_v , s4_array[7].m_v , s4_array[8].m_v , s4_array[9].m_v , s4_array[10].m_v , s4_array[11].m_v , op );
 }