3 RNA secondary structure with
4 basepair distance d_1 to reference structure 1 and distance d_2 to reference structure 2
13 #include <float.h> /* #defines FLT_MAX ... */
15 #include "fold_vars.h"
17 #include "energy_par.h"
18 #include "loop_energies.h"
24 #################################
26 #################################
30 #################################
32 #################################
36 #################################
37 # PRIVATE FUNCTION DECLARATIONS #
38 #################################
40 PRIVATE void pf2D_linear(TwoDpfold_vars *vars);
41 PRIVATE void pf2D_circ(TwoDpfold_vars *vars);
42 PRIVATE void initialize_TwoDpfold_vars(TwoDpfold_vars *vars);
43 PRIVATE void scale_pf_params2(TwoDpfold_vars *vars);
44 PRIVATE void make_ptypes2(TwoDpfold_vars *vars);
46 PRIVATE char *TwoDpfold_pbacktrack_circ(
51 PRIVATE void backtrack(
55 unsigned int i, unsigned int j);
56 PRIVATE void backtrack_qm(
60 unsigned int i, unsigned int j);
61 PRIVATE void backtrack_qm1(
65 unsigned int i, unsigned int j);
66 PRIVATE void backtrack_qm2(
71 PRIVATE void backtrack_qcH(
75 PRIVATE void backtrack_qcI(
79 PRIVATE void backtrack_qcM(
84 PRIVATE void adjustArrayBoundaries(
86 int *k_min, int *k_max,
87 int **l_min, int **l_max,
88 int k_min_real, int k_max_real,
89 int *l_min_real, int *l_max_real);
91 INLINE PRIVATE void preparePosteriorBoundaries(
93 int *min_k, int *max_k,
94 int **min_l, int **max_l);
95 INLINE PRIVATE void updatePosteriorBoundaries(
97 int *min_k, int *max_k,
98 int **min_l, int **max_l);
99 INLINE PRIVATE void prepareBoundaries(
100 int min_k_pre, int max_k_pre,
101 int min_l_pre, int max_l_pre,
103 int *min_k, int *max_k,
104 int **min_l, int **max_l);
105 INLINE PRIVATE void prepareArray(
107 int min_k, int max_k,
108 int *min_l, int *max_l);
111 #################################
112 # BEGIN OF FUNCTION DEFINITIONS #
113 #################################
116 PUBLIC TwoDpfold_vars *get_TwoDpfold_variables(const char *seq, const char *structure1, char *structure2, int circ){
117 unsigned int size, length;
119 TwoDpfold_vars *vars;
121 vars = (TwoDpfold_vars *)malloc(sizeof(TwoDpfold_vars));
122 length = (unsigned int) strlen(seq);
123 vars->sequence = (char *)space(length + 1);
124 strcpy(vars->sequence, seq);
125 vars->seq_length = length;
126 if(vars->seq_length < 1) nrerror("get_TwoDfold_variables: sequence must be longer than 0");
127 size = ((length + 1) * (length + 2)/2);
129 vars->reference_pt1 = make_pair_table(structure1);
130 vars->reference_pt2 = make_pair_table(structure2);
131 vars->referenceBPs1 = make_referenceBP_array(vars->reference_pt1, TURN); /* matrix containing number of basepairs of reference structure1 in interval [i,j] */
132 vars->referenceBPs2 = make_referenceBP_array(vars->reference_pt2, TURN); /* matrix containing number of basepairs of reference structure2 in interval [i,j] */
134 /* compute maximum matching with reference structure 1 disallowed */
135 vars->mm1 = maximumMatchingConstraint(vars->sequence, vars->reference_pt1);
136 /* compute maximum matching with reference structure 2 disallowed */
137 vars->mm2 = maximumMatchingConstraint(vars->sequence, vars->reference_pt2);
138 vars->bpdist = compute_BPdifferences(vars->reference_pt1, vars->reference_pt2, TURN);
140 vars->dangles = dangles;
142 vars->temperature = temperature;
143 vars->init_temp = temperature;
144 vars->pf_scale = pf_scale;
145 vars->pf_params = NULL;
147 vars->scale = (FLT_OR_DBL *) space(sizeof(FLT_OR_DBL)*(length+1));
148 vars->ptype = space(sizeof(char) * size);
152 vars->jindx = get_indx(length);
153 vars->my_iindx = get_iindx(length);
154 index = vars->my_iindx;
159 vars->maxD1 = vars->mm1[index[1]-length] + vars->referenceBPs1[index[1]-length];
160 vars->maxD2 = vars->mm2[index[1]-length] + vars->referenceBPs2[index[1]-length];
162 /* allocate memory for the pf matrices and min-/max-index helper arrays */
163 vars->Q = (FLT_OR_DBL ***) space(sizeof(FLT_OR_DBL **) * size);
164 vars->l_min_values = (int **) space(sizeof(int *) * size);
165 vars->l_max_values = (int **) space(sizeof(int *) * size);
166 vars->k_min_values = (int *) space(sizeof(int) * size);
167 vars->k_max_values = (int *) space(sizeof(int) * size);
169 vars->Q_B = (FLT_OR_DBL ***) space(sizeof(FLT_OR_DBL **) * size);
170 vars->l_min_values_b = (int **) space(sizeof(int *) * size);
171 vars->l_max_values_b = (int **) space(sizeof(int *) * size);
172 vars->k_min_values_b = (int *) space(sizeof(int) * size);
173 vars->k_max_values_b = (int *) space(sizeof(int) * size);
175 vars->Q_M = (FLT_OR_DBL ***) space(sizeof(FLT_OR_DBL **) * size);
176 vars->l_min_values_m = (int **) space(sizeof(int *) * size);
177 vars->l_max_values_m = (int **) space(sizeof(int *) * size);
178 vars->k_min_values_m = (int *) space(sizeof(int) * size);
179 vars->k_max_values_m = (int *) space(sizeof(int) * size);
181 vars->Q_M1 = (FLT_OR_DBL ***) space(sizeof(FLT_OR_DBL **) * size);
182 vars->l_min_values_m1 = (int **) space(sizeof(int *) * size);
183 vars->l_max_values_m1 = (int **) space(sizeof(int *) * size);
184 vars->k_min_values_m1 = (int *) space(sizeof(int) * size);
185 vars->k_max_values_m1 = (int *) space(sizeof(int) * size);
189 vars->Q_M2_rem = (FLT_OR_DBL *) space(sizeof(FLT_OR_DBL) * (length + 1));
190 vars->Q_M2 = (FLT_OR_DBL ***) space(sizeof(FLT_OR_DBL **) * (length + 1));
191 vars->l_min_values_m2 = (int **) space(sizeof(int *) * (length + 1));
192 vars->l_max_values_m2 = (int **) space(sizeof(int *) * (length + 1));
193 vars->k_min_values_m2 = (int *) space(sizeof(int) * (length + 1));
194 vars->k_max_values_m2 = (int *) space(sizeof(int) * (length + 1));
197 vars->Q_M2_rem = NULL;
199 vars->l_min_values_m2 = NULL;
200 vars->l_max_values_m2 = NULL;
201 vars->k_min_values_m2 = NULL;
202 vars->k_max_values_m2 = NULL;
213 vars->Q_rem = (FLT_OR_DBL *) space(sizeof(FLT_OR_DBL) * size);
214 vars->Q_B_rem = (FLT_OR_DBL *) space(sizeof(FLT_OR_DBL) * size);
215 vars->Q_M_rem = (FLT_OR_DBL *) space(sizeof(FLT_OR_DBL) * size);
216 vars->Q_M1_rem = (FLT_OR_DBL *) space(sizeof(FLT_OR_DBL) * size);
223 PUBLIC TwoDpfold_vars *get_TwoDpfold_variables_from_MFE(TwoDfold_vars *mfe_vars){
224 unsigned int i, j, size, length;
226 TwoDpfold_vars *vars;
227 vars = (TwoDpfold_vars *)malloc(sizeof(TwoDpfold_vars));
228 vars->sequence = strdup(mfe_vars->sequence);
229 length = mfe_vars->seq_length;
230 vars->seq_length = length;
231 size = ((length + 1) * (length + 2)/2);
233 vars->reference_pt1 = copy_pair_table(mfe_vars->reference_pt1);
234 vars->reference_pt2 = copy_pair_table(mfe_vars->reference_pt2);
235 vars->referenceBPs1 = make_referenceBP_array(vars->reference_pt1, TURN);
236 vars->referenceBPs2 = make_referenceBP_array(vars->reference_pt2, TURN);
238 /* compute maximum matching with reference structure 1 disallowed */
239 vars->mm1 = maximumMatchingConstraint(vars->sequence, vars->reference_pt1);
240 /* compute maximum matching with reference structure 2 disallowed */
241 vars->mm2 = maximumMatchingConstraint(vars->sequence, vars->reference_pt2);
242 vars->bpdist = compute_BPdifferences(vars->reference_pt1, vars->reference_pt2, TURN);
245 vars->dangles = mfe_vars->dangles;
246 vars->circ = mfe_vars->circ;
247 vars->temperature = mfe_vars->temperature;
248 vars->init_temp = mfe_vars->temperature;
249 vars->pf_scale = pf_scale;
251 vars->scale = (FLT_OR_DBL *) space(sizeof(FLT_OR_DBL)*(length+1));
252 vars->ptype = space(sizeof(char) * size);
255 vars->pf_params = NULL;
256 vars->maxD1 = mfe_vars->maxD1;
257 vars->maxD2 = mfe_vars->maxD2;
259 vars->jindx = get_indx(vars->seq_length);
260 vars->my_iindx = get_iindx(vars->seq_length);
262 /* allocate memory for the pf matrices and min-/max-index helper arrays */
263 vars->Q = (FLT_OR_DBL ***) space(sizeof(FLT_OR_DBL **) * size);
264 vars->l_min_values = (int **) space(sizeof(int *) * size);
265 vars->l_max_values = (int **) space(sizeof(int *) * size);
266 vars->k_min_values = (int *) space(sizeof(int) * size);
267 vars->k_max_values = (int *) space(sizeof(int) * size);
269 vars->Q_B = (FLT_OR_DBL ***) space(sizeof(FLT_OR_DBL **) * size);
270 vars->l_min_values_b = (int **) space(sizeof(int *) * size);
271 vars->l_max_values_b = (int **) space(sizeof(int *) * size);
272 vars->k_min_values_b = (int *) space(sizeof(int) * size);
273 vars->k_max_values_b = (int *) space(sizeof(int) * size);
275 vars->Q_M = (FLT_OR_DBL ***) space(sizeof(FLT_OR_DBL **) * size);
276 vars->l_min_values_m = (int **) space(sizeof(int *) * size);
277 vars->l_max_values_m = (int **) space(sizeof(int *) * size);
278 vars->k_min_values_m = (int *) space(sizeof(int) * size);
279 vars->k_max_values_m = (int *) space(sizeof(int) * size);
281 vars->Q_M1 = (FLT_OR_DBL ***) space(sizeof(FLT_OR_DBL **) * size);
282 vars->l_min_values_m1 = (int **) space(sizeof(int *) * size);
283 vars->l_max_values_m1 = (int **) space(sizeof(int *) * size);
284 vars->k_min_values_m1 = (int *) space(sizeof(int) * size);
285 vars->k_max_values_m1 = (int *) space(sizeof(int) * size);
289 vars->Q_M2 = (FLT_OR_DBL ***) space(sizeof(FLT_OR_DBL **) * (length + 1));
290 vars->l_min_values_m2 = (int **) space(sizeof(int *) * (length + 1));
291 vars->l_max_values_m2 = (int **) space(sizeof(int *) * (length + 1));
292 vars->k_min_values_m2 = (int *) space(sizeof(int) * (length + 1));
293 vars->k_max_values_m2 = (int *) space(sizeof(int) * (length + 1));
297 vars->l_min_values_m2 = NULL;
298 vars->l_max_values_m2 = NULL;
299 vars->k_min_values_m2 = NULL;
300 vars->k_max_values_m2 = NULL;
307 /* prepare everything that is known from previous mfe folding step */
308 for(i = 1; i < length; i++)
309 for(j = i; j <= length; j++){
311 ij = vars->my_iindx[i] - j;
312 jij = vars->jindx[j] + i;
314 if(mfe_vars->E_C[ij]){
315 mem = mfe_vars->k_max_values[ij] - mfe_vars->k_min_values[ij] + 1;
316 vars->k_min_values_b[ij] = mfe_vars->k_min_values[ij];
317 vars->k_max_values_b[ij] = mfe_vars->k_max_values[ij];
318 vars->Q_B[ij] = (FLT_OR_DBL **)space(sizeof(FLT_OR_DBL *) * mem);
319 vars->l_min_values_b[ij] = (int *)space(sizeof(int) * mem);
320 vars->l_max_values_b[ij] = (int *)space(sizeof(int) * mem);
321 vars->Q_B[ij] -= vars->k_min_values_b[ij];
322 vars->l_min_values_b[ij] -= vars->k_min_values_b[ij];
323 vars->l_max_values_b[ij] -= vars->k_min_values_b[ij];
324 for(cnt1 = vars->k_min_values_b[ij]; cnt1 <= vars->k_max_values_b[ij]; cnt1++){
325 vars->l_min_values_b[ij][cnt1] = mfe_vars->l_min_values[ij][cnt1];
326 vars->l_max_values_b[ij][cnt1] = mfe_vars->l_max_values[ij][cnt1];
327 if(vars->l_min_values_b[ij][cnt1] < INF){
328 vars->Q_B[ij][cnt1] = (FLT_OR_DBL *)space(sizeof(FLT_OR_DBL) * ((vars->l_max_values_b[ij][cnt1] - vars->l_min_values_b[ij][cnt1] + 1)/2 + 1));
329 vars->Q_B[ij][cnt1] -= vars->l_min_values_b[ij][cnt1]/2;
334 if(mfe_vars->E_M[ij]){
335 mem = mfe_vars->k_max_values_m[ij] - mfe_vars->k_min_values_m[ij] + 1;
336 vars->k_min_values_m[ij] = mfe_vars->k_min_values_m[ij];
337 vars->k_max_values_m[ij] = mfe_vars->k_max_values_m[ij];
338 vars->Q_M[ij] = (FLT_OR_DBL **)space(sizeof(FLT_OR_DBL *) * mem);
339 vars->l_min_values_m[ij] = (int *)space(sizeof(int) * mem);
340 vars->l_max_values_m[ij] = (int *)space(sizeof(int) * mem);
341 vars->Q_M[ij] -= vars->k_min_values_m[ij];
342 vars->l_min_values_m[ij] -= vars->k_min_values_m[ij];
343 vars->l_max_values_m[ij] -= vars->k_min_values_m[ij];
344 for(cnt1 = vars->k_min_values_m[ij]; cnt1 <= vars->k_max_values_m[ij]; cnt1++){
345 vars->l_min_values_m[ij][cnt1] = mfe_vars->l_min_values_m[ij][cnt1];
346 vars->l_max_values_m[ij][cnt1] = mfe_vars->l_max_values_m[ij][cnt1];
347 if(vars->l_min_values_m[ij][cnt1] < INF){
348 vars->Q_M[ij][cnt1] = (FLT_OR_DBL *)space(sizeof(FLT_OR_DBL) * ((vars->l_max_values_m[ij][cnt1] - vars->l_min_values_m[ij][cnt1] + 1)/2 + 1));
349 vars->Q_M[ij][cnt1] -= vars->l_min_values_m[ij][cnt1]/2;
354 if(mfe_vars->E_M1[ij]){
355 mem = mfe_vars->k_max_values_m1[ij] - mfe_vars->k_min_values_m1[ij] + 1;
356 vars->k_min_values_m1[jij] = mfe_vars->k_min_values_m1[ij];
357 vars->k_max_values_m1[jij] = mfe_vars->k_max_values_m1[ij];
358 vars->Q_M1[jij] = (FLT_OR_DBL **)space(sizeof(FLT_OR_DBL *) * mem);
359 vars->l_min_values_m1[jij] = (int *)space(sizeof(int) * mem);
360 vars->l_max_values_m1[jij] = (int *)space(sizeof(int) * mem);
361 vars->Q_M1[jij] -= vars->k_min_values_m1[jij];
362 vars->l_min_values_m1[jij] -= vars->k_min_values_m1[jij];
363 vars->l_max_values_m1[jij] -= vars->k_min_values_m1[jij];
364 for(cnt1 = vars->k_min_values_m1[jij]; cnt1 <= vars->k_max_values_m1[jij]; cnt1++){
365 vars->l_min_values_m1[jij][cnt1] = mfe_vars->l_min_values_m1[ij][cnt1];
366 vars->l_max_values_m1[jij][cnt1] = mfe_vars->l_max_values_m1[ij][cnt1];
367 if(vars->l_min_values_m1[jij][cnt1] < INF){
368 vars->Q_M1[jij][cnt1] = (FLT_OR_DBL *)space(sizeof(FLT_OR_DBL) * ((vars->l_max_values_m1[jij][cnt1] - vars->l_min_values_m1[jij][cnt1] + 1)/2 + 1));
369 vars->Q_M1[jij][cnt1] -= vars->l_min_values_m1[jij][cnt1]/2;
378 mem = mfe_vars->k_max_values_fc - mfe_vars->k_min_values_fc + 1;
379 vars->Q_c = (FLT_OR_DBL **)space(sizeof(FLT_OR_DBL *) * mem);
380 vars->l_min_values_qc = (int *)space(sizeof(int) * mem);
381 vars->l_max_values_qc = (int *)space(sizeof(int) * mem);
382 vars->k_min_values_qc = mfe_vars->k_min_values_fc;
383 vars->k_max_values_qc = mfe_vars->k_max_values_fc;
384 vars->Q_c -= vars->k_min_values_qc;
385 vars->l_min_values_qc -= vars->k_min_values_qc;
386 vars->l_max_values_qc -= vars->k_min_values_qc;
387 for(cnt1 = vars->k_min_values_qc; cnt1 <= vars->k_max_values_qc; cnt1++){
388 mem = (mfe_vars->l_max_values_fc[cnt1] - mfe_vars->l_min_values_fc[cnt1] + 1)/2 + 1;
389 vars->l_min_values_qc[cnt1] = mfe_vars->l_min_values_fc[cnt1];
390 vars->l_max_values_qc[cnt1] = mfe_vars->l_max_values_fc[cnt1];
391 if(vars->l_min_values_qc[cnt1] < INF){
392 vars->Q_c[cnt1] = (FLT_OR_DBL *)space(sizeof(FLT_OR_DBL) * mem);
393 vars->Q_c[cnt1] -= vars->l_min_values_qc[cnt1]/2;
399 mem = mfe_vars->k_max_values_fcH - mfe_vars->k_min_values_fcH + 1;
400 vars->Q_cH = (FLT_OR_DBL **)space(sizeof(FLT_OR_DBL *) * mem);
401 vars->l_min_values_qcH = (int *)space(sizeof(int) * mem);
402 vars->l_max_values_qcH = (int *)space(sizeof(int) * mem);
403 vars->k_min_values_qcH = mfe_vars->k_min_values_fcH;
404 vars->k_max_values_qcH = mfe_vars->k_max_values_fcH;
405 vars->Q_cH -= vars->k_min_values_qcH;
406 vars->l_min_values_qcH -= vars->k_min_values_qcH;
407 vars->l_max_values_qcH -= vars->k_min_values_qcH;
408 for(cnt1 = vars->k_min_values_qcH; cnt1 <= vars->k_max_values_qcH; cnt1++){
409 mem = (mfe_vars->l_max_values_fcH[cnt1] - mfe_vars->l_min_values_fcH[cnt1] + 1)/2 + 1;
410 vars->l_min_values_qcH[cnt1] = mfe_vars->l_min_values_fcH[cnt1];
411 vars->l_max_values_qcH[cnt1] = mfe_vars->l_max_values_fcH[cnt1];
412 if(vars->l_min_values_qcH[cnt1] < INF){
413 vars->Q_cH[cnt1] = (FLT_OR_DBL *)space(sizeof(FLT_OR_DBL) * mem);
414 vars->Q_cH[cnt1] -= vars->l_min_values_qcH[cnt1]/2;
420 mem = mfe_vars->k_max_values_fcI - mfe_vars->k_min_values_fcI + 1;
421 vars->Q_cI = (FLT_OR_DBL **)space(sizeof(FLT_OR_DBL *) * mem);
422 vars->l_min_values_qcI = (int *)space(sizeof(int) * mem);
423 vars->l_max_values_qcI = (int *)space(sizeof(int) * mem);
424 vars->k_min_values_qcI = mfe_vars->k_min_values_fcI;
425 vars->k_max_values_qcI = mfe_vars->k_max_values_fcI;
426 vars->Q_cI -= vars->k_min_values_qcI;
427 vars->l_min_values_qcI -= vars->k_min_values_qcI;
428 vars->l_max_values_qcI -= vars->k_min_values_qcI;
429 for(cnt1 = vars->k_min_values_qcI; cnt1 <= vars->k_max_values_qcI; cnt1++){
430 mem = (mfe_vars->l_max_values_fcI[cnt1] - mfe_vars->l_min_values_fcI[cnt1] + 1)/2 + 1;
431 vars->l_min_values_qcI[cnt1] = mfe_vars->l_min_values_fcI[cnt1];
432 vars->l_max_values_qcI[cnt1] = mfe_vars->l_max_values_fcI[cnt1];
433 if(vars->l_min_values_qcI[cnt1] < INF){
434 vars->Q_cI[cnt1] = (FLT_OR_DBL *)space(sizeof(FLT_OR_DBL) * mem);
435 vars->Q_cI[cnt1] -= vars->l_min_values_qcI[cnt1]/2;
441 mem = mfe_vars->k_max_values_fcM - mfe_vars->k_min_values_fcM + 1;
442 vars->Q_cM = (FLT_OR_DBL **)space(sizeof(FLT_OR_DBL *) * mem);
443 vars->l_min_values_qcM = (int *)space(sizeof(int) * mem);
444 vars->l_max_values_qcM = (int *)space(sizeof(int) * mem);
445 vars->k_min_values_qcM = mfe_vars->k_min_values_fcM;
446 vars->k_max_values_qcM = mfe_vars->k_max_values_fcM;
447 vars->Q_cM -= vars->k_min_values_qcM;
448 vars->l_min_values_qcM -= vars->k_min_values_qcM;
449 vars->l_max_values_qcM -= vars->k_min_values_qcM;
450 for(cnt1 = vars->k_min_values_qcM; cnt1 <= vars->k_max_values_qcM; cnt1++){
451 mem = (mfe_vars->l_max_values_fcM[cnt1] - mfe_vars->l_min_values_fcM[cnt1] + 1)/2 + 1;
452 vars->l_min_values_qcM[cnt1] = mfe_vars->l_min_values_fcM[cnt1];
453 vars->l_max_values_qcM[cnt1] = mfe_vars->l_max_values_fcM[cnt1];
454 if(vars->l_min_values_qcM[cnt1] < INF){
455 vars->Q_cM[cnt1] = (FLT_OR_DBL *)space(sizeof(FLT_OR_DBL) * mem);
456 vars->Q_cM[cnt1] -= vars->l_min_values_qcM[cnt1]/2;
462 vars->Q_M2 = (FLT_OR_DBL ***)space(sizeof(FLT_OR_DBL **) * (length + 1));
463 vars->k_min_values_m2 = (int *)space(sizeof(int) * (length + 1));
464 vars->k_max_values_m2 = (int *)space(sizeof(int) * (length + 1));
465 vars->l_min_values_m2 = (int **)space(sizeof(int *) * (length + 1));
466 vars->l_max_values_m2 = (int **)space(sizeof(int *) * (length + 1));
467 for(i=1; i < length - TURN - 1; i++){
468 if(!mfe_vars->E_M2[i]) continue;
469 mem = mfe_vars->k_max_values_m2[i] - mfe_vars->k_min_values_m2[i] + 1;
470 vars->k_min_values_m2[i] = mfe_vars->k_min_values_m2[i];
471 vars->k_max_values_m2[i] = mfe_vars->k_max_values_m2[i];
472 vars->Q_M2[i] = (FLT_OR_DBL **)space(sizeof(FLT_OR_DBL *) * mem);
473 vars->l_min_values_m2[i] = (int *)space(sizeof(int) * mem);
474 vars->l_max_values_m2[i] = (int *)space(sizeof(int) * mem);
475 vars->Q_M2[i] -= vars->k_min_values_m2[i];
476 vars->l_min_values_m2[i] -= vars->k_min_values_m2[i];
477 vars->l_max_values_m2[i] -= vars->k_min_values_m2[i];
478 for(cnt1 = vars->k_min_values_m2[i]; cnt1 <= vars->k_max_values_m2[i]; cnt1++){
479 mem = (mfe_vars->l_max_values_m2[i][cnt1] - mfe_vars->l_min_values_m2[i][cnt1] + 1)/2 + 1;
480 vars->l_min_values_m2[i][cnt1] = mfe_vars->l_min_values_m2[i][cnt1];
481 vars->l_max_values_m2[i][cnt1] = mfe_vars->l_max_values_m2[i][cnt1];
482 if(vars->l_min_values_m2[i][cnt1] < INF){
483 vars->Q_M2[i][cnt1] = (FLT_OR_DBL *)space(sizeof(FLT_OR_DBL) * mem);
484 vars->Q_M2[i][cnt1] -= vars->l_min_values_m2[i][cnt1]/2;
492 vars->Q_c = vars->Q_cH = vars->Q_cI = vars->Q_cM = NULL;
493 vars->k_min_values_m2 = vars->k_max_values_m2 = NULL;
494 vars->l_min_values_m2 = vars->l_max_values_m2 = NULL;
495 vars->l_min_values_qc = vars->l_max_values_qc = NULL;
496 vars->l_min_values_qcH = vars->l_max_values_qcH = NULL;
497 vars->l_min_values_qcI = vars->l_max_values_qcI = NULL;
498 vars->l_min_values_qcM = vars->l_max_values_qcM = NULL;
504 PUBLIC void destroy_TwoDpfold_variables(TwoDpfold_vars *vars){
505 unsigned int i, j, ij;
507 if(vars == NULL) return;
510 #pragma omp sections private(i,j,ij)
517 for(i = 1; i <= vars->seq_length; i++){
518 for(j = i; j <= vars->seq_length; j++){
519 ij = vars->my_iindx[i] - j;
520 if(!vars->Q[ij]) continue;
521 for(cnt1 = vars->k_min_values[ij]; cnt1 <= vars->k_max_values[ij]; cnt1++)
522 if(vars->l_min_values[ij][cnt1] < INF){
523 vars->Q[ij][cnt1] += vars->l_min_values[ij][cnt1]/2;
524 free(vars->Q[ij][cnt1]);
526 if(vars->k_min_values[ij] < INF){
527 vars->Q[ij] += vars->k_min_values[ij];
529 vars->l_min_values[ij] += vars->k_min_values[ij];
530 vars->l_max_values[ij] += vars->k_min_values[ij];
531 free(vars->l_min_values[ij]);
532 free(vars->l_max_values[ij]);
537 free(vars->l_min_values);
538 free(vars->l_max_values);
539 free(vars->k_min_values);
540 free(vars->k_max_values);
547 if(vars->Q_B != NULL){
548 for(i = 1; i < vars->seq_length; i++){
549 for(j = i; j <= vars->seq_length; j++){
550 ij = vars->my_iindx[i] - j;
551 if(!vars->Q_B[ij]) continue;
552 for(cnt1 = vars->k_min_values_b[ij]; cnt1 <= vars->k_max_values_b[ij]; cnt1++)
553 if(vars->l_min_values_b[ij][cnt1] < INF){
554 vars->Q_B[ij][cnt1] += vars->l_min_values_b[ij][cnt1]/2;
555 free(vars->Q_B[ij][cnt1]);
557 if(vars->k_min_values_b[ij] < INF){
558 vars->Q_B[ij] += vars->k_min_values_b[ij];
560 vars->l_min_values_b[ij] += vars->k_min_values_b[ij];
561 vars->l_max_values_b[ij] += vars->k_min_values_b[ij];
562 free(vars->l_min_values_b[ij]);
563 free(vars->l_max_values_b[ij]);
568 free(vars->l_min_values_b);
569 free(vars->l_max_values_b);
570 free(vars->k_min_values_b);
571 free(vars->k_max_values_b);
578 if(vars->Q_M != NULL){
579 for(i = 1; i < vars->seq_length; i++){
580 for(j = i; j <= vars->seq_length; j++){
581 ij = vars->my_iindx[i] - j;
582 if(!vars->Q_M[ij]) continue;
583 for(cnt1 = vars->k_min_values_m[ij]; cnt1 <= vars->k_max_values_m[ij]; cnt1++)
584 if(vars->l_min_values_m[ij][cnt1] < INF){
585 vars->Q_M[ij][cnt1] += vars->l_min_values_m[ij][cnt1]/2;
586 free(vars->Q_M[ij][cnt1]);
588 if(vars->k_min_values_m[ij] < INF){
589 vars->Q_M[ij] += vars->k_min_values_m[ij];
591 vars->l_min_values_m[ij] += vars->k_min_values_m[ij];
592 vars->l_max_values_m[ij] += vars->k_min_values_m[ij];
593 free(vars->l_min_values_m[ij]);
594 free(vars->l_max_values_m[ij]);
599 free(vars->l_min_values_m);
600 free(vars->l_max_values_m);
601 free(vars->k_min_values_m);
602 free(vars->k_max_values_m);
609 if(vars->Q_M1 != NULL){
610 for(i = 1; i < vars->seq_length; i++){
611 for(j = i; j <= vars->seq_length; j++){
612 ij = vars->jindx[j] + i;
613 if(!vars->Q_M1[ij]) continue;
614 for(cnt1 = vars->k_min_values_m1[ij]; cnt1 <= vars->k_max_values_m1[ij]; cnt1++)
615 if(vars->l_min_values_m1[ij][cnt1] < INF){
616 vars->Q_M1[ij][cnt1] += vars->l_min_values_m1[ij][cnt1]/2;
617 free(vars->Q_M1[ij][cnt1]);
619 if(vars->k_min_values_m1[ij] < INF){
620 vars->Q_M1[ij] += vars->k_min_values_m1[ij];
621 free(vars->Q_M1[ij]);
622 vars->l_min_values_m1[ij] += vars->k_min_values_m1[ij];
623 vars->l_max_values_m1[ij] += vars->k_min_values_m1[ij];
624 free(vars->l_min_values_m1[ij]);
625 free(vars->l_max_values_m1[ij]);
630 free(vars->l_min_values_m1);
631 free(vars->l_max_values_m1);
632 free(vars->k_min_values_m1);
633 free(vars->k_max_values_m1);
640 if(vars->Q_M2 != NULL){
641 for(i = 1; i < vars->seq_length-TURN-1; i++){
642 if(!vars->Q_M2[i]) continue;
643 for(cnt1 = vars->k_min_values_m2[i]; cnt1 <= vars->k_max_values_m2[i]; cnt1++)
644 if(vars->l_min_values_m2[i][cnt1] < INF){
645 vars->Q_M2[i][cnt1] += vars->l_min_values_m2[i][cnt1]/2;
646 free(vars->Q_M2[i][cnt1]);
648 if(vars->k_min_values_m2[i] < INF){
649 vars->Q_M2[i] += vars->k_min_values_m2[i];
651 vars->l_min_values_m2[i] += vars->k_min_values_m2[i];
652 vars->l_max_values_m2[i] += vars->k_min_values_m2[i];
653 free(vars->l_min_values_m2[i]);
654 free(vars->l_max_values_m2[i]);
658 free(vars->l_min_values_m2);
659 free(vars->l_max_values_m2);
660 free(vars->k_min_values_m2);
661 free(vars->k_max_values_m2);
668 if(vars->Q_c != NULL){
669 for(cnt1 = vars->k_min_values_qc; cnt1 <= vars->k_max_values_qc; cnt1++)
670 if(vars->l_min_values_qc[cnt1] < INF){
671 vars->Q_c[cnt1] += vars->l_min_values_qc[cnt1]/2;
672 free(vars->Q_c[cnt1]);
674 if(vars->k_min_values_qc < INF){
675 vars->Q_c += vars->k_min_values_qc;
677 vars->l_min_values_qc += vars->k_min_values_qc;
678 vars->l_max_values_qc += vars->k_min_values_qc;
679 free(vars->l_min_values_qc);
680 free(vars->l_max_values_qc);
688 if(vars->Q_cI != NULL){
689 for(cnt1 = vars->k_min_values_qcI; cnt1 <= vars->k_max_values_qcI; cnt1++)
690 if(vars->l_min_values_qcI[cnt1] < INF){
691 vars->Q_cI[cnt1] += vars->l_min_values_qcI[cnt1]/2;
692 free(vars->Q_cI[cnt1]);
694 if(vars->k_min_values_qcI < INF){
695 vars->Q_cI += vars->k_min_values_qcI;
697 vars->l_min_values_qcI += vars->k_min_values_qcI;
698 vars->l_max_values_qcI += vars->k_min_values_qcI;
699 free(vars->l_min_values_qcI);
700 free(vars->l_max_values_qcI);
708 if(vars->Q_cH != NULL){
709 for(cnt1 = vars->k_min_values_qcH; cnt1 <= vars->k_max_values_qcH; cnt1++)
710 if(vars->l_min_values_qcH[cnt1] < INF){
711 vars->Q_cH[cnt1] += vars->l_min_values_qcH[cnt1]/2;
712 free(vars->Q_cH[cnt1]);
714 if(vars->k_min_values_qcH < INF){
715 vars->Q_cH += vars->k_min_values_qcH;
717 vars->l_min_values_qcH += vars->k_min_values_qcH;
718 vars->l_max_values_qcH += vars->k_min_values_qcH;
719 free(vars->l_min_values_qcH);
720 free(vars->l_max_values_qcH);
728 if(vars->Q_cM != NULL){
729 for(cnt1 = vars->k_min_values_qcM; cnt1 <= vars->k_max_values_qcM; cnt1++)
730 if(vars->l_min_values_qcM[cnt1] < INF){
731 vars->Q_cM[cnt1] += vars->l_min_values_qcM[cnt1]/2;
732 free(vars->Q_cM[cnt1]);
734 if(vars->k_min_values_qcM < INF){
735 vars->Q_cM += vars->k_min_values_qcM;
737 vars->l_min_values_qcM += vars->k_min_values_qcM;
738 vars->l_max_values_qcM += vars->k_min_values_qcM;
739 free(vars->l_min_values_qcM);
740 free(vars->l_max_values_qcM);
750 if(vars->Q_rem) free(vars->Q_rem);
751 if(vars->Q_B_rem) free(vars->Q_B_rem);
752 if(vars->Q_M_rem) free(vars->Q_M_rem);
753 if(vars->Q_M1_rem) free(vars->Q_M1_rem);
754 if(vars->Q_M2_rem) free(vars->Q_M2_rem);
756 if(vars->sequence != NULL) free(vars->sequence);
757 if(vars->reference_pt1 != NULL) free(vars->reference_pt1);
758 if(vars->reference_pt2 != NULL) free(vars->reference_pt2);
759 if(vars->referenceBPs1 != NULL) free(vars->referenceBPs1);
760 if(vars->referenceBPs2 != NULL) free(vars->referenceBPs2);
761 if(vars->ptype != NULL) free(vars->ptype);
762 if(vars->scale != NULL) free(vars->scale);
764 if(vars->S != NULL) free(vars->S);
765 if(vars->pf_params != NULL) free(vars->pf_params);
766 if(vars->S1 != NULL) free(vars->S1);
767 if(vars->mm1 != NULL) free(vars->mm1);
768 if(vars->mm2 != NULL) free(vars->mm2);
769 if(vars->bpdist != NULL) free(vars->bpdist);
775 if(vars->my_iindx != NULL) free(vars->my_iindx);
776 if(vars->jindx != NULL) free(vars->jindx);
782 PRIVATE void initialize_TwoDpfold_vars(TwoDpfold_vars *vars){
783 scale_pf_params2(vars);
787 TwoDpfold_solution *TwoDpfoldList(TwoDpfold_vars *vars, int distance1, int distance2){
788 unsigned int maxD1 = 0, maxD2 = 0, counter = 0;
789 int cnt1, cnt2, k_min, k_max, l_min, l_max, ndx;
792 TwoDpfold_solution *output;
794 initialize_TwoDpfold_vars(vars);
796 vars->S = encode_sequence(vars->sequence, 0);
797 vars->S1 = encode_sequence(vars->sequence, 1);
804 if((unsigned int)distance1 > maxD1)
806 "TwoDpfoldList@2Dpfold.c: limiting maximum basepair distance 1 to %u\n",
809 maxD1 = (unsigned int)distance1;
813 if((unsigned int)distance2 > maxD2)
815 "TwoDpfoldList@2Dpfold.c: limiting maximum basepair distance 2 to %u\n",
818 maxD2 = (unsigned int)distance2;
823 output = (TwoDpfold_solution *)space((((maxD1+1)*(maxD2+2))/2 + 2) * sizeof(TwoDpfold_solution));
826 if(vars->circ) pf2D_circ(vars);
828 ndx = vars->my_iindx[1] - vars->seq_length;
829 k_min = (vars->circ) ? vars->k_min_values_qc: vars->k_min_values[ndx];
830 k_max = (vars->circ) ? vars->k_max_values_qc: vars->k_max_values[ndx];
835 l_min = (vars->circ) ? vars->l_min_values_qc[cnt1] : vars->l_min_values[ndx][cnt1];
836 l_max = (vars->circ) ? vars->l_max_values_qc[cnt1] : vars->l_max_values[ndx][cnt1];
840 q = (vars->circ) ? vars->Q_c[cnt1][cnt2/2] : vars->Q[ndx][cnt1][cnt2/2];
841 if(q == 0.) continue;
842 output[counter].k = cnt1;
843 output[counter].l = cnt2;
844 output[counter].q = q;
849 /* store entry for remaining partition if it exists */
850 q = (vars->circ) ? vars->Q_c_rem : vars->Q_rem[ndx];
852 output[counter].k = -1;
853 output[counter].l = -1;
854 output[counter].q = q;
858 /* insert end-marker entry */
859 output[counter].k = output[counter].l = INF;
862 /* resize to actual dataset amount */
863 output = (TwoDpfold_solution*)xrealloc(output, sizeof(TwoDpfold_solution) * counter);
867 PUBLIC FLT_OR_DBL **TwoDpfold(TwoDpfold_vars *vars, int distance1, int distance2){
869 unsigned int maxD1 = 0;
870 unsigned int maxD2 = 0;
876 initialize_TwoDpfold_vars(vars);
878 vars->S = encode_sequence(vars->sequence, 0);
879 vars->S1 = encode_sequence(vars->sequence, 1);
882 for(i=1; i<=(unsigned int)vars->reference_pt1[0]; i++)
883 if(i < (unsigned int)vars->reference_pt1[i]) maxD1++;
884 for(i=1; i<=(unsigned int)vars->reference_pt2[0]; i++)
885 if(i < (unsigned int)vars->reference_pt2[i]) maxD2++;
886 mm = maximumMatching(vars->sequence);
891 if((unsigned int)distance1 > maxD1)
892 fprintf(stderr, "limiting maximum basepair distance 1 to %u\n", maxD1);
893 maxD1 = (unsigned int)distance1;
897 if((unsigned int)distance2 > maxD2)
898 fprintf(stderr, "limiting maximum basepair distance 2 to %u\n", maxD2);
899 maxD2 = (unsigned int)distance2;
905 output = (FLT_OR_DBL **) space(sizeof(FLT_OR_DBL*) * (maxD1+1));
907 int ndx = vars->my_iindx[1] - vars->seq_length;
908 for(cnt1 = vars->k_min_values[ndx]; cnt1 <= MIN2(vars->k_max_values[ndx], vars->maxD1); cnt1++){
909 output[cnt1] = (FLT_OR_DBL *)space((vars->maxD2+1)*sizeof(FLT_OR_DBL));
910 for(cnt2 = vars->l_min_values[ndx][cnt1]; cnt2 <= MIN2(vars->l_max_values[ndx][cnt1], vars->maxD2); cnt2+=2){
911 output[cnt1][cnt2] = vars->Q[ndx][cnt1][cnt2/2];
917 PUBLIC FLT_OR_DBL **TwoDpfold_circ(TwoDpfold_vars *vars, int distance1, int distance2){
919 unsigned int maxD1 = 0;
920 unsigned int maxD2 = 0;
925 initialize_TwoDpfold_vars(vars);
927 vars->S = encode_sequence(vars->sequence, 0);
928 vars->S1 = encode_sequence(vars->sequence, 1);
931 for(i=1; i<=(unsigned int)vars->reference_pt1[0]; i++)
932 if(i < (unsigned int)vars->reference_pt1[i]) maxD1++;
933 for(i=1; i<=(unsigned int)vars->reference_pt2[0]; i++)
934 if(i < (unsigned int)vars->reference_pt2[i]) maxD2++;
935 mm = maximumMatching(vars->sequence);
940 if((unsigned int)distance1 > maxD1)
941 fprintf(stderr, "limiting maximum basepair distance 1 to %u\n", maxD1);
942 maxD1 = (unsigned int)distance1;
946 if((unsigned int)distance2 > maxD2)
947 fprintf(stderr, "limiting maximum basepair distance 2 to %u\n", maxD2);
948 maxD2 = (unsigned int)distance2;
953 output = (FLT_OR_DBL **) space(sizeof(FLT_OR_DBL*) * (maxD1+1));
957 for(cnt1 = vars->k_min_values_qc; cnt1 <= MIN2(vars->k_max_values_qc, vars->maxD1); cnt1++){
958 output[cnt1] = (FLT_OR_DBL *)space((vars->maxD2+1)*sizeof(FLT_OR_DBL));
959 for(cnt2 = vars->l_min_values_qc[cnt1]; cnt2 <= MIN2(vars->l_max_values_qc[cnt1], vars->maxD2); cnt2+=2){
960 output[cnt1][cnt2] = vars->Q_c[cnt1][cnt2/2];
966 PRIVATE void pf2D_linear(TwoDpfold_vars *vars){
968 char *sequence, *ptype;
969 short *S1, *reference_pt1, *reference_pt2;
970 unsigned int *referenceBPs1, *referenceBPs2,
971 d, i, j, ij, seq_length, maxD1,
972 maxD2, *mm1, *mm2, *bpdist;
973 int *my_iindx, *jindx, circ, cnt1, cnt2, cnt3, cnt4;
975 FLT_OR_DBL *scale, Qmax;
976 pf_paramT *pf_params;
978 max_real = (sizeof(FLT_OR_DBL) == sizeof(float)) ? FLT_MAX : DBL_MAX;
980 pf_params = vars->pf_params;
981 sequence = vars->sequence;
982 seq_length = vars->seq_length;
988 reference_pt1 = vars->reference_pt1;
989 reference_pt2 = vars->reference_pt2;
990 my_iindx = vars->my_iindx;
992 referenceBPs1 = vars->referenceBPs1;
993 referenceBPs2 = vars->referenceBPs2;
994 dangles = vars->dangles;
998 bpdist = vars->bpdist;
1001 /*array initialization ; qb,qm,q
1002 qb,qm,q (i,j) are stored as ((n+1-i)*(n-i) div 2 + n+1-j */
1004 for (j = 1; j<=seq_length; j++)
1005 for (i=(j>TURN?(j-TURN):1); i<=j; i++){
1007 vars->k_min_values[ij] = 0;
1008 vars->k_max_values[ij] = 0;
1009 vars->l_min_values[ij] = (int *)space(sizeof(int));
1010 vars->l_max_values[ij] = (int *)space(sizeof(int));
1011 vars->l_min_values[ij][0] = 0;
1012 vars->l_max_values[ij][0] = 0;
1013 vars->Q[ij] = (FLT_OR_DBL **) space(sizeof(FLT_OR_DBL *));
1014 vars->Q[ij][0] = (FLT_OR_DBL *) space(sizeof(FLT_OR_DBL));
1015 vars->Q[ij][0][0] = 1.0 * scale[j-i+1];
1019 for (d = TURN+2; d <= seq_length; d++) { /* i,j in [1..seq_length] */
1021 #pragma omp parallel for private(i, j, ij, cnt1, cnt2, cnt3, cnt4)
1023 for (j = d; j <= seq_length; j++) {
1024 unsigned int k,l, kl, u, ii, dij;
1025 int no_close, type, type_2, tt, da, db, base_da, base_db;
1026 FLT_OR_DBL temp2, aux_en;
1034 no_close = (((type==3)||(type==4))&&no_closingGU);
1036 if (type) { /* we have a pair */
1038 int k_min_b, k_max_b, l_min_b, l_max_b;
1039 int k_min_post_b, k_max_post_b, *l_min_post_b, *l_max_post_b;
1044 k_min_b = l_min_b = 0;
1045 k_max_b = mm1[ij] + referenceBPs1[ij];
1046 l_max_b = mm2[ij] + referenceBPs2[ij];
1048 prepareBoundaries(k_min_b,
1053 &vars->k_min_values_b[ij],
1054 &vars->k_max_values_b[ij],
1055 &vars->l_min_values_b[ij],
1056 &vars->l_max_values_b[ij]
1058 preparePosteriorBoundaries( vars->k_max_values_b[ij] - vars->k_min_values_b[ij] + 1,
1059 vars->k_min_values_b[ij],
1066 prepareArray( &vars->Q_B[ij],
1067 vars->k_min_values_b[ij],
1068 vars->k_max_values_b[ij],
1069 vars->l_min_values_b[ij],
1070 vars->l_max_values_b[ij]
1075 /* hairpin ----------------------------------------------*/
1077 /* get distance to reference if closing the hairpin
1078 * d1a = dbp(T1_{i,j}, {i,j})
1080 base_da = ((unsigned int)reference_pt1[i] != j) ? 1 : -1;
1081 base_db = ((unsigned int)reference_pt2[i] != j) ? 1 : -1;
1083 da = base_da + referenceBPs1[ij];
1084 db = base_db + referenceBPs2[ij];
1087 if((da >= 0) && (db >= 0)){
1088 if(((unsigned int)da<=maxD1) && ((unsigned int)db <= maxD2)){
1089 vars->Q_B[ij][da][db/2] = exp_E_Hairpin(dij, type, S1[i+1], S1[j-1], sequence+i-1, pf_params) * scale[dij+2];
1091 updatePosteriorBoundaries( da,
1101 vars->Q_B_rem[ij] = exp_E_Hairpin(dij, type, S1[i+1], S1[j-1], sequence+i-1, pf_params) * scale[dij+2];
1104 /*--------------------------------------------------------
1105 check for elementary structures involving more than one
1107 --------------------------------------------------------*/
1108 for (k = i+1; k <= MIN2(j-2-TURN,i+MAXLOOP+1) ; k++) {
1109 unsigned int minl, ln_pre;
1110 minl = k + TURN + 1;
1112 if(ln_pre > minl + MAXLOOP) minl = ln_pre - MAXLOOP - 1;
1113 for (l = minl; l < j; l++) {
1114 kl = my_iindx[k] - l;
1117 if (type_2==0) continue;
1118 type_2 = rtype[type_2];
1119 aux_en = exp_E_IntLoop(k-i-1, j-l-1, type, type_2, S1[i+1], S1[j-1], S1[k-1], S1[l+1], pf_params) * scale[k-i+j-l];
1121 /* get distance to reference if closing the interior loop
1122 * d2 = dbp(S_{i,j}, S_{k,l} + {i,j})
1124 da = base_da + referenceBPs1[ij] - referenceBPs1[kl];
1125 db = base_db + referenceBPs2[ij] - referenceBPs2[kl];
1127 if(vars->Q_B_rem[kl]){
1128 vars->Q_B_rem[ij] += vars->Q_B_rem[kl] * aux_en;
1130 if(!vars->Q_B[kl]) continue;
1131 for(cnt1 = vars->k_min_values_b[kl];
1132 cnt1 <= vars->k_max_values_b[kl];
1134 for(cnt2 = vars->l_min_values_b[kl][cnt1];
1135 cnt2 <= vars->l_max_values_b[kl][cnt1];
1137 if(((cnt1 + da) <= maxD1) && ((cnt2 + db) <= maxD2)){
1138 vars->Q_B[ij][cnt1 + da][(cnt2 + db)/2] += vars->Q_B[kl][cnt1][cnt2/2] * aux_en;
1140 updatePosteriorBoundaries( da + cnt1,
1150 vars->Q_B_rem[ij] += vars->Q_B[kl][cnt1][cnt2/2] * aux_en;
1157 /* multi-loop contribution ------------------------*/
1159 for(u=i+TURN+2; u<j-TURN-2;u++){
1161 temp2 = pf_params->expMLclosing * exp_E_MLstem(tt, S1[j-1], S1[i+1], pf_params) * scale[2];
1163 if(vars->Q_M_rem[my_iindx[i+1]-u]){
1164 if(vars->Q_M1[jindx[j-1]+u+1])
1165 for(cnt1 = vars->k_min_values_m1[jindx[j-1]+u+1];
1166 cnt1 <= vars->k_max_values_m1[jindx[j-1]+u+1];
1168 for(cnt2 = vars->l_min_values_m1[jindx[j-1]+u+1][cnt1];
1169 cnt2 <= vars->l_max_values_m1[jindx[j-1]+u+1][cnt1];
1171 vars->Q_B_rem[ij] += vars->Q_M_rem[my_iindx[i+1]-u] * vars->Q_M1[jindx[j-1]+u+1][cnt1][cnt2/2] * temp2;
1173 if(vars->Q_M1_rem[jindx[j-1]+u+1])
1174 vars->Q_B_rem[ij] += vars->Q_M_rem[my_iindx[i+1]-u] * vars->Q_M1_rem[jindx[j-1]+u+1] * temp2;
1176 if(vars->Q_M1_rem[jindx[j-1]+u+1]){
1177 if(vars->Q_M[my_iindx[i+1]-u])
1178 for(cnt1 = vars->k_min_values_m[my_iindx[i+1]-u];
1179 cnt1 <= vars->k_max_values_m[my_iindx[i+1]-u];
1181 for(cnt2 = vars->l_min_values_m[my_iindx[i+1]-u][cnt1];
1182 cnt2 <= vars->l_max_values_m[my_iindx[i+1]-u][cnt1];
1184 vars->Q_B_rem[ij] += vars->Q_M[my_iindx[i+1]-u][cnt1][cnt2/2] * vars->Q_M1_rem[jindx[j-1]+u+1] * temp2;
1187 /* get distance to reference if closing the multiloop
1188 * dist3 = dbp(S_{i,j}, {i,j} + S_{i+1,u} + S_{u+1,j-1})
1190 da = base_da + referenceBPs1[ij] - referenceBPs1[my_iindx[i+1]-u] - referenceBPs1[my_iindx[u+1]-j+1];
1191 db = base_db + referenceBPs2[ij] - referenceBPs2[my_iindx[i+1]-u] - referenceBPs2[my_iindx[u+1]-j+1];
1193 if(!vars->Q_M[my_iindx[i+1]-u]) continue;
1194 if(!vars->Q_M1[jindx[j-1]+u+1]) continue;
1195 for(cnt1 = vars->k_min_values_m[my_iindx[i+1]-u];
1196 cnt1 <= vars->k_max_values_m[my_iindx[i+1]-u];
1198 for(cnt2 = vars->l_min_values_m[my_iindx[i+1]-u][cnt1];
1199 cnt2 <= vars->l_max_values_m[my_iindx[i+1]-u][cnt1];
1201 for(cnt3 = vars->k_min_values_m1[jindx[j-1]+u+1];
1202 cnt3 <= vars->k_max_values_m1[jindx[j-1]+u+1];
1204 for(cnt4 = vars->l_min_values_m1[jindx[j-1]+u+1][cnt3];
1205 cnt4 <= vars->l_max_values_m1[jindx[j-1]+u+1][cnt3];
1207 if(((cnt1 + cnt3 + da) <= maxD1) && ((cnt2 + cnt4 + db) <= maxD2)){
1208 vars->Q_B[ij][cnt1 + cnt3 + da][(cnt2 + cnt4 + db)/2] += vars->Q_M[my_iindx[i+1]-u][cnt1][cnt2/2]
1209 * vars->Q_M1[jindx[j-1]+u+1][cnt3][cnt4/2]
1212 updatePosteriorBoundaries( cnt1 + cnt3 + da,
1222 vars->Q_B_rem[ij] += vars->Q_M[my_iindx[i+1]-u][cnt1][cnt2/2]
1223 * vars->Q_M1[jindx[j-1]+u+1][cnt3][cnt4/2]
1234 adjustArrayBoundaries(&vars->Q_B[ij],
1235 &vars->k_min_values_b[ij],
1236 &vars->k_max_values_b[ij],
1237 &vars->l_min_values_b[ij],
1238 &vars->l_max_values_b[ij],
1245 } /* end >> if (pair) << */
1247 /* free ends ? -----------------------------------------*/
1249 int k_min_m, k_max_m, l_min_m, l_max_m;
1250 int k_min_post_m, k_max_post_m, *l_min_post_m, *l_max_post_m;
1252 int k_min_m1, k_max_m1, l_min_m1, l_max_m1;
1253 int k_min_post_m1, k_max_post_m1, *l_min_post_m1, *l_max_post_m1;
1258 k_min_m = l_min_m = 0;
1259 k_max_m = mm1[ij] + referenceBPs1[ij];
1260 l_max_m = mm2[ij] + referenceBPs2[ij];
1262 prepareBoundaries(k_min_m,
1267 &vars->k_min_values_m[ij],
1268 &vars->k_max_values_m[ij],
1269 &vars->l_min_values_m[ij],
1270 &vars->l_max_values_m[ij]
1272 preparePosteriorBoundaries( vars->k_max_values_m[ij] - vars->k_min_values_m[ij] + 1,
1273 vars->k_min_values_m[ij],
1280 prepareArray( &vars->Q_M[ij],
1281 vars->k_min_values_m[ij],
1282 vars->k_max_values_m[ij],
1283 vars->l_min_values_m[ij],
1284 vars->l_max_values_m[ij]
1287 if(!vars->Q_M1[jindx[j]+i]){
1289 k_min_m1 = l_min_m1 = 0;
1290 k_max_m1 = mm1[ij] + referenceBPs1[ij];
1291 l_max_m1 = mm2[ij] + referenceBPs2[ij];
1293 prepareBoundaries(k_min_m1,
1298 &vars->k_min_values_m1[jindx[j]+i],
1299 &vars->k_max_values_m1[jindx[j]+i],
1300 &vars->l_min_values_m1[jindx[j]+i],
1301 &vars->l_max_values_m1[jindx[j]+i]
1303 preparePosteriorBoundaries( vars->k_max_values_m1[jindx[j]+i] - vars->k_min_values_m1[jindx[j]+i] + 1,
1304 vars->k_min_values_m1[jindx[j]+i],
1311 prepareArray( &vars->Q_M1[jindx[j]+i],
1312 vars->k_min_values_m1[jindx[j]+i],
1313 vars->k_max_values_m1[jindx[j]+i],
1314 vars->l_min_values_m1[jindx[j]+i],
1315 vars->l_max_values_m1[jindx[j]+i]
1321 da = referenceBPs1[ij] - referenceBPs1[ij+1];
1322 db = referenceBPs2[ij] - referenceBPs2[ij+1];
1324 if(vars->Q_M_rem[ij+1])
1325 vars->Q_M_rem[ij] += vars->Q_M_rem[ij+1] * pf_params->expMLbase * scale[1];
1328 for(cnt1 = vars->k_min_values_m[ij+1];
1329 cnt1 <= vars->k_max_values_m[ij+1];
1331 for(cnt2 = vars->l_min_values_m[ij+1][cnt1];
1332 cnt2 <= vars->l_max_values_m[ij+1][cnt1];
1334 if(((cnt1 + da) <= maxD1) && ((cnt2 + db) <= maxD2)){
1335 vars->Q_M[ij][cnt1 + da][(cnt2 + db)/2] += vars->Q_M[ij+1][cnt1][cnt2/2] * pf_params->expMLbase * scale[1];
1337 updatePosteriorBoundaries(cnt1 + da,
1347 vars->Q_M_rem[ij] += vars->Q_M[ij+1][cnt1][cnt2/2] * pf_params->expMLbase * scale[1];
1352 if(vars->Q_M1_rem[jindx[j-1]+i])
1353 vars->Q_M1_rem[jindx[j]+i] += vars->Q_M1_rem[jindx[j-1]+i] * pf_params->expMLbase * scale[1];
1355 if(vars->Q_M1[jindx[j-1]+i])
1356 for(cnt1 = vars->k_min_values_m1[jindx[j-1]+i];
1357 cnt1 <= vars->k_max_values_m1[jindx[j-1]+i];
1359 for(cnt2 = vars->l_min_values_m1[jindx[j-1]+i][cnt1];
1360 cnt2 <= vars->l_max_values_m1[jindx[j-1]+i][cnt1];
1362 if(((cnt1 + da) <= maxD1) && ((cnt2 + db) <= maxD2)){
1363 vars->Q_M1[jindx[j]+i][cnt1 + da][(cnt2 + db)/2] += vars->Q_M1[jindx[j-1]+i][cnt1][cnt2/2] * pf_params->expMLbase * scale[1];
1365 updatePosteriorBoundaries(cnt1 + da,
1375 vars->Q_M1_rem[jindx[j]+i] += vars->Q_M1[jindx[j-1]+i][cnt1][cnt2/2] * pf_params->expMLbase * scale[1];
1380 /* j pairs with i */
1381 if((!no_close) && type){
1382 FLT_OR_DBL aux_en = exp_E_MLstem(type, (i>1) || circ ? S1[i-1] : -1, (j<seq_length) || circ ? S1[j+1] : -1, pf_params);
1384 if(vars->Q_B_rem[ij]){
1385 vars->Q_M_rem[ij] += vars->Q_B_rem[ij] * aux_en;
1386 vars->Q_M1_rem[jindx[j]+i] += vars->Q_B_rem[ij] * aux_en;
1390 for(cnt1 = vars->k_min_values_b[ij];
1391 cnt1 <= vars->k_max_values_b[ij];
1393 for(cnt2 = vars->l_min_values_b[ij][cnt1];
1394 cnt2 <= vars->l_max_values_b[ij][cnt1];
1396 vars->Q_M[ij][cnt1][cnt2/2] += vars->Q_B[ij][cnt1][cnt2/2] * aux_en;
1398 updatePosteriorBoundaries(cnt1,
1406 vars->Q_M1[jindx[j]+i][cnt1][cnt2/2] += vars->Q_B[ij][cnt1][cnt2/2] * aux_en;
1408 updatePosteriorBoundaries(cnt1,
1420 /* j pairs with k: i<k<j */
1422 for (k=i+1; k<=j; k++){
1423 tt = ptype[my_iindx[k]-j];
1424 temp2 = exp_E_MLstem(tt, S1[k-1], (j<seq_length) || circ ? S1[j+1] : -1, pf_params);
1426 if(vars->Q_B_rem[my_iindx[k]-j]){
1427 vars->Q_M_rem[ij] += vars->Q_B_rem[my_iindx[k]-j] * pow(pf_params->expMLbase, (double)(k-i)) * scale[k-i] * temp2;
1428 if(vars->Q_M[ii-k+1])
1429 for(cnt1 = vars->k_min_values_m[ii-k+1];
1430 cnt1 <= vars->k_max_values_m[ii-k+1];
1432 for(cnt2 = vars->l_min_values_m[ii-k+1][cnt1];
1433 cnt2 <= vars->l_max_values_m[ii-k+1][cnt1];
1435 vars->Q_M_rem[ij] += vars->Q_M[ii-k+1][cnt1][cnt2/2] * vars->Q_B_rem[my_iindx[k]-j] * temp2;
1437 if(vars->Q_M_rem[ii-k+1])
1438 vars->Q_M_rem[ij] += vars->Q_M_rem[ii-k+1] * vars->Q_B_rem[my_iindx[k]-j] * temp2;
1440 if(vars->Q_M_rem[ii-k+1]){
1441 if(vars->Q_B[my_iindx[k]-j])
1442 for(cnt1 = vars->k_min_values_b[my_iindx[k]-j];
1443 cnt1 <= vars->k_max_values_b[my_iindx[k]-j];
1445 for(cnt2 = vars->l_min_values_b[my_iindx[k]-j][cnt1];
1446 cnt2 <= vars->l_max_values_b[my_iindx[k]-j][cnt1];
1448 vars->Q_M_rem[ij] += vars->Q_M_rem[my_iindx[k]-j] * vars->Q_B[my_iindx[k]-j][cnt1][cnt2/2] * temp2;
1451 /* add contributions of QM(i,k-1)*QB(k,j)*e^b and
1452 * e^((k-i) * c) * QB(k,j) * e^b
1453 * therefor we need d1a = dbp(T1_{i,j}, T1_{i,k-1} + T1_{k,j}),
1454 * d1b = dbp(T2_{i,j}, T2_{i,k-1} + T2_{k,j})
1455 * d1c = dbp(T1_{i,j}, T1_{k,j})circ = 0;
1456 * d1d = dbp(T2_{i,j}, T2_{k,j})
1458 da = referenceBPs1[ij] - referenceBPs1[my_iindx[k]-j];
1459 db = referenceBPs2[ij] - referenceBPs2[my_iindx[k]-j];
1461 if(!vars->Q_B[my_iindx[k]-j]) continue;
1462 for(cnt1 = vars->k_min_values_b[my_iindx[k]-j];
1463 cnt1 <= vars->k_max_values_b[my_iindx[k]-j];
1465 for(cnt2 = vars->l_min_values_b[my_iindx[k]-j][cnt1];
1466 cnt2 <= vars->l_max_values_b[my_iindx[k]-j][cnt1];
1468 if(((cnt1 + da) <= maxD1) && ((cnt2 + db) <= maxD2)){
1469 vars->Q_M[ij][cnt1 + da][(cnt2 + db)/2] += vars->Q_B[my_iindx[k]-j][cnt1][cnt2/2] * pow(pf_params->expMLbase, (double)(k-i)) * scale[k-i] * temp2;
1471 updatePosteriorBoundaries(cnt1 + da,
1481 vars->Q_M_rem[ij] += vars->Q_B[my_iindx[k]-j][cnt1][cnt2/2] * pow(pf_params->expMLbase, (double)(k-i)) * scale[k-i] * temp2;
1485 if(!vars->Q_M[ii-k+1]) continue;
1486 da -= referenceBPs1[ii-k+1];
1487 db -= referenceBPs2[ii-k+1];
1489 for(cnt1 = vars->k_min_values_m[ii-k+1];
1490 cnt1 <= vars->k_max_values_m[ii-k+1];
1492 for(cnt2 = vars->l_min_values_m[ii-k+1][cnt1];
1493 cnt2 <= vars->l_max_values_m[ii-k+1][cnt1];
1495 for(cnt3 = vars->k_min_values_b[my_iindx[k]-j];
1496 cnt3 <= vars->k_max_values_b[my_iindx[k]-j];
1498 for(cnt4 = vars->l_min_values_b[my_iindx[k]-j][cnt3];
1499 cnt4 <= vars->l_max_values_b[my_iindx[k]-j][cnt3];
1501 if(((cnt1 + cnt3 + da) <= maxD1) && ((cnt2 + cnt4 + db) <= maxD2)){
1502 vars->Q_M[ij][cnt1 + cnt3 + da][(cnt2 + cnt4 + db)/2] += vars->Q_M[ii-k+1][cnt1][cnt2/2] * vars->Q_B[my_iindx[k]-j][cnt3][cnt4/2] * temp2;
1504 updatePosteriorBoundaries(cnt1 + cnt3 + da,
1514 vars->Q_M_rem[ij] += vars->Q_M[ii-k+1][cnt1][cnt2/2] * vars->Q_B[my_iindx[k]-j][cnt3][cnt4/2] * temp2;
1520 adjustArrayBoundaries(&vars->Q_M[ij],
1521 &vars->k_min_values_m[ij],
1522 &vars->k_max_values_m[ij],
1523 &vars->l_min_values_m[ij],
1524 &vars->l_max_values_m[ij],
1532 adjustArrayBoundaries(&vars->Q_M1[jindx[j]+i],
1533 &vars->k_min_values_m1[jindx[j]+i],
1534 &vars->k_max_values_m1[jindx[j]+i],
1535 &vars->l_min_values_m1[jindx[j]+i],
1536 &vars->l_max_values_m1[jindx[j]+i],
1544 /* compute contributions for Q(i,j) */
1545 int k_min, k_max, l_min, l_max;
1546 int k_min_post, k_max_post, *l_min_post, *l_max_post;
1551 k_max = mm1[ij] + referenceBPs1[ij];
1552 l_max = mm2[ij] + referenceBPs2[ij];
1554 prepareBoundaries(k_min,
1559 &vars->k_min_values[ij],
1560 &vars->k_max_values[ij],
1561 &vars->l_min_values[ij],
1562 &vars->l_max_values[ij]
1564 preparePosteriorBoundaries( vars->k_max_values[ij] - vars->k_min_values[ij] + 1,
1565 vars->k_min_values[ij],
1572 prepareArray( &vars->Q[ij],
1573 vars->k_min_values[ij],
1574 vars->k_max_values[ij],
1575 vars->l_min_values[ij],
1576 vars->l_max_values[ij]
1581 aux_en = exp_E_ExtLoop(type, (i>1) || circ ? S1[i-1] : -1, (j < seq_length) || circ ? S1[j+1] : -1, pf_params);
1583 if(vars->Q_B_rem[ij])
1584 vars->Q_rem[ij] += vars->Q_B_rem[ij] * aux_en;
1587 for(cnt1 = vars->k_min_values_b[ij];
1588 cnt1 <= vars->k_max_values_b[ij];
1590 for(cnt2 = vars->l_min_values_b[ij][cnt1];
1591 cnt2 <= vars->l_max_values_b[ij][cnt1];
1593 vars->Q[ij][cnt1][cnt2/2] += vars->Q_B[ij][cnt1][cnt2/2] * aux_en;
1595 updatePosteriorBoundaries(cnt1,
1607 if(vars->Q_rem[ij+1])
1608 vars->Q_rem[ij] += vars->Q_rem[ij+1] * scale[1];
1610 /* da = dbp(T1_{i,j}, T1_{i,j-1})
1611 * db = dbp(T2_{i,j}, T2_{i,j-1})
1613 da = referenceBPs1[ij] - referenceBPs1[ij+1];
1614 db = referenceBPs2[ij] - referenceBPs2[ij+1];
1616 for(cnt1 = vars->k_min_values[ij+1];
1617 cnt1 <= vars->k_max_values[ij+1];
1619 for(cnt2 = vars->l_min_values[ij+1][cnt1];
1620 cnt2 <= vars->l_max_values[ij+1][cnt1];
1622 if(((cnt1 + da) <= maxD1) && ((cnt2 + db) <= maxD2)){
1623 vars->Q[ij][cnt1 + da][(cnt2 + db)/2] += vars->Q[ij+1][cnt1][cnt2/2] * scale[1];
1625 updatePosteriorBoundaries(cnt1 + da,
1635 vars->Q_rem[ij] += vars->Q[ij+1][cnt1][cnt2/2] * scale[1];
1639 for(k=j-TURN-1; k>i; k--){
1640 tt = ptype[my_iindx[k]-j];
1641 temp2 = exp_E_ExtLoop(tt, S1[k-1], (j<seq_length) || circ ? S1[j+1] : -1, pf_params);
1643 if(vars->Q_rem[my_iindx[i]-k+1]){
1644 if(vars->Q_B[my_iindx[k]-j])
1645 for(cnt1 = vars->k_min_values_b[my_iindx[k]-j];
1646 cnt1 <= vars->k_max_values_b[my_iindx[k]-j];
1648 for(cnt2 = vars->l_min_values_b[my_iindx[k]-j][cnt1];
1649 cnt2 <= vars->l_max_values_b[my_iindx[k]-j][cnt1];
1651 vars->Q_rem[ij] += vars->Q_rem[my_iindx[i]-k+1] * vars->Q_B[my_iindx[k]-j][cnt1][cnt2/2] * temp2;
1652 if(vars->Q_B_rem[my_iindx[k]-j])
1653 vars->Q_rem[ij] += vars->Q_rem[my_iindx[i]-k+1] * vars->Q_B_rem[my_iindx[k]-j] * temp2;
1655 if(vars->Q_B_rem[my_iindx[k]-j]){
1656 if(vars->Q[my_iindx[i]-k+1])
1657 for(cnt1 = vars->k_min_values[my_iindx[i]-k+1];
1658 cnt1 <= vars->k_max_values[my_iindx[i]-k+1];
1660 for(cnt2 = vars->l_min_values[my_iindx[i]-k+1][cnt1];
1661 cnt2 <= vars->l_max_values[my_iindx[i]-k+1][cnt1];
1663 vars->Q_rem[ij] += vars->Q[my_iindx[i]-k+1][cnt1][cnt2/2] * vars->Q_B_rem[my_iindx[k]-j] * temp2;
1666 /* da = dbp{T1_{i,j}, T1_{k,j}
1667 * db = dbp{T2_{i,j}, T2_{k,j}}
1669 da = referenceBPs1[ij] - referenceBPs1[my_iindx[k] - j] - referenceBPs1[my_iindx[i]-k+1];
1670 db = referenceBPs2[ij] - referenceBPs2[my_iindx[k] - j] - referenceBPs2[my_iindx[i]-k+1];
1673 if(!vars->Q[my_iindx[i]-k+1]) continue;
1674 if(!vars->Q_B[my_iindx[k]-j]) continue;
1675 for(cnt1 = vars->k_min_values[my_iindx[i]-k+1];
1676 cnt1 <= vars->k_max_values[my_iindx[i]-k+1];
1678 for(cnt2 = vars->l_min_values[my_iindx[i]-k+1][cnt1];
1679 cnt2 <= vars->l_max_values[my_iindx[i]-k+1][cnt1];
1681 for(cnt3 = vars->k_min_values_b[my_iindx[k]-j];
1682 cnt3 <= vars->k_max_values_b[my_iindx[k]-j];
1684 for(cnt4 = vars->l_min_values_b[my_iindx[k]-j][cnt3];
1685 cnt4 <= vars->l_max_values_b[my_iindx[k]-j][cnt3];
1687 if(((cnt1 + cnt3 + da) <= maxD1) && ((cnt2 + cnt4 + db) <= maxD2)){
1688 vars->Q[ij][cnt1 + cnt3 + da][(cnt2 + cnt4 + db)/2] += vars->Q[my_iindx[i]-k+1][cnt1][cnt2/2] * vars->Q_B[my_iindx[k]-j][cnt3][cnt4/2] * temp2;
1690 updatePosteriorBoundaries(cnt1 + cnt3 + da,
1700 vars->Q_rem[ij] += vars->Q[my_iindx[i]-k+1][cnt1][cnt2/2] * vars->Q_B[my_iindx[k]-j][cnt3][cnt4/2] * temp2;
1706 adjustArrayBoundaries(&vars->Q[ij],
1707 &vars->k_min_values[ij],
1708 &vars->k_max_values[ij],
1709 &vars->l_min_values[ij],
1710 &vars->l_max_values[ij],
1718 for(cnt1 = vars->k_min_values[ij];
1719 cnt1 <= vars->k_max_values[ij];
1721 for(cnt2 = vars->l_min_values[ij][cnt1];
1722 cnt2 <= vars->l_max_values[ij][cnt1];
1724 if(vars->Q[ij][cnt1][cnt2/2] > Qmax) {
1725 Qmax = vars->Q[ij][cnt1][cnt2/2];
1726 if (Qmax > max_real/10.)
1727 fprintf(stderr, "Q close to overflow: %u %u %g\n", i,j,vars->Q[ij][cnt1][cnt2/2]);
1729 if(vars->Q[ij][cnt1][cnt2/2] >= max_real) {
1730 PRIVATE char msg[128];
1731 sprintf(msg, "overflow in pf_fold while calculating q[%u,%u]\n"
1732 "use larger pf_scale", i,j);
1740 } /* end of j-loop */
1744 /* calculate partition function for circular case */
1745 /* NOTE: this is the postprocessing step ONLY */
1746 /* You have to call pf2D_linear first to calculate */
1747 /* complete circular case!!! */
1748 PRIVATE void pf2D_circ(TwoDpfold_vars *vars){
1750 unsigned int d, p, q, pq, k, l, kl, u, da, db, seq_length, maxD1, maxD2, base_d1, base_d2, *mm1, *mm2, *bpdist;
1751 int *my_iindx, *jindx, type, cnt1, cnt2, cnt3, cnt4;
1753 unsigned int *referenceBPs1, *referenceBPs2;
1754 char *sequence, *ptype;
1756 pf_paramT *pf_params; /* holds all [unscaled] pf parameters */
1758 pf_params = vars->pf_params;
1759 sequence = vars->sequence;
1760 seq_length = vars->seq_length;
1761 maxD1 = vars->maxD1;
1762 maxD2 = vars->maxD2;
1764 ptype = vars->ptype;
1765 scale = vars->scale;
1766 my_iindx = vars->my_iindx;
1767 jindx = vars->jindx;
1768 referenceBPs1 = vars->referenceBPs1;
1769 referenceBPs2 = vars->referenceBPs2;
1770 dangles = vars->dangles;
1773 bpdist = vars->bpdist;
1775 FLT_OR_DBL ***Q_B, ***Q_M, ***Q_M1;
1776 FLT_OR_DBL *Q_B_rem, *Q_M_rem, *Q_M1_rem;
1777 int **l_min_values_b, **l_max_values_b, **l_min_values_m, **l_max_values_m, **l_min_values_m1, **l_max_values_m1;
1778 int *k_min_values_b, *k_max_values_b,*k_min_values_m, *k_max_values_m,*k_min_values_m1, *k_max_values_m1;
1781 l_min_values_b = vars->l_min_values_b;
1782 l_max_values_b = vars->l_max_values_b;
1783 k_min_values_b = vars->k_min_values_b;
1784 k_max_values_b = vars->k_max_values_b;
1787 l_min_values_m = vars->l_min_values_m;
1788 l_max_values_m = vars->l_max_values_m;
1789 k_min_values_m = vars->k_min_values_m;
1790 k_max_values_m = vars->k_max_values_m;
1793 l_min_values_m1 = vars->l_min_values_m1;
1794 l_max_values_m1 = vars->l_max_values_m1;
1795 k_min_values_m1 = vars->k_min_values_m1;
1796 k_max_values_m1 = vars->k_max_values_m1;
1799 Q_B_rem = vars->Q_B_rem;
1800 Q_M_rem = vars->Q_M_rem;
1801 Q_M1_rem = vars->Q_M1_rem;
1804 vars->Q_cH_rem = 0.;
1805 vars->Q_cI_rem = 0.;
1806 vars->Q_cM_rem = 0.;
1809 /* construct qm2 matrix from qm1 entries */
1811 #pragma omp parallel for private(d, k, l, da, db, cnt1, cnt2, cnt3, cnt4)
1813 for(k=1; k<seq_length-TURN-1; k++){
1814 int k_min_m2, k_max_m2, l_min_m2, l_max_m2;
1815 int k_min_post_m2, k_max_post_m2, *l_min_post_m2, *l_max_post_m2;
1819 k_min_m2 = l_min_m2 = 0;
1820 k_max_m2 = mm1[my_iindx[k]-seq_length] + referenceBPs1[my_iindx[k] - seq_length];
1821 l_max_m2 = mm2[my_iindx[k]-seq_length] + referenceBPs2[my_iindx[k] - seq_length];
1823 prepareBoundaries(k_min_m2,
1827 bpdist[my_iindx[k]-seq_length],
1828 &vars->k_min_values_m2[k],
1829 &vars->k_max_values_m2[k],
1830 &vars->l_min_values_m2[k],
1831 &vars->l_max_values_m2[k]
1833 preparePosteriorBoundaries( vars->k_max_values_m2[k] - vars->k_min_values_m2[k] + 1,
1834 vars->k_min_values_m2[k],
1841 prepareArray( &vars->Q_M2[k],
1842 vars->k_min_values_m2[k],
1843 vars->k_max_values_m2[k],
1844 vars->l_min_values_m2[k],
1845 vars->l_max_values_m2[k]
1849 /* construct Q_M2 */
1850 for (l=k+TURN+1; l<seq_length-TURN-1; l++){
1851 if(Q_M1_rem[jindx[l]+k]){
1852 if(Q_M1[jindx[seq_length]+l+1]){
1853 for(cnt1 = k_min_values_m1[jindx[seq_length]+l+1];
1854 cnt1 <= k_max_values_m1[jindx[seq_length]+l+1];
1856 for(cnt2 = l_min_values_m1[jindx[seq_length]+l+1][cnt1];
1857 cnt2 <= l_max_values_m1[jindx[seq_length]+l+1][cnt1];
1859 vars->Q_M2_rem[k] += Q_M1_rem[jindx[l]+k] * Q_M1[jindx[seq_length]+l+1][cnt1][cnt2/2];
1861 if(Q_M1_rem[jindx[seq_length]+l+1])
1862 vars->Q_M2_rem[k] += Q_M1_rem[jindx[l]+k] * Q_M1_rem[jindx[seq_length]+l+1];
1864 if(Q_M1_rem[jindx[seq_length]+l+1]){
1865 if(Q_M1[jindx[l]+k])
1866 for(cnt1 = k_min_values_m1[jindx[l]+k];
1867 cnt1 <= k_max_values_m1[jindx[l]+k];
1869 for(cnt2 = l_min_values_m1[jindx[l]+k][cnt1];
1870 cnt2 <= l_max_values_m1[jindx[l]+k][cnt1];
1872 vars->Q_M2_rem[k] += Q_M1[jindx[l]+k][cnt1][cnt2/2]*Q_M1_rem[jindx[seq_length]+l+1];
1876 if(vars->Q_M1[jindx[l]+k] && vars->Q_M1[jindx[seq_length] + l + 1]){
1877 da = referenceBPs1[my_iindx[k]-seq_length] - referenceBPs1[my_iindx[k]-l] - referenceBPs1[my_iindx[l+1]-seq_length];
1878 db = referenceBPs2[my_iindx[k]-seq_length] - referenceBPs2[my_iindx[k]-l] - referenceBPs2[my_iindx[l+1]-seq_length];
1879 for(cnt1 = k_min_values_m1[jindx[l]+k]; cnt1 <= k_max_values_m1[jindx[l]+k]; cnt1++)
1880 for(cnt2 = l_min_values_m1[jindx[l]+k][cnt1]; cnt2 <= l_max_values_m1[jindx[l]+k][cnt1]; cnt2+=2){
1881 for(cnt3 = k_min_values_m1[jindx[seq_length] + l + 1]; cnt3 <= k_max_values_m1[jindx[seq_length] + l + 1]; cnt3++)
1882 for(cnt4 = l_min_values_m1[jindx[seq_length] + l + 1][cnt3]; cnt4 <= l_max_values_m1[jindx[seq_length] + l + 1][cnt3]; cnt4+=2){
1883 if(((cnt1 + cnt3 + da) <= maxD1) && ((cnt2 + cnt4 + db) <= maxD2)){
1884 vars->Q_M2[k][cnt1 + cnt3 + da][(cnt2 + cnt4 + db)/2] += Q_M1[jindx[l]+k][cnt1][cnt2/2] * Q_M1[jindx[seq_length] + l + 1][cnt3][cnt4/2];
1886 updatePosteriorBoundaries(cnt1 + cnt3 + da,
1896 vars->Q_M2_rem[k] += Q_M1[jindx[l]+k][cnt1][cnt2/2] * Q_M1[jindx[seq_length] + l + 1][cnt3][cnt4/2];
1903 adjustArrayBoundaries(&vars->Q_M2[k],
1904 &vars->k_min_values_m2[k],
1905 &vars->k_max_values_m2[k],
1906 &vars->l_min_values_m2[k],
1907 &vars->l_max_values_m2[k],
1916 base_d1 = referenceBPs1[my_iindx[1]-seq_length];
1917 base_d2 = referenceBPs2[my_iindx[1]-seq_length];
1919 int min_k, max_k, max_l, min_l;
1920 int min_k_real, max_k_real, min_k_real_qcH, max_k_real_qcH, min_k_real_qcI, max_k_real_qcI, min_k_real_qcM, max_k_real_qcM;
1921 int *min_l_real, *max_l_real, *min_l_real_qcH, *max_l_real_qcH, *min_l_real_qcI, *max_l_real_qcI,*min_l_real_qcM, *max_l_real_qcM;
1922 int update_c, update_cH, update_cI, update_cM;
1924 update_c = update_cH = update_cI, update_cM = 0;
1928 max_k = mm1[my_iindx[1] - seq_length] + referenceBPs1[my_iindx[1] - seq_length];
1929 max_l = mm2[my_iindx[1] - seq_length] + referenceBPs2[my_iindx[1] - seq_length];
1932 #pragma omp sections
1940 prepareBoundaries(min_k,
1944 bpdist[my_iindx[1] - seq_length],
1945 &vars->k_min_values_qc,
1946 &vars->k_max_values_qc,
1947 &vars->l_min_values_qc,
1948 &vars->l_max_values_qc
1950 prepareArray( &vars->Q_c,
1951 vars->k_min_values_qc,
1952 vars->k_max_values_qc,
1953 vars->l_min_values_qc,
1954 vars->l_max_values_qc
1956 preparePosteriorBoundaries( max_k - min_k + 1,
1971 prepareBoundaries(min_k,
1975 bpdist[my_iindx[1] - seq_length],
1976 &vars->k_min_values_qcH,
1977 &vars->k_max_values_qcH,
1978 &vars->l_min_values_qcH,
1979 &vars->l_max_values_qcH
1981 prepareArray( &vars->Q_cH,
1982 vars->k_min_values_qcH,
1983 vars->k_max_values_qcH,
1984 vars->l_min_values_qcH,
1985 vars->l_max_values_qcH
1987 preparePosteriorBoundaries( max_k - min_k + 1,
2002 prepareBoundaries(min_k,
2006 bpdist[my_iindx[1] - seq_length],
2007 &vars->k_min_values_qcI,
2008 &vars->k_max_values_qcI,
2009 &vars->l_min_values_qcI,
2010 &vars->l_max_values_qcI
2012 prepareArray( &vars->Q_cI,
2013 vars->k_min_values_qcI,
2014 vars->k_max_values_qcI,
2015 vars->l_min_values_qcI,
2016 vars->l_max_values_qcI
2018 preparePosteriorBoundaries( max_k - min_k + 1,
2033 prepareBoundaries(min_k,
2037 bpdist[my_iindx[1] - seq_length],
2038 &vars->k_min_values_qcM,
2039 &vars->k_max_values_qcM,
2040 &vars->l_min_values_qcM,
2041 &vars->l_max_values_qcM
2043 prepareArray( &vars->Q_cM,
2044 vars->k_min_values_qcM,
2045 vars->k_max_values_qcM,
2046 vars->l_min_values_qcM,
2047 vars->l_max_values_qcM
2049 preparePosteriorBoundaries( max_k - min_k + 1,
2065 for (d = TURN+2; d <= seq_length; d++) /* i,j in [1..length] */
2067 #pragma omp parallel for private(p, q, pq, k, l, kl, u, da, db, type, cnt1, cnt2, cnt3, cnt4)
2069 for (q = d; q <= seq_length; q++) {
2075 /* 1. get exterior hairpin contribution */
2076 u = seq_length-q + p-1;
2077 if (u<TURN) continue;
2079 if (!type) continue;
2080 if(((type==3)||(type==4))&&no_closingGU) continue;
2082 /* cause we want to calc the exterior loops, we need the reversed pair type from now on */
2086 strcpy(loopseq , sequence+q-1);
2087 strncat(loopseq, sequence, p);
2089 /* get distance to reference if closing the hairpin
2090 * da = dbp(T1_[1,n}, T1_{p,q})
2091 * db = dbp(T2_{1,n}, T2_{p,q})
2093 da = base_d1 - referenceBPs1[pq];
2094 db = base_d2 - referenceBPs2[pq];
2095 qot = exp_E_Hairpin(u, type, S1[q+1], S1[p-1], loopseq, pf_params) * scale[u];
2098 vars->Q_cH_rem += Q_B_rem[pq] * qot;
2101 for(cnt1 = k_min_values_b[pq];
2102 cnt1 <= k_max_values_b[pq];
2104 for(cnt2 = l_min_values_b[pq][cnt1];
2105 cnt2 <= l_max_values_b[pq][cnt1];
2107 if(((cnt1 + da) <= maxD1) && ((cnt2 + db) <= maxD2)){
2108 vars->Q_cH[cnt1 + da][(cnt2 + db)/2] += Q_B[pq][cnt1][cnt2/2] * qot;
2110 updatePosteriorBoundaries(cnt1 + da,
2120 vars->Q_cH_rem += Q_B[pq][cnt1][cnt2/2] * qot;
2125 /* 2. exterior interior loops, i "define" the (k,l) pair as "outer pair" */
2126 /* so "outer type" is rtype[type[k,l]] and inner type is type[p,q] */
2128 for(k=q+1; k < seq_length; k++){
2129 unsigned int ln1, lstart, ln_pre;
2131 if(ln1+p-1>MAXLOOP) break;
2132 lstart = k + TURN + 1;
2133 ln_pre = ln1 + p + seq_length;
2134 if(ln_pre > lstart + MAXLOOP) lstart = ln_pre - MAXLOOP - 1;
2135 for(l=lstart;l <= seq_length; l++){
2139 ln2 = (p - 1) + (seq_length - l);
2141 if((ln1+ln2) > MAXLOOP) continue;
2144 if(!type2) continue;
2146 qot = exp_E_IntLoop(ln2, ln1, rtype[type2], type, S1[l+1], S1[k-1], S1[p-1], S1[q+1], pf_params) * scale[ln1+ln2];
2149 vars->Q_cI_rem += Q_B_rem[pq] * Q_B_rem[kl] * qot;
2152 for(cnt1 = k_min_values_b[kl];
2153 cnt1 <= k_max_values_b[kl];
2155 for(cnt2 = l_min_values_b[kl][cnt1];
2156 cnt2 <= l_max_values_b[kl][cnt1];
2158 vars->Q_cI_rem += Q_B_rem[pq] * Q_B[kl][cnt1][cnt2/2] * qot;
2163 for(k=q+1; k < seq_length; k++){
2164 unsigned int ln1, lstart, ln_pre;
2166 if(ln1+p-1>MAXLOOP) break;
2167 lstart = k + TURN + 1;
2168 ln_pre = ln1 + p + seq_length;
2169 if(ln_pre > lstart + MAXLOOP) lstart = ln_pre - MAXLOOP - 1;
2170 for(l=lstart;l <= seq_length; l++){
2174 ln2 = (p - 1) + (seq_length - l);
2176 if((ln1+ln2) > MAXLOOP) continue;
2179 if(!type2) continue;
2181 qot = exp_E_IntLoop(ln2, ln1, rtype[type2], type, S1[l+1], S1[k-1], S1[p-1], S1[q+1], pf_params) * scale[ln1+ln2];
2184 for(cnt1 = k_min_values_b[pq];
2185 cnt1 <= k_max_values_b[pq];
2187 for(cnt2 = l_min_values_b[pq][cnt1];
2188 cnt2 <= l_max_values_b[pq][cnt1];
2190 vars->Q_cI_rem += Q_B[pq][cnt1][cnt2/2] * Q_B_rem[kl] * qot;
2193 if(!Q_B[kl]) continue;
2195 /* get distance to reference if closing the interior loop
2196 * d2a = dbp(T1_[1,n}, T1_{p,q} + T1_{k,l})
2197 * d2b = dbp(T2_[1,n}, T2_{p,q} + T2_{k,l})
2199 da = base_d1 - referenceBPs1[pq] - referenceBPs1[kl];
2200 db = base_d2 - referenceBPs2[pq] - referenceBPs2[kl];
2202 for(cnt1 = k_min_values_b[pq]; cnt1 <= k_max_values_b[pq]; cnt1++)
2203 for(cnt2 = l_min_values_b[pq][cnt1]; cnt2 <= l_max_values_b[pq][cnt1]; cnt2+=2)
2204 for(cnt3 = k_min_values_b[kl]; cnt3 <= k_max_values_b[kl]; cnt3++)
2205 for(cnt4 = l_min_values_b[kl][cnt3]; cnt4 <= l_max_values_b[kl][cnt3]; cnt4+=2){
2206 if(((cnt1 + cnt3 + da) <= maxD1) && ((cnt2 + cnt4 + db) <= maxD2)){
2207 vars->Q_cI[cnt1 + cnt3 + da][(cnt2 + cnt4 + db)/2] += Q_B[pq][cnt1][cnt2/2] * Q_B[kl][cnt3][cnt4/2] * qot;
2209 updatePosteriorBoundaries(cnt1 + cnt3 + da,
2219 vars->Q_cI_rem += Q_B[pq][cnt1][cnt2/2] * Q_B[kl][cnt3][cnt4/2] * qot;
2227 adjustArrayBoundaries(&vars->Q_cH,
2228 &vars->k_min_values_qcH,
2229 &vars->k_max_values_qcH,
2230 &vars->l_min_values_qcH,
2231 &vars->l_max_values_qcH,
2239 adjustArrayBoundaries(&vars->Q_cI,
2240 &vars->k_min_values_qcI,
2241 &vars->k_max_values_qcI,
2242 &vars->l_min_values_qcI,
2243 &vars->l_max_values_qcI,
2252 if(seq_length > 2*TURN-3)
2254 #pragma omp parallel for private(k, da, db, cnt1, cnt2, cnt3, cnt4)
2256 for(k=TURN+2; k<seq_length-2*TURN-3; k++){
2257 if(Q_M_rem[my_iindx[1]-k]){
2259 for(cnt1 = vars->k_min_values_m2[k+1];
2260 cnt1 <= vars->k_max_values_m2[k+1];
2262 for(cnt2 = vars->l_min_values_m2[k+1][cnt1];
2263 cnt2 <= vars->l_max_values_m2[k+1][cnt1];
2265 vars->Q_cM_rem += Q_M_rem[my_iindx[1]-k] * vars->Q_M2[k+1][cnt1][cnt2/2] * pf_params->expMLclosing;
2266 if(vars->Q_M2_rem[k+1])
2267 vars->Q_cM_rem += Q_M_rem[my_iindx[1]-k] * vars->Q_M2_rem[k+1] * pf_params->expMLclosing;
2269 if(vars->Q_M2_rem[k+1]){
2270 if(Q_M[my_iindx[1]-k])
2271 for(cnt1 = k_min_values_m[my_iindx[1]-k];
2272 cnt1 <= k_max_values_m[my_iindx[1]-k];
2274 for(cnt2 = l_min_values_m[my_iindx[1]-k][cnt1];
2275 cnt2 <= l_max_values_m[my_iindx[1]-k][cnt1];
2277 vars->Q_cM_rem += Q_M[my_iindx[1]-k][cnt1][cnt2/2] * vars->Q_M2_rem[k+1] * pf_params->expMLclosing;
2280 /* get distancies to references
2281 * d3a = dbp(T1_[1,n}, T1_{1,k} + T1_{k+1, n})
2282 * d3b = dbp(T2_[1,n}, T2_{1,k} + T2_{k+1, n})
2284 da = base_d1 - referenceBPs1[my_iindx[1]-k] - referenceBPs1[my_iindx[k+1]-seq_length];
2285 db = base_d2 - referenceBPs2[my_iindx[1]-k] - referenceBPs2[my_iindx[k+1]-seq_length];
2286 if(Q_M[my_iindx[1]-k] && vars->Q_M2[k+1])
2287 for(cnt1 = k_min_values_m[my_iindx[1]-k]; cnt1 <= k_max_values_m[my_iindx[1]-k]; cnt1++)
2288 for(cnt2 = l_min_values_m[my_iindx[1]-k][cnt1]; cnt2 <= l_max_values_m[my_iindx[1]-k][cnt1]; cnt2+=2)
2289 for(cnt3 = vars->k_min_values_m2[k+1]; cnt3 <= vars->k_max_values_m2[k+1]; cnt3++)
2290 for(cnt4 = vars->l_min_values_m2[k+1][cnt3]; cnt4 <= vars->l_max_values_m2[k+1][cnt3]; cnt4+=2){
2291 if(((cnt1 + cnt3 + da) <= maxD1) && ((cnt2 + cnt4 + db) <= maxD2)){
2292 vars->Q_cM[cnt1 + cnt3 + da][(cnt2 + cnt4 + db)/2] += Q_M[my_iindx[1]-k][cnt1][cnt2/2] * vars->Q_M2[k+1][cnt3][cnt4/2] * pf_params->expMLclosing;
2294 updatePosteriorBoundaries(cnt1 + cnt3 + da,
2304 vars->Q_cM_rem += Q_M[my_iindx[1]-k][cnt1][cnt2/2] * vars->Q_M2[k+1][cnt3][cnt4/2] * pf_params->expMLclosing;
2309 adjustArrayBoundaries(&vars->Q_cM,
2310 &vars->k_min_values_qcM,
2311 &vars->k_max_values_qcM,
2312 &vars->l_min_values_qcM,
2313 &vars->l_max_values_qcM,
2321 for(cnt1 = vars->k_min_values_qcH;
2322 cnt1 <= vars->k_max_values_qcH;
2324 for(cnt2 = vars->l_min_values_qcH[cnt1];
2325 cnt2 <= vars->l_max_values_qcH[cnt1];
2327 vars->Q_c[cnt1][cnt2/2] += vars->Q_cH[cnt1][cnt2/2];
2329 updatePosteriorBoundaries(cnt1,
2338 for(cnt1 = vars->k_min_values_qcI;
2339 cnt1 <= vars->k_max_values_qcI;
2341 for(cnt2 = vars->l_min_values_qcI[cnt1];
2342 cnt2 <= vars->l_max_values_qcI[cnt1];
2344 vars->Q_c[cnt1][cnt2/2] += vars->Q_cI[cnt1][cnt2/2];
2346 updatePosteriorBoundaries(cnt1,
2355 for(cnt1 = vars->k_min_values_qcM;
2356 cnt1 <= vars->k_max_values_qcM;
2358 for(cnt2 = vars->l_min_values_qcM[cnt1];
2359 cnt2 <= vars->l_max_values_qcM[cnt1];
2361 vars->Q_c[cnt1][cnt2/2] += vars->Q_cM[cnt1][cnt2/2];
2363 updatePosteriorBoundaries(cnt1,
2373 vars->Q_c_rem = vars->Q_cH_rem + vars->Q_cI_rem + vars->Q_cM_rem;
2375 /* add the case were structure is unfolded chain */
2376 if((referenceBPs1[my_iindx[1]-seq_length] <= maxD1) && (referenceBPs2[my_iindx[1]-seq_length] <= maxD2)){
2377 vars->Q_c[referenceBPs1[my_iindx[1]-seq_length]][referenceBPs2[my_iindx[1]-seq_length]/2] += 1.0 * scale[seq_length];
2379 updatePosteriorBoundaries(referenceBPs1[my_iindx[1]-seq_length],
2380 referenceBPs2[my_iindx[1]-seq_length],
2389 vars->Q_c_rem += 1.0 * scale[seq_length];
2392 adjustArrayBoundaries(&vars->Q_c,
2393 &vars->k_min_values_qc,
2394 &vars->k_max_values_qc,
2395 &vars->l_min_values_qc,
2396 &vars->l_max_values_qc,
2405 PRIVATE void make_ptypes2(TwoDpfold_vars *vars) {
2409 for (k=1; k<n-TURN; k++)
2410 for (l=1; l<=2; l++) {
2411 int type,ntype=0,otype=0;
2412 i=k; j = i+TURN+l; if (j>n) continue;
2413 type = pair[vars->S[i]][vars->S[j]];
2414 while ((i>=1)&&(j<=n)) {
2415 if ((i>1)&&(j<n)) ntype = pair[vars->S[i-1]][vars->S[j+1]];
2416 if (noLonelyPairs && (!otype) && (!ntype))
2417 type = 0; /* i.j can only form isolated pairs */
2418 vars->ptype[vars->my_iindx[i]-j] = (char) type;
2426 PRIVATE void scale_pf_params2(TwoDpfold_vars *vars)
2428 /* scale energy parameters and pre-calculate Boltzmann weights */
2432 if(vars->pf_params) free(vars->pf_params);
2433 vars->pf_params = get_scaled_pf_parameters();
2434 vars->init_temp = vars->pf_params->temperature;
2435 vars->temperature = vars->init_temp;
2437 kT = vars->pf_params->kT; /* kT in cal/mol */
2439 /* scaling factors (to avoid overflows) */
2440 if (vars->pf_scale == -1) { /* mean energy for random sequences: 184.3*length cal */
2441 vars->pf_scale = exp(-(-185+(vars->temperature-37.)*7.27)/kT);
2442 if (vars->pf_scale<1) vars->pf_scale=1;
2444 vars->scale[0] = 1.; vars->scale[1] = 1./vars->pf_scale;
2445 for (i=2; i<=vars->seq_length; i++) {
2446 vars->scale[i] = vars->scale[i/2]*vars->scale[i-(i/2)];
2451 * ###################################################
2452 * stochastic backtracking
2453 * ###################################################
2456 PUBLIC char *TwoDpfold_pbacktrack(TwoDpfold_vars *vars, int d1, int d2){
2457 return TwoDpfold_pbacktrack5(vars, d1, d2, vars->seq_length);
2460 PUBLIC char *TwoDpfold_pbacktrack5(TwoDpfold_vars *vars, int d1, int d2, unsigned int length){
2461 char *pstruc, *ptype;
2463 unsigned int i, j, n, start, maxD1, maxD2, da, db,
2464 *referenceBPs1, *referenceBPs2;
2465 int *my_iindx, ij, cnt1, cnt2, cnt3, cnt4, type,
2466 **l_min_values, **l_max_values,
2467 **l_min_values_b, **l_max_values_b,
2468 *k_min_values, *k_max_values,
2469 *k_min_values_b, *k_max_values_b;
2470 FLT_OR_DBL r, qt, *scale, ***Q, ***Q_B, *Q_rem, *Q_B_rem;
2471 pf_paramT *pf_params;
2473 n = vars->seq_length;
2477 nrerror("pbacktrack@2Dfold.c: cotranscriptional backtracking for circular RNAs not supported!");
2478 return TwoDpfold_pbacktrack_circ(vars, d1, d2);
2481 pf_params = vars->pf_params;
2482 maxD1 = vars->maxD1;
2483 maxD2 = vars->maxD2;
2484 my_iindx = vars->my_iindx;
2485 scale = vars->scale;
2486 ptype = vars->ptype;
2488 referenceBPs1 = vars->referenceBPs1;
2489 referenceBPs2 = vars->referenceBPs2;
2492 l_min_values = vars->l_min_values;
2493 l_max_values = vars->l_max_values;
2494 k_min_values = vars->k_min_values;
2495 k_max_values = vars->k_max_values;
2498 l_min_values_b = vars->l_min_values_b;
2499 l_max_values_b = vars->l_max_values_b;
2500 k_min_values_b = vars->k_min_values_b;
2501 k_max_values_b = vars->k_max_values_b;
2503 Q_rem = vars->Q_rem;
2504 Q_B_rem = vars->Q_B_rem;
2507 nrerror("pbacktrack@2Dpfold.c: requested transcript length exceeds sequence length!");
2511 nrerror("pbacktrack@2Dpfold.c: distance to 1st reference structure to high!");
2513 nrerror("pbacktrack@2Dpfold.c: distance to 2nd reference structure to high!");
2516 /* check whether the chosen neighborhood exists at all */
2518 ij = my_iindx[1]-length;
2519 if((d1 == -1) && (Q_rem[ij] != 0.)) dumb = 0;
2521 if((k_min_values[ij] <= d1) && (k_max_values[ij] >= d1)){
2522 int l_min = l_min_values[ij][d1];
2523 if((d2 % 2) == (l_min%2))
2524 if((l_min <= d2) && (l_max_values[ij][d1] >= d2))
2529 fprintf(stderr, "neighborhood %d:%d is not in scope of calculated partition function!\n", d1, d2);
2530 nrerror("pbacktrack@2Dpfold.c: exiting cheerless...");
2533 pstruc = space((length+1)*sizeof(char));
2535 for (i=0; i<length; i++) pstruc[i] = '.';
2539 while (start<length) {
2540 int sn = my_iindx[start] - length;
2541 /* find i position of first pair */
2542 FLT_OR_DBL qln_i = 0, qln_i1 = 0;
2548 if( (maxD1 > referenceBPs1[sn])
2549 && (maxD2 > referenceBPs2[sn])){
2551 if(scale[length-start+1] > r)
2555 /* lets see if we find a base pair with i involved */
2556 for (i=start; i<length; i++) {
2559 qln_i1 = Q_rem[my_iindx[i+1] - length];
2561 da = referenceBPs1[sn] - referenceBPs1[my_iindx[i+1] - length];
2562 db = referenceBPs2[sn] - referenceBPs2[my_iindx[i+1] - length];
2564 for(cnt1 = k_min_values[my_iindx[i+1] - length];
2565 cnt1 <= k_max_values[my_iindx[i+1] - length];
2567 for(cnt2 = l_min_values[my_iindx[i+1] - length][cnt1];
2568 cnt2 <= l_max_values[my_iindx[i+1] - length][cnt1];
2570 if(((cnt1 + da) > maxD1) || ((cnt2 + db) > maxD2)){
2571 qln_i1 += Q[my_iindx[i+1] - length][cnt1][cnt2/2];
2574 if(r > qln_i1*scale[1]) break;
2578 if (i>=length) break; /* no more pairs */
2580 /* i is paired, find pairing partner j */
2581 r = urn() * (qln_i - qln_i1*scale[1]);
2582 for (qt=0, j=i+TURN+1; j<length; j++) {
2586 cnt1 = cnt2 = cnt3 = cnt4 = -1;
2587 double qkl = exp_E_ExtLoop(type, (i>1) ? S1[i-1] : -1, S1[j+1], pf_params);
2589 if(Q_B_rem[ij] != 0.){
2590 if(Q_rem[my_iindx[j+1]-length] != 0.){
2591 qt += qkl * Q_B_rem[ij] * Q_rem[my_iindx[j+1]-length];
2593 goto pbacktrack_ext_loop_early_escape_rem;
2595 if(Q[my_iindx[j+1]-length])
2596 for(cnt3 = k_min_values[my_iindx[j+1]-length];
2597 cnt3 <= k_max_values[my_iindx[j+1]-length];
2599 for(cnt4 = l_min_values[my_iindx[j+1]-length][cnt3];
2600 cnt4 <= l_max_values[my_iindx[j+1]-length][cnt3];
2602 qt += qkl * Q_B_rem[ij] * Q[my_iindx[j+1]-length][cnt3][cnt4/2];
2604 goto pbacktrack_ext_loop_early_escape_rem;
2607 if(Q_rem[my_iindx[j+1]-length] != 0.){
2610 for(cnt1 = k_min_values_b[ij];
2611 cnt1 <= k_max_values_b[ij];
2613 for(cnt2 = l_min_values_b[ij][cnt1];
2614 cnt2 <= l_max_values_b[ij][cnt1];
2616 qt += qkl * Q_B[ij][cnt1][cnt2/2] * Q_rem[my_iindx[j+1]-length];
2618 goto pbacktrack_ext_loop_early_escape_rem;
2622 /* if we still search for pairing partner j, we go on here... */
2623 if(Q_B[ij] && Q[my_iindx[j+1]-length]){
2624 da = referenceBPs1[sn] - referenceBPs1[ij] - referenceBPs1[my_iindx[j+1]-length];
2625 db = referenceBPs2[sn] - referenceBPs2[ij] - referenceBPs2[my_iindx[j+1]-length];
2626 for(cnt1 = k_min_values_b[ij];
2627 cnt1 <= k_max_values_b[ij];
2629 for(cnt2 = l_min_values_b[ij][cnt1];
2630 cnt2 <= l_max_values_b[ij][cnt1];
2632 for(cnt3 = k_min_values[my_iindx[j+1]-length];
2633 cnt3 <= k_max_values[my_iindx[j+1]-length];
2635 for(cnt4 = l_min_values[my_iindx[j+1]-length][cnt3];
2636 cnt4 <= l_max_values[my_iindx[j+1]-length][cnt3];
2638 if(((cnt1 + cnt3 + da) > maxD1) || ((cnt2 + cnt4 + db) > maxD2)){
2639 qt += qkl * Q_B[ij][cnt1][cnt2/2] * Q[my_iindx[j+1]-length][cnt3][cnt4/2];
2641 goto pbacktrack_ext_loop_early_escape_rem;
2644 } /* end if(type) */
2646 cnt1 = cnt2 = cnt3 = cnt4 = -1;
2647 /* dont forget the case where i pairs with n */
2652 double qkl = exp_E_ExtLoop(type, (i>1) ? S1[i-1] : -1, (j<n) ? S1[j+1] : -1, pf_params);
2653 if(Q_B_rem[ij] != 0.){
2654 qt += qkl * Q_B_rem[ij];
2656 goto pbacktrack_ext_loop_early_escape_rem;
2658 /* if we still search for pairing partner j, we go on here... */
2660 da = referenceBPs1[sn] - referenceBPs1[ij];
2661 db = referenceBPs2[sn] - referenceBPs2[ij];
2662 for(cnt1 = k_min_values_b[ij];
2663 cnt1 <= k_max_values_b[ij];
2665 for(cnt2 = l_min_values_b[ij][cnt1];
2666 cnt2 <= l_max_values_b[ij][cnt1];
2668 if(((cnt1 + da) > maxD1) || ((cnt2 + db) > maxD2)){
2669 qt += qkl * Q_B[ij][cnt1][cnt2/2];
2671 goto pbacktrack_ext_loop_early_escape_rem;
2674 } /* end if(type) */
2677 pbacktrack_ext_loop_early_escape_rem:
2680 nrerror("pbacktrack@2Dpfold.c: backtracking failed in ext loop (rem)");
2683 /* finally start backtracking the first exterior stem */
2684 backtrack(vars, pstruc, cnt1, cnt2, i,j);
2685 if(j==length) break;
2690 } /* end if d1 ==-1 */
2692 qln_i = Q[sn][d1][d2/2];
2695 if( (d1 == referenceBPs1[sn])
2696 && (d2 == referenceBPs2[sn])){
2698 if(scale[length-start+1] > r)
2702 for (i=start; i<length; i++) {
2704 da = referenceBPs1[sn] - referenceBPs1[my_iindx[i+1] - length];
2705 db = referenceBPs2[sn] - referenceBPs2[my_iindx[i+1] - length];
2707 if(d1 >= da && d2 >= db)
2709 (d1-da >= k_min_values[my_iindx[i+1] - length])
2710 && (d1 - da <= k_max_values[my_iindx[i+1] - length]))
2712 (d2 - db >= l_min_values[my_iindx[i+1] - length][d1 - da])
2713 && (d2 - db <= l_max_values[my_iindx[i+1] - length][d1 - da]))
2714 qln_i1 += Q[my_iindx[i+1] - length][d1-da][(d2-db)/2];
2715 if (r > qln_i1*scale[1]) break; /* i is paired */
2719 if (i>=length) break; /* no more pairs */
2721 /* now find the pairing partner j */
2722 r = urn() * (qln_i - qln_i1*scale[1]);
2724 for (qt=0, j=i+1; j<length; j++) {
2730 qkl *= exp_E_ExtLoop(type, (i>1) ? S1[i-1] : -1, S1[j+1], pf_params);
2732 da = referenceBPs1[sn] - referenceBPs1[ij] - referenceBPs1[my_iindx[j+1]-length];
2733 db = referenceBPs2[sn] - referenceBPs2[ij] - referenceBPs2[my_iindx[j+1]-length];
2738 && Q[my_iindx[j+1]-length])
2739 for(cnt1 = k_min_values_b[ij];
2740 cnt1 <= MIN2(k_max_values_b[ij], d1-da);
2742 for(cnt2 = l_min_values_b[ij][cnt1];
2743 cnt2 <= MIN2(l_max_values_b[ij][cnt1], d2-db);
2745 if( (d1-da-cnt1 >= k_min_values[my_iindx[j+1]-length])
2746 && (d1-da-cnt1 <= k_max_values[my_iindx[j+1]-length]))
2747 if( (d2 - db - cnt2 >= l_min_values[my_iindx[j+1]-length][d1-da-cnt1])
2748 && (d2 - db - cnt2 <= l_max_values[my_iindx[j+1]-length][d1-da-cnt1])){
2749 qt += qkl * Q_B[ij][cnt1][cnt2/2] * Q[my_iindx[j+1]-length][d1-da-cnt1][(d2-db-cnt2)/2];
2751 goto pbacktrack_ext_loop_early_escape;
2755 /* now dont forget the case j==n */
2758 int type = ptype[ij];
2762 qkl *= exp_E_ExtLoop(type, (i>1) ? S1[i-1] : -1, (j<n) ? S1[j+1] : -1, pf_params);
2764 da = referenceBPs1[sn] - referenceBPs1[ij];
2765 db = referenceBPs2[sn] - referenceBPs2[ij];
2766 if(d1 >= da && d2 >= db){
2769 if((cnt1 >= k_min_values_b[ij]) && (cnt1 <= k_max_values_b[ij]))
2770 if((cnt2 >= l_min_values_b[ij][cnt1]) && (cnt2 <= l_max_values_b[ij][cnt1])){
2771 qt += qkl * Q_B[ij][cnt1][cnt2/2];
2773 goto pbacktrack_ext_loop_early_escape; /* j is paired */
2779 pbacktrack_ext_loop_early_escape:
2782 nrerror("pbacktrack@2Dpfold.c: backtracking failed in ext loop");
2785 backtrack(vars, pstruc, cnt1, cnt2, i,j);
2787 if(j==length) break;
2791 } /* end if d1!=-1 */
2797 PRIVATE char *TwoDpfold_pbacktrack_circ(TwoDpfold_vars *vars, int d1, int d2){
2799 unsigned int i, n, maxD1, maxD2,
2800 *referenceBPs1, *referenceBPs2;
2802 k_min_values_qc, k_max_values_qc,
2803 k_min_values_qcH, k_max_values_qcH,
2804 k_min_values_qcI, k_max_values_qcI,
2805 k_min_values_qcM, k_max_values_qcM,
2806 *l_min_values_qc, *l_max_values_qc,
2807 *l_min_values_qcH, *l_max_values_qcH,
2808 *l_min_values_qcI, *l_max_values_qcI,
2809 *l_min_values_qcM, *l_max_values_qcM;
2810 FLT_OR_DBL r, *scale, qot,
2811 **Q_c, **Q_cH, **Q_cI, **Q_cM,
2812 Q_c_rem, Q_cH_rem, Q_cI_rem, Q_cM_rem;
2814 n = vars->seq_length;
2815 maxD1 = vars->maxD1;
2816 maxD2 = vars->maxD2;
2817 my_iindx = vars->my_iindx;
2818 scale = vars->scale;
2819 referenceBPs1 = vars->referenceBPs1;
2820 referenceBPs2 = vars->referenceBPs2;
2823 l_min_values_qc = vars->l_min_values_qc;
2824 l_max_values_qc = vars->l_max_values_qc;
2825 k_min_values_qc = vars->k_min_values_qc;
2826 k_max_values_qc = vars->k_max_values_qc;
2829 l_min_values_qcH = vars->l_min_values_qcH;
2830 l_max_values_qcH = vars->l_max_values_qcH;
2831 k_min_values_qcH = vars->k_min_values_qcH;
2832 k_max_values_qcH = vars->k_max_values_qcH;
2835 l_min_values_qcI = vars->l_min_values_qcI;
2836 l_max_values_qcI = vars->l_max_values_qcI;
2837 k_min_values_qcI = vars->k_min_values_qcI;
2838 k_max_values_qcI = vars->k_max_values_qcI;
2841 l_min_values_qcM = vars->l_min_values_qcM;
2842 l_max_values_qcM = vars->l_max_values_qcM;
2843 k_min_values_qcM = vars->k_min_values_qcM;
2844 k_max_values_qcM = vars->k_max_values_qcM;
2846 Q_c_rem = vars->Q_c_rem;
2847 Q_cH_rem = vars->Q_cH_rem;
2848 Q_cI_rem = vars->Q_cI_rem;
2849 Q_cM_rem = vars->Q_cM_rem;
2851 /* check whether the chosen neighborhood exists at all */
2853 if((d1 == -1) && (Q_c_rem != 0.)) dumb = 0;
2855 if((k_min_values_qc <= d1) && (k_max_values_qc >= d1)){
2856 int l_min = l_min_values_qc[d1];
2857 if((d2 % 2) == (l_min%2))
2858 if((l_min <= d2) && (l_max_values_qc[d1] >= d2))
2863 fprintf(stderr, "neighborhood %d:%d is not in scope of calculated partition function!\n", d1, d2);
2864 nrerror("pbacktrack_circ@2Dpfold.c: exiting cheerless...");
2867 pstruc = space((n+1)*sizeof(char));
2869 for (i=0; i<n; i++) pstruc[i] = '.';
2872 /* now we come to the actual backtracking process */
2875 /* backtrack in rest-partition */
2877 r = urn() * Q_c_rem;
2879 if((referenceBPs1[my_iindx[1]-n] > maxD1) || (referenceBPs2[my_iindx[1]-n] > maxD2)){
2880 qot = 1.0 * scale[n];
2882 goto pbacktrack_circ_escape;
2886 backtrack_qcH(vars, pstruc, d1, d2);
2887 goto pbacktrack_circ_escape;
2891 backtrack_qcI(vars, pstruc, d1, d2);
2892 goto pbacktrack_circ_escape;
2896 backtrack_qcM(vars, pstruc, d1, d2);
2897 goto pbacktrack_circ_escape;
2899 nrerror("pbacktrack_circ@2Dpfold.c: backtracking failed in exterior loop! Exiting cheerless...");
2901 /* normal backtracking */
2903 r = urn() * Q_c[d1][d2/2];
2906 if((referenceBPs1[my_iindx[1]-n] == d1) && (referenceBPs2[my_iindx[1]-n] == d2)){
2907 qot += 1.0 * scale[n];
2909 goto pbacktrack_circ_escape;
2912 /* exterior hairpin loop ? */
2913 if((k_min_values_qcH <= d1) && (k_max_values_qcH >= d1)){
2914 int l_min = l_min_values_qcH[d1];
2915 if((d2 % 2) == (l_min%2))
2916 if((l_min <= d2) && (l_max_values_qcH[d1] >= d2)){
2917 qot += Q_cH[d1][d2/2];
2919 backtrack_qcH(vars, pstruc, d1, d2);
2920 goto pbacktrack_circ_escape;
2925 /* exterior interior loop ? */
2926 if((k_min_values_qcI <= d1) && (k_max_values_qcI >= d1)){
2927 int l_min = l_min_values_qcI[d1];
2928 if((d2 % 2) == (l_min%2))
2929 if((l_min <= d2) && (l_max_values_qcI[d1] >= d2)){
2930 qot += Q_cI[d1][d2/2];
2932 backtrack_qcI(vars, pstruc, d1, d2);
2933 goto pbacktrack_circ_escape;
2938 /* exterior multibranch loop ? */
2939 if((k_min_values_qcM <= d1) && (k_max_values_qcM >= d1)){
2940 int l_min = l_min_values_qcM[d1];
2941 if((d2 % 2) == (l_min%2))
2942 if((l_min <= d2) && (l_max_values_qcM[d1] >= d2)){
2943 qot += Q_cM[d1][d2/2];
2945 backtrack_qcM(vars, pstruc, d1, d2);
2946 goto pbacktrack_circ_escape;
2952 pbacktrack_circ_escape:
2958 PRIVATE void backtrack_qcH(TwoDpfold_vars *vars, char *pstruc, int d1, int d2){
2959 char *ptype, *sequence;
2961 unsigned int i, j, n, maxD1, maxD2,
2962 base_d1, base_d2, da, db,
2963 *referenceBPs1, *referenceBPs2;
2964 int u, *my_iindx, ij, cnt1, cnt2,type,
2965 **l_min_values_b, **l_max_values_b,
2966 *k_min_values_b, *k_max_values_b;
2967 FLT_OR_DBL r, qt, *scale, qot,
2968 ***Q_B, **Q_cH, *Q_B_rem,
2970 pf_paramT *pf_params;
2973 pf_params = vars->pf_params;
2974 sequence = vars->sequence;
2975 n = vars->seq_length;
2976 my_iindx = vars->my_iindx;
2977 scale = vars->scale;
2978 ptype = vars->ptype;
2980 referenceBPs1 = vars->referenceBPs1;
2981 referenceBPs2 = vars->referenceBPs2;
2982 maxD1 = vars->maxD1;
2983 maxD2 = vars->maxD2;
2985 Q_B_rem = vars->Q_B_rem;
2987 l_min_values_b = vars->l_min_values_b;
2988 l_max_values_b = vars->l_max_values_b;
2989 k_min_values_b = vars->k_min_values_b;
2990 k_max_values_b = vars->k_max_values_b;
2992 Q_cH_rem = vars->Q_cH_rem;
2997 base_d1 = referenceBPs1[my_iindx[1]-n];
2998 base_d2 = referenceBPs2[my_iindx[1]-n];
3001 r = urn() * Q_cH_rem;
3003 for(j=i+TURN+1;j<=n;j++){
3007 if (u<TURN) continue;
3009 if (!type) continue;
3010 if(((type==3)||(type==4))&&no_closingGU) continue;
3013 strcpy(loopseq , sequence+j-1);
3014 strncat(loopseq, sequence, i);
3016 qt = exp_E_Hairpin(u, type,
3022 qot += Q_B_rem[ij] * qt;
3024 backtrack(vars, pstruc, d1, d2, i, j);
3029 da = base_d1 - referenceBPs1[ij];
3030 db = base_d2 - referenceBPs2[ij];
3033 for(cnt1 = k_min_values_b[ij];
3034 cnt1 <= k_max_values_b[ij];
3036 for(cnt2 = l_min_values_b[ij][cnt1];
3037 cnt2 <= l_max_values_b[ij][cnt1];
3039 if( ((cnt1 + da) > maxD1)
3040 || ((cnt2 + db) > maxD2)){
3041 qot += Q_B[ij][cnt1][cnt2/2] * qt;
3043 backtrack(vars, pstruc, cnt1, cnt2, i, j);
3052 r = urn() * Q_cH[d1][d2/2];
3054 for(j=i+TURN+1;j<=n;j++){
3057 if(!Q_B[ij]) continue;
3059 if (u<TURN) continue;
3061 if (!type) continue;
3062 if(((type==3)||(type==4))&&no_closingGU) continue;
3065 strcpy(loopseq , sequence+j-1);
3066 strncat(loopseq, sequence, i);
3068 qt = exp_E_Hairpin(u, type,
3072 da = base_d1 - referenceBPs1[ij];
3073 db = base_d2 - referenceBPs2[ij];
3075 for(cnt1 = k_min_values_b[ij];
3076 cnt1 <= k_max_values_b[ij];
3078 for(cnt2 = l_min_values_b[ij][cnt1];
3079 cnt2 <= l_max_values_b[ij][cnt1];
3081 if( ((cnt1 + da) == d1)
3082 && ((cnt2 + db) == d2)){
3083 qot += Q_B[ij][cnt1][cnt2/2] * qt;
3085 backtrack(vars, pstruc, cnt1, cnt2, i, j);
3092 nrerror("backtrack_qcH@2Dpfold.c: failed to find closing pair!");
3095 PRIVATE void backtrack_qcI(TwoDpfold_vars *vars,
3101 unsigned int i, j, ij, p, q, pq, n, maxD1, maxD2,
3102 base_d1, base_d2, da, db,
3103 *referenceBPs1, *referenceBPs2;
3104 int *my_iindx, cnt1, cnt2, cnt3, cnt4, type,
3105 **l_min_values_b, **l_max_values_b,
3106 *k_min_values_b, *k_max_values_b;
3107 FLT_OR_DBL r, qt, *scale, qot,
3110 pf_paramT *pf_params;
3113 pf_params = vars->pf_params;
3114 n = vars->seq_length;
3115 my_iindx = vars->my_iindx;
3116 scale = vars->scale;
3117 ptype = vars->ptype;
3119 referenceBPs1 = vars->referenceBPs1;
3120 referenceBPs2 = vars->referenceBPs2;
3121 maxD1 = vars->maxD1;
3122 maxD2 = vars->maxD2;
3125 l_min_values_b = vars->l_min_values_b;
3126 l_max_values_b = vars->l_max_values_b;
3127 k_min_values_b = vars->k_min_values_b;
3128 k_max_values_b = vars->k_max_values_b;
3131 Q_B_rem = vars->Q_B_rem;
3132 Q_cI_rem = vars->Q_cI_rem;
3136 base_d1 = referenceBPs1[my_iindx[1]-n];
3137 base_d2 = referenceBPs2[my_iindx[1]-n];
3140 r = urn() * Q_cI_rem;
3142 for(j=i+TURN+1;j<=n;j++){
3144 type = rtype[(unsigned int)ptype[ij]];
3145 if(!ptype) continue;
3148 for(p=j+1; p < n; p++){
3149 unsigned int ln1, qstart, ln_pre;
3151 if(ln1+i-1>MAXLOOP) break;
3152 qstart = p + TURN + 1;
3153 ln_pre = ln1 + i + n;
3154 if(ln_pre > qstart + MAXLOOP)
3155 qstart = ln_pre - MAXLOOP - 1;
3156 for(q=qstart;q <= n; q++){
3160 ln2 = (i - 1) + (n - q);
3161 if((ln1+ln2) > MAXLOOP) continue;
3163 if(!type2) continue;
3164 qt = exp_E_IntLoop(ln2, ln1,
3171 qot += Q_B_rem[ij] * Q_B_rem[pq] * qt;
3173 backtrack(vars, pstruc, d1, d2, i, j);
3174 backtrack(vars, pstruc, d1, d2, p, q);
3179 for(cnt1 = k_min_values_b[pq];
3180 cnt1 <= k_max_values_b[pq];
3182 for(cnt2 = l_min_values_b[pq][cnt1];
3183 cnt2 <= l_max_values_b[pq][cnt1];
3185 qot += Q_B_rem[ij] * Q_B[pq][cnt1][cnt2/2] * qt;
3187 backtrack(vars, pstruc, d1, d2, i, j);
3188 backtrack(vars, pstruc, cnt1, cnt2, p, q);
3196 for(p=j+1; p < n; p++){
3197 unsigned int ln1, qstart, ln_pre;
3199 if(ln1+i-1>MAXLOOP) break;
3200 qstart = p + TURN + 1;
3201 ln_pre = ln1 + i + n;
3202 if(ln_pre > qstart + MAXLOOP)
3203 qstart = ln_pre - MAXLOOP - 1;
3204 for(q=qstart;q <= n; q++){
3208 ln2 = (i - 1) + (n - q);
3209 if((ln1+ln2) > MAXLOOP) continue;
3211 if(!type2) continue;
3212 qt = exp_E_IntLoop(ln2, ln1,
3219 for(cnt1 = k_min_values_b[ij];
3220 cnt1 <= k_max_values_b[ij];
3222 for(cnt2 = l_min_values_b[ij][cnt1];
3223 cnt2 <= l_max_values_b[ij][cnt1];
3225 qot += Q_B[ij][cnt1][cnt2/2] * Q_B_rem[pq] * qt;
3227 backtrack(vars, pstruc, cnt1, cnt2, i, j);
3228 backtrack(vars, pstruc, d1, d2, p, q);
3235 - referenceBPs1[pq];
3238 - referenceBPs2[pq];
3239 for(cnt1 = k_min_values_b[ij];
3240 cnt1 <= k_max_values_b[ij];
3242 for(cnt2 = l_min_values_b[ij][cnt1];
3243 cnt2 <= l_max_values_b[ij][cnt1];
3245 for(cnt3 = k_min_values_b[pq];
3246 cnt3 <= k_max_values_b[pq];
3248 for(cnt4 = l_min_values_b[pq][cnt3];
3249 cnt4 <= l_max_values_b[pq][cnt3];
3251 if( ((cnt1 + cnt3 + da) > maxD1)
3252 || ((cnt2 + cnt4 + db) > maxD2)){
3253 qot += Q_B[ij][cnt1][cnt2/2]
3254 * Q_B[pq][cnt3][cnt4/2]
3257 backtrack(vars, pstruc, cnt1, cnt2, i, j);
3258 backtrack(vars, pstruc, cnt3, cnt4, p, q);
3271 r = urn() * Q_cI[d1][d2/2];
3273 for(j=i+TURN+1;j<=n;j++){
3275 type = rtype[(unsigned int)ptype[ij]];
3276 if(!ptype) continue;
3277 if(!Q_B[ij]) continue;
3278 for(p=j+1; p < n; p++){
3279 unsigned int ln1, qstart, ln_pre;
3281 if(ln1+i-1>MAXLOOP) break;
3282 qstart = p + TURN + 1;
3283 ln_pre = ln1 + i + n;
3284 if(ln_pre > qstart + MAXLOOP)
3285 qstart = ln_pre - MAXLOOP - 1;
3286 for(q=qstart;q <= n; q++){
3290 if(!Q_B[pq]) continue;
3291 ln2 = (i - 1) + (n - q);
3292 if((ln1+ln2) > MAXLOOP) continue;
3294 if(!type2) continue;
3295 qt = exp_E_IntLoop( ln2, ln1,
3303 - referenceBPs1[pq];
3306 - referenceBPs2[pq];
3307 for(cnt1 = k_min_values_b[ij];
3308 cnt1 <= k_max_values_b[ij];
3310 for(cnt2 = l_min_values_b[ij][cnt1];
3311 cnt2 <= l_max_values_b[ij][cnt1];
3313 for(cnt3 = k_min_values_b[pq];
3314 cnt3 <= k_max_values_b[pq];
3316 for(cnt4 = l_min_values_b[pq][cnt3];
3317 cnt4 <= l_max_values_b[pq][cnt3];
3319 if( ((cnt1 + cnt3 + da) == d1)
3320 && ((cnt2 + cnt4 + db) == d2)){
3321 qot += Q_B[ij][cnt1][cnt2/2]
3322 * Q_B[pq][cnt3][cnt4/2]
3325 backtrack(vars, pstruc, cnt1, cnt2, i, j);
3326 backtrack(vars, pstruc, cnt3, cnt4, p, q);
3337 PRIVATE void backtrack_qcM(TwoDpfold_vars *vars,
3341 unsigned int k, n, maxD1, maxD2, base_d1, base_d2,
3342 da, db, *referenceBPs1, *referenceBPs2;
3343 int *my_iindx, cnt1, cnt2, cnt3, cnt4,
3344 **l_min_values_m, **l_max_values_m,
3345 **l_min_values_m2, **l_max_values_m2,
3346 *k_min_values_m, *k_max_values_m,
3347 *k_min_values_m2, *k_max_values_m2;
3348 FLT_OR_DBL r, qt, qot,
3349 ***Q_M, ***Q_M2, **Q_cM,
3350 *Q_M_rem, *Q_M2_rem, Q_cM_rem;
3351 pf_paramT *pf_params;
3354 pf_params = vars->pf_params;
3355 n = vars->seq_length;
3356 my_iindx = vars->my_iindx;
3357 referenceBPs1 = vars->referenceBPs1;
3358 referenceBPs2 = vars->referenceBPs2;
3359 maxD1 = vars->maxD1;
3360 maxD2 = vars->maxD2;
3365 l_min_values_m = vars->l_min_values_m;
3366 l_max_values_m = vars->l_max_values_m;
3367 k_min_values_m = vars->k_min_values_m;
3368 k_max_values_m = vars->k_max_values_m;
3371 l_min_values_m2 = vars->l_min_values_m2;
3372 l_max_values_m2 = vars->l_max_values_m2;
3373 k_min_values_m2 = vars->k_min_values_m2;
3374 k_max_values_m2 = vars->k_max_values_m2;
3376 Q_cM_rem = vars->Q_cM_rem;
3377 Q_M_rem = vars->Q_M_rem;
3378 Q_M2_rem = vars->Q_M2_rem;
3380 base_d1 = referenceBPs1[my_iindx[1]-n];
3381 base_d2 = referenceBPs2[my_iindx[1]-n];
3385 r = urn() * Q_cM_rem;
3387 k < n - 2 * TURN - 3;
3390 if(Q_M_rem[my_iindx[1]-k]){
3393 for(cnt1 = k_min_values_m2[k+1];
3394 cnt1 <= k_max_values_m2[k+1];
3396 for(cnt2 = l_min_values_m2[k+1][cnt1];
3397 cnt2 <= l_max_values_m2[k+1][cnt1];
3399 qot += Q_M_rem[my_iindx[1]-k]
3400 * Q_M2[k+1][cnt1][cnt2/2]
3401 * pf_params->expMLclosing;
3403 backtrack_qm(vars, pstruc, d1, d2, 1, k);
3404 backtrack_qm2(vars, pstruc, cnt1, cnt2, k+1);
3410 qot += Q_M_rem[my_iindx[1]-k]
3412 * pf_params->expMLclosing;
3414 backtrack_qm(vars, pstruc, d1, d2, 1, k);
3415 backtrack_qm2(vars, pstruc, d1, d2, k+1);
3424 if(Q_M[my_iindx[1]-k])
3425 for(cnt1 = k_min_values_m[my_iindx[1]-k];
3426 cnt1 <= k_max_values_m[my_iindx[1]-k];
3428 for(cnt2 = l_min_values_m[my_iindx[1]-k][cnt1];
3429 cnt2 <= l_max_values_m[my_iindx[1]-k][cnt1];
3431 qot += Q_M[my_iindx[1]-k][cnt1][cnt2/2]
3433 * pf_params->expMLclosing;
3435 backtrack_qm(vars, pstruc, cnt1, cnt2, 1, k);
3436 backtrack_qm2(vars, pstruc, d1, d2, k+1);
3444 - referenceBPs1[my_iindx[1]-k]
3445 - referenceBPs1[my_iindx[k+1]-n];
3447 - referenceBPs2[my_iindx[1]-k]
3448 - referenceBPs2[my_iindx[k+1]-n];
3450 if( Q_M[my_iindx[1]-k]
3452 for(cnt1 = k_min_values_m[my_iindx[1]-k];
3453 cnt1 <= k_max_values_m[my_iindx[1]-k];
3455 for(cnt2 = l_min_values_m[my_iindx[1]-k][cnt1];
3456 cnt2 <= l_max_values_m[my_iindx[1]-k][cnt1];
3458 for(cnt3 = k_min_values_m2[k+1];
3459 cnt3 <= k_max_values_m2[k+1];
3461 for(cnt4 = l_min_values_m2[k+1][cnt3];
3462 cnt4 <= l_max_values_m2[k+1][cnt3];
3464 if( ((cnt1 + cnt3 + da) > maxD1)
3465 || ((cnt2 + cnt4 + db) > maxD2)){
3466 qot += Q_M[my_iindx[1]-k][cnt1][cnt2/2]
3467 * Q_M2[k+1][cnt3][cnt4/2]
3468 * pf_params->expMLclosing;
3470 backtrack_qm(vars, pstruc, cnt1, cnt2, 1, k);
3471 backtrack_qm2(vars, pstruc, cnt3, cnt4, k+1);
3480 r = urn() * Q_cM[d1][d2/2];
3482 k < n - 2 * TURN - 3;
3485 - referenceBPs1[my_iindx[1]-k]
3486 - referenceBPs1[my_iindx[k+1]-n];
3488 - referenceBPs2[my_iindx[1]-k]
3489 - referenceBPs2[my_iindx[k+1]-n];
3490 if( Q_M[my_iindx[1]-k]
3492 for(cnt1 = k_min_values_m[my_iindx[1]-k];
3493 cnt1 <= k_max_values_m[my_iindx[1]-k];
3495 for(cnt2 = l_min_values_m[my_iindx[1]-k][cnt1];
3496 cnt2 <= l_max_values_m[my_iindx[1]-k][cnt1];
3498 for(cnt3 = k_min_values_m2[k+1];
3499 cnt3 <= k_max_values_m2[k+1];
3501 for(cnt4 = l_min_values_m2[k+1][cnt3];
3502 cnt4 <= l_max_values_m2[k+1][cnt3];
3504 if( ((cnt1 + cnt3 + da) == d1)
3505 && ((cnt2 + cnt4 + db) == d2)){
3506 qot += Q_M[my_iindx[1]-k][cnt1][cnt2/2]
3507 * Q_M2[k+1][cnt3][cnt4/2]
3508 * pf_params->expMLclosing;
3510 backtrack_qm(vars, pstruc, cnt1, cnt2, 1, k);
3511 backtrack_qm2(vars, pstruc, cnt3, cnt4, k+1);
3517 nrerror("backtrack_qcM@2Dpfold.c: backtracking failed");
3520 PRIVATE void backtrack_qm2( TwoDpfold_vars *vars,
3522 int d1, int d2, unsigned int k){
3524 unsigned int l, n, maxD1, maxD2, da, db,
3525 *referenceBPs1, *referenceBPs2;
3526 int *my_iindx, *jindx, cnt1, cnt2, cnt3, cnt4,
3527 *k_min_values_m1, *k_max_values_m1,
3528 **l_min_values_m1, **l_max_values_m1;
3529 FLT_OR_DBL r, qt, qot,
3531 *Q_M2_rem, *Q_M1_rem;
3534 n = vars->seq_length;
3535 my_iindx = vars->my_iindx;
3536 jindx = vars->jindx;
3537 referenceBPs1 = vars->referenceBPs1;
3538 referenceBPs2 = vars->referenceBPs2;
3539 maxD1 = vars->maxD1;
3540 maxD2 = vars->maxD2;
3542 Q_M1_rem = vars->Q_M1_rem;
3544 l_min_values_m1 = vars->l_min_values_m1;
3545 l_max_values_m1 = vars->l_max_values_m1;
3546 k_min_values_m1 = vars->k_min_values_m1;
3547 k_max_values_m1 = vars->k_max_values_m1;
3549 Q_M2_rem = vars->Q_M2_rem;
3555 r = urn() * Q_M2_rem[k];
3556 for (l=k+TURN+1; l<n-TURN-1; l++){
3557 if(Q_M1_rem[jindx[l]+k]){
3558 if(Q_M1[jindx[n]+l+1]){
3559 for(cnt1 = k_min_values_m1[jindx[n]+l+1];
3560 cnt1 <= k_max_values_m1[jindx[n]+l+1];
3562 for(cnt2 = l_min_values_m1[jindx[n]+l+1][cnt1];
3563 cnt2 <= l_max_values_m1[jindx[n]+l+1][cnt1];
3565 qot += Q_M1_rem[jindx[l]+k] * Q_M1[jindx[n]+l+1][cnt1][cnt2/2];
3567 backtrack_qm1(vars, pstruc, d1, d2, k, l);
3568 backtrack_qm1(vars, pstruc, cnt1, cnt2, l+1, n);
3573 if(Q_M1_rem[jindx[n]+l+1]){
3574 qot += Q_M1_rem[jindx[l]+k]
3575 * Q_M1_rem[jindx[n]+l+1];
3577 backtrack_qm1(vars, pstruc, d1, d2, k, l);
3578 backtrack_qm1(vars, pstruc, d1, d2, l+1, n);
3583 if(Q_M1_rem[jindx[n]+l+1]){
3584 if(Q_M1[jindx[l]+k])
3585 for(cnt1 = k_min_values_m1[jindx[l]+k];
3586 cnt1 <= k_max_values_m1[jindx[l]+k];
3588 for(cnt2 = l_min_values_m1[jindx[l]+k][cnt1];
3589 cnt2 <= l_max_values_m1[jindx[l]+k][cnt1];
3591 qot += Q_M1[jindx[l]+k][cnt1][cnt2/2]
3592 * Q_M1_rem[jindx[n]+l+1];
3594 backtrack_qm1(vars, pstruc, cnt1, cnt2, k, l);
3595 backtrack_qm1(vars, pstruc, d1, d2, l+1, n);
3601 if(!Q_M1[jindx[l]+k]) continue;
3602 if(!Q_M1[jindx[n] + l + 1]) continue;
3604 da = referenceBPs1[my_iindx[k]-n]
3605 - referenceBPs1[my_iindx[k]-l]
3606 - referenceBPs1[my_iindx[l+1]-n];
3607 db = referenceBPs2[my_iindx[k]-n]
3608 - referenceBPs2[my_iindx[k]-l]
3609 - referenceBPs2[my_iindx[l+1]-n];
3610 for(cnt1 = k_min_values_m1[jindx[l]+k];
3611 cnt1 <= k_max_values_m1[jindx[l]+k];
3613 for(cnt2 = l_min_values_m1[jindx[l]+k][cnt1];
3614 cnt2 <= l_max_values_m1[jindx[l]+k][cnt1];
3616 for(cnt3 = k_min_values_m1[jindx[n] + l + 1];
3617 cnt3 <= k_max_values_m1[jindx[n] + l + 1];
3619 for(cnt4 = l_min_values_m1[jindx[n] + l + 1][cnt3];
3620 cnt4 <= l_max_values_m1[jindx[n] + l + 1][cnt3];
3622 if( ((cnt1 + cnt3 + da) > maxD1)
3623 || ((cnt2 + cnt4 + db) > maxD2)){
3624 qot += Q_M1[jindx[l]+k][cnt1][cnt2/2]
3625 * Q_M1[jindx[n] + l + 1][cnt3][cnt4/2];
3627 backtrack_qm1(vars, pstruc, cnt1, cnt2, k, l);
3628 backtrack_qm1(vars, pstruc, cnt3, cnt4, l+1, n);
3638 r = urn() * Q_M2[k][d1][d2/2];
3639 for (l=k+TURN+1; l<n-TURN-1; l++){
3640 if(!Q_M1[jindx[l]+k]) continue;
3641 if(!Q_M1[jindx[n] + l + 1]) continue;
3643 da = referenceBPs1[my_iindx[k]-n]
3644 - referenceBPs1[my_iindx[k]-l]
3645 - referenceBPs1[my_iindx[l+1]-n];
3646 db = referenceBPs2[my_iindx[k]-n]
3647 - referenceBPs2[my_iindx[k]-l]
3648 - referenceBPs2[my_iindx[l+1]-n];
3649 for(cnt1 = k_min_values_m1[jindx[l]+k];
3650 cnt1 <= k_max_values_m1[jindx[l]+k];
3652 for(cnt2 = l_min_values_m1[jindx[l]+k][cnt1];
3653 cnt2 <= l_max_values_m1[jindx[l]+k][cnt1];
3655 for(cnt3 = k_min_values_m1[jindx[n] + l + 1];
3656 cnt3 <= k_max_values_m1[jindx[n] + l + 1];
3658 for(cnt4 = l_min_values_m1[jindx[n] + l + 1][cnt3];
3659 cnt4 <= l_max_values_m1[jindx[n] + l + 1][cnt3];
3661 if( ((cnt1 + cnt3 + da) == d1)
3662 && ((cnt2 + cnt4 + db) == d2)){
3663 qot += Q_M1[jindx[l]+k][cnt1][cnt2/2]
3664 * Q_M1[jindx[n] + l + 1][cnt3][cnt4/2];
3666 backtrack_qm1(vars, pstruc, cnt1, cnt2, k, l);
3667 backtrack_qm1(vars, pstruc, cnt3, cnt4, l+1, n);
3675 nrerror("backtrack_qm2@2Dpfold.c: backtracking failed");
3679 PRIVATE void backtrack(TwoDpfold_vars *vars, char *pstruc, int d1, int d2, unsigned int i, unsigned int j) {
3681 unsigned int maxD1, maxD2, base_d1, base_d2, da, db;
3682 unsigned int *referenceBPs1, *referenceBPs2;
3683 pf_paramT *pf_params; /* holds all [unscaled] pf parameters */
3684 char *ptype, *sequence;
3685 short *S1, *reference_pt1, *reference_pt2;
3686 int *my_iindx, *jindx, ij, cnt1, cnt2, cnt3, cnt4;
3688 pf_params = vars->pf_params;
3689 sequence = vars->sequence;
3690 maxD1 = vars->maxD1;
3691 maxD2 = vars->maxD2;
3692 my_iindx = vars->my_iindx;
3693 jindx = vars->jindx;
3694 scale = vars->scale;
3695 ptype = vars->ptype;
3697 reference_pt1 = vars->reference_pt1;
3698 reference_pt2 = vars->reference_pt2;
3699 referenceBPs1 = vars->referenceBPs1;
3700 referenceBPs2 = vars->referenceBPs2;
3702 FLT_OR_DBL ***Q_B, ***Q_M, ***Q_M1, *Q_B_rem, *Q_M_rem, *Q_M1_rem;
3703 int *k_min_values_m, *k_max_values_m,*k_min_values_m1, *k_max_values_m1,*k_min_values_b, *k_max_values_b;
3704 int **l_min_values_m, **l_max_values_m,**l_min_values_m1, **l_max_values_m1,**l_min_values_b, **l_max_values_b;
3707 k_min_values_b = vars->k_min_values_b;
3708 k_max_values_b = vars->k_max_values_b;
3709 l_min_values_b = vars->l_min_values_b;
3710 l_max_values_b = vars->l_max_values_b;
3713 k_min_values_m = vars->k_min_values_m;
3714 k_max_values_m = vars->k_max_values_m;
3715 l_min_values_m = vars->l_min_values_m;
3716 l_max_values_m = vars->l_max_values_m;
3719 k_min_values_m1 = vars->k_min_values_m1;
3720 k_max_values_m1 = vars->k_max_values_m1;
3721 l_min_values_m1 = vars->l_min_values_m1;
3722 l_max_values_m1 = vars->l_max_values_m1;
3724 Q_B_rem = vars->Q_B_rem;
3725 Q_M_rem = vars->Q_M_rem;
3726 Q_M1_rem = vars->Q_M1_rem;
3729 double r, qbt1 = 0.;
3730 unsigned int k, l, u, u1;
3733 pstruc[i-1] = '('; pstruc[j-1] = ')';
3739 r= urn() * Q_B_rem[ij];
3740 if(r == 0.) nrerror("backtrack@2Dpfold.c: backtracking failed\n");
3744 base_d1 = ((unsigned int)reference_pt1[i] != j) ? 1 : -1;
3745 base_d2 = ((unsigned int)reference_pt2[i] != j) ? 1 : -1;
3747 da = base_d1 + referenceBPs1[ij];
3748 db = base_d2 + referenceBPs2[ij];
3751 if((da > maxD1) || (db > maxD2))
3752 if(!(((type==3)||(type==4))&&no_closingGU))
3753 qbt1 = exp_E_Hairpin(u, type, S1[i+1], S1[j-1], sequence+i-1, pf_params) * scale[u+2];
3755 if (qbt1>=r) return; /* found the hairpin we're done */
3757 /* lets see if we form an interior loop */
3758 for (k=i+1; k<=MIN2(i+MAXLOOP+1,j-TURN-2); k++) {
3759 unsigned int u_pre, lmin;
3761 lmin = k + TURN + 1;
3763 /* lmin = MAX2(k + TURN + 1, u1 + j - 1 - MAXLOOP) */
3764 if(u_pre > lmin + MAXLOOP) lmin = u_pre - 1 - MAXLOOP;
3765 for (l=lmin; l<j; l++) {
3767 type_2 = ptype[my_iindx[k]-l];
3770 da = base_d1 + referenceBPs1[my_iindx[i]-j] - referenceBPs1[my_iindx[k]-l];
3771 db = base_d2 + referenceBPs2[my_iindx[i]-j] - referenceBPs2[my_iindx[k]-l];
3772 type_2 = rtype[type_2];
3773 FLT_OR_DBL tmp_en = exp_E_IntLoop(u1, j-l-1, type, type_2, S1[i+1], S1[j-1], S1[k-1], S1[l+1], pf_params) * scale[u1+j-l+1];
3775 if(Q_B_rem[my_iindx[k]-l] != 0.){
3776 qbt1 += Q_B_rem[my_iindx[k]-l] * tmp_en;
3777 if(qbt1 > r) goto backtrack_int_early_escape_rem;
3780 if(Q_B[my_iindx[k]-l])
3781 for(cnt1 = k_min_values_b[my_iindx[k]-l];
3782 cnt1 <= k_max_values_b[my_iindx[k]-l];
3784 for(cnt2 = l_min_values_b[my_iindx[k]-l][cnt1];
3785 cnt2 <= l_max_values_b[my_iindx[k]-l][cnt1];
3787 if(((cnt1 + da) > maxD1) || ((cnt2 + db) > maxD2)){
3788 qbt1 += Q_B[my_iindx[k]-l][cnt1][cnt2/2] * tmp_en;
3789 if(qbt1 > r) goto backtrack_int_early_escape_rem;
3794 backtrack_int_early_escape_rem:
3804 if((d1 >= k_min_values_b[ij]) && (d1 <= k_max_values_b[ij]))
3805 if((d2 >= l_min_values_b[ij][d1]) && (d2 <= l_max_values_b[ij][d1]))
3806 r = urn() * Q_B[ij][d1][d2/2];
3808 if(r == 0.) nrerror("backtrack@2Dpfold.c: backtracking failed\n");
3812 base_d1 = ((unsigned int)reference_pt1[i] != j) ? 1 : -1;
3813 base_d2 = ((unsigned int)reference_pt2[i] != j) ? 1 : -1;
3815 da = base_d1 + referenceBPs1[ij];
3816 db = base_d2 + referenceBPs2[ij];
3818 /*hairpin contribution*/
3819 if((da == d1) && (db == d2))
3820 if(!(((type==3)||(type==4))&&no_closingGU))
3821 qbt1 = exp_E_Hairpin(u, type, S1[i+1], S1[j-1], sequence+i-1, pf_params) * scale[u+2];
3823 if (qbt1>=r) return; /* found the hairpin we're done */
3825 for (k=i+1; k<=MIN2(i+MAXLOOP+1,j-TURN-2); k++) {
3826 unsigned int u_pre, lmin;
3828 lmin = k + TURN + 1;
3830 /* lmin = MAX2(k + TURN + 1, u1 + j - 1 - MAXLOOP) */
3831 if(u_pre > lmin + MAXLOOP) lmin = u_pre - 1 - MAXLOOP;
3832 for (l=lmin; l<j; l++) {
3834 type_2 = ptype[my_iindx[k]-l];
3836 da = base_d1 + referenceBPs1[my_iindx[i]-j] - referenceBPs1[my_iindx[k]-l];
3837 db = base_d2 + referenceBPs2[my_iindx[i]-j] - referenceBPs2[my_iindx[k]-l];
3838 type_2 = rtype[type_2];
3839 FLT_OR_DBL tmp_en = exp_E_IntLoop(u1, j-l-1, type, type_2, S1[i+1], S1[j-1], S1[k-1], S1[l+1], pf_params) * scale[u1+j-l+1];
3840 if(d1 >= da && d2 >= db)
3841 if((d1 - da >= k_min_values_b[my_iindx[k]-l]) && (d1 - da <= k_max_values_b[my_iindx[k]-l]))
3842 if((d2 - db >= l_min_values_b[my_iindx[k]-l][d1 - da]) && (d2 - db <= l_max_values_b[my_iindx[k]-l][d1 - da])){
3845 qbt1 += Q_B[my_iindx[k]-l][cnt1][cnt2/2] * tmp_en;
3846 if(qbt1 > r) goto backtrack_int_early_escape;
3852 backtrack_int_early_escape:
3862 /* backtrack in multi-loop */
3865 unsigned int k, ii, jj;
3867 base_d1 = ((unsigned int)reference_pt1[i] != j) ? 1 : -1;
3868 base_d2 = ((unsigned int)reference_pt2[i] != j) ? 1 : -1;
3870 base_d1 += referenceBPs1[my_iindx[i]-j];
3871 base_d2 += referenceBPs2[my_iindx[i]-j];
3874 /* find the first split index */
3875 ii = my_iindx[i]; /* ii-j=[i,j] */
3876 jj = jindx[j]; /* jj+i=[j,i] */
3878 /* get total contribution for current part */
3879 for (qt=0., k=i+1; k<j; k++){
3880 if(Q_M_rem[ii-k+1] != 0.){
3882 for(cnt1 = k_min_values_m1[jj+k];
3883 cnt1 <= k_max_values_m1[jj+k];
3885 for(cnt2 = l_min_values_m1[jj+k][cnt1];
3886 cnt2 <= l_max_values_m1[jj+k][cnt1];
3888 qt += Q_M_rem[ii-k+1] * Q_M1[jj+k][cnt1][cnt2/2];
3889 if(Q_M1_rem[jj+k] != 0.)
3890 qt += Q_M_rem[ii-k+1] * Q_M1_rem[jj+k];
3892 if(Q_M1_rem[jj+k] != 0.){
3894 for(cnt1 = k_min_values_m[ii-k+1];
3895 cnt1 <= k_max_values_m[ii-k+1];
3897 for(cnt2 = l_min_values_m[ii-k+1][cnt1];
3898 cnt2 <= l_max_values_m[ii-k+1][cnt1];
3900 qt += Q_M[ii-k+1][cnt1][cnt2/2] * Q_M1_rem[jj+k];
3902 /* calculate introduced distance to reference structures */
3903 if(!Q_M[ii-k+1]) continue;
3904 if(!Q_M1[jj+k]) continue;
3905 da = base_d1 - referenceBPs1[my_iindx[i]-k+1] - referenceBPs1[my_iindx[k]-j];
3906 db = base_d2 - referenceBPs2[my_iindx[i]-k+1] - referenceBPs2[my_iindx[k]-j];
3907 /* collect all contributing energies */
3908 for(cnt1 = k_min_values_m[ii-k+1];
3909 cnt1 <= k_max_values_m[ii-k+1];
3911 for(cnt2 = l_min_values_m[ii-k+1][cnt1];
3912 cnt2 <= l_max_values_m[ii-k+1][cnt1];
3914 for(cnt3 = k_min_values_m1[jj+k];
3915 cnt3 <= k_max_values_m1[jj+k];
3917 for(cnt4 = l_min_values_m1[jj+k][cnt3];
3918 cnt4 <= l_max_values_m1[jj+k][cnt3];
3920 if(((cnt1 + cnt3 + da) > maxD1) || ((cnt2 + cnt4 + db) > maxD2))
3921 qt += Q_M[ii-k+1][cnt1][cnt2/2] * Q_M1[jj+k][cnt3][cnt4/2];
3923 /* throw the dice */
3925 for (qt=0., k=i+1; k<j; k++) {
3926 cnt1 = cnt2 = cnt3 = cnt4 = -1;
3927 if(Q_M_rem[ii-k+1] != 0.){
3928 if(Q_M1_rem[jj+k] != 0){
3929 qt += Q_M_rem[ii-k+1] * Q_M1_rem[jj+k];
3930 if(qt >= r) goto backtrack_ml_early_escape;
3933 for(cnt3 = k_min_values_m1[jj+k];
3934 cnt3 <= k_max_values_m1[jj+k];
3936 for(cnt4 = l_min_values_m1[jj+k][cnt3];
3937 cnt4 <= l_max_values_m1[jj+k][cnt3];
3939 qt += Q_M_rem[ii-k+1] * Q_M1[jj+k][cnt3][cnt4/2];
3940 if(qt >= r) goto backtrack_ml_early_escape;
3943 if(Q_M1_rem[jj+k] != 0.){
3946 for(cnt1 = k_min_values_m[ii-k+1];
3947 cnt1 <= k_max_values_m[ii-k+1];
3949 for(cnt2 = l_min_values_m[ii-k+1][cnt1];
3950 cnt2 <= l_max_values_m[ii-k+1][cnt1];
3952 qt += Q_M[ii-k+1][cnt1][cnt2/2] * Q_M1_rem[jj+k];
3953 if(qt >= r) goto backtrack_ml_early_escape;
3956 /* calculate introduced distance to reference structures */
3957 da = base_d1 - referenceBPs1[my_iindx[i]-k+1] - referenceBPs1[my_iindx[k]-j];
3958 db = base_d2 - referenceBPs2[my_iindx[i]-k+1] - referenceBPs2[my_iindx[k]-j];
3959 /* collect all contributing energies */
3960 if(!Q_M[ii-k+1]) continue;
3961 if(!Q_M1[jj+k]) continue;
3962 for(cnt1 = k_min_values_m[ii-k+1];
3963 cnt1 <= k_max_values_m[ii-k+1];
3965 for(cnt2 = l_min_values_m[ii-k+1][cnt1];
3966 cnt2 <= l_max_values_m[ii-k+1][cnt1];
3968 for(cnt3 = k_min_values_m1[jj+k];
3969 cnt3 <= k_max_values_m1[jj+k];
3971 for(cnt4 = l_min_values_m1[jj+k][cnt3];
3972 cnt4 <= l_max_values_m1[jj+k][cnt3];
3974 if(((cnt1 + cnt3 + da) > maxD1) || ((cnt2 + cnt4 + db) > maxD2)){
3975 qt += Q_M[ii-k+1][cnt1][cnt2/2] * Q_M1[jj+k][cnt3][cnt4/2];
3976 if (qt>=r) goto backtrack_ml_early_escape;
3981 /* get total contribution */
3982 for (qt=0., k=i+1; k<j; k++){
3983 /* calculate introduced distance to reference structures */
3984 da = base_d1 - referenceBPs1[my_iindx[i]-k+1] - referenceBPs1[my_iindx[k]-j];
3985 db = base_d2 - referenceBPs2[my_iindx[i]-k+1] - referenceBPs2[my_iindx[k]-j];
3986 /* collect all contributing energies */
3987 if(d1 >= da && d2 >= db && Q_M[ii-k+1] && Q_M1[jj+k])
3988 for(cnt1 = k_min_values_m[ii-k+1]; cnt1 <= MIN2(k_max_values_m[ii-k+1], d1-da); cnt1++)
3989 for(cnt2 = l_min_values_m[ii-k+1][cnt1]; cnt2 <= MIN2(l_max_values_m[ii-k+1][cnt1], d2 - db); cnt2+=2)
3990 if((d1-cnt1-da >= k_min_values_m1[jj+k]) && (d1-cnt1-da <= k_max_values_m1[jj+k]))
3991 if((d2 - cnt2 - db >= l_min_values_m1[jj+k][d1-da-cnt1]) && (d2 - cnt2 - db <= l_max_values_m1[jj+k][d1-cnt1-da]))
3992 qt += Q_M[ii-k+1][cnt1][cnt2/2] * Q_M1[jj+k][d1-da-cnt1][(d2-db-cnt2)/2];
3995 for (qt=0., k=i+1; k<j; k++) {
3996 /* calculate introduced distance to reference structures */
3997 da = base_d1 - referenceBPs1[my_iindx[i]-k+1] - referenceBPs1[my_iindx[k]-j];
3998 db = base_d2 - referenceBPs2[my_iindx[i]-k+1] - referenceBPs2[my_iindx[k]-j];
3999 /* collect all contributing energies */
4000 if(d1 >= da && d2 >= db && Q_M[ii-k+1] && Q_M1[jj+k])
4001 for(cnt1 = k_min_values_m[ii-k+1]; cnt1 <= MIN2(k_max_values_m[ii-k+1], d1-da); cnt1++)
4002 for(cnt2 = l_min_values_m[ii-k+1][cnt1]; cnt2 <= MIN2(l_max_values_m[ii-k+1][cnt1], d2 - db); cnt2+=2)
4003 if((d1-cnt1-da >= k_min_values_m1[jj+k]) && (d1-cnt1-da <= k_max_values_m1[jj+k]))
4004 if((d2 - cnt2 - db >= l_min_values_m1[jj+k][d1-da-cnt1]) && (d2 - cnt2 - db <= l_max_values_m1[jj+k][d1-cnt1-da])){
4007 qt += Q_M[ii-k+1][cnt1][cnt2/2] * Q_M1[jj+k][cnt3][cnt4/2];
4008 if (qt>=r) goto backtrack_ml_early_escape;
4012 if (k>=j) nrerror("backtrack failed, can't find split index ");
4014 backtrack_ml_early_escape:
4016 backtrack_qm1(vars, pstruc, cnt3, cnt4, k, j);
4019 backtrack_qm(vars, pstruc, cnt1, cnt2, i, j);
4023 PRIVATE void backtrack_qm1(TwoDpfold_vars *vars, char *pstruc, int d1, int d2, unsigned int i, unsigned int j){
4024 /* i is paired to l, i<l<j; backtrack in qm1 to find l */
4025 FLT_OR_DBL r, qt, *scale;
4026 unsigned int maxD1, maxD2, da, db;
4027 unsigned int *referenceBPs1, *referenceBPs2;
4028 pf_paramT *pf_params; /* holds all [unscaled] pf parameters */
4031 int *my_iindx, *jindx, cnt1, cnt2;
4032 pf_params = vars->pf_params;
4033 maxD1 = vars->maxD1;
4034 maxD2 = vars->maxD2;
4035 my_iindx = vars->my_iindx;
4036 jindx = vars->jindx;
4037 scale = vars->scale;
4038 ptype = vars->ptype;
4040 referenceBPs1 = vars->referenceBPs1;
4041 referenceBPs2 = vars->referenceBPs2;
4043 FLT_OR_DBL ***Q_B, ***Q_M1, *Q_B_rem, *Q_M1_rem;
4044 int *k_min_values_m1, *k_max_values_m1,*k_min_values_b, *k_max_values_b;
4045 int **l_min_values_m1, **l_max_values_m1,**l_min_values_b, **l_max_values_b;
4048 k_min_values_b = vars->k_min_values_b;
4049 k_max_values_b = vars->k_max_values_b;
4050 l_min_values_b = vars->l_min_values_b;
4051 l_max_values_b = vars->l_max_values_b;
4054 k_min_values_m1 = vars->k_min_values_m1;
4055 k_max_values_m1 = vars->k_max_values_m1;
4056 l_min_values_m1 = vars->l_min_values_m1;
4057 l_max_values_m1 = vars->l_max_values_m1;
4059 Q_B_rem = vars->Q_B_rem;
4060 Q_M1_rem = vars->Q_M1_rem;
4065 /* find qm1 contribution */
4067 r = urn() * Q_M1_rem[jindx[j]+i];
4069 if((d1 >= k_min_values_m1[jindx[j]+i]) && (d1 <= k_max_values_m1[jindx[j]+i]))
4070 if((d2 >= l_min_values_m1[jindx[j]+i][d1]) && (d2 <= l_max_values_m1[jindx[j]+i][d1]))
4071 r = urn() * Q_M1[jindx[j]+i][d1][d2/2];
4073 if(r == 0.) nrerror("backtrack_qm1@2Dpfold.c: backtracking failed\n");
4076 for (qt=0., l=i+TURN+1; l<=j; l++) {
4079 FLT_OR_DBL tmp = exp_E_MLstem(type, S1[i-1], S1[l+1], pf_params) * pow(pf_params->expMLbase, j-l) * scale[j-l];
4080 /* compute the introduced distance to reference structures */
4081 da = referenceBPs1[my_iindx[i]-j] - referenceBPs1[my_iindx[i]-l];
4082 db = referenceBPs2[my_iindx[i]-j] - referenceBPs2[my_iindx[i]-l];
4085 if(Q_B_rem[ii-l] != 0.){
4086 qt += Q_B_rem[ii-l] * tmp;
4087 if(qt >= r) goto backtrack_qm1_early_escape;
4090 for(cnt1 = k_min_values_b[ii-l];
4091 cnt1 <= k_max_values_b[ii-l];
4093 for(cnt2 = l_min_values_b[ii-l][cnt1];
4094 cnt2 <= l_max_values_b[ii-l][cnt1];
4096 if(((cnt1 + da) > maxD1) || ((cnt2 + db) > maxD2)){
4097 qt += Q_B[ii-l][cnt1][cnt2/2] * tmp;
4098 if(qt >= r) goto backtrack_qm1_early_escape;
4102 /* get energy contributions */
4103 if(d1 >= da && d2 >= db)
4104 if((d1 - da >= k_min_values_b[ii-l]) && (d1 - da <= k_max_values_b[ii-l]))
4105 if((d2 - db >= l_min_values_b[ii-l][d1-da]) && (d2 - db <= l_max_values_b[ii-l][d1-da])){
4108 qt += Q_B[ii-l][cnt1][cnt2/2] * tmp;
4109 if (qt>=r) goto backtrack_qm1_early_escape;
4114 if (l>j) nrerror("backtrack failed in qm1");
4115 backtrack_qm1_early_escape:
4117 backtrack(vars, pstruc, cnt1, cnt2, i,l);
4120 PRIVATE void backtrack_qm(TwoDpfold_vars *vars, char *pstruc, int d1, int d2, unsigned int i, unsigned int j){
4121 /* divide multiloop into qm and qm1 */
4122 FLT_OR_DBL r, *scale;
4123 unsigned int maxD1, maxD2, da, db, da2, db2;
4124 unsigned int *referenceBPs1, *referenceBPs2;
4125 pf_paramT *pf_params; /* holds all [unscaled] pf parameters */
4126 int *my_iindx, *jindx, cnt1, cnt2, cnt3, cnt4;
4128 pf_params = vars->pf_params;
4129 maxD1 = vars->maxD1;
4130 maxD2 = vars->maxD2;
4131 my_iindx = vars->my_iindx;
4132 jindx = vars->jindx;
4133 scale = vars->scale;
4134 referenceBPs1 = vars->referenceBPs1;
4135 referenceBPs2 = vars->referenceBPs2;
4137 FLT_OR_DBL ***Q_M, ***Q_M1, *Q_M_rem, *Q_M1_rem;
4138 int *k_min_values_m, *k_max_values_m,*k_min_values_m1, *k_max_values_m1;
4139 int **l_min_values_m, **l_max_values_m,**l_min_values_m1, **l_max_values_m1;
4142 k_min_values_m = vars->k_min_values_m;
4143 k_max_values_m = vars->k_max_values_m;
4144 l_min_values_m = vars->l_min_values_m;
4145 l_max_values_m = vars->l_max_values_m;
4148 k_min_values_m1 = vars->k_min_values_m1;
4149 k_max_values_m1 = vars->k_max_values_m1;
4150 l_min_values_m1 = vars->l_min_values_m1;
4151 l_max_values_m1 = vars->l_max_values_m1;
4152 Q_M_rem = vars->Q_M_rem;
4153 Q_M1_rem = vars->Q_M1_rem;
4158 /* now backtrack [i ... j] in qm[] */
4160 /* find qm contribution */
4162 r = urn() * Q_M_rem[my_iindx[i]-j];
4164 if(Q_M[my_iindx[i]-j])
4165 if((d1 >= k_min_values_m[my_iindx[i]-j]) && (d1 <= k_max_values_m[my_iindx[i]-j]))
4166 if((d2 >= l_min_values_m[my_iindx[i]-j][d1]) && (d2 <= l_max_values_m[my_iindx[i]-j][d1]))
4167 r = urn() * Q_M[my_iindx[i]-j][d1][d2/2];
4169 if(r == 0.) nrerror("backtrack_qm@2Dpfold.c: backtracking failed in finding qm contribution\n");
4173 if(Q_M1_rem[jindx[j]+i] != 0.){
4174 qmt += Q_M1_rem[jindx[j]+i];
4176 backtrack_qm1(vars, pstruc, d1, d2, i, j);
4181 for(k=i+1; k<=j; k++){
4182 FLT_OR_DBL tmp = pow(pf_params->expMLbase, k-i) * scale[k-i];
4183 if(Q_M1_rem[jindx[j]+k] != 0.){
4184 qmt += Q_M1_rem[jindx[j]+k] * tmp;
4186 backtrack_qm1(vars, pstruc, d1, d2, k, j);
4190 da2 = referenceBPs1[my_iindx[i]-j] - referenceBPs1[my_iindx[k]-j];
4191 db2 = referenceBPs2[my_iindx[i]-j] - referenceBPs2[my_iindx[k]-j];
4192 if(Q_M1[jindx[j]+k])
4193 for(cnt1 = k_min_values_m1[jindx[j]+k];
4194 cnt1 <= k_max_values_m1[jindx[j]+k];
4196 for(cnt2 = l_min_values_m1[jindx[j]+k][cnt1];
4197 cnt2 <= l_max_values_m1[jindx[j]+k][cnt1];
4199 if(((cnt1 + da2) > maxD1) || ((cnt2 + db2) > maxD2)){
4200 qmt += Q_M1[jindx[j]+k][cnt1][cnt2/2] * tmp;
4202 backtrack_qm1(vars, pstruc, cnt1, cnt2, k, j);
4207 da = da2 - referenceBPs1[my_iindx[i]-k+1];
4208 db = db2 - referenceBPs2[my_iindx[i]-k+1];
4210 cnt1 = cnt2 = cnt3 = cnt4 = -1;
4211 if(Q_M_rem[my_iindx[i]-k+1] != 0.){
4212 if(Q_M1_rem[jindx[j]+k] != 0.){
4213 qmt += Q_M_rem[my_iindx[i]-k+1] * Q_M1_rem[jindx[j]+k];
4214 if(qmt >= r) goto backtrack_qm_early_escape;
4216 if(Q_M1[jindx[j]+k])
4217 for(cnt3 = k_min_values_m1[jindx[j]+k];
4218 cnt3 <= k_max_values_m1[jindx[j]+k];
4220 for(cnt4 = l_min_values_m1[jindx[j]+k][cnt3];
4221 cnt4 <= l_max_values_m1[jindx[j]+k][cnt3];
4223 qmt += Q_M_rem[my_iindx[i]-k+1] * Q_M1[jindx[j]+k][cnt3][cnt4/2];
4224 if(qmt >= r) goto backtrack_qm_early_escape;
4227 if(Q_M1_rem[jindx[j]+k] != 0.){
4229 if(Q_M[my_iindx[i]-k+1])
4230 for(cnt1 = k_min_values_m[my_iindx[i]-k+1];
4231 cnt1 <= k_max_values_m[my_iindx[i]-k+1];
4233 for(cnt2 = l_min_values_m[my_iindx[i]-k+1][cnt1];
4234 cnt2 <= l_max_values_m[my_iindx[i]-k+1][cnt1];
4236 qmt += Q_M[my_iindx[i]-k+1][cnt1][cnt2/2] * Q_M1_rem[jindx[j]+k];
4237 if(qmt >= r) goto backtrack_qm_early_escape;
4241 if(!Q_M[my_iindx[i]-k+1]) continue;
4242 if(!Q_M1[jindx[j]+k]) continue;
4243 for(cnt1 = k_min_values_m[my_iindx[i]-k+1];
4244 cnt1 <= k_max_values_m[my_iindx[i]-k+1];
4246 for(cnt2 = l_min_values_m[my_iindx[i]-k+1][cnt1];
4247 cnt2 <= l_max_values_m[my_iindx[i]-k+1][cnt1];
4249 for(cnt3 = k_min_values_m1[jindx[j]+k];
4250 cnt3 <= k_max_values_m1[jindx[j]+k];
4252 for(cnt4 = l_min_values_m1[jindx[j]+k][cnt3];
4253 cnt4 <= l_max_values_m1[jindx[j]+k][cnt3];
4255 if(((cnt1 + cnt3 + da) > maxD1) || ((cnt2 + cnt4 + db) > maxD2)){
4256 qmt += Q_M[my_iindx[i]-k+1][cnt1][cnt2/2] * Q_M1[jindx[j]+k][cnt3][cnt4/2];
4257 if(qmt >= r) goto backtrack_qm_early_escape;
4263 /* find corresponding qm1 contribution */
4264 if(Q_M1[jindx[j]+i])
4265 if((d1 >= k_min_values_m1[jindx[j]+i]) && (d1 <= k_max_values_m1[jindx[j]+i]))
4266 if((d2 >= l_min_values_m1[jindx[j]+i][d1]) && (d2 <= l_max_values_m1[jindx[j]+i][d1])){
4267 qmt = Q_M1[jindx[j]+i][d1][d2/2];
4272 for(k=i+1; k<=j; k++){
4273 /* calculate introduced distancies to reference structures */
4274 da2 = referenceBPs1[my_iindx[i]-j] - referenceBPs1[my_iindx[k]-j];
4275 db2 = referenceBPs2[my_iindx[i]-j] - referenceBPs2[my_iindx[k]-j];
4276 da = da2 - referenceBPs1[my_iindx[i]-k+1];
4277 db = db2 - referenceBPs2[my_iindx[i]-k+1];
4280 FLT_OR_DBL tmp = pow(pf_params->expMLbase, k-i) * scale[k-i];
4282 /* collect unpaired + qm1 contributions */
4283 if(d1 >= da2 && d2 >= db2)
4284 if((d1 - da2 >= k_min_values_m1[jindx[j]+k]) && (d1 - da2 <= k_max_values_m1[jindx[j]+k]))
4285 if((d2 - db2 >= l_min_values_m1[jindx[j]+k][d1-da2]) && (d2 - db2 <= l_max_values_m1[jindx[j]+k][d1-da2])){
4288 qmt += Q_M1[jindx[j]+k][cnt3][cnt4/2] * tmp;
4290 backtrack_qm1(vars, pstruc, cnt3, cnt4, k, j);
4295 /* collect qm + qm1 contributions */
4296 if(d1 >= da && d2 >= db && Q_M[my_iindx[i]-k+1] && Q_M1[jindx[j]+k])
4297 for(cnt1 = k_min_values_m[my_iindx[i]-k+1]; cnt1 <= MIN2(k_max_values_m[my_iindx[i]-k+1], d1 - da); cnt1++)
4298 for(cnt2 = l_min_values_m[my_iindx[i]-k+1][cnt1]; cnt2 <= MIN2(l_max_values_m[my_iindx[i]-k+1][cnt1], d2 - db); cnt2+=2)
4299 if((d1 - da - cnt1 >= k_min_values_m1[jindx[j]+k]) && (d1 - da - cnt1 <= k_max_values_m1[jindx[j]+k]))
4300 if((d2 - db - cnt2 >= l_min_values_m1[jindx[j]+k][d1-da-cnt1]) && (d2 - db - cnt2 <= l_max_values_m1[jindx[j]+k][d1-da-cnt1])){
4301 cnt3 = d1 - da - cnt1;
4302 cnt4 = d2 - db - cnt2;
4303 qmt += Q_M[my_iindx[i]-k+1][cnt1][cnt2/2] * Q_M1[jindx[j]+k][cnt3][cnt4/2];
4304 if(qmt >= r) goto backtrack_qm_early_escape;
4309 backtrack_qm1(vars, pstruc, d1, d2, k, j);
4314 if(k>j) nrerror("backtrack_qm@2Dpfold.c: backtrack failed in qm");
4316 backtrack_qm_early_escape:
4318 backtrack_qm1(vars, pstruc, cnt3, cnt4, k, j);
4320 if(k<i+TURN) break; /* no more pairs */
4326 if(d1 == referenceBPs1[my_iindx[i]-k+1] && d2 == referenceBPs2[my_iindx[i]-k+1]){
4327 /* is interval [i,k] totally unpaired? */
4328 FLT_OR_DBL tmp = pow(pf_params->expMLbase, k-i) * scale[k-i];
4329 r = urn() * (Q_M[my_iindx[i]-k+1][d1][d2/2] + tmp);
4330 if(tmp >= r) return; /* no more pairs */
4339 PRIVATE void adjustArrayBoundaries(FLT_OR_DBL ***array,
4340 int *k_min, int *k_max,
4341 int **l_min, int **l_max,
4342 int k_min_post, int k_max_post,
4343 int *l_min_post, int *l_max_post){
4346 int k_diff_pre = k_min_post - *k_min;
4347 int mem_size = k_max_post - k_min_post + 1;
4349 if(k_min_post < INF){
4350 /* free all the unused memory behind actual data */
4351 for(cnt1 = k_max_post + 1; cnt1 <= *k_max; cnt1++){
4352 (*array)[cnt1] += (*l_min)[cnt1]/2;
4353 free((*array)[cnt1]);
4356 /* free unused memory before actual data */
4357 for(cnt1 = *k_min; cnt1 < k_min_post; cnt1++){
4358 (*array)[cnt1] += (*l_min)[cnt1]/2;
4359 free((*array)[cnt1]);
4361 /* move data to front and thereby eliminating unused memory in front of actual data */
4363 memmove((FLT_OR_DBL **)(*array),((FLT_OR_DBL **)(*array)) + k_diff_pre, sizeof(FLT_OR_DBL *) * mem_size);
4364 memmove((int *) (*l_min),((int *) (*l_min)) + k_diff_pre, sizeof(int) * mem_size);
4365 memmove((int *) (*l_max),((int *) (*l_max)) + k_diff_pre, sizeof(int) * mem_size);
4368 /* reallocating memory to actual size used */
4370 *array = (FLT_OR_DBL **)realloc(*array, sizeof(FLT_OR_DBL *) * mem_size);
4371 *array -= k_min_post;
4374 *l_min = (int *)realloc(*l_min, sizeof(int) * mem_size);
4375 *l_min -= k_min_post;
4378 *l_max = (int *)realloc(*l_max, sizeof(int) * mem_size);
4379 *l_max -= k_min_post;
4382 for(cnt1 = k_min_post; cnt1 <= k_max_post; cnt1++){
4383 if(l_min_post[cnt1] < INF){
4385 mem_size = (l_max_post[cnt1] - l_min_post[cnt1] + 1)/2 + 1;
4386 /* reshift the pointer */
4387 (*array)[cnt1] += (*l_min)[cnt1]/2;
4389 int shift = (l_min_post[cnt1]%2 == (*l_min)[cnt1]%2) ? 0 : 1;
4390 /* eliminate unused memory in front of actual data */
4391 unsigned int start = (l_min_post[cnt1] - (*l_min)[cnt1])/2 + shift;
4393 memmove((FLT_OR_DBL *)((*array)[cnt1]), (FLT_OR_DBL *)((*array)[cnt1])+start, sizeof(FLT_OR_DBL) * mem_size);
4394 (*array)[cnt1] = (FLT_OR_DBL *) realloc((*array)[cnt1], sizeof(FLT_OR_DBL) * mem_size);
4396 (*array)[cnt1] -= l_min_post[cnt1]/2;
4399 /* free according memory */
4400 (*array)[cnt1] += (*l_min)[cnt1]/2;
4401 free((*array)[cnt1]);
4404 (*l_min)[cnt1] = l_min_post[cnt1];
4405 (*l_max)[cnt1] = l_max_post[cnt1];
4409 /* we have to free all unused memory */
4410 for(cnt1 = *k_min; cnt1 <= *k_max; cnt1++){
4411 (*array)[cnt1] += (*l_min)[cnt1]/2;
4412 free((*array)[cnt1]);
4423 l_min_post += *k_min;
4424 l_max_post += *k_min;
4425 *k_min = k_min_post;
4426 *k_max = k_max_post;
4433 INLINE PRIVATE void preparePosteriorBoundaries(int size, int shift, int *min_k, int *max_k, int **min_l, int **max_l){
4438 *min_l = (int *)space(sizeof(int) * size);
4439 *max_l = (int *)space(sizeof(int) * size);
4441 for(i = 0; i < size; i++){
4450 INLINE PRIVATE void updatePosteriorBoundaries(int d1, int d2, int *min_k, int *max_k, int **min_l, int **max_l){
4451 (*min_l)[d1] = MIN2((*min_l)[d1], d2);
4452 (*max_l)[d1] = MAX2((*max_l)[d1], d2);
4453 *min_k = MIN2(*min_k, d1);
4454 *max_k = MAX2(*max_k, d1);
4457 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){
4459 int mem = max_k_pre - min_k_pre + 1;
4463 *min_l = (int *) space(sizeof(int) * mem);
4464 *max_l = (int *) space(sizeof(int) * mem);
4466 *min_l -= min_k_pre;
4467 *max_l -= min_k_pre;
4469 /* for each k guess the according minimum l*/
4470 for(cnt = min_k_pre; cnt <= max_k_pre; cnt++){
4471 (*min_l)[cnt] = min_l_pre;
4472 (*max_l)[cnt] = max_l_pre;
4473 while((*min_l)[cnt] + cnt < bpdist) (*min_l)[cnt]++;
4474 if((bpdist % 2) != (((*min_l)[cnt] + cnt) % 2)) (*min_l)[cnt]++;
4478 INLINE PRIVATE void prepareArray(FLT_OR_DBL ***array, int min_k, int max_k, int *min_l, int *max_l){
4480 *array = (FLT_OR_DBL **)space(sizeof(FLT_OR_DBL *) * (max_k - min_k + 1));
4483 for(i = min_k; i <= max_k; i++){
4484 mem = (max_l[i] - min_l[i] + 1)/2 + 1;
4485 (*array)[i] = (FLT_OR_DBL *)space(sizeof(FLT_OR_DBL) * mem);
4486 (*array)[i] -= min_l[i]/2;