JPRED-2 Add sources of all binaries (except alscript) to Git
[jpred.git] / sources / multicoil / dyn.c
diff --git a/sources/multicoil/dyn.c b/sources/multicoil/dyn.c
new file mode 100644 (file)
index 0000000..6fd1bab
--- /dev/null
@@ -0,0 +1,214 @@
+/*  Ethan Wolf 1995 */
+
+#include <stdio.h>
+#include "scconst.h"
+#include "math.h"
+
+/* Compute scores for residues to be the max window score of windows containing
+ * that residue. Windows are defined by where they start.  
+ * windowscore[0..seqlen-window] are the window scores so window[i] is
+ *     the score for the window starting in position i.
+ *  The answer is placed in maxima[0..seqlen-1]
+ */
+/* Note that the last windowscore is windowscore[seqlen-1-(window-1)]. */
+
+
+
+/*  A rough idea of the dynamic programming algorithm presented here:
+*
+*    Suppose have seq of scores (a_1,a_2,....,a_n)
+*   and you want to get values  (m_1,m_2,....,m_n) from the window scores 
+*   m_i= max{a_{i-(window-1)}, a_{i-window+1},...., a_i}.
+*
+*   Then divide the seq into blocks:
+*   ( [a_1,....,a_window], [a_{window+1},...,a_{2window}],...,[....,a_n] )
+*   and compute block_maxima[i]= max{a_start, a_{start+1},...., a_i},
+*   which is the max of the first i scores in the block.
+
+*   Also for k in a block ending at end define
+*   prev_block_maxima[k]= max{a_end, a_{end-1},..., a_k},
+*   which computes the max of the last k residues in the block.
+
+*    Then m_j = max{block_maxima[j], prev_block_maxima[j-(window-1)]}
+*/ 
+
+/*  Note that for us a_i = windowscore[i] do not exist for                */
+/*  i=seqlen - window+1 to seqlen-1 (i.e. number_windows=seqlen-window+1. */
+/*  
+/*  For these values of i, m_i=prev_block_maxima[i-window].         */
+
+
+
+
+void max_over_windows (double maxima[],
+                 double windowscore[],
+                 int seqlen,
+                 int window)
+{
+ int number_blocks= (int)seqlen/window;   /* Truncates */
+ int number_windows=seqlen-window+1;
+ int i,j;
+ double prev_block_maxima[MAXSEQLEN], block_maxima[MAXSEQLEN];
+ int start; 
+
+  
+  /*  First compute prev_block_max[k] defined above.  */ 
+
+/*  Dealing with position j in block i from right to left. In the         */
+/*  last block (last complete block) need to check if windowscore has any */
+/*  meaning (i.e. if are further than window from sequence end).          */
+/*  So start at position seqlen-window which is always in the last        */
+/*  complete block in window position (seqlen mod window). */
+
+
+ for (i=number_blocks-1, start=seqlen%window; i>=0; i--) {
+                                /* First block, start at seqlen-window. */
+   prev_block_maxima[i*window + start]=       /* Initialize block for   */
+            windowscore[i*window+ start];     /* the window-1 position. */
+   for (j=start-1; j>=0; j--)   /* Iterate through block passing values left.*/
+     prev_block_maxima[i*window +j]= 
+       MAX(windowscore[i*window +j],prev_block_maxima[i*window+j+1]);
+
+   start= window-1;          /* For all but last block start at end of block*/
+ }
+
+ /* Now compute block_maxima[i] defined above with a_i=windowscore[i]. */
+ for (i=0; i< number_blocks; i++)  {
+   
+   block_maxima[i*window] = windowscore[i*window];  /* Initialize block for */
+                                                    /* the first position.  */
+   for (j=1; j<window; j++){   /*Iterate through block passing values right.*/
+     if ( (i*window+j +window-1) < seqlen) /* If there is a complete window */
+                                           /* starting at the current pos.  */
+       block_maxima[i*window +j] =         /* so winscore is defined...     */
+            MAX(windowscore[i*window +j],block_maxima[i*window+j-1]) ;
+     else
+       block_maxima[i*window +j]= block_maxima[i*window+j-1];
+
+     if (i>0)  /* so there is a previous window */
+       maxima[i*window +j]= MAX(block_maxima[i*window+j],
+                             prev_block_maxima[(i-1)*window+j+1]);
+     else      /* In the first window. */
+       maxima[i*window +j]= block_maxima[i*window+j];
+   }    
+ }
+
+   
+  /* Now calculate the scores for the last partial window.  */
+   for (i= window*number_blocks; i<seqlen; i++)  
+     maxima[i]=prev_block_maxima[i-window+1];
+
+  /* Set maxima[window*i] which didn't get set before.  */
+   maxima[0]=windowscore[0];
+   for (i=1; i<number_blocks; i++)
+     maxima[i*window]=MAX(prev_block_maxima[(i-1)*window +1],
+                         windowscore[i*window]);
+
+}
+
+/*********************************************************************/
+void min_over_windows (double minima[],
+                  double windowscore[],
+                  int seqlen,
+                  int window)
+{
+ int number_blocks= (int)seqlen/window;   /* Truncates */
+ int number_windows=seqlen-window+1;
+ int i,j;
+ double prev_block_minima[MAXSEQLEN], block_minima[MAXSEQLEN];
+ int start; 
+
+  
+  /*  First compute prev_block_min[k] defined above.  */ 
+
+/*  Dealing with position j in block i from right to left. In the         */
+/*  last block (last complete block) need to check if windowscore has any */
+/*  meaning (i.e. if are further than window from sequence end).          */
+/*  So start at position seqlen-window which is always in the last        */
+/*  complete block in window position (seqlen mod window). */
+
+
+ for (i=number_blocks-1, start=seqlen%window; i>=0; i--) {
+                                /* First block, start at seqlen-window. */
+   prev_block_minima[i*window + start]=       /* Initialize block for   */
+            windowscore[i*window+ start];     /* the window-1 position. */
+   for (j=start-1; j>=0; j--)   /* Iterate through block passing values left.*/
+     prev_block_minima[i*window +j]= 
+       MIN(windowscore[i*window +j],prev_block_minima[i*window+j+1]);
+
+   start= window-1;          /* For all but last block start at end of block*/
+ }
+
+ /* Now compute block_minima[i] defined above with a_i=windowscore[i]. */
+ for (i=0; i< number_blocks; i++)  {
+   
+   block_minima[i*window] = windowscore[i*window];  /* Initialize block for */
+                                                    /* the first position.  */
+   for (j=1; j<window; j++){   /*Iterate through block passing values right.*/
+     if ( (i*window+j +window-1) < seqlen) /* If there is a complete window */
+                                           /* starting at the current pos.  */
+       block_minima[i*window +j] =         /* so winscore is defined...     */
+            MIN(windowscore[i*window +j],block_minima[i*window+j-1]) ;
+     else
+       block_minima[i*window +j]= block_minima[i*window+j-1];
+
+     if (i>0)  /* so there is a previous window */
+       minima[i*window +j]= MIN(block_minima[i*window+j],
+                              prev_block_minima[(i-1)*window+j+1]);
+     else      /* In the first window. */
+       minima[i*window +j]= block_minima[i*window+j];
+   }    
+ }
+
+   
+  
+  /* Now calculate the scores for the last partial window.  */
+   for (i= window*number_blocks; i<seqlen; i++)  
+     minima[i]=prev_block_minima[i-window+1];
+
+  /* Set minima[window*i] which didn't get set before.  */
+   minima[0]=windowscore[0];
+   for (i=1; i<number_blocks; i++)
+     minima[i*window]=MIN(prev_block_minima[(i-1)*window +1],
+                          windowscore[i*window]);
+
+}
+
+
+
+
+
+
+/*********************************************************************/
+
+void avg_over_windows (double average[],
+                 double windowscore[],
+                 int seqlen,
+                 int window)
+{
+
+
+  int i;
+  int number_windows=0;
+  double total=0;
+
+
+  for(i=0; i<seqlen; i++) {
+
+    if ( i-window >= 0)  {
+      total -= exp(windowscore[i-window]);
+      number_windows--;
+    }
+
+    if ( i< seqlen - window+1) {    /** There are no window scores within **/
+      total += exp(windowscore[i]); /* window residues of the end. **/
+      number_windows++;
+    }
+
+    average[i] = getdlog(total/number_windows);
+  }
+}
+