void CapR::CalcLogSumBulgeAndInternalProbability(vector<double> &bulge_probability, vector<double> &internal_probability){ double probability = 0; double temp = 0; int type = 0; int type2 = 0; vector<bool> b_flag_array; b_flag_array.resize(_seq_length,0); vector<bool> i_flag_array; i_flag_array.resize(_seq_length,0); for(int i = 1; i<_seq_length-TURN-2;i++){ for(int j = i+TURN+3; j<=min(i+_maximal_span,_seq_length);j++){ type = BP_pair[_int_sequence[i]][_int_sequence[j]]; if (type!=0) { for (int p =i+1; p <= min(i+MAXLOOP+1,j-TURN-2); p++) { int u1 = p-i-1; for (int q=max(p+TURN+1,j-MAXLOOP+u1-1); q<j; q++) { type2 = BP_pair[_int_sequence[p]][_int_sequence[q]]; if (type2 != 0 && !(p == i+1 && q == j-1)) { type2 = rtype[type2]; if(_Beta_stemend[i][j-i-1] != -INF && _Alpha_stem[p-1][q-p+1] != -INF){ temp = _Beta_stemend[i][j-i-1] + LoopEnergy(type, type2,i,j,p,q)+_Alpha_stem[p-1][q-p+1]; for(int k = i+1; k <= p-1;k++){ if(j == q+1){ bulge_probability[k-1] = b_flag_array[k-1] == 1 ? logsumexp(bulge_probability[k-1], temp) : temp; b_flag_array[k-1] = 1; }else{ internal_probability[k-1] = i_flag_array[k-1] == 1 ? logsumexp(internal_probability[k-1], temp) : temp; i_flag_array[k-1] = 1; } } for(int k = q+1; k <= j-1;k++){ if(i == p-1){ bulge_probability[k-1] = b_flag_array[k-1] == 1 ? logsumexp(bulge_probability[k-1], temp) : temp; b_flag_array[k-1] = 1; }else{ internal_probability[k-1] = i_flag_array[k-1] == 1 ? logsumexp(internal_probability[k-1], temp) : temp; i_flag_array[k-1] = 1; } } } } } } } } } for(int i=0;i<_seq_length;i++){ if(b_flag_array[i]==1){ bulge_probability[i] = exp(bulge_probability[i]-_Alpha_outer[_seq_length]); } if(i_flag_array[i]==1){ internal_probability[i] = exp(internal_probability[i]-_Alpha_outer[_seq_length]); } } }
PRIVATE char *backtrack(int i, int j) { /* backtrack structure going backwards from i, and forwards from j return structure in bracket notation with & as separator */ int k, l, type, type2, E, traced, i0, j0; char *st1, *st2, *struc; st1 = (char *) space(sizeof(char)*(n1+1)); st2 = (char *) space(sizeof(char)*(n2+1)); i0=MIN2(i+1,n1); j0=MAX2(j-1,1); while (i>0 && j<=n2) { E = c[i][j]; traced=0; st1[i-1] = '('; st2[j-1] = ')'; type = pair[S1[i]][S2[j]]; if (!type) nrerror("backtrack failed in fold duplex"); for (k=i-1; k>0 && k>i-MAXLOOP-2; k--) { for (l=j+1; l<=n2; l++) { int LE; if (i-k+l-j-2>MAXLOOP) break; type2 = pair[S1[k]][S2[l]]; if (!type2) continue; LE = LoopEnergy(i-k-1, l-j-1, type2, rtype[type], SS1[k+1], SS2[l-1], SS1[i-1], SS2[j+1]); if (E == c[k][l]+LE) { traced=1; i=k; j=l; break; } } if (traced) break; } if (!traced) { if (i>1) E -= P->dangle5[type][SS1[i-1]]; if (j<n2) E -= P->dangle3[type][SS2[j+1]]; if (type>2) E -= P->TerminalAU; if (E != P->DuplexInit) { nrerror("backtrack failed in fold duplex"); } else break; } } if (i>1) i--; if (j<n2) j++; struc = (char *) space(i0-i+1+j-j0+1+2); for (k=MAX2(i,1); k<=i0; k++) if (!st1[k-1]) st1[k-1] = '.'; for (k=j0; k<=j; k++) if (!st2[k-1]) st2[k-1] = '.'; strcpy(struc, st1+MAX2(i-1,0)); strcat(struc, "&"); strcat(struc, st2+j0-1); /* printf("%s %3d,%-3d : %3d,%-3d\n", struc, i,i0,j0,j); */ free(st1); free(st2); return struc; }
void CapR::CalcBulgeAndInternalProbability(vector<double> &bulge_probability, vector<double> &internal_probability){ double temp = 0; int type = 0; int type2 = 0; for(int i = 1; i<_seq_length-TURN-2;i++){ for(int j = i+TURN+3; j<=min(i+_maximal_span,_seq_length);j++){ type = BP_pair[_int_sequence[i]][_int_sequence[j]]; if (type!=0) { for (int p =i+1; p <= min(i+MAXLOOP+1,j-TURN-2); p++) { int u1 = p-i-1; for (int q=max(p+TURN+1,j-MAXLOOP+u1-1); q<j; q++) { type2 = BP_pair[_int_sequence[p]][_int_sequence[q]]; if (type2 != 0 && !(p == i+1 && q == j-1)) { type2 = rtype[type2]; if(_Beta_stemend[i][j-i-1] != -INF && _Alpha_stem[p-1][q-p+1] != -INF){ temp = exp(_Beta_stemend[i][j-i-1] + LoopEnergy(type, type2,i,j,p,q)+_Alpha_stem[p-1][q-p+1]); for(int k = i+1; k <= p-1;k++){ if(j == q+1){ bulge_probability[k-1] += temp; }else{ internal_probability[k-1] += temp; } } for(int k = q+1; k <= j-1;k++){ if(i == p-1){ bulge_probability[k-1] += temp; }else{ internal_probability[k-1] += temp; } } } } } } } } } for(int i=0;i<_seq_length;i++){ if(bulge_probability[i] != 0){ bulge_probability[i] /= exp(_Alpha_outer[_seq_length]); } if(internal_probability[i] != 0){ internal_probability[i] /= exp(_Alpha_outer[_seq_length]); } } }
PRIVATE int fill_arrays(const char *string) { /* fill "c", "fML" and "f5" arrays and return optimal energy */ int i, j, k, length, energy; int decomp, new_fML, max_separation; int no_close, type, type_2, tt; int bonus=0; length = (int) strlen(string); max_separation = (int) ((1.-LOCALITY)*(double)(length-2)); /* not in use */ for (j=1; j<=length; j++) { Fmi[j]=DMLi[j]=DMLi1[j]=DMLi2[j]=INF; } for (j = 1; j<=length; j++) for (i=(j>TURN?(j-TURN):1); i<j; i++) { c[indx[j]+i] = fML[indx[j]+i] = INF; if (uniq_ML) fM1[indx[j]+i] = INF; } if (length <= TURN) return 0; for (i = length-TURN-1; i >= 1; i--) { /* i,j in [1..length] */ for (j = i+TURN+1; j <= length; j++) { int p, q, ij; ij = indx[j]+i; bonus = 0; type = ptype[ij]; /* enforcing structure constraints */ if ((BP[i]==j)||(BP[i]==-1)||(BP[i]==-2)) bonus -= BONUS; if ((BP[j]==-1)||(BP[j]==-3)) bonus -= BONUS; if ((BP[i]==-4)||(BP[j]==-4)) type=0; no_close = (((type==3)||(type==4))&&no_closingGU&&(bonus==0)); if (j-i-1 > max_separation) type = 0; /* forces locality degree */ if (type) { /* we have a pair */ int new_c=0, stackEnergy=INF; /* hairpin ----------------------------------------------*/ if (no_close) new_c = FORBIDDEN; else new_c = HairpinE(j-i-1, type, S1[i+1], S1[j-1], string+i-1); /*-------------------------------------------------------- check for elementary structures involving more than one closing pair. --------------------------------------------------------*/ for (p = i+1; p <= MIN2(j-2-TURN,i+MAXLOOP+1) ; p++) { int minq = j-i+p-MAXLOOP-2; if (minq<p+1+TURN) minq = p+1+TURN; for (q = minq; q < j; q++) { type_2 = ptype[indx[q]+p]; if (type_2==0) continue; type_2 = rtype[type_2]; if (no_closingGU) if (no_close||(type_2==3)||(type_2==4)) if ((p>i+1)||(q<j-1)) continue; /* continue unless stack */ #if 1 energy = LoopEnergy(p-i-1, j-q-1, type, type_2, S1[i+1], S1[j-1], S1[p-1], S1[q+1]); #else /* duplicated code is faster than function call */ #endif new_c = MIN2(energy+c[indx[q]+p], new_c); if ((p==i+1)&&(j==q+1)) stackEnergy = energy; /* remember stack energy */ } /* end q-loop */ } /* end p-loop */ /* multi-loop decomposition ------------------------*/ if (!no_close) { int MLenergy; decomp = DMLi1[j-1]; if (dangles) { int d3=0, d5=0; tt = rtype[type]; d3 = P->dangle3[tt][S1[i+1]]; d5 = P->dangle5[tt][S1[j-1]]; if (dangles==2) /* double dangles */ decomp += d5 + d3; else { /* normal dangles */ decomp = MIN2(DMLi2[j-1]+d3+P->MLbase, decomp); decomp = MIN2(DMLi1[j-2]+d5+P->MLbase, decomp); decomp = MIN2(DMLi2[j-2]+d5+d3+2*P->MLbase, decomp); } } MLenergy = P->MLclosing+P->MLintern[type]+decomp; new_c = MLenergy < new_c ? MLenergy : new_c; } /* coaxial stacking of (i.j) with (i+1.k) or (k+1.j-1) */ if (dangles==3) { decomp = INF; for (k = i+2+TURN; k < j-2-TURN; k++) { type_2 = ptype[indx[k]+i+1]; type_2 = rtype[type_2]; if (type_2) decomp = MIN2(decomp, c[indx[k]+i+1]+P->stack[type][type_2]+ fML[indx[j-1]+k+1]); type_2 = ptype[indx[j-1]+k+1]; type_2 = rtype[type_2]; if (type_2) decomp = MIN2(decomp, c[indx[j-1]+k+1]+P->stack[type][type_2]+ fML[indx[k]+i+1]); } /* no TermAU penalty if coax stack */ decomp += 2*P->MLintern[1] + P->MLclosing; new_c = MIN2(new_c, decomp); } new_c = MIN2(new_c, cc1[j-1]+stackEnergy); cc[j] = new_c + bonus; if (noLonelyPairs) c[ij] = cc1[j-1]+stackEnergy+bonus; else c[ij] = cc[j]; } /* end >> if (pair) << */ else c[ij] = INF; /* done with c[i,j], now compute fML[i,j] */ /* free ends ? -----------------------------------------*/ new_fML = fML[ij+1]+P->MLbase; new_fML = MIN2(fML[indx[j-1]+i]+P->MLbase, new_fML); energy = c[ij]+P->MLintern[type]; if (dangles==2) { /* double dangles */ energy += (i==1) ? /* works also for circfold */ P->dangle5[type][S1[length]] : P->dangle5[type][S1[i-1]]; /* if (j<length) */ energy += P->dangle3[type][S1[j+1]]; } new_fML = MIN2(energy, new_fML); if (uniq_ML) fM1[ij] = MIN2(fM1[indx[j-1]+i] + P->MLbase, energy); if (dangles%2==1) { /* normal dangles */ tt = ptype[ij+1]; /* i+1,j */ new_fML = MIN2(c[ij+1]+P->dangle5[tt][S1[i]] +P->MLintern[tt]+P->MLbase,new_fML); tt = ptype[indx[j-1]+i]; new_fML = MIN2(c[indx[j-1]+i]+P->dangle3[tt][S1[j]] +P->MLintern[tt]+P->MLbase, new_fML); tt = ptype[indx[j-1]+i+1]; new_fML = MIN2(c[indx[j-1]+i+1]+P->dangle5[tt][S1[i]]+ P->dangle3[tt][S1[j]]+P->MLintern[tt]+2*P->MLbase, new_fML); } /* modular decomposition -------------------------------*/ for (decomp = INF, k = i+1+TURN; k <= j-2-TURN; k++) decomp = MIN2(decomp, Fmi[k]+fML[indx[j]+k+1]); DMLi[j] = decomp; /* store for use in ML decompositon */ new_fML = MIN2(new_fML,decomp); /* coaxial stacking */ if (dangles==3) { /* additional ML decomposition as two coaxially stacked helices */ for (decomp = INF, k = i+1+TURN; k <= j-2-TURN; k++) { type = ptype[indx[k]+i]; type = rtype[type]; type_2 = ptype[indx[j]+k+1]; type_2 = rtype[type_2]; if (type && type_2) decomp = MIN2(decomp, c[indx[k]+i]+c[indx[j]+k+1]+P->stack[type][type_2]); } decomp += 2*P->MLintern[1]; /* no TermAU penalty if coax stack */ #if 0 /* This is needed for Y shaped ML loops with coax stacking of interior pairts, but backtracking will fail if activated */ DMLi[j] = MIN2(DMLi[j], decomp); DMLi[j] = MIN2(DMLi[j], DMLi[j-1]+P->MLbase); DMLi[j] = MIN2(DMLi[j], DMLi1[j]+P->MLbase); new_fML = MIN2(new_fML, DMLi[j]); #endif new_fML = MIN2(new_fML, decomp); } fML[ij] = Fmi[j] = new_fML; /* substring energy */ } { int *FF; /* rotate the auxilliary arrays */ FF = DMLi2; DMLi2 = DMLi1; DMLi1 = DMLi; DMLi = FF; FF = cc1; cc1=cc; cc=FF; for (j=1; j<=length; j++) {cc[j]=Fmi[j]=DMLi[j]=INF; } } } /* calculate energies of 5' and 3' fragments */ f5[TURN+1]=0; for (j=TURN+2; j<=length; j++) { f5[j] = f5[j-1]; type=ptype[indx[j]+1]; if (type) { energy = c[indx[j]+1]; if (type>2) energy += P->TerminalAU; if ((dangles==2)&&(j<length)) /* double dangles */ energy += P->dangle3[type][S1[j+1]]; f5[j] = MIN2(f5[j], energy); } type=ptype[indx[j-1]+1]; if ((type)&&(dangles%2==1)) { energy = c[indx[j-1]+1]+P->dangle3[type][S1[j]]; if (type>2) energy += P->TerminalAU; f5[j] = MIN2(f5[j], energy); } for (i=j-TURN-1; i>1; i--) { type = ptype[indx[j]+i]; if (type) { energy = f5[i-1]+c[indx[j]+i]; if (type>2) energy += P->TerminalAU; if (dangles==2) { energy += P->dangle5[type][S1[i-1]]; if (j<length) energy += P->dangle3[type][S1[j+1]]; } f5[j] = MIN2(f5[j], energy); if (dangles%2==1) { energy = f5[i-2]+c[indx[j]+i]+P->dangle5[type][S1[i-1]]; if (type>2) energy += P->TerminalAU; f5[j] = MIN2(f5[j], energy); } } type = ptype[indx[j-1]+i]; if ((type)&&(dangles%2==1)) { energy = c[indx[j-1]+i]+P->dangle3[type][S1[j]]; if (type>2) energy += P->TerminalAU; f5[j] = MIN2(f5[j], f5[i-1]+energy); f5[j] = MIN2(f5[j], f5[i-2]+energy+P->dangle5[type][S1[i-1]]); } } } return f5[length]; }
void CapR::CalcInsideVariable(){ for (int j =TURN+1; j <= _seq_length; j++){ for (int i=j-TURN; i >= max(0,j-_maximal_span-1); i--){ //Alpha_stem int type = BP_pair[_int_sequence[i+1]][_int_sequence[j]]; int type2 = BP_pair[_int_sequence[i+2]][_int_sequence[j-1]]; double temp = 0; bool flag = 0; if (type != 0) { type2 = rtype[type2]; if(_Alpha_stem[i+1][j-i-2] != -INF){ //Stem¨Stem if(type2 != 0){ temp = _Alpha_stem[i+1][j-i-2]+ LoopEnergy(type, type2,i+1,j,i+2,j-1); } flag = 1; } if(_Alpha_stemend[i+1][j-i-2] != -INF){ //Stem¨StemEnd temp = flag == 1 ? logsumexp(temp,_Alpha_stemend[i+1][j-i-2]) : _Alpha_stemend[i+1][j-i-2]; flag = 1; } _Alpha_stem[i][j-i] = flag == 0 ? -INF : temp; }else{ _Alpha_stem[i][j-i] = -INF; } //Alpha_multiBif temp = 0; flag = 0; for (int k=i+1; k<=j-1; k++){ if(_Alpha_multi1[i][k-i] != -INF && _Alpha_multi2[k][j-k] != -INF){ temp = flag == 0 ? _Alpha_multi1[i][k-i]+_Alpha_multi2[k][j-k] : logsumexp(temp,_Alpha_multi1[i][k-i]+_Alpha_multi2[k][j-k]); flag = 1; } } _Alpha_multibif[i][j-i] = flag == 0 ? -INF : temp; //Alpha_multi2 temp = 0; flag = 0; if (type != 0) { if(_Alpha_stem[i][j-i] != -INF){ temp = _Alpha_stem[i][j-i]+MLintern+CalcDangleEnergy(type,i,j); flag = 1; } } if(_Alpha_multi2[i][j-i-1] != -INF){ _Alpha_multi2[i][j-i] = _Alpha_multi2[i][j-i-1]+MLbase; if(flag == 1){ _Alpha_multi2[i][j-i] = logsumexp(temp,_Alpha_multi2[i][j-i]); } }else{ _Alpha_multi2[i][j-i] = flag == 0 ? -INF : temp; } //Alpha_multi1 if(_Alpha_multi2[i][j-i] != -INF && _Alpha_multibif[i][j-i] != -INF){ _Alpha_multi1[i][j-i] = logsumexp(_Alpha_multi2[i][j-i],_Alpha_multibif[i][j-i]); }else if(_Alpha_multi2[i][j-i] == -INF){ _Alpha_multi1[i][j-i] = _Alpha_multibif[i][j-i]; }else if(_Alpha_multibif[i][j-i] == -INF){ _Alpha_multi1[i][j-i] = _Alpha_multi2[i][j-i]; }else{ _Alpha_multi1[i][j-i] = -INF; } //Alpha_multi flag = 0; if(_Alpha_multi[i+1][j-i-1] != -INF){ _Alpha_multi[i][j-i] = _Alpha_multi[i+1][j-i-1]+MLbase; flag = 1; } if(flag == 1){ if(_Alpha_multibif[i][j-i] != -INF){ _Alpha_multi[i][j-i] = logsumexp(_Alpha_multi[i][j-i],_Alpha_multibif[i][j-i]); } }else{ _Alpha_multi[i][j-i] = _Alpha_multibif[i][j-i]; } //Alpha_stemend if(j != _seq_length){ temp = 0; type = BP_pair[_int_sequence[i]][_int_sequence[j+1]]; if (type!=0) { //StemEnd¨sn temp = HairpinEnergy(type, i,j+1); //StemEnd¨sm_Stem_sn for (int p =i; p <= min(i+MAXLOOP,j-TURN-2); p++) { int u1 = p-i; for (int q=max(p+TURN+2,j-MAXLOOP+u1); q<=j; q++) { type2 = BP_pair[_int_sequence[p+1]][_int_sequence[q]]; if(_Alpha_stem[p][q-p] != -INF){ if (type2 != 0 && !(p == i && q == j)) { type2 = rtype[type2]; temp = logsumexp(temp,_Alpha_stem[p][q-p]+LoopEnergy(type, type2,i,j+1,p+1,q)); } } } } //StemEnd¨Multi int tt = rtype[type]; temp = logsumexp(temp,_Alpha_multi[i][j-i]+MLclosing+MLintern+dangle3[tt][_int_sequence[i+1]]+dangle5[tt][_int_sequence[j]]); _Alpha_stemend[i][j-i] = temp; }else{ _Alpha_stemend[i][j-i] = -INF; } } } } //Alpha_Outer for(int i = 1;i <= _seq_length;i++){ double temp = _Alpha_outer[i-1]; for(int p = max(0,i-_maximal_span-1); p <i;p++){ if(_Alpha_stem[p][i-p] != -INF){ int type = BP_pair[_int_sequence[p+1]][_int_sequence[i]]; double ao = _Alpha_stem[p][i-p]+CalcDangleEnergy(type,p,i); temp = logsumexp(temp,ao+_Alpha_outer[p]); } } _Alpha_outer[i] = temp; } }
void CapR::CalcOutsideVariable(){ //Beta_outer for(int i = _seq_length-1;i >= 0;i--){ double temp = _Beta_outer[i+1]; for(int p = i+1; p <= min(i+_maximal_span+1,_seq_length);p++){ if(_Alpha_stem[i][p-i] != -INF){ int type = BP_pair[_int_sequence[i+1]][_int_sequence[p]]; double bo = _Alpha_stem[i][p-i] + CalcDangleEnergy(type,i,p); temp = logsumexp(temp,bo+_Beta_outer[p]); } } _Beta_outer[i] = temp; } for (int q=_seq_length; q>=TURN+1; q--) { for (int p=max(0,q-_maximal_span-1); p<= q-TURN; p++) { int type = 0; int type2 = 0; double temp = 0; bool flag = 0; if(p != 0 && q != _seq_length){ //Beta_stemend _Beta_stemend[p][q-p] = q-p >= _maximal_span ? -INF : _Beta_stem[p-1][q-p+2]; //Beta_Multi flag = 0; if(q-p+1 <= _maximal_span+1){ if(_Beta_multi[p-1][q-p+1] != -INF){ temp = _Beta_multi[p-1][q-p+1] + MLbase; flag = 1; } } type = BP_pair[_int_sequence[p]][_int_sequence[q+1]]; int tt = rtype[type]; if(flag == 1){ if(_Beta_stemend[p][q-p] != -INF){ temp = logsumexp(temp,_Beta_stemend[p][q-p]+MLclosing+MLintern+ dangle3[tt][_int_sequence[p+1]]+dangle5[tt][_int_sequence[q]]); } }else{ if(_Beta_stemend[p][q-p] != -INF){ temp = _Beta_stemend[p][q-p]+MLclosing+MLintern+dangle3[tt][_int_sequence[p+1]]+dangle5[tt][_int_sequence[q]]; }else{ temp = -INF; } } _Beta_multi[p][q-p] = temp; //Beta_Multi1 temp = 0; flag = 0; for(int k = q+1 ; k<= min(_seq_length,p+_maximal_span);k++){ if(_Beta_multibif[p][k-p] != -INF && _Alpha_multi2[q][k-q] != -INF){ temp = flag == 0 ? _Beta_multibif[p][k-p]+_Alpha_multi2[q][k-q] : logsumexp(temp,_Beta_multibif[p][k-p]+_Alpha_multi2[q][k-q]) ; flag = 1; } } _Beta_multi1[p][q-p] = flag == 1 ? temp: -INF; //Beta_Multi2 temp = 0; flag = 0; if(_Beta_multi1[p][q-p] != -INF){ temp = _Beta_multi1[p][q-p]; flag = 1; } if(q-p <= _maximal_span){ if(_Beta_multi2[p][q-p+1] != -INF){ temp = flag == 1 ? logsumexp(temp,_Beta_multi2[p][q-p+1]+MLbase) : _Beta_multi2[p][q-p+1]+MLbase; flag = 1; } } for(int k = max(0,q-_maximal_span); k < p ;k++){ if(_Beta_multibif[k][q-k] != -INF && _Alpha_multi1[k][p-k] != -INF){ temp = flag == 0 ? _Beta_multibif[k][q-k]+_Alpha_multi1[k][p-k] : logsumexp(temp,_Beta_multibif[k][q-k]+_Alpha_multi1[k][p-k]); flag = 1; } } _Beta_multi2[p][q-p] = flag == 0 ? -INF : temp; //Beta_multibif if(_Beta_multi1[p][q-p] != -INF && _Beta_multi[p][q-p] != -INF){ _Beta_multibif[p][q-p] = logsumexp(_Beta_multi1[p][q-p],_Beta_multi[p][q-p]); }else if(_Beta_multi[p][q-p] == -INF){ _Beta_multibif[p][q-p] = _Beta_multi1[p][q-p]; }else if(_Beta_multi1[p][q-p] == -INF){ _Beta_multibif[p][q-p] = _Beta_multi[p][q-p]; }else{ _Beta_multibif[p][q-p] = -INF; } } //Beta_stem type2 = BP_pair[_int_sequence[p+1]][_int_sequence[q]]; if(type2 != 0){ temp = _Alpha_outer[p]+_Beta_outer[q]+CalcDangleEnergy(type2,p,q); type2 = rtype[type2]; for (int i=max(1,p-MAXLOOP); i<=p; i++){ for (int j=q; j<=min(q+ MAXLOOP -p+i,_seq_length-1); j++) { type = BP_pair[_int_sequence[i]][_int_sequence[j+1]]; if (type != 0 && !(i == p && j == q)) { if(j-i <= _maximal_span+1 && _Beta_stemend[i][j-i] != -INF){ temp = logsumexp(temp,_Beta_stemend[i][j-i]+LoopEnergy(type,type2,i,j+1,p+1,q)); } } } } if(p != 0 && q != _seq_length){ type = BP_pair[_int_sequence[p]][_int_sequence[q+1]]; if(type != 0){ if(q-p+2 <= _maximal_span+1 && _Beta_stem[p-1][q-p+2] != -INF){ temp = logsumexp(temp,_Beta_stem[p-1][q-p+2]+LoopEnergy(type,type2,p,q+1,p+1,q)); } } } _Beta_stem[p][q-p] = temp; if(_Beta_multi2[p][q-p] != -INF){ type2 = rtype[type2]; temp = _Beta_multi2[p][q-p] + MLintern + CalcDangleEnergy(type2,p,q); _Beta_stem[p][q-p] = logsumexp(temp,_Beta_stem[p][q-p]); } }else{ _Beta_stem[p][q-p] = -INF; } } } }
duplexT duplexfold(const char *s1, const char *s2) { int i, j, l1, Emin=INF, i_min=0, j_min=0; char *struc; duplexT mfe; n1 = (int) strlen(s1); n2 = (int) strlen(s2); if ((!P) || (fabs(P->temperature - temperature)>1e-6)) { update_fold_params(); P = scale_parameters(); make_pair_matrix(); } c = (int **) space(sizeof(int *) * (n1+1)); for (i=1; i<=n1; i++) c[i] = (int *) space(sizeof(int) * (n2+1)); encode_seq(s1, s2); for (i=1; i<=n1; i++) { for (j=n2; j>0; j--) { int type, type2, E, k,l; type = pair[S1[i]][S2[j]]; c[i][j] = type ? P->DuplexInit : INF; if (!type) continue; if (i>1) c[i][j] += P->dangle5[type][SS1[i-1]]; if (j<n2) c[i][j] += P->dangle3[type][SS2[j+1]]; if (type>2) c[i][j] += P->TerminalAU; for (k=i-1; k>0 && k>i-MAXLOOP-2; k--) { for (l=j+1; l<=n2; l++) { if (i-k+l-j-2>MAXLOOP) break; type2 = pair[S1[k]][S2[l]]; if (!type2) continue; E = LoopEnergy(i-k-1, l-j-1, type2, rtype[type], SS1[k+1], SS2[l-1], SS1[i-1], SS2[j+1]); c[i][j] = MIN2(c[i][j], c[k][l]+E); } } E = c[i][j]; if (i<n1) E += P->dangle3[rtype[type]][SS1[i+1]]; if (j>1) E += P->dangle5[rtype[type]][SS2[j-1]]; if (type>2) E += P->TerminalAU; if (E<Emin) { Emin=E; i_min=i; j_min=j; } } } struc = backtrack(i_min, j_min); if (i_min<n1) i_min++; if (j_min>1 ) j_min--; l1 = strchr(struc, '&')-struc; /* printf("%s %3d,%-3d : %3d,%-3d (%5.2f)\n", struc, i_min+1-l1, i_min, j_min, j_min+strlen(struc)-l1-2, Emin*0.01); */ mfe.i = i_min; mfe.j = j_min; mfe.energy = (float) Emin/100.; mfe.structure = struc; if (!delay_free) { for (i=1; i<=n1; i++) free(c[i]); free(c); free(S1); free(S2); free(SS1); free(SS2); } return mfe; }