/* Ethan Wolf 1995 */ #include #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; j0) /* 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=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; j0) /* 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= 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); } }