1struct sc_mb_exp_dat;
2
3typedef FLT_OR_DBL (sc_mb_exp_pair_cb)(int                  i,
4                                       int                  j,
5                                       struct sc_mb_exp_dat *data);
6
7
8typedef FLT_OR_DBL (sc_mb_exp_red_cb)(int                   i,
9                                      int                   j,
10                                      int                   k,
11                                      int                   l,
12                                      struct sc_mb_exp_dat  *data);
13
14
15struct sc_mb_exp_dat {
16  unsigned int                n_seq;
17  unsigned int                **a2s;
18
19  int                         *idx;
20
21  FLT_OR_DBL                  **up;
22  FLT_OR_DBL                  ***up_comparative;
23  FLT_OR_DBL                  *bp;
24  FLT_OR_DBL                  **bp_comparative;
25  FLT_OR_DBL                  **bp_local;
26  FLT_OR_DBL                  ***bp_local_comparative;
27
28  sc_mb_exp_pair_cb           *pair;
29  sc_mb_exp_red_cb            *red_stem;
30  sc_mb_exp_red_cb            *red_ml;
31  sc_mb_exp_red_cb            *decomp_ml;
32
33  vrna_callback_sc_exp_energy *user_cb;
34  void                        *user_data;
35
36  vrna_callback_sc_exp_energy **user_cb_comparative;
37  void                        **user_data_comparative;
38};
39
40
41PRIVATE INLINE FLT_OR_DBL
42sc_mb_exp_pair_cb_bp(int                  i,
43                     int                  j,
44                     struct sc_mb_exp_dat *data)
45{
46  return data->bp[data->idx[j] + i];
47}
48
49
50PRIVATE INLINE FLT_OR_DBL
51sc_mb_exp_pair_cb_bp_comparative(int                  i,
52                                 int                  j,
53                                 struct sc_mb_exp_dat *data)
54{
55  unsigned int  s;
56  FLT_OR_DBL    sc;
57
58  sc = 1.;
59
60  for (s = 0; s < data->n_seq; s++)
61    if (data->bp_comparative[s])
62      sc *= data->bp_comparative[s][data->idx[j] + i];
63
64  return sc;
65}
66
67
68PRIVATE INLINE FLT_OR_DBL
69sc_mb_exp_pair_cb_bp_local(int                  i,
70                           int                  j,
71                           struct sc_mb_exp_dat *data)
72{
73  return data->bp_local[i][j - i];
74}
75
76
77PRIVATE INLINE FLT_OR_DBL
78sc_mb_exp_pair_cb_bp_local_comparative(int                  i,
79                                       int                  j,
80                                       struct sc_mb_exp_dat *data)
81{
82  unsigned int  s;
83  FLT_OR_DBL    sc;
84
85  sc = 1.;
86
87  for (s = 0; s < data->n_seq; s++)
88    if (data->bp_local_comparative[s])
89      sc *= data->bp_local_comparative[s][i][j - i];
90
91  return sc;
92}
93
94
95PRIVATE INLINE FLT_OR_DBL
96sc_mb_exp_pair_cb_user(int                  i,
97                       int                  j,
98                       struct sc_mb_exp_dat *data)
99{
100  return data->user_cb(i, j, i + 1, j - 1,
101                       VRNA_DECOMP_PAIR_ML,
102                       data->user_data);
103}
104
105
106PRIVATE INLINE FLT_OR_DBL
107sc_mb_exp_pair_cb_user_comparative(int                  i,
108                                   int                  j,
109                                   struct sc_mb_exp_dat *data)
110{
111  unsigned int  s;
112  FLT_OR_DBL    sc;
113
114  sc = 1.;
115
116  for (s = 0; s < data->n_seq; s++)
117    if (data->user_cb_comparative[s])
118      sc *= data->user_cb_comparative[s](i, j, i + 1, j - 1,
119                                         VRNA_DECOMP_PAIR_ML,
120                                         data->user_data_comparative[s]);
121
122  return sc;
123}
124
125
126PRIVATE INLINE FLT_OR_DBL
127sc_mb_exp_pair_cb_bp_user(int                   i,
128                          int                   j,
129                          struct sc_mb_exp_dat  *data)
130{
131  return sc_mb_exp_pair_cb_bp(i, j, data) *
132         sc_mb_exp_pair_cb_user(i, j, data);
133}
134
135
136PRIVATE INLINE FLT_OR_DBL
137sc_mb_exp_pair_cb_bp_user_comparative(int                   i,
138                                      int                   j,
139                                      struct sc_mb_exp_dat  *data)
140{
141  return sc_mb_exp_pair_cb_bp_comparative(i, j, data) *
142         sc_mb_exp_pair_cb_user_comparative(i, j, data);
143}
144
145
146PRIVATE INLINE FLT_OR_DBL
147sc_mb_exp_pair_cb_bp_local_user(int                   i,
148                                int                   j,
149                                struct sc_mb_exp_dat  *data)
150{
151  return sc_mb_exp_pair_cb_bp_local(i, j, data) *
152         sc_mb_exp_pair_cb_user(i, j, data);
153}
154
155
156PRIVATE INLINE FLT_OR_DBL
157sc_mb_exp_pair_cb_bp_local_user_comparative(int                   i,
158                                            int                   j,
159                                            struct sc_mb_exp_dat  *data)
160{
161  return sc_mb_exp_pair_cb_bp_local_comparative(i, j, data) *
162         sc_mb_exp_pair_cb_user_comparative(i, j, data);
163}
164
165
166PRIVATE INLINE FLT_OR_DBL
167sc_mb_exp_red_cb_up(int                   i,
168                    int                   j,
169                    int                   k,
170                    int                   l,
171                    struct sc_mb_exp_dat  *data)
172{
173  int         l1  = k - i;
174  int         l2  = j - l;
175  FLT_OR_DBL  sc  = 1.;
176
177  if (l1 > 0)
178    sc *= data->up[i][l1];
179
180  if (l2 > 0)
181    sc *= data->up[l + 1][l2];
182
183  return sc;
184}
185
186
187PRIVATE INLINE FLT_OR_DBL
188sc_mb_exp_red_cb_up_comparative(int                   i,
189                                int                   j,
190                                int                   k,
191                                int                   l,
192                                struct sc_mb_exp_dat  *data)
193{
194  unsigned int  s;
195  int           l1, l2, start2;
196  FLT_OR_DBL    sc;
197
198  sc = 1.;
199
200  for (s = 0; s < data->n_seq; s++) {
201    if (data->up_comparative[s]) {
202      l1      = data->a2s[s][k] - data->a2s[s][i];
203      l2      = data->a2s[s][j] - data->a2s[s][l];
204      start2  = data->a2s[s][l] + 1;
205
206      if (l1 > 0)
207        sc *= data->up_comparative[s][data->a2s[s][i]][l1];
208
209      if (l2 > 0)
210        sc *= data->up_comparative[s][start2][l2];
211    }
212  }
213
214  return sc;
215}
216
217
218PRIVATE INLINE FLT_OR_DBL
219sc_mb_exp_red_cb_user(int                   i,
220                      int                   j,
221                      int                   k,
222                      int                   l,
223                      struct sc_mb_exp_dat  *data)
224{
225  return data->user_cb(i, j, k, l,
226                       VRNA_DECOMP_ML_ML,
227                       data->user_data);
228}
229
230
231PRIVATE INLINE FLT_OR_DBL
232sc_mb_exp_red_cb_user_comparative(int                   i,
233                                  int                   j,
234                                  int                   k,
235                                  int                   l,
236                                  struct sc_mb_exp_dat  *data)
237{
238  unsigned int  s;
239  FLT_OR_DBL    sc;
240
241  sc = 1.;
242
243  for (s = 0; s < data->n_seq; s++)
244    if (data->user_cb_comparative[s])
245      sc *= data->user_cb_comparative[s](i, j, k, l,
246                                         VRNA_DECOMP_ML_ML,
247                                         data->user_data_comparative[s]);
248
249  return sc;
250}
251
252
253PRIVATE INLINE FLT_OR_DBL
254sc_mb_exp_red_cb_up_user(int                  i,
255                         int                  j,
256                         int                  k,
257                         int                  l,
258                         struct sc_mb_exp_dat *data)
259{
260  return sc_mb_exp_red_cb_up(i, j, k, l, data) *
261         sc_mb_exp_red_cb_user(i, j, k, l, data);
262}
263
264
265PRIVATE INLINE FLT_OR_DBL
266sc_mb_exp_red_cb_up_user_comparative(int                  i,
267                                     int                  j,
268                                     int                  k,
269                                     int                  l,
270                                     struct sc_mb_exp_dat *data)
271{
272  return sc_mb_exp_red_cb_up_comparative(i, j, k, l, data) *
273         sc_mb_exp_red_cb_user_comparative(i, j, k, l, data);
274}
275
276
277PRIVATE INLINE FLT_OR_DBL
278sc_mb_exp_red_cb_stem_user(int                  i,
279                           int                  j,
280                           int                  k,
281                           int                  l,
282                           struct sc_mb_exp_dat *data)
283{
284  return data->user_cb(i, j, k, l,
285                       VRNA_DECOMP_ML_STEM,
286                       data->user_data);
287}
288
289
290PRIVATE INLINE FLT_OR_DBL
291sc_mb_exp_red_cb_stem_user_comparative(int                  i,
292                                       int                  j,
293                                       int                  k,
294                                       int                  l,
295                                       struct sc_mb_exp_dat *data)
296{
297  unsigned int  s;
298  FLT_OR_DBL    sc;
299
300  sc = 1.;
301
302  for (s = 0; s < data->n_seq; s++)
303    if (data->user_cb_comparative[s])
304      sc *= data->user_cb_comparative[s](i, j, k, l,
305                                         VRNA_DECOMP_ML_STEM,
306                                         data->user_data);
307
308  return sc;
309}
310
311
312PRIVATE INLINE FLT_OR_DBL
313sc_mb_exp_red_cb_stem_up_user(int                   i,
314                              int                   j,
315                              int                   k,
316                              int                   l,
317                              struct sc_mb_exp_dat  *data)
318{
319  return sc_mb_exp_red_cb_up(i, j, k, l, data) *
320         sc_mb_exp_red_cb_stem_user(i, j, k, l, data);
321}
322
323
324PRIVATE INLINE FLT_OR_DBL
325sc_mb_exp_red_cb_stem_up_user_comparative(int                   i,
326                                          int                   j,
327                                          int                   k,
328                                          int                   l,
329                                          struct sc_mb_exp_dat  *data)
330{
331  return sc_mb_exp_red_cb_up_comparative(i, j, k, l, data) *
332         sc_mb_exp_red_cb_stem_user_comparative(i, j, k, l, data);
333}
334
335
336PRIVATE INLINE FLT_OR_DBL
337sc_mb_exp_split_cb_user(int                   i,
338                        int                   j,
339                        int                   k,
340                        int                   l,
341                        struct sc_mb_exp_dat  *data)
342{
343  return data->user_cb(i, j, k, l,
344                       VRNA_DECOMP_ML_ML_ML,
345                       data->user_data);
346}
347
348
349PRIVATE INLINE FLT_OR_DBL
350sc_mb_exp_split_cb_user_comparative(int                   i,
351                                    int                   j,
352                                    int                   k,
353                                    int                   l,
354                                    struct sc_mb_exp_dat  *data)
355{
356  unsigned int  s;
357  FLT_OR_DBL    sc;
358
359  sc = 1.;
360
361  for (s = 0; s < data->n_seq; s++)
362    if (data->user_cb_comparative[s])
363      sc *= data->user_cb_comparative[s](i, j, k, l,
364                                         VRNA_DECOMP_ML_ML_ML,
365                                         data->user_data_comparative[s]);
366
367  return sc;
368}
369
370
371PRIVATE INLINE void
372init_sc_mb_exp(vrna_fold_compound_t *fc,
373               struct sc_mb_exp_dat *sc_wrapper)
374{
375  unsigned char sliding_window;
376  vrna_sc_t     *sc, **scs;
377
378  sc_wrapper->n_seq = 1;
379  sc_wrapper->idx   = fc->jindx;
380  sc_wrapper->a2s   = NULL;
381
382  sc_wrapper->up                    = NULL;
383  sc_wrapper->up_comparative        = NULL;
384  sc_wrapper->bp                    = NULL;
385  sc_wrapper->bp_comparative        = NULL;
386  sc_wrapper->bp_local              = NULL;
387  sc_wrapper->bp_local_comparative  = NULL;
388
389  sc_wrapper->user_cb               = NULL;
390  sc_wrapper->user_data             = NULL;
391  sc_wrapper->user_cb_comparative   = NULL;
392  sc_wrapper->user_data_comparative = NULL;
393
394  sc_wrapper->pair      = NULL;
395  sc_wrapper->red_stem  = NULL;
396  sc_wrapper->red_ml    = NULL;
397  sc_wrapper->decomp_ml = NULL;
398
399  sliding_window = (fc->hc->type == VRNA_HC_WINDOW) ? 1 : 0;
400
401  switch (fc->type) {
402    case VRNA_FC_TYPE_SINGLE:
403      sc = fc->sc;
404
405      if (sc) {
406        unsigned int provides_sc_up, provides_sc_bp, provides_sc_user;
407
408        provides_sc_up    = 0;
409        provides_sc_bp    = 0;
410        provides_sc_user  = 0;
411
412        sc_wrapper->up        = sc->exp_energy_up;
413        sc_wrapper->user_cb   = sc->exp_f;
414        sc_wrapper->user_data = sc->data;
415
416        if (sliding_window)
417          sc_wrapper->bp_local = sc->exp_energy_bp_local;
418        else
419          sc_wrapper->bp = sc->exp_energy_bp;
420
421        if (sc->exp_energy_up)
422          provides_sc_up = 1;
423
424        if (sliding_window) {
425          if (sc->exp_energy_bp_local)
426            provides_sc_bp = 1;
427        } else if (sc->exp_energy_bp) {
428          provides_sc_bp = 1;
429        }
430
431        if (sc->exp_f)
432          provides_sc_user = 1;
433
434        /* done initializing, now assign function pointers */
435        if (provides_sc_user) {
436          sc_wrapper->decomp_ml = &sc_mb_exp_split_cb_user;
437          sc_wrapper->red_stem  = &sc_mb_exp_red_cb_stem_user;
438          sc_wrapper->red_ml    = &sc_mb_exp_red_cb_user;
439          sc_wrapper->pair      = &sc_mb_exp_pair_cb_user;
440
441          if (provides_sc_bp) {
442            if (sliding_window)
443              sc_wrapper->pair = &sc_mb_exp_pair_cb_bp_local_user;
444            else
445              sc_wrapper->pair = &sc_mb_exp_pair_cb_bp_user;
446          }
447
448          if (provides_sc_up) {
449            sc_wrapper->red_stem  = &sc_mb_exp_red_cb_stem_up_user;
450            sc_wrapper->red_ml    = &sc_mb_exp_red_cb_up_user;
451          }
452        } else if (provides_sc_bp) {
453          if (sliding_window)
454            sc_wrapper->pair = &sc_mb_exp_pair_cb_bp_local;
455          else
456            sc_wrapper->pair = &sc_mb_exp_pair_cb_bp;
457
458          if (provides_sc_up) {
459            sc_wrapper->red_stem  = &sc_mb_exp_red_cb_up;
460            sc_wrapper->red_ml    = &sc_mb_exp_red_cb_up;
461          }
462        } else if (provides_sc_up) {
463          sc_wrapper->red_stem  = &sc_mb_exp_red_cb_up;
464          sc_wrapper->red_ml    = &sc_mb_exp_red_cb_up;
465        }
466      }
467
468      break;
469
470    case VRNA_FC_TYPE_COMPARATIVE:
471      sc_wrapper->a2s   = fc->a2s;
472      sc_wrapper->n_seq = fc->n_seq;
473      scs               = fc->scs;
474
475      if (scs) {
476        unsigned int s, provides_sc_up, provides_sc_bp, provides_sc_user;
477
478        provides_sc_up    = 0;
479        provides_sc_bp    = 0;
480        provides_sc_user  = 0;
481
482        sc_wrapper->up_comparative = (FLT_OR_DBL ***)vrna_alloc(
483          sizeof(FLT_OR_DBL * *) *
484          fc->n_seq);
485
486        sc_wrapper->bp_comparative = (FLT_OR_DBL **)vrna_alloc(
487          sizeof(FLT_OR_DBL *) *
488          fc->n_seq);
489
490        sc_wrapper->bp_local_comparative = (FLT_OR_DBL ***)vrna_alloc(
491          sizeof(FLT_OR_DBL * *) *
492          fc->n_seq);
493
494        sc_wrapper->user_cb_comparative = (vrna_callback_sc_exp_energy **)vrna_alloc(
495          sizeof(vrna_callback_sc_exp_energy *) *
496          fc->n_seq);
497
498        sc_wrapper->user_data_comparative = (void **)vrna_alloc(
499          sizeof(void *) *
500          fc->n_seq);
501
502        for (s = 0; s < fc->n_seq; s++) {
503          if (scs[s]) {
504            sc_wrapper->up_comparative[s]       = scs[s]->exp_energy_up;
505            sc_wrapper->bp_comparative[s]       = (sliding_window) ? NULL : scs[s]->exp_energy_bp;
506            sc_wrapper->bp_local_comparative[s] =
507              (sliding_window) ? scs[s]->exp_energy_bp_local : NULL;
508            sc_wrapper->user_cb_comparative[s]    = scs[s]->exp_f;
509            sc_wrapper->user_data_comparative[s]  = scs[s]->data;
510
511            if (scs[s]->exp_energy_up)
512              provides_sc_up = 1;
513
514            if (sliding_window) {
515              if (scs[s]->exp_energy_bp_local)
516                provides_sc_bp = 1;
517            } else if (scs[s]->exp_energy_bp) {
518              provides_sc_bp = 1;
519            }
520
521            if (scs[s]->exp_f)
522              provides_sc_user = 1;
523          }
524        }
525
526        /* done initializing, now assign function pointers */
527        if (provides_sc_user) {
528          sc_wrapper->decomp_ml = &sc_mb_exp_split_cb_user_comparative;
529          sc_wrapper->red_stem  = &sc_mb_exp_red_cb_stem_user_comparative;
530          sc_wrapper->red_ml    = &sc_mb_exp_red_cb_user_comparative;
531          sc_wrapper->pair      = &sc_mb_exp_pair_cb_user_comparative;
532
533          if (provides_sc_bp) {
534            if (sliding_window)
535              sc_wrapper->pair = &sc_mb_exp_pair_cb_bp_local_user_comparative;
536            else
537              sc_wrapper->pair = &sc_mb_exp_pair_cb_bp_user_comparative;
538          }
539
540          if (provides_sc_up) {
541            sc_wrapper->red_stem  = &sc_mb_exp_red_cb_stem_up_user_comparative;
542            sc_wrapper->red_ml    = &sc_mb_exp_red_cb_up_user_comparative;
543          }
544        } else if (provides_sc_bp) {
545          if (sliding_window)
546            sc_wrapper->pair = &sc_mb_exp_pair_cb_bp_local_comparative;
547          else
548            sc_wrapper->pair = &sc_mb_exp_pair_cb_bp_comparative;
549
550          if (provides_sc_up) {
551            sc_wrapper->red_stem  = &sc_mb_exp_red_cb_up_comparative;
552            sc_wrapper->red_ml    = &sc_mb_exp_red_cb_up_comparative;
553          }
554        } else if (provides_sc_up) {
555          sc_wrapper->red_stem  = &sc_mb_exp_red_cb_up_comparative;
556          sc_wrapper->red_ml    = &sc_mb_exp_red_cb_up_comparative;
557        }
558      }
559
560      break;
561  }
562}
563
564
565PRIVATE INLINE void
566free_sc_mb_exp(struct sc_mb_exp_dat *sc_wrapper)
567{
568  free(sc_wrapper->up_comparative);
569  free(sc_wrapper->bp_comparative);
570  free(sc_wrapper->bp_local_comparative);
571  free(sc_wrapper->user_cb_comparative);
572  free(sc_wrapper->user_data_comparative);
573}
574