WSTester updated to work plus hopefully all the other changes that need to go into...
[jabaws.git] / binaries / src / ViennaRNA / RNAforester / src / treeedit.t.cpp
diff --git a/binaries/src/ViennaRNA/RNAforester/src/treeedit.t.cpp b/binaries/src/ViennaRNA/RNAforester/src/treeedit.t.cpp
new file mode 100644 (file)
index 0000000..71283ec
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+  Copyright by Matthias Hoechsmann (C) 2002-2003
+  =====================================                                   
+  You may use, copy and distribute this file freely as long as you
+  - do not change the file,
+  - leave this copyright notice in the file,
+  - do not make any profit with the distribution of this file
+  - give credit where credit is due
+  You are not allowed to copy or distribute this file otherwise
+  The commercial usage and distribution of this file is prohibited
+  Please report bugs and suggestions to <mhoechsm@TechFak.Uni-Bielefeld.DE>
+*/
+
+#ifndef _TREE_EDIT_T_CPP_
+#define _TREE_EDIT_T_CPP_
+
+#include <algorithm>
+#include <cassert>
+
+#include "alignment.h"
+#include "debug.h"
+
+#include "misc.t.cpp"
+#include "ppforestsz.t.cpp"
+
+template<class R,class L>
+Mapping<R,L>::Mapping(const PPForestSZ<L> *ppfx, const PPForestSZ<L> *ppfy, const SZAlgebra<R,L> &alg)
+{
+  assert(ppfx != NULL);
+  assert(ppfy != NULL);
+
+  Ulong m,n,h,cols;
+  Ulong i,j,k,l,r,s;
+  R score,h_score;
+
+
+  // alloc space for the score matrices
+  m=ppfx->size();
+  n=ppfy->size();
+
+  m_mtrxSizeTD=(m)*(n);
+  m_mtrxSizeFD=(m+1)*(n+1);    // +1 because index 0 means the empty forest
+  m_mtrxTD=new R[m_mtrxSizeTD];
+  m_mtrxFD=new R[m_mtrxSizeFD];
+  m_rowStartTD=new Ulong[m];
+  m_rowStartFD=new Ulong[m+1];
+
+  m_ppfx = new PPForestSZ<L>(*ppfx);
+  m_ppfy = new PPForestSZ<L>(*ppfy);
+  m_alg=&alg;
+  
+  cols=n;
+  m_rowStartTD[0]=0;
+  for(h=1;h<m;h++)
+    m_rowStartTD[h]=m_rowStartTD[h-1]+cols;
+
+  cols=n+1;
+  m_rowStartFD[0]=0;
+  for(h=1;h<m+1;h++)
+    m_rowStartFD[h]=m_rowStartFD[h-1]+cols;
+
+  // calculate edit distance
+  for(i=0;i<m;i++)                                             // for all pairs of subtrees
+  {
+    if(!m_ppfx->keyroot(i))
+               continue;
+
+       for(j=0;j<n;j++)
+       {
+               if(!m_ppfy->keyroot(j))
+                       continue;
+
+               // calculate forest distance
+               
+               // edit to empty forest
+               setMtrxFDVal(0,0,0);
+               
+               for(k=m_ppfx->lml(i),r=1;k<=i;k++,r++)          // r is the indexpos of k
+                       setMtrxFDVal(r,0,m_alg->del(m_ppfx->label(k),getMtrxFDVal(r-1,0)));
+       
+               for(l=m_ppfy->lml(j),s=1;l<=j;l++,s++)
+                       setMtrxFDVal(0,s,m_alg->insert(getMtrxFDVal(0,s-1),m_ppfy->label(l)));  // s is the indexpos of j
+
+               for(k=m_ppfx->lml(i),r=1;k<=i;k++,r++)
+               {
+                       for(l=m_ppfy->lml(j),s=1;l<=j;l++,s++)
+                       {
+                               // fdist(k,i,l,j)
+                               // lml(k)==lml(i) && lml(l)==lml(j)
+                               if(m_ppfx->lml(k)==m_ppfx->lml(i) && m_ppfy->lml(l)==m_ppfy->lml(j))
+                               {
+                                       score=m_alg->replace(m_ppfx->label(k),getMtrxFDVal(r-1,s-1),m_ppfy->label(l));
+
+                                       h_score=m_alg->del(m_ppfx->label(k),getMtrxFDVal(r-1,s));
+                                       score=alg.choice(score,h_score);
+
+                                       h_score=m_alg->insert(getMtrxFDVal(r,s-1),m_ppfy->label(l));
+                                       score=alg.choice(score,h_score);
+
+                                       setMtrxFDVal(r,s,score);
+                                       setMtrxTDVal(k,l,score);
+                               }
+                               else
+                               {
+                                       long p,q;
+                                       p=m_ppfx->lml(k) - m_ppfx->lml(i);
+                                       q=m_ppfy->lml(l) - m_ppfy->lml(j);
+
+                                       score=getMtrxFDVal(p,q) + getMtrxTDVal(k,l);
+
+                                       h_score=m_alg->del(m_ppfx->label(k),getMtrxFDVal(r-1,s));
+                                       score=alg.choice(score,h_score);
+
+                                       h_score=m_alg->insert(getMtrxFDVal(r,s-1),m_ppfy->label(l));
+                                       score=alg.choice(score,h_score);
+
+                                       setMtrxFDVal(r,s,score);
+                               }
+                       }
+               }
+       }
+  }
+
+       // until here the original tree edit distance was calculated
+       // to allow edit distances between forests, the distance for a virtual root node is calculated
+       // leftmost leaf of the root node is the first node in postorder traversal
+       // The distances are calculated until the last tree node in postorder traversal which then holds the result
+       // for a virtual root node that is matched with zero cost
+
+       // edit to empty forest
+       setMtrxFDVal(0,0,0);
+       
+       for(k=0,r=1;k<m;k++,r++)                // r is the indexpos of k
+               setMtrxFDVal(r,0,m_alg->del(m_ppfx->label(k),getMtrxFDVal(r-1,0)));
+
+       for(l=0,s=1;l<n;l++,s++)
+               setMtrxFDVal(0,s,m_alg->insert(getMtrxFDVal(0,s-1),m_ppfy->label(l)));  // s is the indexpos of j
+
+       for(k=0,r=1;k<m;k++,r++)        
+       {
+               for(l=0,s=1;l<n;l++,s++)
+               {
+
+                     long p,q;
+                     p=m_ppfx->lml(k);
+                     q=m_ppfy->lml(l);
+                     
+                     score=getMtrxFDVal(p,q) + getMtrxTDVal(k,l);
+                     
+                     h_score=m_alg->del(m_ppfx->label(k),getMtrxFDVal(r-1,s));
+                     score=alg.choice(score,h_score);
+                     
+                     h_score=m_alg->insert(getMtrxFDVal(r,s-1),m_ppfy->label(l));
+                     score=alg.choice(score,h_score);
+                     
+                     setMtrxFDVal(r,s,score);                                              
+               }
+       }
+
+       m_optimum=getMtrxFDVal(m,n);
+}
+
+template<class R,class L>
+Mapping<R,L>::~Mapping()
+{
+       DELETE(m_ppfx);
+       DELETE(m_ppfy);
+
+       delete[] m_mtrxTD;
+       delete[] m_mtrxFD;
+       delete[] m_rowStartTD;
+       delete[] m_rowStartFD;
+}
+#endif