3 RNA secondary structure with
4 basepair distance d_1 to reference structure 1 and distance d_2 to reference structure 2
14 #include "energy_par.h"
15 #include "fold_vars.h"
18 #include "loop_energies.h"
27 #################################
29 #################################
31 int compute_2Dfold_F3 = 0;
34 #################################
36 #################################
40 #################################
41 # PRIVATE FUNCTION DECLARATIONS #
42 #################################
44 PRIVATE void mfe_linear(TwoDfold_vars *vars);
45 PRIVATE void mfe_circ(TwoDfold_vars *vars);
47 PRIVATE void initialize_TwoDfold_vars(TwoDfold_vars *vars);
48 PUBLIC void update_TwoDfold_params(TwoDfold_vars *vars);
49 PRIVATE void make_ptypes(TwoDfold_vars *vars);
51 PRIVATE void backtrack_f5(unsigned int j, int k, int l, char *structure, TwoDfold_vars *vars);
52 PRIVATE void backtrack_c(unsigned int i, unsigned int j, int k, int l, char *structure, TwoDfold_vars *vars);
53 PRIVATE void backtrack_m(unsigned int i, unsigned int j, int k, int l, char *structure, TwoDfold_vars *vars);
54 PRIVATE void backtrack_m1(unsigned int i, unsigned int j, int k, int l, char *structure, TwoDfold_vars *vars);
55 PRIVATE void backtrack_fc(int k, int l, char *structure, TwoDfold_vars *vars);
56 PRIVATE void backtrack_m2(unsigned int i, int k, int l, char *structure, TwoDfold_vars *vars);
58 PRIVATE void adjustArrayBoundaries(int ***array, int *k_min, int *k_max, int **l_min, int **l_max, int k_min_real, int k_max_real, int *l_min_real, int *l_max_real);
59 INLINE PRIVATE void preparePosteriorBoundaries(int size, int shift, int *min_k, int *max_k, int **min_l, int **max_l);
60 INLINE PRIVATE void updatePosteriorBoundaries(int d1, int d2, int *min_k, int *max_k, int **min_l, int **max_l);
61 INLINE PRIVATE void prepareBoundaries(int min_k_pre, int max_k_pre, int min_l_pre, int max_l_pre, int bpdist, int *min_k, int *max_k, int **min_l, int **max_l);
62 INLINE PRIVATE void prepareArray(int ***array, int min_k, int max_k, int *min_l, int *max_l);
63 INLINE PRIVATE void prepareArray2(unsigned long ***array, int min_k, int max_k, int *min_l, int *max_l);
68 #################################
69 # BEGIN OF FUNCTION DEFINITIONS #
70 #################################
73 PUBLIC TwoDfold_vars *get_TwoDfold_variables(const char *seq, const char *structure1, const char *structure2, int circ){
74 unsigned int size, length, i;
78 vars = (TwoDfold_vars *)malloc(sizeof(TwoDfold_vars));
79 vars->sequence = (char *)space(length + 1);
80 strcpy(vars->sequence, seq);
81 vars->seq_length = length;
82 if(vars->seq_length < 1) nrerror("get_TwoDfold_variables: sequence must be longer than 0");
83 size = ((length + 1) * (length + 2)/2);
85 vars->reference_pt1 = make_pair_table(structure1);
86 vars->reference_pt2 = make_pair_table(structure2);
87 vars->referenceBPs1 = make_referenceBP_array(vars->reference_pt1, TURN);
88 vars->referenceBPs2 = make_referenceBP_array(vars->reference_pt2, TURN);
89 vars->bpdist = compute_BPdifferences(vars->reference_pt1, vars->reference_pt2, TURN);
90 vars->do_backtrack = 1;
91 vars->dangles = dangles;
93 vars->temperature = temperature;
94 vars->ptype = space(sizeof(char) * size);
98 vars->my_iindx = get_iindx(length);
99 index = vars->my_iindx;
100 /* compute maximum matching with reference structure 1 disallowed */
101 vars->mm1 = maximumMatchingConstraint(vars->sequence, vars->reference_pt1);
102 /* compute maximum matching with reference structure 2 disallowed */
103 vars->mm2 = maximumMatchingConstraint(vars->sequence, vars->reference_pt2);
105 vars->maxD1 = vars->mm1[index[1]-length] + vars->referenceBPs1[index[1]-length];
106 vars->maxD2 = vars->mm2[index[1]-length] + vars->referenceBPs2[index[1]-length];
108 /* allocate memory for the energy matrices and min-/max-index helper arrays */
109 vars->E_C = (int ***) space(sizeof(int **) * size);
110 vars->l_min_values = (int **) space(sizeof(int *) * size);
111 vars->l_max_values = (int **) space(sizeof(int *) * size);
112 vars->k_min_values = (int *) space(sizeof(int) * size);
113 vars->k_max_values = (int *) space(sizeof(int) * size);
115 vars->E_F5 = (int ***) space(sizeof(int **) * (length + 1));
116 vars->l_min_values_f = (int **) space(sizeof(int *) * (length + 1));
117 vars->l_max_values_f = (int **) space(sizeof(int *) * (length + 1));
118 vars->k_min_values_f = (int *) space(sizeof(int) * (length + 1));
119 vars->k_max_values_f = (int *) space(sizeof(int) * (length + 1));
121 if(compute_2Dfold_F3){
122 vars->E_F3 = (int ***) space(sizeof(int **) * (length + 1));
123 vars->l_min_values_f3 = (int **) space(sizeof(int *) * (length + 1));
124 vars->l_max_values_f3 = (int **) space(sizeof(int *) * (length + 1));
125 vars->k_min_values_f3 = (int *) space(sizeof(int) * (length + 1));
126 vars->k_max_values_f3 = (int *) space(sizeof(int) * (length + 1));
128 else vars->E_F3 = NULL;
130 vars->E_M = (int ***) space(sizeof(int **) * size);
131 vars->l_min_values_m = (int **) space(sizeof(int *) * size);
132 vars->l_max_values_m = (int **) space(sizeof(int *) * size);
133 vars->k_min_values_m = (int *) space(sizeof(int) * size);
134 vars->k_max_values_m = (int *) space(sizeof(int) * size);
136 vars->E_M1 = (int ***) space(sizeof(int **) * size);
137 vars->l_min_values_m1 = (int **) space(sizeof(int *) * size);
138 vars->l_max_values_m1 = (int **) space(sizeof(int *) * size);
139 vars->k_min_values_m1 = (int *) space(sizeof(int) * size);
140 vars->k_max_values_m1 = (int *) space(sizeof(int) * size);
143 vars->N_C = (unsigned long ***) space(sizeof(unsigned long **) * size);
144 vars->N_F5 = (unsigned long ***) space(sizeof(unsigned long **) * (length + 1));
145 vars->N_M = (unsigned long ***) space(sizeof(unsigned long **) * size);
146 vars->N_M1 = (unsigned long ***) space(sizeof(unsigned long **) * size);
151 vars->E_M2_rem = (int *) space(sizeof(int) * (length + 1));
152 vars->E_M2 = (int ***) space(sizeof(int **) * (length + 1));
153 vars->l_min_values_m2 = (int **) space(sizeof(int *) * (length + 1));
154 vars->l_max_values_m2 = (int **) space(sizeof(int *) * (length + 1));
155 vars->k_min_values_m2 = (int *) space(sizeof(int) * (length + 1));
156 vars->k_max_values_m2 = (int *) space(sizeof(int) * (length + 1));
159 vars->E_M2_rem = NULL;
161 vars->l_min_values_m2 = NULL;
162 vars->l_max_values_m2 = NULL;
163 vars->k_min_values_m2 = NULL;
164 vars->k_max_values_m2 = NULL;
172 vars->E_Fc_rem = INF;
173 vars->E_FcH_rem = INF;
174 vars->E_FcI_rem = INF;
175 vars->E_FcM_rem = INF;
177 vars->E_C_rem = (int *) space(sizeof(int) * size);
178 vars->E_M_rem = (int *) space(sizeof(int) * size);
179 vars->E_M1_rem = (int *) space(sizeof(int) * size);
180 vars->E_F5_rem = (int *) space(sizeof(int) * (length+1));
181 /* init rest arrays */
183 vars->E_C_rem[i] = vars->E_M_rem[i] = vars->E_M1_rem[i] = INF;
185 for(i=0;i<=length;i++)
186 vars->E_F5_rem[i] = INF;
188 for(i=0;i<=length;i++)
189 vars->E_M2_rem[i] = INF;
194 PUBLIC void destroy_TwoDfold_variables(TwoDfold_vars *vars){
195 unsigned int i, j, ij;
197 if(vars == NULL) return;
201 free(vars->E_M1_rem);
202 free(vars->E_F5_rem);
203 if(vars->E_M2_rem) free(vars->E_M2_rem);
206 #pragma omp sections private(i,j,ij,cnt1)
214 if(vars->N_C != NULL){
215 for(i = 1; i < vars->seq_length; i++){
216 for(j = i; j <= vars->seq_length; j++){
217 ij = vars->my_iindx[i] - j;
218 if(!vars->N_C[ij]) continue;
219 for(cnt1 = vars->k_min_values[ij]; cnt1 <= vars->k_max_values[ij]; cnt1++)
220 if(vars->l_min_values[ij][cnt1] < INF){
221 vars->N_C[ij][cnt1] += vars->l_min_values[ij][cnt1]/2;
222 free(vars->N_C[ij][cnt1]);
224 if(vars->k_min_values[ij] < INF){
225 vars->N_C[ij] += vars->k_min_values[ij];
234 if(vars->E_C != NULL){
235 for(i = 1; i < vars->seq_length; i++){
236 for(j = i; j <= vars->seq_length; j++){
237 ij = vars->my_iindx[i] - j;
238 if(!vars->E_C[ij]) continue;
239 for(cnt1 = vars->k_min_values[ij]; cnt1 <= vars->k_max_values[ij]; cnt1++)
240 if(vars->l_min_values[ij][cnt1] < INF){
241 vars->E_C[ij][cnt1] += vars->l_min_values[ij][cnt1]/2;
242 free(vars->E_C[ij][cnt1]);
244 if(vars->k_min_values[ij] < INF){
245 vars->E_C[ij] += vars->k_min_values[ij];
247 vars->l_min_values[ij] += vars->k_min_values[ij];
248 vars->l_max_values[ij] += vars->k_min_values[ij];
249 free(vars->l_min_values[ij]);
250 free(vars->l_max_values[ij]);
255 free(vars->l_min_values);
256 free(vars->l_max_values);
257 free(vars->k_min_values);
258 free(vars->k_max_values);
267 if(vars->N_M != NULL){
268 for(i = 1; i < vars->seq_length; i++){
269 for(j = i; j <= vars->seq_length; j++){
270 ij = vars->my_iindx[i] - j;
271 if(!vars->N_M[ij]) continue;
272 for(cnt1 = vars->k_min_values_m[ij]; cnt1 <= vars->k_max_values_m[ij]; cnt1++)
273 if(vars->l_min_values_m[ij][cnt1] < INF){
274 vars->N_M[ij][cnt1] += vars->l_min_values_m[ij][cnt1]/2;
275 free(vars->N_M[ij][cnt1]);
277 if(vars->k_min_values_m[ij] < INF){
278 vars->N_M[ij] += vars->k_min_values_m[ij];
287 if(vars->E_M != NULL){
288 for(i = 1; i < vars->seq_length; i++){
289 for(j = i; j <= vars->seq_length; j++){
290 ij = vars->my_iindx[i] - j;
291 if(!vars->E_M[ij]) continue;
292 for(cnt1 = vars->k_min_values_m[ij]; cnt1 <= vars->k_max_values_m[ij]; cnt1++)
293 if(vars->l_min_values_m[ij][cnt1] < INF){
294 vars->E_M[ij][cnt1] += vars->l_min_values_m[ij][cnt1]/2;
295 free(vars->E_M[ij][cnt1]);
297 if(vars->k_min_values_m[ij] < INF){
298 vars->E_M[ij] += vars->k_min_values_m[ij];
300 vars->l_min_values_m[ij] += vars->k_min_values_m[ij];
301 vars->l_max_values_m[ij] += vars->k_min_values_m[ij];
302 free(vars->l_min_values_m[ij]);
303 free(vars->l_max_values_m[ij]);
308 free(vars->l_min_values_m);
309 free(vars->l_max_values_m);
310 free(vars->k_min_values_m);
311 free(vars->k_max_values_m);
320 if(vars->N_M1 != NULL){
321 for(i = 1; i < vars->seq_length; i++){
322 for(j = i; j <= vars->seq_length; j++){
323 ij = vars->my_iindx[i] - j;
324 if(!vars->N_M1[ij]) continue;
325 for(cnt1 = vars->k_min_values_m1[ij]; cnt1 <= vars->k_max_values_m1[ij]; cnt1++)
326 if(vars->l_min_values_m1[ij][cnt1] < INF){
327 vars->N_M1[ij][cnt1] += vars->l_min_values_m1[ij][cnt1]/2;
328 free(vars->N_M1[ij][cnt1]);
330 if(vars->k_min_values_m1[ij] < INF){
331 vars->N_M1[ij] += vars->k_min_values_m1[ij];
332 free(vars->N_M1[ij]);
340 if(vars->E_M1 != NULL){
341 for(i = 1; i < vars->seq_length; i++){
342 for(j = i; j <= vars->seq_length; j++){
343 ij = vars->my_iindx[i] - j;
344 if(!vars->E_M1[ij]) continue;
345 for(cnt1 = vars->k_min_values_m1[ij]; cnt1 <= vars->k_max_values_m1[ij]; cnt1++)
346 if(vars->l_min_values_m1[ij][cnt1] < INF){
347 vars->E_M1[ij][cnt1] += vars->l_min_values_m1[ij][cnt1]/2;
348 free(vars->E_M1[ij][cnt1]);
350 if(vars->k_min_values_m1[ij] < INF){
351 vars->E_M1[ij] += vars->k_min_values_m1[ij];
352 free(vars->E_M1[ij]);
353 vars->l_min_values_m1[ij] += vars->k_min_values_m1[ij];
354 vars->l_max_values_m1[ij] += vars->k_min_values_m1[ij];
355 free(vars->l_min_values_m1[ij]);
356 free(vars->l_max_values_m1[ij]);
361 free(vars->l_min_values_m1);
362 free(vars->l_max_values_m1);
363 free(vars->k_min_values_m1);
364 free(vars->k_max_values_m1);
371 if(vars->E_M2 != NULL){
372 for(i = 1; i < vars->seq_length-TURN-1; i++){
373 if(!vars->E_M2[i]) continue;
374 for(cnt1 = vars->k_min_values_m2[i]; cnt1 <= vars->k_max_values_m2[i]; cnt1++)
375 if(vars->l_min_values_m2[i][cnt1] < INF){
376 vars->E_M2[i][cnt1] += vars->l_min_values_m2[i][cnt1]/2;
377 free(vars->E_M2[i][cnt1]);
379 if(vars->k_min_values_m2[i] < INF){
380 vars->E_M2[i] += vars->k_min_values_m2[i];
382 vars->l_min_values_m2[i] += vars->k_min_values_m2[i];
383 vars->l_max_values_m2[i] += vars->k_min_values_m2[i];
384 free(vars->l_min_values_m2[i]);
385 free(vars->l_max_values_m2[i]);
389 free(vars->l_min_values_m2);
390 free(vars->l_max_values_m2);
391 free(vars->k_min_values_m2);
392 free(vars->k_max_values_m2);
401 if(vars->N_F5 != NULL){
402 for(i = 1; i <= vars->seq_length; i++){
403 if(!vars->N_F5[i]) continue;
404 for(cnt1 = vars->k_min_values_f[i]; cnt1 <= vars->k_max_values_f[i]; cnt1++)
405 if(vars->l_min_values_f[i][cnt1] < INF){
406 vars->N_F5[i][cnt1] += vars->l_min_values_f[i][cnt1]/2;
407 free(vars->N_F5[i][cnt1]);
409 if(vars->k_min_values_f[i] < INF){
410 vars->N_F5[i] += vars->k_min_values_f[i];
418 if(vars->E_F5 != NULL){
419 for(i = 1; i <= vars->seq_length; i++){
420 if(!vars->E_F5[i]) continue;
421 for(cnt1 = vars->k_min_values_f[i]; cnt1 <= vars->k_max_values_f[i]; cnt1++)
422 if(vars->l_min_values_f[i][cnt1] < INF){
423 vars->E_F5[i][cnt1] += vars->l_min_values_f[i][cnt1]/2;
424 free(vars->E_F5[i][cnt1]);
426 if(vars->k_min_values_f[i] < INF){
427 vars->E_F5[i] += vars->k_min_values_f[i];
429 vars->l_min_values_f[i] += vars->k_min_values_f[i];
430 vars->l_max_values_f[i] += vars->k_min_values_f[i];
431 free(vars->l_min_values_f[i]);
432 free(vars->l_max_values_f[i]);
436 free(vars->l_min_values_f);
437 free(vars->l_max_values_f);
438 free(vars->k_min_values_f);
439 free(vars->k_max_values_f);
442 if(vars->E_F3 != NULL){
443 for(i = 1; i <= vars->seq_length; i++){
444 if(!vars->E_F3[i]) continue;
445 for(cnt1 = vars->k_min_values_f3[i]; cnt1 <= vars->k_max_values_f3[i]; cnt1++)
446 if(vars->l_min_values_f3[i][cnt1] < INF){
447 vars->E_F3[i][cnt1] += vars->l_min_values_f3[i][cnt1]/2;
448 free(vars->E_F3[i][cnt1]);
450 if(vars->k_min_values_f3[i] < INF){
451 vars->E_F3[i] += vars->k_min_values_f3[i];
453 vars->l_min_values_f3[i] += vars->k_min_values_f3[i];
454 vars->l_max_values_f3[i] += vars->k_min_values_f3[i];
455 free(vars->l_min_values_f3[i]);
456 free(vars->l_max_values_f3[i]);
460 free(vars->l_min_values_f3);
461 free(vars->l_max_values_f3);
462 free(vars->k_min_values_f3);
463 free(vars->k_max_values_f3);
471 if(vars->E_Fc != NULL){
472 for(cnt1 = vars->k_min_values_fc; cnt1 <= vars->k_max_values_fc; cnt1++)
473 if(vars->l_min_values_fc[cnt1] < INF){
474 vars->E_Fc[cnt1] += vars->l_min_values_fc[cnt1]/2;
475 free(vars->E_Fc[cnt1]);
477 if(vars->k_min_values_fc < INF){
478 vars->E_Fc += vars->k_min_values_fc;
480 vars->l_min_values_fc += vars->k_min_values_fc;
481 vars->l_max_values_fc += vars->k_min_values_fc;
482 free(vars->l_min_values_fc);
483 free(vars->l_max_values_fc);
491 if(vars->E_FcI != NULL){
492 for(cnt1 = vars->k_min_values_fcI; cnt1 <= vars->k_max_values_fcI; cnt1++)
493 if(vars->l_min_values_fcI[cnt1] < INF){
494 vars->E_FcI[cnt1] += vars->l_min_values_fcI[cnt1]/2;
495 free(vars->E_FcI[cnt1]);
497 if(vars->k_min_values_fcI < INF){
498 vars->E_FcI += vars->k_min_values_fcI;
500 vars->l_min_values_fcI += vars->k_min_values_fcI;
501 vars->l_max_values_fcI += vars->k_min_values_fcI;
502 free(vars->l_min_values_fcI);
503 free(vars->l_max_values_fcI);
511 if(vars->E_FcH != NULL){
512 for(cnt1 = vars->k_min_values_fcH; cnt1 <= vars->k_max_values_fcH; cnt1++)
513 if(vars->l_min_values_fcH[cnt1] < INF){
514 vars->E_FcH[cnt1] += vars->l_min_values_fcH[cnt1]/2;
515 free(vars->E_FcH[cnt1]);
517 if(vars->k_min_values_fcH < INF){
518 vars->E_FcH += vars->k_min_values_fcH;
520 vars->l_min_values_fcH += vars->k_min_values_fcH;
521 vars->l_max_values_fcH += vars->k_min_values_fcH;
522 free(vars->l_min_values_fcH);
523 free(vars->l_max_values_fcH);
531 if(vars->E_FcM != NULL){
532 for(cnt1 = vars->k_min_values_fcM; cnt1 <= vars->k_max_values_fcM; cnt1++)
533 if(vars->l_min_values_fcM[cnt1] < INF){
534 vars->E_FcM[cnt1] += vars->l_min_values_fcM[cnt1]/2;
535 free(vars->E_FcM[cnt1]);
537 if(vars->k_min_values_fcM < INF){
538 vars->E_FcM += vars->k_min_values_fcM;
540 vars->l_min_values_fcM += vars->k_min_values_fcM;
541 vars->l_max_values_fcM += vars->k_min_values_fcM;
542 free(vars->l_min_values_fcM);
543 free(vars->l_max_values_fcM);
553 if(vars->P != NULL) free(vars->P);
554 if(vars->sequence != NULL) free(vars->sequence);
555 if(vars->reference_pt1 != NULL) free(vars->reference_pt1);
556 if(vars->reference_pt2 != NULL) free(vars->reference_pt2);
557 if(vars->referenceBPs1 != NULL) free(vars->referenceBPs1);
558 if(vars->referenceBPs2 != NULL) free(vars->referenceBPs2);
559 if(vars->ptype != NULL) free(vars->ptype);
560 if(vars->S != NULL) free(vars->S);
561 if(vars->S1 != NULL) free(vars->S1);
563 if(vars->mm1 != NULL) free(vars->mm1);
564 if(vars->mm2 != NULL) free(vars->mm2);
565 if(vars->bpdist != NULL) free(vars->bpdist);
571 if(vars->my_iindx != NULL) free(vars->my_iindx);
576 PRIVATE void initialize_TwoDfold_vars(TwoDfold_vars *vars){
577 update_TwoDfold_params(vars);
578 /* this call updates the params in the ViennaRNA fold.o which is a global, so be careful
579 * whith calling it parallel... need a workarround or fix of ViennaRNA fold stuff
581 update_fold_params();
585 PUBLIC TwoDfold_solution **TwoDfold(TwoDfold_vars *vars, int distance1, int distance2){
586 unsigned int i, d1, d2;
590 TwoDfold_solution **output;
592 initialize_TwoDfold_vars(vars);
593 if(fabs(vars->P->temperature - temperature)>1e-6) update_TwoDfold_params(vars);
594 vars->S = encode_sequence(vars->sequence, 0);
595 vars->S1 = encode_sequence(vars->sequence, 1);
603 if((unsigned int)distance1 > maxD1)
605 "limiting maximum basepair distance 1 to %u\n",
608 maxD1 = (unsigned int)distance1;
612 if((unsigned int)distance2 > maxD2)
614 "limiting maximum basepair distance 2 to %u\n",
617 maxD2 = (unsigned int)distance2;
622 output = (TwoDfold_solution **)space((vars->maxD1+1) * sizeof(TwoDfold_solution *));
625 if(vars->circ) mfe_circ(vars);
627 length = vars->seq_length;
629 for(d1=0; d1<=maxD1;d1++){
630 output[d1] = (TwoDfold_solution *)space((vars->maxD2+1)*sizeof(TwoDfold_solution));
632 #pragma omp parallel for private(d2)
634 for(d2=0; d2<=maxD2;d2++){
635 output[d1][d2].en = (float)INF/(float)100.;
636 output[d1][d2].s = NULL;
638 if( (d1 >= ((vars->circ) ? vars->k_min_values_fc : vars->k_min_values_f[length]))
639 && (d1 <= ((vars->circ) ? vars->k_max_values_fc : vars->k_max_values_f[length]))){
641 #pragma omp parallel for private(d2, i)
643 for( d2 = ((vars->circ) ? vars->l_min_values_fc[d1] : vars->l_min_values_f[length][d1]);
644 d2 <= ((vars->circ) ? vars->l_max_values_fc[d1] : vars->l_max_values_f[length][d1]);
646 output[d1][d2].en = (float)((vars->circ) ? vars->E_Fc[d1][d2/2] : vars->E_F5[length][d1][d2/2])/(float)100.;
647 if(vars->do_backtrack && (output[d1][d2].en != (float)INF/(float)100.)){
648 char *mfe_structure = (char *)space(length+1);
649 for(i=0;i<length;i++) mfe_structure[i] = '.';
650 mfe_structure[i] = '\0';
651 (vars->circ) ? backtrack_fc(d1, d2, mfe_structure, vars) : backtrack_f5(length, d1, d2, mfe_structure, vars);
652 output[d1][d2].s = mfe_structure;
661 PUBLIC TwoDfold_solution *TwoDfoldList(TwoDfold_vars *vars, int distance1, int distance2){
662 unsigned int i, d1, d2;
666 unsigned int counter = 0;
668 TwoDfold_solution *output;
670 initialize_TwoDfold_vars(vars);
671 if(fabs(vars->P->temperature - temperature)>1e-6) update_TwoDfold_params(vars);
672 vars->S = encode_sequence(vars->sequence, 0);
673 vars->S1 = encode_sequence(vars->sequence, 1);
681 if((unsigned int)distance1 > maxD1)
683 "TwoDfoldList@2Dfold.c: limiting maximum basepair distance 1 to %u\n",
686 maxD1 = (unsigned int)distance1;
690 if((unsigned int)distance2 > maxD2)
692 "TwoDfoldList@2Dfold.c: limiting maximum basepair distance 2 to %u\n",
695 maxD2 = (unsigned int)distance2;
700 output = (TwoDfold_solution *)space((((vars->maxD1+1)*(vars->maxD2+2))/2 + 2) * sizeof(TwoDfold_solution));
703 if(vars->circ) mfe_circ(vars);
705 length = vars->seq_length;
707 for(d1=0; d1<=maxD1;d1++){
708 if((d1 >= ((vars->circ) ? vars->k_min_values_fc : vars->k_min_values_f[length]))
709 && (d1 <= ((vars->circ) ? vars->k_max_values_fc : vars->k_max_values_f[length]))){
710 for(d2 = ((vars->circ) ? vars->l_min_values_fc[d1] : vars->l_min_values_f[length][d1]);
711 d2 <= ((vars->circ) ? vars->l_max_values_fc[d1] : vars->l_max_values_f[length][d1]);
713 en = ((vars->circ) ? vars->E_Fc[d1][d2/2] : vars->E_F5[length][d1][d2/2]);
714 if(en == INF) continue;
715 output[counter].k = d1;
716 output[counter].l = d2;
717 output[counter].en = (float)en/(float)100.;
718 if(vars->do_backtrack){
719 char *mfe_structure = (char *)space(length+1);
720 for(i=0;i<length;i++) mfe_structure[i] = '.';
721 mfe_structure[i] = '\0';
722 (vars->circ) ? backtrack_fc((int)d1, (int)d2, mfe_structure, vars) : backtrack_f5(length, (int)d1, (int)d2, mfe_structure, vars);
723 output[counter].s = mfe_structure;
725 else output[counter].s = NULL;
731 /* store entry for remaining partition if it exists */
732 en = ((vars->circ) ? vars->E_Fc_rem : vars->E_F5_rem[length]);
734 output[counter].k = -1;
735 output[counter].l = -1;
736 output[counter].en = (float)en/(float)100.;
737 if(vars->do_backtrack){
738 char *mfe_structure = (char *)space(length+1);
739 for(i=0;i<length;i++) mfe_structure[i] = '.';
740 mfe_structure[i] = '\0';
741 (vars->circ) ? backtrack_fc(-1, -1, mfe_structure, vars) : backtrack_f5(length, -1, -1, mfe_structure, vars);
742 output[counter].s = mfe_structure;
744 else output[counter].s = NULL;
748 /* insert end-marker entry */
749 output[counter].k = output[counter].l = INF;
752 /* resize to actual dataset amount */
753 output = (TwoDfold_solution*)xrealloc(output, sizeof(TwoDfold_solution) * counter);
758 PUBLIC char *TwoDfold_backtrack_f5(unsigned int j, int k, int l, TwoDfold_vars *vars){
760 char *mfe_structure = (char *)space(j+1);
761 if(j < TURN + 2) return NULL;
763 for(i=0; i < j; i++) mfe_structure[i] = '.';
764 mfe_structure[i] = '\0';
766 backtrack_f5(j, k, l, mfe_structure, vars);
767 return mfe_structure;
770 PRIVATE void mfe_linear(TwoDfold_vars *vars){
772 unsigned int d, i, j, ij, maxD1, maxD2, seq_length, dia, dib, dja, djb, *referenceBPs1, *referenceBPs2, *mm1, *mm2, *bpdist;
773 int cnt1, cnt2, cnt3, cnt4, d1, d2, energy, dangles, temp2, type, additional_en, *my_iindx, circ;
774 short *S1, *reference_pt1, *reference_pt2;
775 char *sequence, *ptype;
778 /* dereferenciate things we often need */
780 sequence = vars->sequence;
781 seq_length = vars->seq_length;
786 reference_pt1 = vars->reference_pt1;
787 reference_pt2 = vars->reference_pt2;
788 my_iindx = vars->my_iindx;
789 referenceBPs1 = vars->referenceBPs1;
790 referenceBPs2 = vars->referenceBPs2;
791 dangles = vars->dangles;
794 bpdist = vars->bpdist;
797 for (d = TURN+2; d <= seq_length; d++) { /* i,j in [1..length] */
799 #pragma omp parallel for private(additional_en, j, energy, temp2, i, ij, dia,dib,dja,djb,cnt1,cnt2,cnt3,cnt4, d1, d2)
801 for (j = d; j <= seq_length; j++) {
802 unsigned int p, q, pq, u, maxp, dij;
803 int type_2, type, tt, no_close, base_d1, base_d2;
810 no_close = (((type==3)||(type==4))&&no_closingGU);
812 if (type) { /* we have a pair */
813 /* increase or decrease distance-to-reference value depending whether (i,j) is included in
814 * reference or has to be introduced
816 base_d1 = ((unsigned int)reference_pt1[i] != j) ? 1 : -1;
817 base_d2 = ((unsigned int)reference_pt2[i] != j) ? 1 : -1;
819 /* HAIRPIN STRUCTURES */
821 /* get distance to reference if closing the hairpin
822 * d = dbp(T_{i,j}, {i,j})
824 d1 = base_d1 + referenceBPs1[ij];
825 d2 = base_d2 + referenceBPs2[ij];
827 int min_k, max_k, min_l, max_l;
828 int real_min_k, real_max_k, *min_l_real, *max_l_real;
831 max_k = mm1[ij] + referenceBPs1[ij];
832 max_l = mm2[ij] + referenceBPs2[ij];
834 prepareBoundaries(min_k,
839 &vars->k_min_values[ij],
840 &vars->k_max_values[ij],
841 &vars->l_min_values[ij],
842 &vars->l_max_values[ij]
845 preparePosteriorBoundaries( vars->k_max_values[ij] - vars->k_min_values[ij] + 1,
846 vars->k_min_values[ij],
853 prepareArray( &vars->E_C[ij],
854 vars->k_min_values[ij],
855 vars->k_max_values[ij],
856 vars->l_min_values[ij],
857 vars->l_max_values[ij]
861 prepareArray2( &vars->N_C[ij],
862 vars->k_min_values[ij],
863 vars->k_max_values[ij],
864 vars->l_min_values[ij],
865 vars->l_max_values[ij]
869 /* d1 and d2 are the distancies to both references introduced by closing a hairpin structure at (i,j) */
870 if((d1 >= 0) && (d2 >= 0)){
871 if(((unsigned int)d1<=maxD1) && ((unsigned int)d2 <= maxD2)){
872 vars->E_C[ij][d1][d2/2] = (no_close) ? FORBIDDEN : E_Hairpin(dij, type, S1[i+1], S1[j-1], sequence+i-1, P);
873 updatePosteriorBoundaries(d1,
881 vars->N_C[ij][d1][d2/2] = 1;
885 vars->E_C_rem[ij] = (no_close) ? FORBIDDEN : E_Hairpin(dij, type, S1[i+1], S1[j-1], sequence+i-1, P);
888 /* INTERIOR LOOP STRUCTURES */
889 maxp = MIN2(j-2-TURN,i+MAXLOOP+1);
890 for(p = i+1; p <= maxp; p++){
891 unsigned int minq = p + TURN + 1;
892 unsigned int ln_pre = dij + p;
893 if(ln_pre > minq + MAXLOOP) minq = ln_pre - MAXLOOP - 1;
894 for(q = minq; q < j; q++){
896 /* set distance to reference structure... */
899 if (type_2==0) continue;
900 type_2 = rtype[type_2];
902 /* get distance to reference if closing the interior loop
903 * d2 = dbp(S_{i,j}, S_{p.q} + {i,j})
905 d1 = base_d1 + referenceBPs1[ij] - referenceBPs1[pq];
906 d2 = base_d2 + referenceBPs2[ij] - referenceBPs2[pq];
909 if(no_close||(type_2==3)||(type_2==4))
910 if((p>i+1)||(q<j-1)) continue; /* continue unless stack */
912 energy = E_IntLoop(p-i-1, j-q-1, type, type_2, S1[i+1], S1[j-1], S1[p-1], S1[q+1], P);
914 if(vars->E_C[pq] != NULL){
915 for(cnt1 = vars->k_min_values[pq]; cnt1 <= vars->k_max_values[pq]; cnt1++){
916 for(cnt2 = vars->l_min_values[pq][cnt1]; cnt2 <= vars->l_max_values[pq][cnt1]; cnt2+=2){
917 if(vars->E_C[pq][cnt1][cnt2/2] != INF){
918 if(((cnt1 + d1) <= maxD1) && ((cnt2+d2) <= maxD2)){
919 vars->E_C[ij][cnt1 + d1][(cnt2 + d2)/2] = MIN2( vars->E_C[ij][cnt1 + d1][(cnt2 + d2)/2],
920 vars->E_C[pq][cnt1][cnt2/2] + energy
922 updatePosteriorBoundaries(cnt1 + d1,
930 vars->N_C[ij][cnt1 + d1][(cnt2 + d2)/2] += vars->N_C[pq][cnt1][cnt2/2];
933 /* collect all cases where d1+cnt1 or d2+cnt2 exceeds maxD1, maxD2, respectively */
935 vars->E_C_rem[ij] = MIN2(vars->E_C_rem[ij], vars->E_C[pq][cnt1][cnt2/2] + energy);
941 /* collect all contributions where C[pq] already lies outside k_max, l_max boundary */
942 if(vars->E_C_rem[pq] != INF){
943 vars->E_C_rem[ij] = MIN2(vars->E_C_rem[ij], vars->E_C_rem[pq] + energy);
950 /* MULTI LOOP STRUCTURES */
953 /* dangle energies for multiloop closing stem */
955 temp2 = P->MLclosing;
957 temp2 += E_MLstem(tt, S1[j-1], S1[i+1], P);
959 temp2 += E_MLstem(tt, -1, -1, P);
961 for(u=i+TURN+2; u<j-TURN-2;u++){
962 int i1u = my_iindx[i+1]-u;
963 int u1j1 = my_iindx[u+1]-j+1;
964 /* check all cases where either M or M1 are already out of scope of maxD1 and/or maxD2 */
965 if(vars->E_M_rem[i1u] != INF){
966 for(cnt3 = vars->k_min_values_m1[u1j1];
967 cnt3 <= vars->k_max_values_m1[u1j1];
969 for(cnt4 = vars->l_min_values_m1[u1j1][cnt3];
970 cnt4 <= vars->l_max_values_m1[u1j1][cnt3];
972 if(vars->E_M1[u1j1][cnt3][cnt4/2]!= INF){
973 vars->E_C_rem[ij] = MIN2(vars->E_C_rem[ij],
975 + vars->E_M1[u1j1][cnt3][cnt4/2]
980 if(vars->E_M1_rem[u1j1] != INF){
981 vars->E_C_rem[ij] = MIN2(vars->E_C_rem[ij],
983 + vars->E_M1_rem[u1j1]
988 if(vars->E_M1_rem[u1j1] != INF){
989 for(cnt1 = vars->k_min_values_m[i1u];
990 cnt1 <= vars->k_max_values_m[i1u];
992 for(cnt2 = vars->l_min_values_m[i1u][cnt1];
993 cnt2 <= vars->l_max_values_m[i1u][cnt1];
995 if(vars->E_M[i1u][cnt1][cnt2/2] != INF){
996 vars->E_C_rem[ij] = MIN2(vars->E_C_rem[ij],
997 vars->E_M[i1u][cnt1][cnt2/2]
998 + vars->E_M1_rem[u1j1]
1003 /* get distance to reference if closing the multiloop
1004 * d = dbp(S_{i,j}, {i,j} + S_{i+1,u} + S_{u+1,j-1})
1006 if(!vars->E_M[i1u]) continue;
1007 if(!vars->E_M1[u1j1]) continue;
1009 d1 = base_d1 + referenceBPs1[ij] - referenceBPs1[i1u] - referenceBPs1[u1j1];
1010 d2 = base_d2 + referenceBPs2[ij] - referenceBPs2[i1u] - referenceBPs2[u1j1];
1012 for(cnt1 = vars->k_min_values_m[i1u];
1013 cnt1 <= vars->k_max_values_m[i1u];
1015 for(cnt2 = vars->l_min_values_m[i1u][cnt1];
1016 cnt2 <= vars->l_max_values_m[i1u][cnt1];
1018 for(cnt3 = vars->k_min_values_m1[u1j1];
1019 cnt3 <= vars->k_max_values_m1[u1j1];
1021 for(cnt4 = vars->l_min_values_m1[u1j1][cnt3];
1022 cnt4 <= vars->l_max_values_m1[u1j1][cnt3];
1024 if((vars->E_M[i1u][cnt1][cnt2/2] != INF) && (vars->E_M1[u1j1][cnt3][cnt4/2]!= INF)){
1025 if(((cnt1+cnt3+d1) <= maxD1) && ((cnt2+cnt4+d2) <= maxD2)){
1026 vars->E_C[ij][cnt1+cnt3+d1][(cnt2+cnt4+d2)/2] = MIN2( vars->E_C[ij][cnt1+cnt3+d1][(cnt2+cnt4+d2)/2],
1027 vars->E_M[i1u][cnt1][cnt2/2]
1028 + vars->E_M1[u1j1][cnt3][cnt4/2]
1031 updatePosteriorBoundaries(cnt1 + cnt3 + d1,
1039 vars->N_C[ij][cnt1+cnt3+d1][(cnt2+cnt4+d2)/2] += vars->N_M[i1u][cnt1][cnt2/2] * vars->N_M1[u1j1][cnt3][cnt4/2];
1042 /* collect all cases where d1+cnt1+cnt3 or d2+cnt2+cnt4 exceeds maxD1, maxD2, respectively */
1044 vars->E_C_rem[ij] = MIN2( vars->E_C_rem[ij],
1045 vars->E_M[i1u][cnt1][cnt2/2]
1046 + vars->E_M1[u1j1][cnt3][cnt4/2]
1055 /* resize and move memory portions of energy matrix E_C */
1056 adjustArrayBoundaries(&vars->E_C[ij],
1057 &vars->k_min_values[ij],
1058 &vars->k_max_values[ij],
1059 &vars->l_min_values[ij],
1060 &vars->l_max_values[ij],
1067 /* actually we should adjust the array boundaries here but we might never use the count states option more than once so what....*/
1069 } /* end >> if (pair) << */
1073 /* done with c[i,j], now compute fML[i,j] */
1074 /* free ends ? -----------------------------------------*/
1077 dia = referenceBPs1[ij] - referenceBPs1[my_iindx[i+1]-j];
1078 dib = referenceBPs2[ij] - referenceBPs2[my_iindx[i+1]-j];
1079 dja = referenceBPs1[ij] - referenceBPs1[ij+1];
1080 djb = referenceBPs2[ij] - referenceBPs2[ij+1];
1083 temp2 = E_MLstem(type, ((i > 1) || circ) ? S1[i-1] : -1, ((j < seq_length) || circ) ? S1[j+1] : -1, P);
1085 temp2 = E_MLstem(type, -1, -1, P);
1087 int min_k_guess, max_k_guess, min_l_guess, max_l_guess;
1088 int min_k_real_m, max_k_real_m, *min_l_real_m, *max_l_real_m;
1089 int min_k_real_m1, max_k_real_m1, *min_l_real_m1, *max_l_real_m1;
1091 min_k_guess = min_l_guess = 0;
1092 max_k_guess = mm1[ij] + referenceBPs1[ij];
1093 max_l_guess = mm2[ij] + referenceBPs2[ij];
1095 prepareBoundaries(min_k_guess,
1100 &vars->k_min_values_m[ij],
1101 &vars->k_max_values_m[ij],
1102 &vars->l_min_values_m[ij],
1103 &vars->l_max_values_m[ij]
1106 prepareBoundaries(min_k_guess,
1111 &vars->k_min_values_m1[ij],
1112 &vars->k_max_values_m1[ij],
1113 &vars->l_min_values_m1[ij],
1114 &vars->l_max_values_m1[ij]
1117 preparePosteriorBoundaries( vars->k_max_values_m[ij] - vars->k_min_values_m[ij] + 1,
1118 vars->k_min_values_m[ij],
1124 preparePosteriorBoundaries( vars->k_max_values_m1[ij] - vars->k_min_values_m1[ij] + 1,
1125 vars->k_min_values_m1[ij],
1132 prepareArray( &vars->E_M[ij],
1133 vars->k_min_values_m[ij],
1134 vars->k_max_values_m[ij],
1135 vars->l_min_values_m[ij],
1136 vars->l_max_values_m[ij]
1139 prepareArray( &vars->E_M1[ij],
1140 vars->k_min_values_m1[ij],
1141 vars->k_max_values_m1[ij],
1142 vars->l_min_values_m1[ij],
1143 vars->l_max_values_m1[ij]
1146 prepareArray2( &vars->N_M[ij],
1147 vars->k_min_values_m[ij],
1148 vars->k_max_values_m[ij],
1149 vars->l_min_values_m[ij],
1150 vars->l_max_values_m[ij]
1152 prepareArray2( &vars->N_M1[ij],
1153 vars->k_min_values_m1[ij],
1154 vars->k_max_values_m1[ij],
1155 vars->l_min_values_m1[ij],
1156 vars->l_max_values_m1[ij]
1160 /* now to the actual computations... */
1161 /* 1st E_M[ij] = E_M1[ij] = E_C[ij] + b */
1162 if(vars->E_C_rem[ij] != INF){
1163 vars->E_M_rem[ij] = vars->E_M1_rem[ij] = temp2 + vars->E_C_rem[ij];
1166 for(cnt1 = vars->k_min_values[ij]; cnt1 <= vars->k_max_values[ij]; cnt1++){
1167 for(cnt2 = vars->l_min_values[ij][cnt1]; cnt2 <= vars->l_max_values[ij][cnt1]; cnt2+=2){
1168 if(vars->E_C[ij][cnt1][cnt2/2] != INF){
1169 vars->E_M[ij][cnt1][cnt2/2] = vars->E_M1[ij][cnt1][cnt2/2] = temp2 + vars->E_C[ij][cnt1][cnt2/2];
1170 updatePosteriorBoundaries(cnt1,
1177 updatePosteriorBoundaries(cnt1,
1185 vars->N_M[ij][cnt1][cnt2/2] = vars->N_M1[ij][cnt1][cnt2/2] = vars->N_C[ij][cnt1][cnt2/2];
1191 /* 2nd E_M[ij] = MIN(E_M[ij], E_M[i+1,j] + c) */
1192 if(vars->E_M_rem[my_iindx[i+1]-j] != INF){
1193 vars->E_M_rem[ij] = MIN2(vars->E_M_rem[ij],
1194 vars->E_M_rem[my_iindx[i+1]-j] + P->MLbase
1197 if(vars->E_M[my_iindx[i+1]-j])
1198 for(cnt1 = vars->k_min_values_m[my_iindx[i+1]-j];
1199 cnt1 <= vars->k_max_values_m[my_iindx[i+1]-j];
1201 for(cnt2 = vars->l_min_values_m[my_iindx[i+1]-j][cnt1];
1202 cnt2 <= vars->l_max_values_m[my_iindx[i+1]-j][cnt1];
1204 if(vars->E_M[my_iindx[i+1]-j][cnt1][cnt2/2] != INF){
1205 if(((cnt1 + dia) <= maxD1) && ((cnt2 + dib) <= maxD2)){
1206 vars->E_M[ij][cnt1+dia][(cnt2+dib)/2] = MIN2( vars->E_M[ij][cnt1+dia][(cnt2+dib)/2],
1207 vars->E_M[my_iindx[i+1]-j][cnt1][cnt2/2] + P->MLbase
1209 updatePosteriorBoundaries(cnt1 + dia,
1217 vars->N_M[ij][cnt1+dia][(cnt2+dib)/2] += vars->N_M[my_iindx[i+1]-j][cnt1][cnt2/2];
1220 /* collect all cases where dia+cnt1 or dib+cnt2 exceeds maxD1, maxD2, respectively */
1222 vars->E_M_rem[ij] = MIN2(vars->E_M_rem[ij],
1223 vars->E_M[my_iindx[i+1]-j][cnt1][cnt2/2] + P->MLbase
1230 /* 3rd E_M[ij] = MIN(E_M[ij], E_M[i,j-1] + c) */
1231 if(vars->E_M_rem[ij+1] != INF){
1232 vars->E_M_rem[ij] = MIN2(vars->E_M_rem[ij],
1233 vars->E_M_rem[ij+1] + P->MLbase
1237 for(cnt1 = vars->k_min_values_m[ij+1];
1238 cnt1 <= vars->k_max_values_m[ij+1];
1240 for(cnt2 = vars->l_min_values_m[ij+1][cnt1];
1241 cnt2 <= vars->l_max_values_m[ij+1][cnt1];
1243 if(vars->E_M[ij+1][cnt1][cnt2/2] != INF){
1244 if(((cnt1 + dja) <= maxD1) && ((cnt2 + djb) <= maxD2)){
1245 vars->E_M[ij][cnt1+dja][(cnt2+djb)/2] = MIN2( vars->E_M[ij][cnt1+dja][(cnt2+djb)/2],
1246 vars->E_M[ij+1][cnt1][cnt2/2] + P->MLbase
1248 updatePosteriorBoundaries(cnt1 + dja,
1256 vars->N_M[ij][cnt1+dja][(cnt2+djb)/2] += vars->N_M[ij+1][cnt1][cnt2/2];
1259 /* collect all cases where dja+cnt1 or djb+cnt2 exceeds maxD1, maxD2, respectively */
1261 vars->E_M_rem[ij] = MIN2(vars->E_M_rem[ij],
1262 vars->E_M[ij+1][cnt1][cnt2/2] + P->MLbase
1269 /* 4th E_M1[ij] = MIN(E_M1[ij], E_M1[i,j-1] + c) */
1270 if(vars->E_M1_rem[ij+1] != INF){
1271 vars->E_M1_rem[ij] = MIN2( vars->E_M1_rem[ij],
1272 vars->E_M1_rem[ij+1] + P->MLbase
1275 if(vars->E_M1[ij+1])
1276 for(cnt1 = vars->k_min_values_m1[ij+1];
1277 cnt1 <= vars->k_max_values_m1[ij+1];
1279 for(cnt2 = vars->l_min_values_m1[ij+1][cnt1];
1280 cnt2 <= vars->l_max_values_m1[ij+1][cnt1];
1282 if(vars->E_M1[ij+1][cnt1][cnt2/2] != INF){
1283 if(((cnt1 + dja) <= maxD1) && ((cnt2 + djb) <= maxD2)){
1284 vars->E_M1[ij][cnt1+dja][(cnt2+djb)/2] = MIN2( vars->E_M1[ij][cnt1+dja][(cnt2+djb)/2],
1285 vars->E_M1[ij+1][cnt1][cnt2/2] + P->MLbase
1287 updatePosteriorBoundaries(cnt1 + dja,
1295 vars->N_M1[ij][cnt1+dja][(cnt2+djb)/2] += vars->N_M1[ij+1][cnt1][cnt2/2];
1298 /* collect all cases where dja+cnt1 or djb+cnt2 exceeds maxD1, maxD2, respectively */
1300 vars->E_M1_rem[ij] = MIN2( vars->E_M1_rem[ij],
1301 vars->E_M1[ij+1][cnt1][cnt2/2] + P->MLbase
1309 /* 5th E_M[ij] = MIN(E_M[ij], min(E_M[i,k] + E_M[k+1,j])) */
1311 for (u = i+1+TURN; u <= j-2-TURN; u++){
1312 /* check all cases where M(i,u) and/or M(u+1,j) are already out of scope of maxD1 and/or maxD2 */
1313 if(vars->E_M_rem[my_iindx[i]-u] != INF){
1314 for(cnt3 = vars->k_min_values_m[my_iindx[u+1]-j];
1315 cnt3 <= vars->k_max_values_m[my_iindx[u+1]-j];
1317 for(cnt4 = vars->l_min_values_m[my_iindx[u+1]-j][cnt3];
1318 cnt4 <= vars->l_max_values_m[my_iindx[u+1]-j][cnt3];
1320 if(vars->E_M[my_iindx[u+1]-j][cnt3][cnt4/2] != INF){
1321 vars->E_M_rem[ij] = MIN2(vars->E_M_rem[ij],
1322 vars->E_M_rem[my_iindx[i]-u] + vars->E_M[my_iindx[u+1]-j][cnt3][cnt4/2]
1327 if(vars->E_M_rem[my_iindx[u+1]-j] != INF){
1328 vars->E_M_rem[ij] = MIN2(vars->E_M_rem[ij],
1329 vars->E_M_rem[my_iindx[i]-u] + vars->E_M_rem[my_iindx[u+1]-j]
1333 if(vars->E_M_rem[my_iindx[u+1]-j] != INF){
1334 for(cnt1 = vars->k_min_values_m[my_iindx[i]-u];
1335 cnt1 <= vars->k_max_values_m[my_iindx[i]-u];
1337 for(cnt2 = vars->l_min_values_m[my_iindx[i]-u][cnt1];
1338 cnt2 <= vars->l_max_values_m[my_iindx[i]-u][cnt1];
1340 if(vars->E_M[my_iindx[i]-u][cnt1][cnt2/2] != INF){
1341 vars->E_M_rem[ij] = MIN2(vars->E_M_rem[ij],
1342 vars->E_M[my_iindx[i]-u][cnt1][cnt2/2] + vars->E_M_rem[my_iindx[u+1]-j]
1348 if(!vars->E_M[my_iindx[i]-u]) continue;
1349 if(!vars->E_M[my_iindx[u+1]-j]) continue;
1351 dia = referenceBPs1[ij] - referenceBPs1[my_iindx[i]-u] - referenceBPs1[my_iindx[u+1]-j];
1352 dib = referenceBPs2[ij] - referenceBPs2[my_iindx[i]-u] - referenceBPs2[my_iindx[u+1]-j];
1354 for(cnt1 = vars->k_min_values_m[my_iindx[i]-u];
1355 cnt1 <= vars->k_max_values_m[my_iindx[i]-u];
1357 for(cnt2 = vars->l_min_values_m[my_iindx[i]-u][cnt1];
1358 cnt2 <= vars->l_max_values_m[my_iindx[i]-u][cnt1];
1360 for(cnt3 = vars->k_min_values_m[my_iindx[u+1]-j];
1361 cnt3 <= vars->k_max_values_m[my_iindx[u+1]-j];
1363 for(cnt4 = vars->l_min_values_m[my_iindx[u+1]-j][cnt3];
1364 cnt4 <= vars->l_max_values_m[my_iindx[u+1]-j][cnt3];
1366 if((vars->E_M[my_iindx[i]-u][cnt1][cnt2/2] != INF) && (vars->E_M[my_iindx[u+1]-j][cnt3][cnt4/2] != INF)){
1367 if(((cnt1 + cnt3 + dia) <= maxD1) && ((cnt2 + cnt4 + dib) <= maxD2)){
1368 vars->E_M[ij][cnt1+cnt3+dia][(cnt2+cnt4+dib)/2] = MIN2( vars->E_M[ij][cnt1+cnt3+dia][(cnt2+cnt4+dib)/2],
1369 vars->E_M[my_iindx[i]-u][cnt1][cnt2/2]
1370 + vars->E_M[my_iindx[u+1]-j][cnt3][cnt4/2]
1372 updatePosteriorBoundaries(cnt1 + cnt3 + dia,
1380 vars->N_M[ij][cnt1+cnt3+dia][(cnt2+cnt4+dib)/2] += vars->N_M[my_iindx[i]-u][cnt1][cnt2/2] * vars->N_M1[my_iindx[u+1]-j][cnt3][cnt4/2];
1383 /* collect all cases where dia+cnt1+cnt3 or dib+cnt2+cnt4 exceeds maxD1, maxD2, respectively */
1385 vars->E_M_rem[ij] = MIN2(vars->E_M_rem[ij],
1386 vars->E_M[my_iindx[i]-u][cnt1][cnt2/2] + vars->E_M[my_iindx[u+1]-j][cnt3][cnt4/2]
1396 /* thats all folks for the multiloop decomposition... */
1398 adjustArrayBoundaries(&vars->E_M[ij],
1399 &vars->k_min_values_m[ij],
1400 &vars->k_max_values_m[ij],
1401 &vars->l_min_values_m[ij],
1402 &vars->l_max_values_m[ij],
1409 adjustArrayBoundaries(&vars->E_M1[ij],
1410 &vars->k_min_values_m1[ij],
1411 &vars->k_max_values_m1[ij],
1412 &vars->l_min_values_m1[ij],
1413 &vars->l_max_values_m1[ij],
1421 /* actually we should adjust the array boundaries here but we might never use the count states option more than once so what....*/
1423 } /* end of j-loop */
1426 /* calculate energies of 5' and 3' fragments */
1428 /* prepare first entries in E_F5 */
1429 for(cnt1 = 1; cnt1 <= TURN+1; cnt1++){
1430 vars->E_F5[cnt1] = (int **)space(sizeof(int *));
1431 vars->E_F5[cnt1][0] = (int *)space(sizeof(int));
1432 vars->E_F5[cnt1][0][0] = 0;
1433 vars->E_F5_rem[cnt1] = INF;
1434 vars->k_min_values_f[cnt1] = vars->k_max_values_f[cnt1] = 0;
1435 vars->l_min_values_f[cnt1] = (int *)space(sizeof(int));
1436 vars->l_max_values_f[cnt1] = (int *)space(sizeof(int));
1437 vars->l_min_values_f[cnt1][0] = vars->l_max_values_f[cnt1][0] = 0;
1439 vars->N_F5[cnt1] = (unsigned long **)space(sizeof(unsigned long *));
1440 vars->N_F5[cnt1][0] = (unsigned long *)space(sizeof(unsigned long));
1441 vars->N_F5[cnt1][0][0] = 1;
1448 for (j=TURN+2; j <= seq_length; j++) {
1450 unsigned int da = referenceBPs1[my_iindx[1]-j] - referenceBPs1[my_iindx[1]-j+1];
1451 unsigned int db = referenceBPs2[my_iindx[1]-j] - referenceBPs2[my_iindx[1]-j+1];
1453 type=ptype[my_iindx[1]-j];
1457 additional_en += E_ExtLoop(type, -1, j < seq_length ? S1[j+1] : -1, P);
1459 additional_en += E_ExtLoop(type, -1, -1, P);
1462 /* make min and max k guess for memory allocation */
1463 int min_k_guess, max_k_guess, min_l_guess, max_l_guess;
1464 int *min_l_real, *max_l_real, min_k_real, max_k_real;
1466 min_k_guess = min_l_guess = 0;
1467 max_k_guess = referenceBPs1[my_iindx[1]-j] + mm1[my_iindx[1]-j];
1468 max_l_guess = referenceBPs2[my_iindx[1]-j] + mm2[my_iindx[1]-j];
1470 prepareBoundaries(min_k_guess,
1474 bpdist[my_iindx[1]-j],
1475 &vars->k_min_values_f[j],
1476 &vars->k_max_values_f[j],
1477 &vars->l_min_values_f[j],
1478 &vars->l_max_values_f[j]
1481 preparePosteriorBoundaries( vars->k_max_values_f[j] - vars->k_min_values_f[j] + 1,
1482 vars->k_min_values_f[j],
1489 prepareArray( &vars->E_F5[j],
1490 vars->k_min_values_f[j],
1491 vars->k_max_values_f[j],
1492 vars->l_min_values_f[j],
1493 vars->l_max_values_f[j]
1496 prepareArray2( &vars->N_F5[j],
1497 vars->k_min_values_f[j],
1498 vars->k_max_values_f[j],
1499 vars->l_min_values_f[j],
1500 vars->l_max_values_f[j]
1504 /* begin the actual computation of 5' end energies */
1506 /* j-1 is unpaired ... */
1507 vars->E_F5_rem[j] = vars->E_F5_rem[j-1];
1508 for(cnt1 = vars->k_min_values_f[j-1]; cnt1 <= vars->k_max_values_f[j-1]; cnt1++){
1509 for(cnt2 = vars->l_min_values_f[j-1][cnt1]; cnt2 <= vars->l_max_values_f[j-1][cnt1]; cnt2+=2){
1510 if(((cnt1 + da) <= maxD1) && ((cnt2 + db) <= maxD2)){
1511 vars->E_F5[j][cnt1+da][(cnt2+db)/2] = MIN2( vars->E_F5[j][cnt1+da][(cnt2+db)/2],
1512 vars->E_F5[j-1][cnt1][cnt2/2]
1514 updatePosteriorBoundaries(cnt1 + da,
1522 vars->N_F5[j][cnt1+da][(cnt2+db)/2] += vars->N_F5[j-1][cnt1][cnt2/2];
1525 /* collect all cases where da+cnt1 or db+cnt2 exceeds maxD1, maxD2, respectively */
1527 vars->E_F5_rem[j] = MIN2(vars->E_F5_rem[j], vars->E_F5[j-1][cnt1][cnt2/2]);
1531 /* j pairs with 1 */
1532 if(vars->E_C_rem[my_iindx[1]-j] != INF){
1533 vars->E_F5_rem[j] = MIN2(vars->E_F5_rem[j], vars->E_C_rem[my_iindx[1]-j] + additional_en);
1535 if(vars->E_C[my_iindx[1]-j])
1536 for(cnt1 = vars->k_min_values[my_iindx[1]-j]; cnt1 <= vars->k_max_values[my_iindx[1]-j]; cnt1++)
1537 for(cnt2 = vars->l_min_values[my_iindx[1]-j][cnt1]; cnt2 <= vars->l_max_values[my_iindx[1]-j][cnt1]; cnt2+=2){
1538 if(vars->E_C[my_iindx[1]-j][cnt1][cnt2/2] != INF){
1539 vars->E_F5[j][cnt1][cnt2/2] = MIN2( vars->E_F5[j][cnt1][cnt2/2],
1540 vars->E_C[my_iindx[1]-j][cnt1][cnt2/2]+ additional_en
1542 updatePosteriorBoundaries(cnt1,
1550 vars->N_F5[j][cnt1][cnt2/2] += vars->N_C[my_iindx[1]-j][cnt1][cnt2/2];
1555 /* j pairs with some other nucleotide -> see below */
1556 for (i=j-TURN-1; i>1; i--) {
1561 additional_en = E_ExtLoop(type, S1[i-1], j < seq_length ? S1[j+1] : -1, P);
1563 additional_en = E_ExtLoop(type, -1, -1, P);
1565 if(vars->E_C_rem[ij] != INF){
1566 for(cnt3 = vars->k_min_values_f[i-1]; cnt3 <= vars->k_max_values_f[i-1]; cnt3++)
1567 for(cnt4 = vars->l_min_values_f[i-1][cnt3]; cnt4 <= vars->l_max_values_f[i-1][cnt3]; cnt4+=2){
1568 if(vars->E_F5[i-1][cnt3][cnt4/2] != INF){
1569 vars->E_F5_rem[j] = MIN2(vars->E_F5_rem[j],
1570 vars->E_F5[i-1][cnt3][cnt4/2] + vars->E_C_rem[ij] + additional_en
1574 if(vars->E_F5_rem[i-1] != INF){
1575 vars->E_F5_rem[j] = MIN2(vars->E_F5_rem[j],
1576 vars->E_F5_rem[i-1] + vars->E_C_rem[ij] + additional_en
1580 if((vars->E_F5_rem[i-1] != INF) && (vars->E_C[ij])){
1581 for(cnt1 = vars->k_min_values[ij]; cnt1 <= vars->k_max_values[ij]; cnt1++)
1582 for(cnt2 = vars->l_min_values[ij][cnt1]; cnt2 <= vars->l_max_values[ij][cnt1]; cnt2+=2)
1583 if(vars->E_C[ij][cnt1][cnt2/2]!= INF){
1584 vars->E_F5_rem[j] = MIN2(vars->E_F5_rem[j],
1585 vars->E_F5_rem[i-1] + vars->E_C[ij][cnt1][cnt2/2] + additional_en
1589 if(!vars->E_C[ij]) continue;
1591 unsigned int d1a = referenceBPs1[my_iindx[1]-j] - referenceBPs1[ij] - referenceBPs1[my_iindx[1]-i+1];
1592 unsigned int d1b = referenceBPs2[my_iindx[1]-j] - referenceBPs2[ij] - referenceBPs2[my_iindx[1]-i+1];
1594 for(cnt1 = vars->k_min_values[ij]; cnt1 <= vars->k_max_values[ij]; cnt1++)
1595 for(cnt2 = vars->l_min_values[ij][cnt1]; cnt2 <= vars->l_max_values[ij][cnt1]; cnt2+=2)
1596 for(cnt3 = vars->k_min_values_f[i-1]; cnt3 <= vars->k_max_values_f[i-1]; cnt3++)
1597 for(cnt4 = vars->l_min_values_f[i-1][cnt3]; cnt4 <= vars->l_max_values_f[i-1][cnt3]; cnt4+=2){
1598 if(vars->E_F5[i-1][cnt3][cnt4/2] != INF && vars->E_C[ij][cnt1][cnt2/2]!= INF){
1599 if(((cnt1 + cnt3 + d1a) <= maxD1) && ((cnt2 + cnt4 + d1b) <= maxD2)){
1600 vars->E_F5[j][cnt1+cnt3+d1a][(cnt2+cnt4+d1b)/2] = MIN2( vars->E_F5[j][cnt1+cnt3+d1a][(cnt2+cnt4+d1b)/2],
1601 vars->E_F5[i-1][cnt3][cnt4/2] + vars->E_C[ij][cnt1][cnt2/2] + additional_en
1603 updatePosteriorBoundaries(cnt1 + cnt3 + d1a,
1611 vars->N_F5[j][cnt1+cnt3+d1a][(cnt2+cnt4+d1b)/2] += vars->N_F5[i-1][cnt3][cnt4/2] * vars->N_C[ij][cnt1][cnt2/2];
1614 /* collect all cases where d1a+cnt1+cnt3 or d1b+cnt2+cnt4 exceeds maxD1, maxD2, respectively */
1616 vars->E_F5_rem[j] = MIN2(vars->E_F5_rem[j],
1617 vars->E_F5[i-1][cnt3][cnt4/2] + vars->E_C[ij][cnt1][cnt2/2] + additional_en
1625 /* resize and move memory portions of energy matrix E_F5 */
1626 adjustArrayBoundaries(&vars->E_F5[j],
1627 &vars->k_min_values_f[j],
1628 &vars->k_max_values_f[j],
1629 &vars->l_min_values_f[j],
1630 &vars->l_max_values_f[j],
1637 } /* end of j-loop */
1640 if(compute_2Dfold_F3){
1642 /* prepare first entries in E_F3 */
1643 for(cnt1 = seq_length; cnt1 >= seq_length-TURN-1; cnt1--){
1644 vars->E_F3[cnt1] = (int **)space(sizeof(int *));
1645 vars->E_F3[cnt1][0] = (int *) space(sizeof(int));
1646 vars->E_F3[cnt1][0][0] = 0;
1647 vars->k_min_values_f3[cnt1] = vars->k_max_values_f3[cnt1] = 0;
1648 vars->l_min_values_f3[cnt1] = (int *)space(sizeof(int));
1649 vars->l_max_values_f3[cnt1] = (int *)space(sizeof(int));
1650 vars->l_min_values_f3[cnt1][0] = vars->l_max_values_f3[cnt1][0] = 0;
1652 /* begin calculations */
1653 for (j=seq_length-TURN-2; j >= 1; j--){
1655 unsigned int da = referenceBPs1[my_iindx[j]-seq_length] - referenceBPs1[my_iindx[j+1]-seq_length];
1656 unsigned int db = referenceBPs2[my_iindx[j]-seq_length] - referenceBPs2[my_iindx[j+1]-seq_length];
1658 type=ptype[my_iindx[j]-seq_length];
1662 additional_en += E_ExtLoop(type, j > 1 ? S1[j-1] : -1, -1, P);
1664 additional_en += E_ExtLoop(type, -1, -1, P);
1667 /* make min and max k guess for memory allocation */
1668 int min_k_guess, max_k_guess, min_l_guess, max_l_guess;
1669 int *min_l_real, *max_l_real, min_k_real, max_k_real;
1671 min_k_guess = min_l_guess = 0;
1672 max_k_guess = referenceBPs1[my_iindx[j]-seq_length] + mm1[my_iindx[j]-seq_length];
1673 max_l_guess = referenceBPs2[my_iindx[j]-seq_length] + mm2[my_iindx[j]-seq_length];
1675 prepareBoundaries(min_k_guess,
1679 bpdist[my_iindx[j]-seq_length],
1680 &vars->k_min_values_f3[j],
1681 &vars->k_max_values_f3[j],
1682 &vars->l_min_values_f3[j],
1683 &vars->l_max_values_f3[j]
1686 preparePosteriorBoundaries( vars->k_max_values_f3[j] - vars->k_min_values_f3[j] + 1,
1687 vars->k_min_values_f3[j],
1694 prepareArray( &vars->E_F3[j],
1695 vars->k_min_values_f3[j],
1696 vars->k_max_values_f3[j],
1697 vars->l_min_values_f3[j],
1698 vars->l_max_values_f3[j]
1700 /* begin the actual computation of 5' end energies */
1702 /* j is unpaired ... */
1703 for(cnt1 = vars->k_min_values_f3[j+1]; cnt1 <= vars->k_max_values_f3[j+1]; cnt1++){
1704 for(cnt2 = vars->l_min_values_f3[j+1][cnt1]; cnt2 <= vars->l_max_values_f3[j+1][cnt1]; cnt2+=2){
1705 vars->E_F3[j][cnt1+da][(cnt2+db)/2] = MIN2( vars->E_F3[j][cnt1+da][(cnt2+db)/2],
1706 vars->E_F3[j+1][cnt1][cnt2/2]
1708 updatePosteriorBoundaries(cnt1 + da,
1717 /* j pairs with n */
1718 if(vars->E_C[my_iindx[j]-seq_length])
1719 for(cnt1 = vars->k_min_values[my_iindx[j]-seq_length]; cnt1 <= vars->k_max_values[my_iindx[j]-seq_length]; cnt1++)
1720 for(cnt2 = vars->l_min_values[my_iindx[j]-seq_length][cnt1]; cnt2 <= vars->l_max_values[my_iindx[j]-seq_length][cnt1]; cnt2+=2){
1721 if(vars->E_C[my_iindx[j]-seq_length][cnt1][cnt2/2] != INF){
1722 vars->E_F3[j][cnt1][cnt2/2] = MIN2( vars->E_F3[j][cnt1][cnt2/2],
1723 vars->E_C[my_iindx[j]-seq_length][cnt1][cnt2/2]+ additional_en
1725 updatePosteriorBoundaries(cnt1,
1735 /* j pairs with some other nucleotide -> see below */
1736 for (i=j-TURN-1; i>1; i--) {
1738 if(!vars->E_C[ij]) continue;
1741 unsigned int d1a = referenceBPs1[my_iindx[1]-j] - referenceBPs1[ij] - referenceBPs1[my_iindx[1]-i+1];
1742 unsigned int d1b = referenceBPs2[my_iindx[1]-j] - referenceBPs2[ij] - referenceBPs2[my_iindx[1]-i+1];
1745 additional_en = E_ExtLoop(type, S1[i-1], j < seq_length ? S1[j+1] : -1, P);
1747 additional_en = E_ExtLoop(type, -1, -1, P);
1749 for(cnt1 = vars->k_min_values[ij]; cnt1 <= vars->k_max_values[ij]; cnt1++)
1750 for(cnt2 = vars->l_min_values[ij][cnt1]; cnt2 <= vars->l_max_values[ij][cnt1]; cnt2+=2)
1751 for(cnt3 = vars->k_min_values_f[i-1]; cnt3 <= vars->k_max_values_f[i-1]; cnt3++)
1752 for(cnt4 = vars->l_min_values_f[i-1][cnt3]; cnt4 <= vars->l_max_values_f[i-1][cnt3]; cnt4+=2){
1753 if(vars->E_F5[i-1][cnt3][cnt4/2] != INF && vars->E_C[ij][cnt1][cnt2/2]!= INF){
1754 vars->E_F5[j][cnt1+cnt3+d1a][(cnt2+cnt4+d1b)/2] = MIN2( vars->E_F5[j][cnt1+cnt3+d1a][(cnt2+cnt4+d1b)/2],
1755 vars->E_F5[i-1][cnt3][cnt4/2] + vars->E_C[ij][cnt1][cnt2/2] + additional_en
1757 updatePosteriorBoundaries(cnt1 + cnt3 + d1a,
1765 vars->N_F5[j][cnt1+cnt3+d1a][(cnt2+cnt4+d1b)/2] += vars->N_F5[i-1][cnt3][cnt4/2] * vars->N_C[ij][cnt1][cnt2/2];
1772 /* resize and move memory portions of energy matrix E_F5 */
1773 adjustArrayBoundaries(&vars->E_F5[j],
1774 &vars->k_min_values_f[j],
1775 &vars->k_max_values_f[j],
1776 &vars->l_min_values_f[j],
1777 &vars->l_max_values_f[j],
1784 } /* end of j-loop */
1793 /*---------------------------------------------------------------------------*/
1795 PUBLIC void update_TwoDfold_params(TwoDfold_vars *vars){
1796 if(vars->P) free(vars->P);
1797 vars->P = scale_parameters();
1801 /*---------------------------------------------------------------------------*/
1802 PRIVATE void make_ptypes(TwoDfold_vars *vars) {
1806 for (k=1; k<n-TURN; k++)
1807 for (l=1; l<=2; l++) {
1808 int type,ntype=0,otype=0;
1809 i=k; j = i+TURN+l; if (j>n) continue;
1810 type = pair[vars->S[i]][vars->S[j]];
1811 while ((i>=1)&&(j<=n)) {
1812 if ((i>1)&&(j<n)) ntype = pair[vars->S[i-1]][vars->S[j+1]];
1813 if (noLonelyPairs && (!otype) && (!ntype))
1814 type = 0; /* i.j can only form isolated pairs */
1815 vars->ptype[vars->my_iindx[i]-j] = (char) type;
1823 PRIVATE void backtrack_f5(unsigned int j, int k, int l, char *structure, TwoDfold_vars *vars){
1824 int *my_iindx, energy, type, dangles, cnt1, cnt2, cnt3, cnt4;
1825 int **l_min_values, **l_max_values,**l_min_values_f, **l_max_values_f;
1826 int *k_min_values, *k_max_values,*k_min_values_f, *k_max_values_f;
1827 int ***E_C, ***E_F5;
1828 int *E_C_rem, *E_F5_rem;
1829 unsigned int i, ij, seq_length, maxD1, maxD2;
1831 unsigned int *referenceBPs1, *referenceBPs2;
1834 unsigned int da, db;
1837 seq_length = vars->seq_length;
1839 ptype = vars->ptype;
1840 my_iindx = vars->my_iindx;
1841 referenceBPs1 = vars->referenceBPs1;
1842 referenceBPs2 = vars->referenceBPs2;
1843 dangles = vars->dangles;
1845 l_min_values_f = vars->l_min_values_f;
1846 l_max_values_f = vars->l_max_values_f;
1847 k_min_values_f = vars->k_min_values_f;
1848 k_max_values_f = vars->k_max_values_f;
1851 l_min_values = vars->l_min_values;
1852 l_max_values = vars->l_max_values;
1853 k_min_values = vars->k_min_values;
1854 k_max_values = vars->k_max_values;
1856 E_F5_rem = vars->E_F5_rem;
1857 E_C_rem = vars->E_C_rem;
1858 maxD1 = vars->maxD1;
1859 maxD2 = vars->maxD2;
1861 da = referenceBPs1[my_iindx[1]-j] - referenceBPs1[my_iindx[1]-j+1];
1862 db = referenceBPs2[my_iindx[1]-j] - referenceBPs2[my_iindx[1]-j+1];
1864 if(j<TURN+2) return;
1866 /* F5[j] == F5[j-1] ? */
1868 if(E_F5_rem[j]==INF)
1870 else if(E_F5_rem[j] == E_F5_rem[j-1]){
1871 backtrack_f5(j-1,k,l,structure, vars);
1875 for(cnt1 = k_min_values_f[j-1];
1876 cnt1 <= k_max_values_f[j-1];
1878 for(cnt2 = l_min_values_f[j-1][cnt1];
1879 cnt2 <= l_max_values_f[j-1][cnt1];
1881 if(((cnt1 + da) > maxD1) || ((cnt2 + db) > maxD2)){
1882 if(E_F5_rem[j] == E_F5[j-1][cnt1][cnt2/2]){
1883 backtrack_f5(j-1, cnt1, cnt2, structure, vars);
1891 else if((k >= da) && (l >= db)){
1893 if((k - da >= k_min_values_f[j-1]) && (k - da <= k_max_values_f[j-1])){
1894 if((l - db >= l_min_values_f[j-1][k-da]) && (l - db <= l_max_values_f[j-1][k-da]))
1895 if(E_F5[j-1][k-da][(l-db)/2] == E_F5[j][k][l/2]){
1896 backtrack_f5(j-1, k-da, l-db, structure, vars);
1903 type = ptype[my_iindx[1]-j];
1906 energy = E_ExtLoop(type, -1, j < seq_length ? S1[j+1] : -1, P);
1908 energy = E_ExtLoop(type, -1, -1, P);
1911 if(E_C_rem[my_iindx[1]-j] + energy == E_F5_rem[j]){
1912 backtrack_c(1, j, -1, -1, structure, vars);
1916 else if(k >= k_min_values[my_iindx[1]-j] && (k <= k_max_values[my_iindx[1]-j])){
1918 if((l >= l_min_values[my_iindx[1]-j][k]) && (l <= l_max_values[my_iindx[1]-j][k]))
1919 if(E_C[my_iindx[1]-j][k][l/2] + energy == E_F5[j][k][l/2]){
1920 backtrack_c(1, j, k, l, structure, vars);
1926 for (i=j-TURN-1; i>1; i--) {
1930 unsigned int d1a = referenceBPs1[my_iindx[1]-j] - referenceBPs1[ij] - referenceBPs1[my_iindx[1]-i+1];
1931 unsigned int d1b = referenceBPs2[my_iindx[1]-j] - referenceBPs2[ij] - referenceBPs2[my_iindx[1]-i+1];
1934 energy = E_ExtLoop(type, S1[i-1], j < seq_length ? S1[j+1] : -1, P);
1936 energy = E_ExtLoop(type, -1, -1, P);
1939 if(E_C_rem[ij] != INF){
1940 for(cnt1 = k_min_values_f[i-1];
1941 cnt1 <= k_max_values_f[i-1];
1943 for(cnt2 = l_min_values_f[i-1][cnt1];
1944 cnt2 <= l_max_values_f[i-1][cnt1];
1946 if(E_F5_rem[j] == (E_F5[i-1][cnt1][cnt2/2] + E_C_rem[ij] + energy)){
1947 backtrack_f5(i-1, cnt1, cnt2, structure, vars);
1948 backtrack_c(i,j,-1,-1,structure, vars);
1953 if(E_F5_rem[j] == (E_F5_rem[i-1] + E_C_rem[ij] + energy)){
1954 backtrack_f5(i-1, -1, -1, structure, vars);
1955 backtrack_c(i,j,-1,-1,structure,vars);
1959 if(E_F5_rem[i-1] != INF){
1960 for(cnt1 = k_min_values[ij];
1961 cnt1 <= k_max_values[ij];
1963 for(cnt2 = l_min_values[ij][cnt1];
1964 cnt2 <= l_max_values[ij][cnt1];
1966 if(E_F5_rem[j] == (E_F5_rem[i-1] + E_C[ij][cnt1][cnt2/2] + energy)){
1967 backtrack_f5(i-1,-1,-1,structure,vars);
1968 backtrack_c(i,j,cnt1,cnt2,structure,vars);
1974 for(cnt1 = k_min_values_f[i-1];
1975 cnt1 <= k_max_values_f[i-1];
1977 for(cnt2 = l_min_values_f[i-1][cnt1];
1978 cnt2 <= l_max_values_f[i-1][cnt1];
1980 for(cnt3 = k_min_values[ij];
1981 cnt3 <= k_max_values[ij];
1983 for(cnt4 = l_min_values[ij][cnt3];
1984 cnt4 <= l_max_values[ij][cnt3];
1986 if(((cnt1 + cnt3 + d1a)>maxD1) || ((cnt2+cnt4+d1b)>maxD2)){
1987 if(E_F5_rem[j] == (E_F5[i-1][cnt1][cnt2/2] + E_C[ij][cnt3][cnt4/2] + energy)){
1988 backtrack_f5(i-1,cnt1,cnt2,structure,vars);
1989 backtrack_c(i,j,cnt3,cnt4,structure,vars);
1995 else if((k >= d1a) && (l >= d1b)){
1996 int k_f_max = MIN2(k-d1a, k_max_values_f[i-1]);
1998 for(cnt1 = k_min_values_f[i-1]; cnt1 <= k_f_max; cnt1++){
1999 int l_f_max = MIN2(l - d1b, l_max_values_f[i-1][cnt1]);
2000 for(cnt2 = l_min_values_f[i-1][cnt1]; cnt2 <= l_f_max; cnt2+=2){
2001 int k_c = k - d1a - cnt1;
2002 if((k_c >= k_min_values[ij]) && (k_c <= k_max_values[ij])){
2003 int l_c = l - d1b - cnt2;
2004 if((l_c >= l_min_values[ij][k_c]) && (l_c <= l_max_values[ij][k_c])){
2005 if(E_F5[j][k][l/2] == (E_F5[i-1][cnt1][cnt2/2] + E_C[ij][k_c][l_c/2] + energy)){
2006 backtrack_f5(i-1, cnt1, cnt2, structure, vars);
2007 backtrack_c(i, j, k_c, l_c, structure, vars);
2018 nrerror("backtracking failed in f5");
2021 PRIVATE void backtrack_c(unsigned int i, unsigned int j, int k, int l, char *structure, TwoDfold_vars *vars){
2022 unsigned int p, q, pq, ij, maxp, maxD1, maxD2;
2023 int *my_iindx, type, type_2, energy, no_close, dangles, base_d1, base_d2, d1, d2, cnt1, cnt2, cnt3, cnt4;
2024 int **l_min_values, **l_max_values,**l_min_values_m, **l_max_values_m,**l_min_values_m1, **l_max_values_m1;
2025 int *k_min_values, *k_max_values,*k_min_values_m, *k_max_values_m,*k_min_values_m1, *k_max_values_m1;
2026 int ***E_C, ***E_M, ***E_M1, *E_C_rem, *E_M_rem, *E_M1_rem;
2028 unsigned int *referenceBPs1, *referenceBPs2;
2029 char *ptype, *sequence;
2033 sequence = vars->sequence;
2035 ptype = vars->ptype;
2036 my_iindx = vars->my_iindx;
2037 referenceBPs1 = vars->referenceBPs1;
2038 referenceBPs2 = vars->referenceBPs2;
2039 dangles = vars->dangles;
2042 l_min_values = vars->l_min_values;
2043 l_max_values = vars->l_max_values;
2044 k_min_values = vars->k_min_values;
2045 k_max_values = vars->k_max_values;
2048 l_min_values_m = vars->l_min_values_m;
2049 l_max_values_m = vars->l_max_values_m;
2050 k_min_values_m = vars->k_min_values_m;
2051 k_max_values_m = vars->k_max_values_m;
2054 l_min_values_m1 = vars->l_min_values_m1;
2055 l_max_values_m1 = vars->l_max_values_m1;
2056 k_min_values_m1 = vars->k_min_values_m1;
2057 k_max_values_m1 = vars->k_max_values_m1;
2059 E_C_rem = vars->E_C_rem;
2060 E_M_rem = vars->E_M_rem;
2061 E_M1_rem = vars->E_M1_rem;
2062 maxD1 = vars->maxD1;
2063 maxD2 = vars->maxD2;
2068 int e = (k==-1) ? E_C_rem[ij] : E_C[ij][k][l/2];
2072 no_close = (((type==3)||(type==4))&&no_closingGU);
2073 structure[i-1] = '(';
2074 structure[j-1] = ')';
2076 base_d1 = ((unsigned int)vars->reference_pt1[i] != j) ? 1 : -1;
2077 base_d2 = ((unsigned int)vars->reference_pt2[i] != j) ? 1 : -1;
2079 base_d1 += referenceBPs1[ij];
2080 base_d2 += referenceBPs2[ij];
2083 if(((unsigned int)base_d1 > maxD1) || ((unsigned int)base_d2 > maxD2)){
2084 if(e == E_Hairpin(j-i-1, type, S1[i+1], S1[j-1], sequence+i-1, P)) return;
2088 if((unsigned int)base_d1 == k)
2089 if((unsigned int)base_d2 == l)
2090 if(E_Hairpin(j-i-1, type, S1[i+1], S1[j-1], sequence+i-1, P) == e) return;
2092 maxp = MIN2(j-2-TURN,i+MAXLOOP+1);
2093 for(p = i+1; p <= maxp; p++){
2094 unsigned int minq, ln_pre;
2095 minq = p + TURN + 1;
2097 if(ln_pre > minq + MAXLOOP) minq = ln_pre - MAXLOOP - 1;
2098 for (q = minq; q < j; q++) {
2101 if (type_2==0) continue;
2102 type_2 = rtype[type_2];
2104 /* d2 = dbp(S_{i,j}, S_{p.q} + {i,j}) */
2105 d1 = base_d1 - referenceBPs1[pq];
2106 d2 = base_d2 - referenceBPs2[pq];
2108 energy = E_IntLoop(p-i-1, j-q-1, type, type_2, S1[i+1], S1[j-1], S1[p-1], S1[q+1], P);
2112 if(E_C_rem[pq] != INF)
2113 if(e == (E_C_rem[pq] + energy)){
2114 backtrack_c(p,q,-1,-1,structure,vars);
2118 for(cnt1 = k_min_values[pq];
2119 cnt1 <= k_max_values[pq];
2121 for(cnt2 = l_min_values[pq][cnt1];
2122 cnt2 <= l_max_values[pq][cnt1];
2124 if(((cnt1 + d1) > maxD1) || ((cnt2 + d2) > maxD2)){
2125 if(e == (E_C[pq][cnt1][cnt2/2] + energy)){
2126 backtrack_c(p,q,cnt1,cnt2,structure,vars);
2133 if(!E_C[pq]) continue;
2134 if(d1 <= k && d2 <= l){
2135 if((k-d1 >= k_min_values[pq]) && (k-d1) <= k_max_values[pq])
2136 if((l - d2 >= l_min_values[pq][k-d1]) && (l-d2 <= l_max_values[pq][k-d1]))
2137 if(E_C[pq][k-d1][(l-d2)/2] + energy == e){
2138 backtrack_c(p, q, k-d1, l-d2, structure, vars);
2146 /* multi-loop decomposition ------------------------*/
2151 for(u=i+TURN+2; u<j-TURN-2;u++){
2153 i1u = my_iindx[i+1]-u;
2154 u1j1 = my_iindx[u+1]-j+1;
2156 energy = P->MLclosing;
2158 energy += E_MLstem(tt, S1[j-1], S1[i+1], P);
2160 energy += E_MLstem(tt, -1, -1, P);
2163 if(E_M_rem[i1u] != INF){
2165 for(cnt1 = k_min_values_m1[u1j1];
2166 cnt1 <= k_max_values_m1[u1j1];
2168 for(cnt2 = l_min_values_m1[u1j1][cnt1];
2169 cnt2 <= l_max_values_m1[u1j1][cnt1];
2171 if(e == (E_M_rem[i1u] + E_M1[u1j1][cnt1][cnt2/2] + energy)){
2172 backtrack_m(i+1,u,-1,-1,structure,vars);
2173 backtrack_m1(u+1,j-1,cnt1,cnt2,structure,vars);
2177 if(E_M1_rem[u1j1] != INF){
2178 if(e == (E_M_rem[i1u] + E_M1_rem[u1j1] + energy)){
2179 backtrack_m(i+1, u, -1, -1, structure, vars);
2180 backtrack_m1(u+1, j-1, -1, -1, structure, vars);
2185 if(E_M1_rem[u1j1] != INF){
2187 for(cnt1 = k_min_values_m[i1u];
2188 cnt1 <= k_max_values_m[i1u];
2190 for(cnt2 = l_min_values_m[i1u][cnt1];
2191 cnt2 <= l_max_values_m[i1u][cnt1];
2193 if(e == (E_M[i1u][cnt1][cnt2/2] + E_M1_rem[u1j1] + energy)){
2194 backtrack_m(i+1,u,cnt1,cnt2,structure,vars);
2195 backtrack_m1(u+1,j-1,-1,-1,structure,vars);
2200 /* now all cases where we exceed the maxD1/D2 scope by combination of E_M and E_M1 */
2201 if(!E_M[i1u]) continue;
2202 if(!E_M1[u1j1]) continue;
2203 /* get distance to reference if closing this multiloop
2204 * dist3 = dbp(S_{i,j}, {i,j} + S_{i+1.u} + S_{u+1,j-1})
2206 d1 = base_d1 - referenceBPs1[i1u] - referenceBPs1[u1j1];
2207 d2 = base_d2 - referenceBPs2[i1u] - referenceBPs2[u1j1];
2209 for(cnt1 = vars->k_min_values_m[i1u];
2210 cnt1 <= vars->k_max_values_m[i1u];
2212 for(cnt2 = vars->l_min_values_m[i1u][cnt1];
2213 cnt2 <= vars->l_max_values_m[i1u][cnt1];
2215 for(cnt3 = vars->k_min_values_m1[u1j1];
2216 cnt3 <= vars->k_max_values_m1[u1j1];
2218 for(cnt4 = vars->l_min_values_m1[u1j1][cnt3];
2219 cnt4 <= vars->l_max_values_m1[u1j1][cnt3];
2221 if(((cnt1 + cnt3 + d1) > maxD1) || ((cnt2 + cnt4 + d2) > maxD2)){
2222 if(e == (E_M[i1u][cnt1][cnt2/2] + E_M1[u1j1][cnt3][cnt4/2] + energy)){
2223 backtrack_m(i+1,u,cnt1,cnt2,structure,vars);
2224 backtrack_m1(u+1,j-1,cnt3,cnt4,structure,vars);
2232 for(u=i+TURN+2; u<j-TURN-2;u++){
2234 i1u = my_iindx[i+1]-u;
2235 u1j1 = my_iindx[u+1]-j+1;
2236 if(!E_M[i1u]) continue;
2237 if(!E_M1[u1j1]) continue;
2239 /* get distance to reference if closing this multiloop
2240 * dist3 = dbp(S_{i,j}, {i,j} + S_{i+1.u} + S_{u+1,j-1})
2242 d1 = base_d1 - referenceBPs1[i1u] - referenceBPs1[u1j1];
2243 d2 = base_d2 - referenceBPs2[i1u] - referenceBPs2[u1j1];
2246 energy = P->MLclosing;
2248 energy += E_MLstem(tt, S1[j-1], S1[i+1], P);
2250 energy += E_MLstem(tt, -1, -1, P);
2252 if((d1 <= k) && (d2 <= l))
2253 for(cnt1 = k_min_values_m[i1u];
2254 cnt1 <= MIN2(k-d1, k_max_values_m[i1u]);
2256 for(cnt2 = l_min_values_m[i1u][cnt1];
2257 cnt2 <= MIN2(l-d2, l_max_values_m[i1u][cnt1]);
2259 if( ((k-d1-cnt1) >= k_min_values_m1[u1j1])
2260 && ((k-d1-cnt1) <= k_max_values_m1[u1j1]))
2261 if( ((l-d2-cnt2) >= l_min_values_m1[u1j1][k-d1-cnt1])
2262 && ((l-d2-cnt2) <= l_max_values_m1[u1j1][k-d1-cnt1]))
2263 if(e == (energy + E_M[i1u][cnt1][cnt2/2] + E_M1[u1j1][k-d1-cnt1][(l-d2-cnt2)/2])){
2264 backtrack_m(i+1, u, cnt1, cnt2, structure, vars);
2265 backtrack_m1(u+1, j-1, k-d1-cnt1, l-d2-cnt2, structure, vars);
2271 nrerror("backtracking failed in c");
2274 PRIVATE void backtrack_m(unsigned int i, unsigned int j, int k, int l, char *structure, TwoDfold_vars *vars){
2275 unsigned int u, ij, seq_length, base_d1, base_d2, d1, d2, maxD1, maxD2;
2276 int *my_iindx, type, energy, dangles,circ, cnt1, cnt2, cnt3, cnt4;
2277 int **l_min_values, **l_max_values,**l_min_values_m, **l_max_values_m;
2278 int *k_min_values, *k_max_values,*k_min_values_m, *k_max_values_m;
2279 int ***E_C, ***E_M, *E_C_rem, *E_M_rem;
2281 unsigned int *referenceBPs1, *referenceBPs2;
2286 seq_length = vars->seq_length;
2289 ptype = vars->ptype;
2290 my_iindx = vars->my_iindx;
2291 referenceBPs1 = vars->referenceBPs1;
2292 referenceBPs2 = vars->referenceBPs2;
2293 dangles = vars->dangles;
2296 l_min_values = vars->l_min_values;
2297 l_max_values = vars->l_max_values;
2298 k_min_values = vars->k_min_values;
2299 k_max_values = vars->k_max_values;
2302 l_min_values_m = vars->l_min_values_m;
2303 l_max_values_m = vars->l_max_values_m;
2304 k_min_values_m = vars->k_min_values_m;
2305 k_max_values_m = vars->k_max_values_m;
2307 E_C_rem = vars->E_C_rem;
2308 E_M_rem = vars->E_M_rem;
2309 maxD1 = vars->maxD1;
2310 maxD2 = vars->maxD2;
2313 int e = (k == -1) ? E_M_rem[ij] : E_M[ij][k][l/2];
2315 base_d1 = referenceBPs1[ij];
2316 base_d2 = referenceBPs2[ij];
2319 /* new_fML = ML(i+1,j)+c */
2320 d1 = base_d1 - referenceBPs1[my_iindx[i+1]-j];
2321 d2 = base_d2 - referenceBPs2[my_iindx[i+1]-j];
2322 if(E_M_rem[my_iindx[i+1]-j] != INF){
2323 if(e == (E_M_rem[my_iindx[i+1]-j] + P->MLbase)){
2324 backtrack_m(i+1,j,-1,-1,structure,vars);
2328 if(E_M[my_iindx[i+1]-j])
2329 for(cnt1 = k_min_values_m[my_iindx[i+1]-j];
2330 cnt1 <= k_max_values_m[my_iindx[i+1]-j];
2332 for(cnt2 = l_min_values_m[my_iindx[i+1]-j][cnt1];
2333 cnt2 <= l_max_values_m[my_iindx[i+1]-j][cnt1];
2335 if(((cnt1 + d1) > maxD1) || ((cnt2 + d2) > maxD2)){
2336 if(e == (E_M[my_iindx[i+1]-j][cnt1][cnt2/2] + P->MLbase)){
2337 backtrack_m(i+1,j,cnt1,cnt2,structure,vars);
2342 /* new_fML = min(ML(i,j-1) + c, new_fML) */
2343 d1 = base_d1 - referenceBPs1[ij+1];
2344 d2 = base_d2 - referenceBPs2[ij+1];
2345 if(E_M_rem[ij+1] != INF){
2346 if(e == (E_M_rem[ij+1] + P->MLbase)){
2347 backtrack_m(i,j-1,-1,-1,structure,vars);
2352 for(cnt1 = k_min_values_m[ij+1];
2353 cnt1 <= k_max_values_m[ij+1];
2355 for(cnt2 = l_min_values_m[ij+1][cnt1];
2356 cnt2 <= l_max_values_m[ij+1][cnt1];
2358 if(((cnt1 + d1) > maxD1) || ((cnt2 + d2) > maxD2)){
2359 if(e == (E_M[ij+1][cnt1][cnt2/2] + P->MLbase)){
2360 backtrack_m(i,j-1,cnt1,cnt2,structure,vars);
2365 /* new_fML = min(new_fML, C(i,j)+b) */
2366 if(E_C_rem[ij] != INF){
2369 energy = E_MLstem(type, ((i > 1) || circ) ? S1[i-1] : -1, ((j < seq_length) || circ) ? S1[j+1] : -1, P);
2371 energy = E_MLstem(type, -1, -1, P);
2372 if(e == (E_C_rem[ij] + energy)){
2373 backtrack_c(i,j,-1,-1,structure,vars);
2378 /* modular decomposition -------------------------------*/
2379 for(u = i+1+TURN; u <= j-2-TURN; u++){
2382 uj = my_iindx[u+1]-j;
2385 d1 = base_d1 - referenceBPs1[iu] - referenceBPs1[uj];
2386 d2 = base_d2 - referenceBPs2[iu] - referenceBPs2[uj];
2389 energy = E_MLstem(type, S1[u], (j < seq_length) || circ ? S1[j+1] : -1, P);
2391 energy = E_MLstem(type, -1, -1, P);
2393 if(E_M_rem[iu] != INF){
2395 for(cnt1 = k_min_values[uj];
2396 cnt1 <= k_max_values[uj];
2398 for(cnt2 = l_min_values[uj][cnt1];
2399 cnt2 <= l_max_values[uj][cnt1];
2401 if(e == (E_M_rem[iu] + E_C[uj][cnt1][cnt2/2] + energy)){
2402 backtrack_m(i,u,-1,-1,structure,vars);
2403 backtrack_c(u+1,j,cnt1,cnt2,structure, vars);
2406 if(E_C_rem[uj] != INF){
2407 if(e == (E_M_rem[iu] + E_C_rem[uj] + energy)){
2408 backtrack_m(i,u,-1,-1,structure,vars);
2409 backtrack_c(u+1,j,-1,-1,structure,vars);
2414 if(E_C_rem[uj] != INF){
2416 for(cnt1 = k_min_values_m[iu];
2417 cnt1 <= k_max_values_m[iu];
2419 for(cnt2 = l_min_values_m[iu][cnt1];
2420 cnt2 <= l_max_values_m[iu][cnt1];
2422 if(e == (E_M[iu][cnt1][cnt2/2] + E_C_rem[uj] + energy)){
2423 backtrack_m(i,u,cnt1,cnt2,structure,vars);
2424 backtrack_c(u+1,j,-1,-1,structure,vars);
2429 if(!E_M[iu]) continue;
2430 if(!E_C[uj]) continue;
2432 for(cnt1 = k_min_values_m[iu];
2433 cnt1 <= k_max_values_m[iu];
2435 for(cnt2 = l_min_values_m[iu][cnt1];
2436 cnt2 <= l_max_values_m[iu][cnt1];
2438 for(cnt3 = k_min_values[uj];
2439 cnt3 <= k_max_values[uj];
2441 for(cnt4 = l_min_values[uj][cnt3];
2442 cnt4 <= l_max_values[uj][cnt3];
2444 if(((cnt1 + cnt3 + d1) > maxD1) || ((cnt2 + cnt4 + d2) > maxD2))
2445 if(e == (E_M[iu][cnt1][cnt2/2] + E_C[uj][cnt3][cnt4/2] + energy)){
2446 backtrack_m(i, u, cnt1, cnt2, structure, vars);
2447 backtrack_c(u+1, j, cnt3, cnt4, structure, vars);
2453 } /* end if (k == -1) */
2455 d1 = base_d1 - referenceBPs1[my_iindx[i+1]-j];
2456 d2 = base_d2 - referenceBPs2[my_iindx[i+1]-j];
2457 /* new_fML = ML(i+1,j)+c */
2458 if(d1 <= k && d2 <= l)
2459 if((k-d1 >= k_min_values_m[my_iindx[i+1]-j]) && (k-d1 <= k_max_values_m[my_iindx[i+1]-j]))
2460 if((l-d2 >= l_min_values_m[my_iindx[i+1]-j][k-d1]) && (l-d2 <= l_max_values_m[my_iindx[i+1]-j][k-d1])){
2461 if(E_M[my_iindx[i+1]-j][k-d1][(l-d2)/2] + P->MLbase == e){
2462 backtrack_m(i+1, j, k-d1, l-d2, structure, vars);
2467 d1 = base_d1 - referenceBPs1[ij+1];
2468 d2 = base_d2 - referenceBPs2[ij+1];
2470 /* new_fML = min(ML(i,j-1) + c, new_fML) */
2472 if(d1 <= k && d2 <= l)
2473 if((k-d1 >= k_min_values_m[ij+1]) && (k-d1 <= k_max_values_m[ij+1]))
2474 if((l-d2 >= l_min_values_m[ij+1][k-d1]) && (l-d2 <= l_max_values_m[ij+1][k-d1]))
2475 if(E_M[ij+1][k-d1][(l-d2)/2] + P->MLbase == e){
2476 backtrack_m(i, j-1, k-d1, l-d2, structure, vars);
2480 /* new_fML = min(new_fML, C(i,j)+b) */
2485 energy = E_MLstem(type, ((i > 1) || circ) ? S1[i-1] : -1, ((j < seq_length) || circ) ? S1[j+1] : -1, P);
2487 energy = E_MLstem(type, -1, -1, P);
2489 if((k >= k_min_values[ij]) && (k <= k_max_values[ij]))
2490 if((l >= l_min_values[ij][k]) && (l <= l_max_values[ij][k])){
2491 if(E_C[ij][k][l/2] + energy == e){
2492 backtrack_c(i, j, k, l, structure, vars);
2498 /* modular decomposition -------------------------------*/
2500 for(u = i+1+TURN; u <= j-2-TURN; u++){
2501 if(!E_M[my_iindx[i]-u]) continue;
2502 if(!E_C[my_iindx[u+1]-j]) continue;
2503 type = ptype[my_iindx[u+1]-j];
2505 d1 = base_d1 - referenceBPs1[my_iindx[i]-u] - referenceBPs1[my_iindx[u+1]-j];
2506 d2 = base_d2 - referenceBPs2[my_iindx[i]-u] - referenceBPs2[my_iindx[u+1]-j];
2509 energy = E_MLstem(type, S1[u], ((j < seq_length) || circ) ? S1[j+1] : -1, P);
2511 energy = E_MLstem(type, -1, -1, P);
2513 if(d1 <= k && d2 <= l)
2514 for(cnt1 = k_min_values_m[my_iindx[i]-u]; cnt1 <= MIN2(k-d1, k_max_values_m[my_iindx[i]-u]); cnt1++)
2515 for(cnt2 = l_min_values_m[my_iindx[i]-u][cnt1]; cnt2 <= MIN2(l-d2, l_max_values_m[my_iindx[i]-u][cnt1]); cnt2+=2)
2516 if((k-d1-cnt1 >= k_min_values[my_iindx[u+1]-j]) && (k-d1-cnt1 <= k_max_values[my_iindx[u+1]-j]))
2517 if((l-d2-cnt2 >= l_min_values[my_iindx[u+1]-j][k-d1-cnt1]) && (l-d2-cnt2 <= l_max_values[my_iindx[u+1]-j][k-d1-cnt1]))
2518 if(E_M[my_iindx[i]-u][cnt1][cnt2/2] + E_C[my_iindx[u+1]-j][k-d1-cnt1][(l-d2-cnt2)/2] + energy == e){
2519 backtrack_m(i, u, cnt1, cnt2, structure, vars);
2520 backtrack_c(u+1, j, k-d1-cnt1, l-d2-cnt2, structure, vars);
2525 nrerror("backtracking failed in fML\n");
2528 PRIVATE void backtrack_m1(unsigned int i, unsigned int j, int k, int l, char *structure, TwoDfold_vars *vars){
2529 unsigned int ij, seq_length, d1, d2, *referenceBPs1, *referenceBPs2, maxD1, maxD2;
2530 int *my_iindx, **l_min_values, **l_max_values,**l_min_values_m1, **l_max_values_m1;
2531 int *k_min_values, *k_max_values,*k_min_values_m1, *k_max_values_m1, cnt1, cnt2;
2532 int ***E_C, ***E_M1, *E_C_rem, *E_M1_rem, type, dangles, circ, energy, e_m1;
2539 seq_length = vars->seq_length;
2541 ptype = vars->ptype;
2543 my_iindx = vars->my_iindx;
2544 referenceBPs1 = vars->referenceBPs1;
2545 referenceBPs2 = vars->referenceBPs2;
2546 dangles = vars->dangles;
2549 l_min_values = vars->l_min_values;
2550 l_max_values = vars->l_max_values;
2551 k_min_values = vars->k_min_values;
2552 k_max_values = vars->k_max_values;
2555 l_min_values_m1 = vars->l_min_values_m1;
2556 l_max_values_m1 = vars->l_max_values_m1;
2557 k_min_values_m1 = vars->k_min_values_m1;
2558 k_max_values_m1 = vars->k_max_values_m1;
2560 E_C_rem = vars->E_C_rem;
2561 E_M1_rem = vars->E_M1_rem;
2562 maxD1 = vars->maxD1;
2563 maxD2 = vars->maxD2;
2566 e_m1 = (k == -1) ? E_M1_rem[ij] : E_M1[ij][k][l/2];
2569 d1 = referenceBPs1[ij] - referenceBPs1[ij+1];
2570 d2 = referenceBPs2[ij] - referenceBPs2[ij+1];
2573 energy = E_MLstem(type, (i > 1) || circ ? S1[i-1] : -1, (j < seq_length) || circ ? S1[j+1] : -1, P);
2575 energy = E_MLstem(type, -1, -1, P);
2578 if(E_C_rem[ij] != INF){
2579 if(e_m1 == (E_C_rem[ij] + energy)){
2580 backtrack_c(i,j,-1,-1,structure,vars);
2584 if(E_M1_rem[ij+1] != INF){
2585 if(e_m1 == (E_M1_rem[ij+1] + P->MLbase)){
2586 backtrack_m1(i,j-1,-1,-1,structure,vars);
2590 for(cnt1 = k_min_values_m1[ij+1];
2591 cnt1 <= k_max_values_m1[ij+1];
2593 for(cnt2 = l_min_values_m1[ij+1][cnt1];
2594 cnt2 <= l_max_values_m1[ij+1][cnt1];
2596 if(((cnt1 + d1) > maxD1) || ((cnt2 + d2) > maxD2)){
2597 if(e_m1 == (E_M1[ij+1][cnt1][cnt2/2] + P->MLbase)){
2598 backtrack_m1(i,j-1,cnt1,cnt2,structure,vars);
2605 if((k >= k_min_values[ij]) && (k <= k_max_values[ij]))
2606 if((l >= l_min_values[ij][k]) && (l <= l_max_values[ij][k]))
2607 if(E_C[ij][k][l/2] + energy == e_m1){
2608 backtrack_c(i, j, k, l, structure, vars);
2612 if(d1 <= k && d2 <= l)
2613 if((k-d1 >= k_min_values_m1[ij+1]) && (k-d1 <= k_max_values_m1[ij+1]))
2614 if((l-d2 >= l_min_values_m1[ij+1][k-d1]) && (l-d2 <= l_max_values_m1[ij+1][k-d1]))
2615 if(E_M1[ij+1][k-d1][(l-d2)/2] + P->MLbase == e_m1){
2616 backtrack_m1(i, j-1, k-d1, l-d2, structure, vars);
2620 nrerror("backtack failed in m1\n");
2623 PRIVATE void backtrack_fc(int k, int l, char *structure, TwoDfold_vars *vars){
2624 unsigned int d, i, j, seq_length, base_d1, base_d2, d1, d2, maxD1, maxD2;
2625 int *my_iindx, energy, cnt1, cnt2, cnt3, cnt4;
2627 unsigned int *referenceBPs1, *referenceBPs2;
2628 char *sequence, *ptype;
2629 int **E_Fc, **E_FcH, **E_FcI, **E_FcM, ***E_C, ***E_M, ***E_M2;
2630 int *E_C_rem, *E_M_rem, *E_M2_rem, E_Fc_rem, E_FcH_rem, E_FcI_rem, E_FcM_rem;
2631 int **l_min_values, **l_max_values, *k_min_values, *k_max_values;
2632 int **l_min_values_m, **l_max_values_m, *k_min_values_m, *k_max_values_m;
2633 int **l_min_values_m2, **l_max_values_m2, *k_min_values_m2, *k_max_values_m2;
2634 int *l_min_values_fcH, *l_max_values_fcH, k_min_values_fcH, k_max_values_fcH;
2635 int *l_min_values_fcI, *l_max_values_fcI, k_min_values_fcI, k_max_values_fcI;
2636 int *l_min_values_fcM, *l_max_values_fcM, k_min_values_fcM, k_max_values_fcM;
2639 sequence = vars->sequence;
2640 seq_length = vars->seq_length;
2642 ptype = vars->ptype;
2643 my_iindx = vars->my_iindx;
2644 referenceBPs1 = vars->referenceBPs1;
2645 referenceBPs2 = vars->referenceBPs2;
2647 base_d1 = referenceBPs1[my_iindx[1]-seq_length];
2648 base_d2 = referenceBPs2[my_iindx[1]-seq_length];
2651 l_min_values = vars->l_min_values;
2652 l_max_values = vars->l_max_values;
2653 k_min_values = vars->k_min_values;
2654 k_max_values = vars->k_max_values;
2657 l_min_values_m = vars->l_min_values_m;
2658 l_max_values_m = vars->l_max_values_m;
2659 k_min_values_m = vars->k_min_values_m;
2660 k_max_values_m = vars->k_max_values_m;
2663 l_min_values_m2 = vars->l_min_values_m2;
2664 l_max_values_m2 = vars->l_max_values_m2;
2665 k_min_values_m2 = vars->k_min_values_m2;
2666 k_max_values_m2 = vars->k_max_values_m2;
2670 E_FcI = vars->E_FcI;
2671 l_min_values_fcI = vars->l_min_values_fcI;
2672 l_max_values_fcI = vars->l_max_values_fcI;
2673 k_min_values_fcI = vars->k_min_values_fcI;
2674 k_max_values_fcI = vars->k_max_values_fcI;
2676 E_FcH = vars->E_FcH;
2677 l_min_values_fcH = vars->l_min_values_fcH;
2678 l_max_values_fcH = vars->l_max_values_fcH;
2679 k_min_values_fcH = vars->k_min_values_fcH;
2680 k_max_values_fcH = vars->k_max_values_fcH;
2682 E_FcM = vars->E_FcM;
2683 l_min_values_fcM = vars->l_min_values_fcM;
2684 l_max_values_fcM = vars->l_max_values_fcM;
2685 k_min_values_fcM = vars->k_min_values_fcM;
2686 k_max_values_fcM = vars->k_max_values_fcM;
2688 E_C_rem = vars->E_C_rem;
2689 E_M_rem = vars->E_M_rem;
2690 E_M2_rem = vars->E_M2_rem;
2691 E_Fc_rem = vars->E_Fc_rem;
2692 E_FcH_rem = vars->E_FcH_rem;
2693 E_FcI_rem = vars->E_FcI_rem;
2694 E_FcM_rem = vars->E_FcM_rem;
2695 maxD1 = vars->maxD1;
2696 maxD2 = vars->maxD2;
2700 /* check if mfe might be open chain */
2702 if((referenceBPs1[my_iindx[1]-seq_length] > maxD1) || (referenceBPs2[my_iindx[1]-seq_length] > maxD2))
2705 /* check for hairpin configurations */
2706 if(E_Fc_rem == E_FcH_rem){
2707 for (d = TURN+2; d <= seq_length; d++) /* i,j in [1..length] */
2708 for (j = d; j <= seq_length; j++) {
2714 u = seq_length-j + i-1;
2715 if (u<TURN) continue;
2717 no_close = (((type==3)||(type==4))&&no_closingGU);
2719 if (!type) continue;
2720 if(no_close) continue;
2722 d1 = base_d1 - referenceBPs1[ij];
2723 d2 = base_d2 - referenceBPs2[ij];
2725 strcpy(loopseq , sequence+j-1);
2726 strncat(loopseq, sequence, i);
2728 energy = E_Hairpin(u, type, S1[j+1], S1[i-1], loopseq, P);
2730 if(E_C_rem[ij] != INF){
2731 if(E_Fc_rem == (E_C_rem[ij] + energy)){
2732 backtrack_c(i,j,-1,-1,structure,vars);
2737 for(cnt1 = k_min_values[ij];
2738 cnt1 <= k_max_values[ij];
2740 for(cnt2 = l_min_values[ij][cnt1];
2741 cnt2 <= l_max_values[ij][cnt1];
2743 if(((cnt1 + d1) > maxD1) || ((cnt2 + d2) > maxD2))
2744 if(E_Fc_rem == (E_C[ij][cnt1][cnt2/2] + energy)){
2745 backtrack_c(i,j,cnt1,cnt2,structure,vars);
2751 /* check for interior loop configurations */
2752 if(E_Fc_rem == E_FcI_rem){
2753 for (d = TURN+2; d <= seq_length; d++) /* i,j in [1..length] */
2754 for (j = d; j <= seq_length; j++) {
2755 unsigned int u, ij, p, q, pq;
2759 u = seq_length-j + i-1;
2760 if (u<TURN) continue;
2761 type = rtype[(unsigned int)ptype[ij]];
2762 if (!type) continue;
2764 for(p = j+1; p < seq_length ; p++){
2765 unsigned int u1, qmin, ln_pre;
2767 if (u1+i-1>MAXLOOP) break;
2768 qmin = p + TURN + 1;
2769 ln_pre = u1 + i + seq_length;
2770 if(ln_pre > qmin + MAXLOOP) qmin = ln_pre - MAXLOOP - 1;
2771 for(q = qmin; q <= seq_length; q++){
2774 type_2 = rtype[(unsigned int)ptype[pq]];
2775 if (type_2==0) continue;
2776 u2 = i-1 + seq_length-q;
2777 if (u1+u2>MAXLOOP) continue;
2778 energy = E_IntLoop(u1, u2, type, type_2, S1[j+1], S1[i-1], S1[p-1], S1[q+1], P);
2779 if(E_C_rem[ij] != INF){
2781 for(cnt1 = k_min_values[pq];
2782 cnt1 <= k_max_values[pq];
2784 for(cnt2 = l_min_values[pq][cnt1];
2785 cnt2 <= l_max_values[pq][cnt1];
2787 if(E_Fc_rem == (E_C_rem[ij] + E_C[pq][cnt1][cnt2/2] + energy)){
2788 backtrack_c(i,j,-1,-1,structure,vars);
2789 backtrack_c(p,q,cnt1,cnt2,structure,vars);
2792 if(E_C_rem[pq] != INF){
2793 if(E_Fc_rem == (E_C_rem[ij] + E_C_rem[pq] + energy)){
2794 backtrack_c(i,j,-1,-1,structure,vars);
2795 backtrack_c(p,q,-1,-1,structure,vars);
2800 if(E_C_rem[pq] != INF){
2802 for(cnt1 = k_min_values[ij];
2803 cnt1 <= k_max_values[ij];
2805 for(cnt2 = l_min_values[ij][cnt1];
2806 cnt2 <= l_max_values[ij][cnt1];
2808 if(E_Fc_rem == (E_C[ij][cnt1][cnt2/2] + E_C_rem[pq] + energy)){
2809 backtrack_c(i,j,cnt1,cnt2,structure,vars);
2810 backtrack_c(p,q,-1,-1,structure,vars);
2815 if(!(E_C[ij])) continue;
2816 if(!(E_C[pq])) continue;
2818 /* get distance to reference if closing the interior loop
2819 * d2a = dbp(T1_[1,n}, T1_{p,q} + T1_{i,j})
2820 * d2b = dbp(T2_[1,n}, T2_{p,q} + T2_{i,j})
2822 d1 = base_d1 - referenceBPs1[ij] - referenceBPs1[pq];
2823 d2 = base_d2 - referenceBPs2[ij] - referenceBPs2[pq];
2824 for(cnt1 = k_min_values[ij];
2825 cnt1 <= k_max_values[ij];
2827 for(cnt2 = l_min_values[ij][cnt1];
2828 cnt2 <= l_max_values[ij][cnt1];
2830 for(cnt3 = k_min_values[pq];
2831 cnt3 <= k_max_values[pq];
2833 for(cnt4 = l_min_values[pq][cnt3];
2834 cnt4 <= l_max_values[pq][cnt3];
2836 if(((cnt1 + cnt3 + d1) > maxD1) || ((cnt2 + cnt4 + d2) > maxD2))
2837 if(E_Fc_rem == (E_C[ij][cnt1][cnt2/2] + E_C[pq][cnt3][cnt4/2] + energy)){
2838 backtrack_c(i, j, cnt1, cnt2, structure, vars);
2839 backtrack_c(p, q, cnt3, cnt4, structure, vars);
2848 /* check for multi loop configurations */
2849 if(E_Fc_rem == E_FcM_rem){
2850 if(seq_length > 2*TURN)
2851 for (i=TURN+1; i<seq_length-2*TURN; i++) {
2852 /* get distancies to references
2853 * d3a = dbp(T1_[1,n}, T1_{1,k} + T1_{k+1, n})
2854 * d3b = dbp(T2_[1,n}, T2_{1,k} + T2_{k+1, n})
2856 if(E_M_rem[my_iindx[1]-i] != INF){
2858 for(cnt1 = k_min_values_m2[i+1];
2859 cnt1 <= k_max_values_m2[i+1];
2861 for(cnt2 = l_min_values_m2[i+1][cnt1];
2862 cnt2 <= l_max_values_m2[i+1][cnt1];
2864 if(E_Fc_rem == (E_M_rem[my_iindx[1]-i] + E_M2[i+1][cnt1][cnt2/2] + P->MLclosing)){
2865 backtrack_m(1,i,-1,-1,structure,vars);
2866 backtrack_m2(i+1,cnt1,cnt2,structure,vars);
2869 if(E_M2_rem[i+1] != INF){
2870 if(E_Fc_rem == (E_M_rem[my_iindx[1]-i] + E_M2_rem[i+1] + P->MLclosing)){
2871 backtrack_m(1,i,-1,-1,structure,vars);
2872 backtrack_m2(i+1,-1,-1,structure,vars);
2877 if(E_M2_rem[i+1] != INF){
2878 if(E_M[my_iindx[1]-i])
2879 for(cnt1 = k_min_values_m[my_iindx[1]-i];
2880 cnt1 <= k_max_values_m[my_iindx[1]-i];
2882 for(cnt2 = l_min_values_m[my_iindx[1]-i][cnt1];
2883 cnt2 <= l_max_values_m[my_iindx[1]-i][cnt1];
2885 if(E_Fc_rem == (E_M[my_iindx[1]-i][cnt1][cnt2/2] + E_M2_rem[i+1] + P->MLclosing)){
2886 backtrack_m(1,i,cnt1,cnt2,structure,vars);
2887 backtrack_m2(i+1,-1,-1,structure,vars);
2892 if(!(E_M[my_iindx[1]-i])) continue;
2893 if(!(E_M2[i+1])) continue;
2895 d1 = base_d1 - referenceBPs1[my_iindx[1]-i] - referenceBPs1[my_iindx[i+1]-seq_length];
2896 d2 = base_d2 - referenceBPs2[my_iindx[1]-i] - referenceBPs2[my_iindx[i+1]-seq_length];
2897 for(cnt1 = k_min_values_m[my_iindx[1]-i];
2898 cnt1 <= k_max_values_m[my_iindx[1]-i];
2900 for(cnt2 = l_min_values_m[my_iindx[1]-i][cnt1];
2901 cnt2 <= l_max_values_m[my_iindx[1]-i][cnt1];
2903 for(cnt3 = k_min_values_m2[i+1];
2904 cnt3 <= k_max_values_m2[i+1];
2906 for(cnt4 = l_min_values_m2[i+1][cnt3];
2907 cnt4 <= l_max_values_m2[i+1][cnt3];
2909 if(((cnt1 + cnt3 + d1) > maxD1) || ((cnt2 + cnt4 + d2) > maxD2)){
2910 if(E_Fc_rem == (E_M[my_iindx[1]-i][cnt1][cnt2/2] + E_M2[i+1][cnt3][cnt4/2] + P->MLclosing)){
2911 backtrack_m(1, i, cnt1, cnt2, structure, vars);
2912 backtrack_m2(i+1, cnt3, cnt4, structure, vars);
2921 if(E_Fc[k][l/2] == 0)
2922 if((k == referenceBPs1[my_iindx[1]-seq_length]) && (l == referenceBPs2[my_iindx[1]-seq_length])){
2925 if((k >= k_min_values_fcH) && (k <= k_max_values_fcH)){
2926 if((l >= l_min_values_fcH[k]) && (l <= l_max_values_fcH[k]))
2927 if(E_Fc[k][l/2] == E_FcH[k][l/2]){
2928 for (d = TURN+2; d <= seq_length; d++) /* i,j in [1..length] */
2929 for (j = d; j <= seq_length; j++) {
2935 if (!E_C[ij]) continue;
2936 u = seq_length-j + i-1;
2937 if (u<TURN) continue;
2941 no_close = (((type==3)||(type==4))&&no_closingGU);
2945 if (!type) continue;
2946 if(no_close) continue;
2948 d1 = base_d1 - referenceBPs1[ij];
2949 d2 = base_d2 - referenceBPs2[ij];
2951 strcpy(loopseq , sequence+j-1);
2952 strncat(loopseq, sequence, i);
2954 energy = E_Hairpin(u, type, S1[j+1], S1[i-1], loopseq, P);
2955 if((k >= d1) && (l >= d2))
2956 if((k-d1 >= k_min_values[ij]) && (k-d1 <= k_max_values[ij]))
2957 if((l-d2 >= l_min_values[ij][k-d1]) && (l-d2 <= l_max_values[ij][k-d1])){
2958 if(E_Fc[k][l/2] == E_C[ij][k-d1][(l-d2)/2] + energy){
2959 backtrack_c(i, j, k-d1, l-d2, structure, vars);
2967 if((k >= k_min_values_fcI) && (k <= k_max_values_fcI)){
2968 if((l >= l_min_values_fcI[k]) && (l <= l_max_values_fcI[k]))
2969 if(E_Fc[k][l/2] == E_FcI[k][l/2]){
2970 for (d = TURN+2; d <= seq_length; d++) /* i,j in [1..length] */
2971 for (j = d; j <= seq_length; j++) {
2972 unsigned int u, ij, p, q, pq;
2976 if(!E_C[ij]) continue;
2977 u = seq_length-j + i-1;
2978 if (u<TURN) continue;
2984 if (!type) continue;
2986 for(p = j+1; p < seq_length ; p++){
2987 unsigned int u1, qmin, ln_pre;
2989 if (u1+i-1>MAXLOOP) break;
2990 qmin = p + TURN + 1;
2991 ln_pre = u1 + i + seq_length;
2992 if(ln_pre > qmin + MAXLOOP) qmin = ln_pre - MAXLOOP - 1;
2993 for(q = qmin; q <= seq_length; q++){
2996 if(!E_C[pq]) continue;
2997 type_2 = rtype[(unsigned int)ptype[pq]];
2998 if (type_2==0) continue;
2999 u2 = i-1 + seq_length-q;
3000 if (u1+u2>MAXLOOP) continue;
3001 /* get distance to reference if closing the interior loop
3002 * d2a = dbp(T1_[1,n}, T1_{p,q} + T1_{i,j})
3003 * d2b = dbp(T2_[1,n}, T2_{p,q} + T2_{i,j})
3005 d1 = base_d1 - referenceBPs1[ij] - referenceBPs1[pq];
3006 d2 = base_d2 - referenceBPs2[ij] - referenceBPs2[pq];
3007 energy = E_IntLoop(u1, u2, type, type_2, S1[j+1], S1[i-1], S1[p-1], S1[q+1], P);
3008 if((k >= d1) && (l >= d2))
3009 for(cnt1 = k_min_values[ij]; cnt1 <= MIN2(k_max_values[ij], k - d1); cnt1++)
3010 for(cnt2 = l_min_values[ij][cnt1]; cnt2 <= MIN2(l_max_values[ij][cnt1], l - d2); cnt2+=2)
3011 if((k - d1 - cnt1 >= k_min_values[pq]) && (k - d1 - cnt1 <= k_max_values[pq]))
3012 if((l - d2 - cnt2 >= l_min_values[pq][k-d1-cnt1]) && (l - d2 - cnt2 <= l_max_values[pq][k-d1-cnt1])){
3013 if((E_C[ij][cnt1][cnt2/2] + E_C[pq][k-d1-cnt1][(l-d2-cnt2)/2] + energy) == E_Fc[k][l/2]){
3014 backtrack_c(i, j, cnt1, cnt2, structure, vars);
3015 backtrack_c(p, q, k - d1 - cnt1, l - d2 - cnt2, structure, vars);
3025 if((k >= k_min_values_fcM) && (k <= k_max_values_fcM)){
3026 if((l >= l_min_values_fcM[k]) && (l <= l_max_values_fcM[k]))
3027 if(E_Fc[k][l/2] == E_FcM[k][l/2]){
3028 if(seq_length > 2*TURN)
3029 for (i=TURN+1; i<seq_length-2*TURN; i++) {
3030 /* get distancies to references
3031 * d3a = dbp(T1_[1,n}, T1_{1,k} + T1_{k+1, n})
3032 * d3b = dbp(T2_[1,n}, T2_{1,k} + T2_{k+1, n})
3034 if(!E_M[my_iindx[1]-i]) continue;
3035 if(!E_M2[i+1]) continue;
3036 d1 = base_d1 - referenceBPs1[my_iindx[1]-i] - referenceBPs1[my_iindx[i+1]-seq_length];
3037 d2 = base_d2 - referenceBPs2[my_iindx[1]-i] - referenceBPs2[my_iindx[i+1]-seq_length];
3038 if((k >= d1) && (l >= d2))
3039 for(cnt1 = k_min_values_m[my_iindx[1]-i]; cnt1 <= MIN2(k_max_values_m[my_iindx[1]-i], k-d1); cnt1++)
3040 for(cnt2 = l_min_values_m[my_iindx[1]-i][cnt1]; cnt2 <= MIN2(l_max_values_m[my_iindx[1]-i][cnt1], l-d2); cnt2+=2)
3041 if((k - d1 - cnt1 >= k_min_values_m2[i+1]) && (k - d1 - cnt1 <= k_max_values_m2[i+1]))
3042 if((l - d2 - cnt2 >= l_min_values_m2[i+1][k-d1-cnt1]) && (l - d2 - cnt2 <= l_max_values_m2[i+1][k-d1-cnt1]))
3043 if((E_M[my_iindx[1]-i][cnt1][cnt2/2] + E_M2[i+1][k-d1-cnt1][(l-d2-cnt2)/2] + P->MLclosing) == E_FcM[k][l/2]){
3044 backtrack_m(1, i, cnt1, cnt2, structure, vars);
3045 backtrack_m2(i+1, k - d1 - cnt1, l - d2 - cnt2, structure, vars);
3052 nrerror("backtack failed in fc\n");
3056 PRIVATE void backtrack_m2(unsigned int i, int k, int l, char *structure, TwoDfold_vars *vars){
3057 unsigned int j, ij, j3, n;
3058 unsigned int *referenceBPs1, *referenceBPs2;
3059 unsigned int d1, d2, base_d1, base_d2, maxD1, maxD2;
3060 int *my_iindx, cnt1, cnt2, cnt3, cnt4;
3061 int ***E_M1, ***E_M2, *E_M2_rem, *E_M1_rem, e;
3062 int **l_min_values_m1, **l_max_values_m1, *k_min_values_m1, *k_max_values_m1;
3064 n = vars->seq_length;
3065 my_iindx = vars->my_iindx;
3066 referenceBPs1 = vars->referenceBPs1;
3067 referenceBPs2 = vars->referenceBPs2;
3070 l_min_values_m1 = vars->l_min_values_m1;
3071 l_max_values_m1 = vars->l_max_values_m1;
3072 k_min_values_m1 = vars->k_min_values_m1;
3073 k_max_values_m1 = vars->k_max_values_m1;
3075 E_M1_rem = vars->E_M1_rem;
3079 E_M2_rem = vars->E_M2_rem;
3081 maxD1 = vars->maxD1;
3082 maxD2 = vars->maxD2;
3084 base_d1 = referenceBPs1[my_iindx[i]-n];
3085 base_d2 = referenceBPs2[my_iindx[i]-n];
3089 for (j=i+TURN+1; j<n-TURN-1; j++){
3090 if(E_M1_rem[my_iindx[i]-j] != INF){
3091 if(E_M1[my_iindx[j+1]-n])
3092 for(cnt1 = k_min_values_m1[my_iindx[j+1]-n];
3093 cnt1 <= k_max_values_m1[my_iindx[j+1]-n];
3095 for(cnt2 = l_min_values_m1[my_iindx[j+1]-n][cnt1];
3096 cnt2 <= l_max_values_m1[my_iindx[j+1]-n][cnt1];
3098 if(e == E_M1_rem[my_iindx[i]-j] + E_M1[my_iindx[j+1]-n][cnt1][cnt2/2]){
3099 backtrack_m1(i, j, k, l, structure, vars);
3100 backtrack_m1(j+1, n, cnt1, cnt2, structure, vars);
3103 if(E_M1_rem[my_iindx[j+1]-n] != INF){
3104 if(e == E_M1_rem[my_iindx[i]-j] + E_M1_rem[my_iindx[j+1]-n]){
3105 backtrack_m1(i, j, k, l, structure, vars);
3106 backtrack_m1(j+1, n, k, l, structure, vars);
3111 if(E_M1_rem[my_iindx[j+1]-n] != INF){
3112 if(E_M1[my_iindx[i]-j])
3113 for(cnt1 = k_min_values_m1[my_iindx[i]-j];
3114 cnt1 <= k_max_values_m1[my_iindx[i]-j];
3116 for(cnt2 = l_min_values_m1[my_iindx[i]-j][cnt1];
3117 cnt2 <= l_max_values_m1[my_iindx[i]-j][cnt1];
3119 if(e == E_M1[my_iindx[i]-j][cnt1][cnt2/2] + E_M1_rem[my_iindx[j+1]-n]){
3120 backtrack_m1(i, j, cnt1, cnt2, structure, vars);
3121 backtrack_m1(j+1, n, k, l, structure, vars);
3127 if(!E_M1[my_iindx[i]-j]) continue;
3128 if(!E_M1[my_iindx[j+1]-n]) continue;
3130 d1 = referenceBPs1[my_iindx[i]-n] - referenceBPs1[my_iindx[i]-j] - referenceBPs1[my_iindx[j+1]-n];
3131 d2 = referenceBPs2[my_iindx[i]-n] - referenceBPs2[my_iindx[i]-j] - referenceBPs2[my_iindx[j+1]-n];
3133 for(cnt1 = k_min_values_m1[my_iindx[i]-j]; cnt1 <= k_max_values_m1[my_iindx[i]-j]; cnt1++)
3134 for(cnt2 = l_min_values_m1[my_iindx[i]-j][cnt1]; cnt2 <= l_max_values_m1[my_iindx[i]-j][cnt1]; cnt2+=2){
3135 for(cnt3 = k_min_values_m1[my_iindx[j+1]-n]; cnt3 <= k_max_values_m1[my_iindx[j+1]-n]; cnt3++)
3136 for(cnt4 = l_min_values_m1[my_iindx[j+1]-n][cnt3]; cnt4 <= l_max_values_m1[my_iindx[j+1]-n][cnt3]; cnt4+=2){
3137 if(((cnt1 + cnt3 + d1) > maxD1) || ((cnt2 + cnt4 + d2) > maxD2)){
3138 if(e == E_M1[my_iindx[i]-j][cnt1][cnt2/2] + E_M1[my_iindx[j+1]-n][cnt3][cnt4/2]){
3139 backtrack_m1(i, j, cnt1, cnt2, structure, vars);
3140 backtrack_m1(j+1, n, cnt3, cnt4, structure, vars);
3149 for(j=i+TURN+1; j<n-TURN-1; j++){
3150 if(!E_M1[my_iindx[i]-j]) continue;
3151 if(!E_M1[my_iindx[j+1]-n]) continue;
3154 j3 = my_iindx[j+1]-n;
3155 d1 = base_d1 - referenceBPs1[ij] - referenceBPs1[j3];
3156 d2 = base_d2 - referenceBPs2[ij] - referenceBPs2[j3];
3158 for(cnt1 = k_min_values_m1[ij]; cnt1 <= MIN2(k_max_values_m1[ij], k - d1); cnt1++)
3159 for(cnt2 = l_min_values_m1[ij][cnt1]; cnt2 <= MIN2(l_max_values_m1[ij][cnt1], l-d2); cnt2+=2)
3160 if((k - d1 - cnt1 >= k_min_values_m1[j3]) && (k - d1 - cnt1 <= k_max_values_m1[j3]))
3161 if((l - d2 - cnt2 >= l_min_values_m1[j3][k - d1 - cnt1]) && (l - d2 - cnt2 <= l_max_values_m1[j3][k-d1-cnt1]))
3162 if(E_M1[ij][cnt1][cnt2/2] + E_M1[j3][k-d1-cnt1][(l-d2-cnt2)/2] == E_M2[i][k][l/2]){
3163 backtrack_m1(i, j, cnt1, cnt2, structure, vars);
3164 backtrack_m1(j+1, n, k-d1-cnt1, l-d2-cnt2, structure, vars);
3169 nrerror("backtack failed in m2\n");
3172 PRIVATE void mfe_circ(TwoDfold_vars *vars){
3173 unsigned int d, i, j, maxD1, maxD2, seq_length, *referenceBPs1, *referenceBPs2, d1, d2, base_d1, base_d2, *mm1, *mm2, *bpdist;
3174 int *my_iindx, energy, cnt1, cnt2, cnt3, cnt4;
3176 char *sequence, *ptype;
3177 int ***E_C, ***E_M, ***E_M1;
3178 int *E_C_rem, *E_M_rem, *E_M1_rem;
3179 int **l_min_values, **l_max_values, **l_min_values_m, **l_max_values_m, **l_min_values_m1, **l_max_values_m1;
3180 int *k_min_values, *k_max_values,*k_min_values_m, *k_max_values_m,*k_min_values_m1, *k_max_values_m1;
3185 sequence = vars->sequence;
3186 seq_length = vars->seq_length;
3187 maxD1 = vars->maxD1;
3188 maxD2 = vars->maxD2;
3190 ptype = vars->ptype;
3191 my_iindx = vars->my_iindx;
3192 referenceBPs1 = vars->referenceBPs1;
3193 referenceBPs2 = vars->referenceBPs2;
3196 bpdist = vars->bpdist;
3199 l_min_values = vars->l_min_values;
3200 l_max_values = vars->l_max_values;
3201 k_min_values = vars->k_min_values;
3202 k_max_values = vars->k_max_values;
3205 l_min_values_m = vars->l_min_values_m;
3206 l_max_values_m = vars->l_max_values_m;
3207 k_min_values_m = vars->k_min_values_m;
3208 k_max_values_m = vars->k_max_values_m;
3211 l_min_values_m1 = vars->l_min_values_m1;
3212 l_max_values_m1 = vars->l_max_values_m1;
3213 k_min_values_m1 = vars->k_min_values_m1;
3214 k_max_values_m1 = vars->k_max_values_m1;
3216 E_C_rem = vars->E_C_rem;
3217 E_M_rem = vars->E_M_rem;
3218 E_M1_rem = vars->E_M1_rem;
3221 #pragma omp parallel for private(d1,d2,cnt1,cnt2,cnt3,cnt4,j, i)
3223 for(i=1; i<seq_length-TURN-1; i++){
3224 /* guess memory requirements for M2 */
3226 int min_k, max_k, max_l, min_l;
3227 int min_k_real, max_k_real, *min_l_real, *max_l_real;
3230 max_k = mm1[my_iindx[i]-seq_length] + referenceBPs1[my_iindx[i] - seq_length];
3231 max_l = mm2[my_iindx[i]-seq_length] + referenceBPs2[my_iindx[i] - seq_length];
3233 prepareBoundaries(min_k,
3237 bpdist[my_iindx[i] - seq_length],
3238 &vars->k_min_values_m2[i],
3239 &vars->k_max_values_m2[i],
3240 &vars->l_min_values_m2[i],
3241 &vars->l_max_values_m2[i]
3244 prepareArray( &vars->E_M2[i],
3245 vars->k_min_values_m2[i],
3246 vars->k_max_values_m2[i],
3247 vars->l_min_values_m2[i],
3248 vars->l_max_values_m2[i]
3251 preparePosteriorBoundaries( vars->k_max_values_m2[i] - vars->k_min_values_m2[i] + 1,
3252 vars->k_min_values_m2[i],
3259 /* begin filling of M2 array */
3260 for (j=i+TURN+1; j<seq_length-TURN-1; j++){
3261 if(E_M1_rem[my_iindx[i]-j] != INF){
3262 if(E_M1[my_iindx[j+1]-seq_length])
3263 for(cnt1 = k_min_values_m1[my_iindx[j+1]-seq_length];
3264 cnt1 <= k_max_values_m1[my_iindx[j+1]-seq_length];
3266 for(cnt2 = l_min_values_m1[my_iindx[j+1]-seq_length][cnt1];
3267 cnt2 <= l_max_values_m1[my_iindx[j+1]-seq_length][cnt1];
3269 vars->E_M2_rem[i] = MIN2(vars->E_M2_rem[i],
3270 E_M1_rem[my_iindx[i]-j] + E_M1[my_iindx[j+1]-seq_length][cnt1][cnt2/2]
3272 if(E_M1_rem[my_iindx[j+1]-seq_length] != INF)
3273 vars->E_M2_rem[i] = MIN2(vars->E_M2_rem[i], E_M1_rem[my_iindx[i]-j] + E_M1_rem[my_iindx[j+1]-seq_length]);
3275 if(E_M1_rem[my_iindx[j+1]-seq_length] != INF){
3276 if(E_M1[my_iindx[i]-j])
3277 for(cnt1 = k_min_values_m1[my_iindx[i]-j];
3278 cnt1 <= k_max_values_m1[my_iindx[i]-j];
3280 for(cnt2 = l_min_values_m1[my_iindx[i]-j][cnt1];
3281 cnt2 <= l_max_values_m1[my_iindx[i]-j][cnt1];
3283 vars->E_M2_rem[i] = MIN2(vars->E_M2_rem[i],
3284 E_M1[my_iindx[i]-j][cnt1][cnt2/2] + E_M1_rem[my_iindx[j+1]-seq_length]
3289 if(!E_M1[my_iindx[i]-j]) continue;
3290 if(!E_M1[my_iindx[j+1]-seq_length]) continue;
3292 d1 = referenceBPs1[my_iindx[i]-seq_length] - referenceBPs1[my_iindx[i]-j] - referenceBPs1[my_iindx[j+1]-seq_length];
3293 d2 = referenceBPs2[my_iindx[i]-seq_length] - referenceBPs2[my_iindx[i]-j] - referenceBPs2[my_iindx[j+1]-seq_length];
3295 for(cnt1 = k_min_values_m1[my_iindx[i]-j]; cnt1 <= k_max_values_m1[my_iindx[i]-j]; cnt1++)
3296 for(cnt2 = l_min_values_m1[my_iindx[i]-j][cnt1]; cnt2 <= l_max_values_m1[my_iindx[i]-j][cnt1]; cnt2+=2){
3297 for(cnt3 = k_min_values_m1[my_iindx[j+1]-seq_length]; cnt3 <= k_max_values_m1[my_iindx[j+1]-seq_length]; cnt3++)
3298 for(cnt4 = l_min_values_m1[my_iindx[j+1]-seq_length][cnt3]; cnt4 <= l_max_values_m1[my_iindx[j+1]-seq_length][cnt3]; cnt4+=2){
3299 if(((cnt1 + cnt3 + d1) <= maxD1) && ((cnt2 + cnt4 + d2) <= maxD2)){
3300 vars->E_M2[i][cnt1 + cnt3 + d1][(cnt2 + cnt4 + d2)/2] = MIN2( vars->E_M2[i][cnt1 + cnt3 + d1][(cnt2 + cnt4 + d2)/2],
3301 E_M1[my_iindx[i]-j][cnt1][cnt2/2] + E_M1[my_iindx[j+1]-seq_length][cnt3][cnt4/2]
3303 updatePosteriorBoundaries(cnt1+cnt3+d1,
3312 vars->E_M2_rem[i] = MIN2(vars->E_M2_rem[i],
3313 E_M1[my_iindx[i]-j][cnt1][cnt2/2] + E_M1[my_iindx[j+1]-seq_length][cnt3][cnt4/2]
3320 /* resize and move memory portions of energy matrix E_M2 */
3321 adjustArrayBoundaries(&vars->E_M2[i],
3322 &vars->k_min_values_m2[i],
3323 &vars->k_max_values_m2[i],
3324 &vars->l_min_values_m2[i],
3325 &vars->l_max_values_m2[i],
3333 base_d1 = referenceBPs1[my_iindx[1]-seq_length];
3334 base_d2 = referenceBPs2[my_iindx[1]-seq_length];
3336 /* guess memory requirements for E_FcH, E_FcI and E_FcM */
3338 int min_k, max_k, max_l, min_l;
3339 int min_k_real, max_k_real, min_k_real_fcH, max_k_real_fcH, min_k_real_fcI, max_k_real_fcI, min_k_real_fcM, max_k_real_fcM;
3340 int *min_l_real, *max_l_real, *min_l_real_fcH, *max_l_real_fcH, *min_l_real_fcI, *max_l_real_fcI,*min_l_real_fcM, *max_l_real_fcM;
3344 max_k = mm1[my_iindx[1] - seq_length] + referenceBPs1[my_iindx[1] - seq_length];
3345 max_l = mm2[my_iindx[1] - seq_length] + referenceBPs2[my_iindx[1] - seq_length];
3348 #pragma omp sections
3354 prepareBoundaries(min_k,
3358 bpdist[my_iindx[1] - seq_length],
3359 &vars->k_min_values_fc,
3360 &vars->k_max_values_fc,
3361 &vars->l_min_values_fc,
3362 &vars->l_max_values_fc
3364 prepareArray( &vars->E_Fc,
3365 vars->k_min_values_fc,
3366 vars->k_max_values_fc,
3367 vars->l_min_values_fc,
3368 vars->l_max_values_fc
3375 prepareBoundaries(min_k,
3379 bpdist[my_iindx[1] - seq_length],
3380 &vars->k_min_values_fcH,
3381 &vars->k_max_values_fcH,
3382 &vars->l_min_values_fcH,
3383 &vars->l_max_values_fcH
3385 prepareArray( &vars->E_FcH,
3386 vars->k_min_values_fcH,
3387 vars->k_max_values_fcH,
3388 vars->l_min_values_fcH,
3389 vars->l_max_values_fcH
3396 prepareBoundaries(min_k,
3400 bpdist[my_iindx[1] - seq_length],
3401 &vars->k_min_values_fcI,
3402 &vars->k_max_values_fcI,
3403 &vars->l_min_values_fcI,
3404 &vars->l_max_values_fcI
3406 prepareArray( &vars->E_FcI,
3407 vars->k_min_values_fcI,
3408 vars->k_max_values_fcI,
3409 vars->l_min_values_fcI,
3410 vars->l_max_values_fcI
3417 prepareBoundaries(min_k,
3421 bpdist[my_iindx[1] - seq_length],
3422 &vars->k_min_values_fcM,
3423 &vars->k_max_values_fcM,
3424 &vars->l_min_values_fcM,
3425 &vars->l_max_values_fcM
3427 prepareArray( &vars->E_FcM,
3428 vars->k_min_values_fcM,
3429 vars->k_max_values_fcM,
3430 vars->l_min_values_fcM,
3431 vars->l_max_values_fcM
3438 preparePosteriorBoundaries( max_k - min_k + 1,
3450 preparePosteriorBoundaries( max_k - min_k + 1,
3462 preparePosteriorBoundaries( max_k - min_k + 1,
3475 preparePosteriorBoundaries( max_k - min_k + 1,
3487 /* begin actual energy calculations */
3489 #pragma omp sections private(d, d1,d2,cnt1,cnt2,cnt3,cnt4,j, i, energy)
3495 for (d = TURN+2; d <= seq_length; d++) /* i,j in [1..length] */
3496 for (j = d; j <= seq_length; j++) {
3502 u = seq_length-j + i-1;
3503 if (u<TURN) continue;
3507 no_close = (((type==3)||(type==4))&&no_closingGU);
3511 if (!type) continue;
3512 if(no_close) continue;
3514 d1 = base_d1 - referenceBPs1[ij];
3515 d2 = base_d2 - referenceBPs2[ij];
3517 strcpy(loopseq , sequence+j-1);
3518 strncat(loopseq, sequence, i);
3520 energy = E_Hairpin(u, type, S1[j+1], S1[i-1], loopseq, P);
3522 if(E_C_rem[ij] != INF)
3523 vars->E_FcH_rem = MIN2(vars->E_FcH_rem, E_C_rem[ij] + energy);
3525 if (!E_C[ij]) continue;
3526 for(cnt1 = k_min_values[ij]; cnt1 <= k_max_values[ij]; cnt1++)
3527 for(cnt2 = l_min_values[ij][cnt1]; cnt2 <= l_max_values[ij][cnt1]; cnt2 += 2){
3528 if(((cnt1 + d1) <= maxD1) && ((cnt2 + d2) <= maxD2)){
3529 vars->E_FcH[cnt1 + d1][(cnt2+d2)/2] = MIN2( vars->E_FcH[cnt1 + d1][(cnt2+d2)/2],
3530 energy + E_C[ij][cnt1][cnt2/2]
3532 updatePosteriorBoundaries(cnt1 + d1,
3541 vars->E_FcH_rem = MIN2(vars->E_FcH_rem, energy + E_C[ij][cnt1][cnt2/2]);
3544 /* end of i-j loop */
3546 /* resize and move memory portions of energy matrix E_FcH */
3547 adjustArrayBoundaries(&vars->E_FcH,
3548 &vars->k_min_values_fcH,
3549 &vars->k_max_values_fcH,
3550 &vars->l_min_values_fcH,
3551 &vars->l_max_values_fcH,
3562 for (d = TURN+2; d <= seq_length; d++) /* i,j in [1..length] */
3563 for (j = d; j <= seq_length; j++) {
3564 unsigned int u, ij, p, q, pq;
3565 int type, type_2, no_close;
3568 u = seq_length-j + i-1;
3569 if (u<TURN) continue;
3573 no_close = (((type==3)||(type==4))&&no_closingGU);
3577 if (!type) continue;
3578 if(no_close) continue;
3580 if(E_C_rem[ij] != INF){
3581 for(p = j+1; p < seq_length ; p++){
3582 unsigned int u1, qmin, ln_pre;
3584 if (u1+i-1>MAXLOOP) break;
3585 qmin = p + TURN + 1;
3586 ln_pre = u1 + i + seq_length;
3587 if(ln_pre > qmin + MAXLOOP) qmin = ln_pre - MAXLOOP - 1;
3588 for(q = qmin; q <= seq_length; q++){
3591 type_2 = rtype[(unsigned int)ptype[pq]];
3592 if (type_2==0) continue;
3593 u2 = i-1 + seq_length-q;
3594 if (u1+u2>MAXLOOP) continue;
3595 /* get distance to reference if closing the interior loop
3596 * d2a = dbp(T1_[1,n}, T1_{p,q} + T1_{i,j})
3597 * d2b = dbp(T2_[1,n}, T2_{p,q} + T2_{i,j})
3599 d1 = base_d1 - referenceBPs1[ij] - referenceBPs1[pq];
3600 d2 = base_d2 - referenceBPs2[ij] - referenceBPs2[pq];
3601 energy = E_IntLoop(u1, u2, type, type_2, S1[j+1], S1[i-1], S1[p-1], S1[q+1], P);
3603 if(E_C_rem[pq] != INF)
3604 vars->E_FcI_rem = MIN2(vars->E_FcI_rem, E_C_rem[ij] + E_C_rem[pq] + energy);
3607 for(cnt1 = k_min_values[pq];
3608 cnt1 <= k_max_values[pq];
3610 for(cnt2 = l_min_values[pq][cnt1];
3611 cnt2 <= l_max_values[pq][cnt1];
3613 vars->E_FcI_rem = MIN2(vars->E_FcI_rem, E_C_rem[ij] + E_C[pq][cnt1][cnt2/2] + energy);
3619 for(p = j+1; p < seq_length ; p++){
3620 unsigned int u1, qmin, ln_pre;
3622 if (u1+i-1>MAXLOOP) break;
3623 qmin = p + TURN + 1;
3624 ln_pre = u1 + i + seq_length;
3625 if(ln_pre > qmin + MAXLOOP) qmin = ln_pre - MAXLOOP - 1;
3626 for(q = qmin; q <= seq_length; q++){
3629 type_2 = rtype[(unsigned int)ptype[pq]];
3630 if (type_2==0) continue;
3631 u2 = i-1 + seq_length-q;
3632 if (u1+u2>MAXLOOP) continue;
3633 /* get distance to reference if closing the interior loop
3634 * d2a = dbp(T1_[1,n}, T1_{p,q} + T1_{i,j})
3635 * d2b = dbp(T2_[1,n}, T2_{p,q} + T2_{i,j})
3637 d1 = base_d1 - referenceBPs1[ij] - referenceBPs1[pq];
3638 d2 = base_d2 - referenceBPs2[ij] - referenceBPs2[pq];
3639 energy = E_IntLoop(u1, u2, type, type_2, S1[j+1], S1[i-1], S1[p-1], S1[q+1], P);
3640 if(E_C_rem[pq] != INF){
3641 for(cnt1 = k_min_values[ij];
3642 cnt1 <= k_max_values[ij];
3644 for(cnt2 = l_min_values[ij][cnt1];
3645 cnt2 <= l_max_values[ij][cnt1];
3647 vars->E_FcI_rem = MIN2(vars->E_FcI_rem, E_C[ij][cnt1][cnt2/2] + E_C_rem[pq] + energy);
3651 for(cnt1 = k_min_values[ij];
3652 cnt1 <= k_max_values[ij];
3654 for(cnt2 = l_min_values[ij][cnt1];
3655 cnt2 <= l_max_values[ij][cnt1];
3657 for(cnt3 = k_min_values[pq];
3658 cnt3 <= k_max_values[pq];
3660 for(cnt4 = l_min_values[pq][cnt3];
3661 cnt4 <= l_max_values[pq][cnt3];
3663 if(((cnt1 + cnt3 + d1) <= maxD1) && ((cnt2 + cnt4 + d2) <= maxD2)){
3664 vars->E_FcI[cnt1 + cnt3 + d1][(cnt2 + cnt4 + d2)/2] = MIN2(
3665 vars->E_FcI[cnt1 + cnt3 + d1][(cnt2 + cnt4 + d2)/2],
3666 E_C[ij][cnt1][cnt2/2]
3667 + E_C[pq][cnt3][cnt4/2]
3670 updatePosteriorBoundaries(cnt1 + cnt3 + d1,
3679 vars->E_FcI_rem = MIN2(
3681 E_C[ij][cnt1][cnt2/2]
3682 + E_C[pq][cnt3][cnt4/2]
3691 /* end of i-j loop */
3693 /* resize and move memory portions of energy matrix E_FcI */
3694 adjustArrayBoundaries(&vars->E_FcI,
3695 &vars->k_min_values_fcI,
3696 &vars->k_max_values_fcI,
3697 &vars->l_min_values_fcI,
3698 &vars->l_max_values_fcI,
3709 if(seq_length > 2*TURN){
3710 for (i=TURN+1; i<seq_length-2*TURN; i++) {
3711 /* get distancies to references
3712 * d3a = dbp(T1_[1,n}, T1_{1,k} + T1_{k+1, n})
3713 * d3b = dbp(T2_[1,n}, T2_{1,k} + T2_{k+1, n})
3715 d1 = base_d1 - referenceBPs1[my_iindx[1]-i] - referenceBPs1[my_iindx[i+1]-seq_length];
3716 d2 = base_d2 - referenceBPs2[my_iindx[1]-i] - referenceBPs2[my_iindx[i+1]-seq_length];
3718 if(E_M_rem[my_iindx[1]-i] != INF){
3720 for(cnt1 = vars->k_min_values_m2[i+1];
3721 cnt1 <= vars->k_max_values_m2[i+1];
3723 for(cnt2 = vars->l_min_values_m2[i+1][cnt1];
3724 cnt2 <= vars->l_max_values_m2[i+1][cnt1];
3726 vars->E_FcM_rem = MIN2(vars->E_FcM_rem, E_M_rem[my_iindx[1]-i] + vars->E_M2[i+1][cnt1][cnt2/2] + P->MLclosing);
3727 if(vars->E_M2_rem[i+1] != INF)
3728 vars->E_FcM_rem = MIN2(vars->E_FcM_rem, E_M_rem[my_iindx[1]-i] + vars->E_M2_rem[i+1] + P->MLclosing);
3730 if(vars->E_M2_rem[i+1] != INF){
3731 if(E_M[my_iindx[1]-i])
3732 for(cnt1 = k_min_values_m[my_iindx[1]-i];
3733 cnt1 <= k_max_values_m[my_iindx[1]-i];
3735 for(cnt2 = l_min_values_m[my_iindx[1]-i][cnt1];
3736 cnt2 <= l_max_values_m[my_iindx[1]-i][cnt1];
3738 vars->E_FcM_rem = MIN2(vars->E_FcM_rem, E_M[my_iindx[1]-i][cnt1][cnt2/2] + vars->E_M2_rem[i+1] + P->MLclosing);
3741 if(!E_M[my_iindx[1]-i]) continue;
3742 if(!vars->E_M2[i+1]) continue;
3743 for(cnt1 = k_min_values_m[my_iindx[1]-i]; cnt1 <= k_max_values_m[my_iindx[1]-i]; cnt1++)
3744 for(cnt2 = l_min_values_m[my_iindx[1]-i][cnt1]; cnt2 <= l_max_values_m[my_iindx[1]-i][cnt1]; cnt2 += 2)
3745 for(cnt3 = vars->k_min_values_m2[i+1]; cnt3 <= vars->k_max_values_m2[i+1]; cnt3++)
3746 for(cnt4 = vars->l_min_values_m2[i+1][cnt3]; cnt4 <= vars->l_max_values_m2[i+1][cnt3]; cnt4 += 2){
3747 if(((cnt1 + cnt3 + d1) <= maxD1) && ((cnt2 + cnt4 + d2) <= maxD2)){
3748 vars->E_FcM[cnt1 + cnt3 + d1][(cnt2 + cnt4 + d2)/2] = MIN2(
3749 vars->E_FcM[cnt1 + cnt3 + d1][(cnt2 + cnt4 + d2)/2],
3750 E_M[my_iindx[1]-i][cnt1][cnt2/2]
3751 + vars->E_M2[i+1][cnt3][cnt4/2]
3754 updatePosteriorBoundaries(cnt1 + cnt3 + d1,
3763 vars->E_FcM_rem = MIN2(
3765 E_M[my_iindx[1]-i][cnt1][cnt2/2]
3766 + vars->E_M2[i+1][cnt3][cnt4/2]
3773 /* resize and move memory portions of energy matrix E_FcM */
3774 adjustArrayBoundaries(&vars->E_FcM,
3775 &vars->k_min_values_fcM,
3776 &vars->k_max_values_fcM,
3777 &vars->l_min_values_fcM,
3778 &vars->l_max_values_fcM,
3791 /* compute E_Fc_rem */
3792 vars->E_Fc_rem = MIN2(vars->E_FcH_rem, vars->E_FcI_rem);
3793 vars->E_Fc_rem = MIN2(vars->E_Fc_rem, vars->E_FcM_rem);
3794 /* add the case were structure is unfolded chain */
3795 if((referenceBPs1[my_iindx[1]-seq_length] > maxD1) || (referenceBPs2[my_iindx[1]-seq_length] > maxD2))
3796 vars->E_Fc_rem = MIN2(vars->E_Fc_rem, 0);
3799 /* compute all E_Fc */
3800 for(cnt1 = vars->k_min_values_fcH; cnt1 <= vars->k_max_values_fcH; cnt1++)
3801 for(cnt2 = vars->l_min_values_fcH[cnt1]; cnt2 <= vars->l_max_values_fcH[cnt1]; cnt2 += 2){
3802 vars->E_Fc[cnt1][cnt2/2] = MIN2(vars->E_Fc[cnt1][cnt2/2],
3803 vars->E_FcH[cnt1][cnt2/2]
3805 updatePosteriorBoundaries(cnt1,
3813 for(cnt1 = vars->k_min_values_fcI; cnt1 <= vars->k_max_values_fcI; cnt1++)
3814 for(cnt2 = vars->l_min_values_fcI[cnt1]; cnt2 <= vars->l_max_values_fcI[cnt1]; cnt2 += 2){
3815 vars->E_Fc[cnt1][cnt2/2] = MIN2(vars->E_Fc[cnt1][cnt2/2],
3816 vars->E_FcI[cnt1][cnt2/2]
3818 updatePosteriorBoundaries(cnt1,
3826 for(cnt1 = vars->k_min_values_fcM; cnt1 <= vars->k_max_values_fcM; cnt1++)
3827 for(cnt2 = vars->l_min_values_fcM[cnt1]; cnt2 <= vars->l_max_values_fcM[cnt1]; cnt2 += 2){
3828 vars->E_Fc[cnt1][cnt2/2] = MIN2(vars->E_Fc[cnt1][cnt2/2],
3829 vars->E_FcM[cnt1][cnt2/2]
3831 updatePosteriorBoundaries(cnt1,
3839 /* add the case were structure is unfolded chain */
3840 vars->E_Fc[referenceBPs1[my_iindx[1]-seq_length]][referenceBPs2[my_iindx[1]-seq_length]/2] = MIN2(vars->E_Fc[referenceBPs1[my_iindx[1]-seq_length]][referenceBPs2[my_iindx[1]-seq_length]/2],
3842 updatePosteriorBoundaries(referenceBPs1[my_iindx[1]-seq_length],
3843 referenceBPs2[my_iindx[1]-seq_length],
3851 adjustArrayBoundaries(&vars->E_Fc,
3852 &vars->k_min_values_fc,
3853 &vars->k_max_values_fc,
3854 &vars->l_min_values_fc,
3855 &vars->l_max_values_fc,
3867 PRIVATE void adjustArrayBoundaries(int ***array, int *k_min, int *k_max, int **l_min, int **l_max, int k_min_post, int k_max_post, int *l_min_post, int *l_max_post){
3869 int k_diff_pre = k_min_post - *k_min;
3870 int mem_size = k_max_post - k_min_post + 1;
3872 if(k_min_post < INF){
3873 /* free all the unused memory behind actual data */
3874 for(cnt1 = k_max_post + 1; cnt1 <= *k_max; cnt1++){
3875 (*array)[cnt1] += (*l_min)[cnt1]/2;
3876 free((*array)[cnt1]);
3879 /* free unused memory before actual data */
3880 for(cnt1 = *k_min; cnt1 < k_min_post; cnt1++){
3881 (*array)[cnt1] += (*l_min)[cnt1]/2;
3882 free((*array)[cnt1]);
3884 /* move data to front and thereby eliminating unused memory in front of actual data */
3886 memmove((int **)(*array),((int **)(*array)) + k_diff_pre, sizeof(int *) * mem_size);
3887 memmove((int *) (*l_min),((int *) (*l_min)) + k_diff_pre, sizeof(int) * mem_size);
3888 memmove((int *) (*l_max),((int *) (*l_max)) + k_diff_pre, sizeof(int) * mem_size);
3891 /* reallocating memory to actual size used */
3893 *array = (int **)realloc(*array, sizeof(int *) * mem_size);
3894 *array -= k_min_post;
3897 *l_min = (int *)realloc(*l_min, sizeof(int) * mem_size);
3898 *l_min -= k_min_post;
3901 *l_max = (int *)realloc(*l_max, sizeof(int) * mem_size);
3902 *l_max -= k_min_post;
3904 /* adjust l dimension of array */
3905 for(cnt1 = k_min_post; cnt1 <= k_max_post; cnt1++){
3906 if(l_min_post[cnt1] < INF){
3908 mem_size = (l_max_post[cnt1] - l_min_post[cnt1] + 1)/2 + 1;
3909 /* reshift the pointer */
3910 (*array)[cnt1] += (*l_min)[cnt1]/2;
3912 int shift = (l_min_post[cnt1]%2 == (*l_min)[cnt1]%2) ? 0 : 1;
3913 /* eliminate unused memory in front of actual data */
3914 unsigned int start = (l_min_post[cnt1] - (*l_min)[cnt1])/2 + shift;
3916 memmove((int *)((*array)[cnt1]), (int *)((*array)[cnt1])+start, sizeof(int) * mem_size);
3917 (*array)[cnt1] = (int *) realloc((*array)[cnt1], sizeof(int) * mem_size);
3919 (*array)[cnt1] -= l_min_post[cnt1]/2;
3922 /* free according memory */
3923 (*array)[cnt1] += (*l_min)[cnt1]/2;
3924 free((*array)[cnt1]);
3927 (*l_min)[cnt1] = l_min_post[cnt1];
3928 (*l_max)[cnt1] = l_max_post[cnt1];
3932 /* we have to free all unused memory */
3933 for(cnt1 = *k_min; cnt1 <= *k_max; cnt1++){
3934 (*array)[cnt1] += (*l_min)[cnt1]/2;
3935 free((*array)[cnt1]);
3946 l_min_post += *k_min;
3947 l_max_post += *k_min;
3950 *k_min = k_min_post;
3951 *k_max = k_max_post;
3954 INLINE PRIVATE void preparePosteriorBoundaries(int size, int shift, int *min_k, int *max_k, int **min_l, int **max_l){
3959 *min_l = (int *)space(sizeof(int) * size);
3960 *max_l = (int *)space(sizeof(int) * size);
3962 for(i = 0; i < size; i++){
3971 INLINE PRIVATE void updatePosteriorBoundaries(int d1, int d2, int *min_k, int *max_k, int **min_l, int **max_l){
3972 (*min_l)[d1] = MIN2((*min_l)[d1], d2);
3973 (*max_l)[d1] = MAX2((*max_l)[d1], d2);
3974 *min_k = MIN2(*min_k, d1);
3975 *max_k = MAX2(*max_k, d1);
3978 INLINE PRIVATE void prepareBoundaries(int min_k_pre, int max_k_pre, int min_l_pre, int max_l_pre, int bpdist, int *min_k, int *max_k, int **min_l, int **max_l){
3980 int mem = max_k_pre - min_k_pre + 1;
3984 *min_l = (int *) space(sizeof(int) * mem);
3985 *max_l = (int *) space(sizeof(int) * mem);
3987 *min_l -= min_k_pre;
3988 *max_l -= min_k_pre;
3990 /* for each k guess the according minimum l*/
3991 for(cnt = min_k_pre; cnt <= max_k_pre; cnt++){
3992 (*min_l)[cnt] = min_l_pre;
3993 (*max_l)[cnt] = max_l_pre;
3994 while((*min_l)[cnt] + cnt < bpdist) (*min_l)[cnt]++;
3995 if((bpdist % 2) != (((*min_l)[cnt] + cnt) % 2)) (*min_l)[cnt]++;
3999 INLINE PRIVATE void prepareArray(int ***array, int min_k, int max_k, int *min_l, int *max_l){
4001 *array = (int **)space(sizeof(int *) * (max_k - min_k + 1));
4004 for(i = min_k; i <= max_k; i++){
4005 mem = (max_l[i] - min_l[i] + 1)/2 + 1;
4006 (*array)[i] = (int *)space(sizeof(int) * mem);
4007 for(j = 0; j < mem; j++)
4008 (*array)[i][j] = INF;
4009 (*array)[i] -= min_l[i]/2;
4013 INLINE PRIVATE void prepareArray2(unsigned long ***array, int min_k, int max_k, int *min_l, int *max_l){
4015 *array = (unsigned long **)space(sizeof(unsigned long *) * (max_k - min_k + 1));
4018 for(i = min_k; i <= max_k; i++){
4019 mem = (max_l[i] - min_l[i] + 1)/2 + 1;
4020 (*array)[i] = (unsigned long *)space(sizeof(unsigned long) * mem);
4021 (*array)[i] -= min_l[i]/2;