1struct sc_int_exp_dat;
2
3typedef FLT_OR_DBL (sc_int_exp_cb)(int                    i,
4                                   int                    j,
5                                   int                    k,
6                                   int                    l,
7                                   struct sc_int_exp_dat  *data);
8
9struct sc_int_exp_dat {
10  unsigned int                n;
11  int                         n_seq;
12  unsigned int                **a2s;
13
14  int                         *idx;
15  FLT_OR_DBL                  **up;
16  FLT_OR_DBL                  ***up_comparative;
17  FLT_OR_DBL                  *bp;
18  FLT_OR_DBL                  **bp_comparative;
19  FLT_OR_DBL                  **bp_local;
20  FLT_OR_DBL                  ***bp_local_comparative;
21  FLT_OR_DBL                  *stack;
22  FLT_OR_DBL                  **stack_comparative;
23
24  vrna_callback_sc_exp_energy *user_cb;
25  void                        *user_data;
26
27  vrna_callback_sc_exp_energy **user_cb_comparative;
28  void                        **user_data_comparative;
29
30  sc_int_exp_cb               *pair;
31  sc_int_exp_cb               *pair_ext;
32};
33
34
35PRIVATE INLINE FLT_OR_DBL
36sc_int_exp_cb_up(int                    i,
37                 int                    j,
38                 int                    k,
39                 int                    l,
40                 struct sc_int_exp_dat  *data)
41{
42  int         u1, u2;
43  FLT_OR_DBL  sc;
44
45  u1  = k - i - 1;
46  u2  = j - l - 1;
47
48  sc = 1.;
49
50  if (u1 > 0)
51    sc *= data->up[i + 1][u1];
52
53  if (u2 > 0)
54    sc *= data->up[l + 1][u2];
55
56  return sc;
57}
58
59
60PRIVATE INLINE FLT_OR_DBL
61sc_int_exp_cb_up_comparative(int                    i,
62                             int                    j,
63                             int                    k,
64                             int                    l,
65                             struct sc_int_exp_dat  *data)
66{
67  unsigned int  s;
68  int           u1, u2;
69  FLT_OR_DBL    sc;
70
71  sc = 1.;
72
73  for (s = 0; s < data->n_seq; s++)
74    if (data->up_comparative[s]) {
75      u1  = data->a2s[s][k - 1] - data->a2s[s][i];
76      u2  = data->a2s[s][j - 1] - data->a2s[s][l];
77
78      if (u1 > 0)
79        sc *= data->up_comparative[s][data->a2s[s][i + 1]][u1];
80
81      if (u2 > 0)
82        sc *= data->up_comparative[s][data->a2s[s][l + 1]][u2];
83    }
84
85  return sc;
86}
87
88
89PRIVATE INLINE FLT_OR_DBL
90sc_int_exp_cb_bp(int                    i,
91                 int                    j,
92                 int                    k,
93                 int                    l,
94                 struct sc_int_exp_dat  *data)
95{
96  return data->bp[data->idx[j] + i];
97}
98
99
100PRIVATE INLINE FLT_OR_DBL
101sc_int_exp_cb_bp_comparative(int                    i,
102                             int                    j,
103                             int                    k,
104                             int                    l,
105                             struct sc_int_exp_dat  *data)
106{
107  unsigned int  s;
108  FLT_OR_DBL    sc;
109
110  sc = 1.;
111
112  for (s = 0; s < data->n_seq; s++)
113    if (data->bp_comparative[s])
114      sc *= data->bp_comparative[s][data->idx[j] + i];
115
116  return sc;
117}
118
119
120PRIVATE INLINE FLT_OR_DBL
121sc_int_exp_cb_bp_local(int                    i,
122                       int                    j,
123                       int                    k,
124                       int                    l,
125                       struct sc_int_exp_dat  *data)
126{
127  return data->bp_local[i][j - i];
128}
129
130
131PRIVATE INLINE FLT_OR_DBL
132sc_int_exp_cb_bp_local_comparative(int                    i,
133                                   int                    j,
134                                   int                    k,
135                                   int                    l,
136                                   struct sc_int_exp_dat  *data)
137{
138  unsigned int  s;
139  FLT_OR_DBL    sc;
140
141  sc = 1.;
142
143  for (s = 0; s < data->n_seq; s++)
144    if (data->bp_local_comparative[s])
145      sc *= data->bp_local_comparative[s][i][j - i];
146
147  return sc;
148}
149
150
151PRIVATE INLINE FLT_OR_DBL
152sc_int_exp_cb_stack(int                   i,
153                    int                   j,
154                    int                   k,
155                    int                   l,
156                    struct sc_int_exp_dat *data)
157{
158  FLT_OR_DBL sc;
159
160  sc = 1.;
161
162  if ((i + 1 == k) && (l + 1 == j)) {
163    sc *= data->stack[i] *
164          data->stack[k] *
165          data->stack[l] *
166          data->stack[j];
167  }
168
169  return sc;
170}
171
172
173PRIVATE INLINE FLT_OR_DBL
174sc_int_exp_cb_stack_comparative(int                   i,
175                                int                   j,
176                                int                   k,
177                                int                   l,
178                                struct sc_int_exp_dat *data)
179{
180  unsigned int  s;
181  FLT_OR_DBL    sc;
182
183  sc = 1.;
184
185  for (s = 0; s < data->n_seq; s++)
186    if (data->stack_comparative[s]) {
187      if ((data->a2s[s][k - 1] == data->a2s[s][i]) && (data->a2s[s][j - 1] == data->a2s[s][l])) {
188        sc *= data->stack_comparative[s][data->a2s[s][i]] *
189              data->stack_comparative[s][data->a2s[s][k]] *
190              data->stack_comparative[s][data->a2s[s][l]] *
191              data->stack_comparative[s][data->a2s[s][j]];
192      }
193    }
194
195  return sc;
196}
197
198
199PRIVATE INLINE FLT_OR_DBL
200sc_int_exp_cb_user(int                    i,
201                   int                    j,
202                   int                    k,
203                   int                    l,
204                   struct sc_int_exp_dat  *data)
205{
206  return data->user_cb(i, j, k, l,
207                       VRNA_DECOMP_PAIR_IL,
208                       data->user_data);
209}
210
211
212PRIVATE INLINE FLT_OR_DBL
213sc_int_exp_cb_user_comparative(int                    i,
214                               int                    j,
215                               int                    k,
216                               int                    l,
217                               struct sc_int_exp_dat  *data)
218{
219  unsigned int  s;
220  FLT_OR_DBL    sc;
221
222  sc = 1.;
223
224  for (s = 0; s < data->n_seq; s++)
225    if (data->user_cb_comparative[s]) {
226      sc *= data->user_cb_comparative[s](i, j, k, l,
227                                         VRNA_DECOMP_PAIR_IL,
228                                         data->user_data_comparative[s]);
229    }
230
231  return sc;
232}
233
234
235PRIVATE INLINE FLT_OR_DBL
236sc_int_exp_cb_up_bp(int                   i,
237                    int                   j,
238                    int                   k,
239                    int                   l,
240                    struct sc_int_exp_dat *data)
241{
242  return sc_int_exp_cb_up(i, j, k, l, data) *
243         sc_int_exp_cb_bp(i, j, k, l, data);
244}
245
246
247PRIVATE INLINE FLT_OR_DBL
248sc_int_exp_cb_up_bp_comparative(int                   i,
249                                int                   j,
250                                int                   k,
251                                int                   l,
252                                struct sc_int_exp_dat *data)
253{
254  return sc_int_exp_cb_up_comparative(i, j, k, l, data) *
255         sc_int_exp_cb_bp_comparative(i, j, k, l, data);
256}
257
258
259PRIVATE INLINE FLT_OR_DBL
260sc_int_exp_cb_up_bp_local(int                   i,
261                          int                   j,
262                          int                   k,
263                          int                   l,
264                          struct sc_int_exp_dat *data)
265{
266  return sc_int_exp_cb_up(i, j, k, l, data) *
267         sc_int_exp_cb_bp_local(i, j, k, l, data);
268}
269
270
271PRIVATE INLINE FLT_OR_DBL
272sc_int_exp_cb_up_bp_local_comparative(int                   i,
273                                      int                   j,
274                                      int                   k,
275                                      int                   l,
276                                      struct sc_int_exp_dat *data)
277{
278  return sc_int_exp_cb_up_comparative(i, j, k, l, data) *
279         sc_int_exp_cb_bp_local_comparative(i, j, k, l, data);
280}
281
282
283PRIVATE INLINE FLT_OR_DBL
284sc_int_exp_cb_up_stack(int                    i,
285                       int                    j,
286                       int                    k,
287                       int                    l,
288                       struct sc_int_exp_dat  *data)
289{
290  return sc_int_exp_cb_up(i, j, k, l, data) *
291         sc_int_exp_cb_stack(i, j, k, l, data);
292}
293
294
295PRIVATE INLINE FLT_OR_DBL
296sc_int_exp_cb_up_stack_comparative(int                    i,
297                                   int                    j,
298                                   int                    k,
299                                   int                    l,
300                                   struct sc_int_exp_dat  *data)
301{
302  return sc_int_exp_cb_up_comparative(i, j, k, l, data) *
303         sc_int_exp_cb_stack_comparative(i, j, k, l, data);
304}
305
306
307PRIVATE INLINE FLT_OR_DBL
308sc_int_exp_cb_up_user(int                   i,
309                      int                   j,
310                      int                   k,
311                      int                   l,
312                      struct sc_int_exp_dat *data)
313{
314  return sc_int_exp_cb_up(i, j, k, l, data) *
315         sc_int_exp_cb_user(i, j, k, l, data);
316}
317
318
319PRIVATE INLINE FLT_OR_DBL
320sc_int_exp_cb_up_user_comparative(int                   i,
321                                  int                   j,
322                                  int                   k,
323                                  int                   l,
324                                  struct sc_int_exp_dat *data)
325{
326  return sc_int_exp_cb_up_comparative(i, j, k, l, data) *
327         sc_int_exp_cb_user_comparative(i, j, k, l, data);
328}
329
330
331PRIVATE INLINE FLT_OR_DBL
332sc_int_exp_cb_bp_stack(int                    i,
333                       int                    j,
334                       int                    k,
335                       int                    l,
336                       struct sc_int_exp_dat  *data)
337{
338  return sc_int_exp_cb_bp(i, j, k, l, data) *
339         sc_int_exp_cb_stack(i, j, k, l, data);
340}
341
342
343PRIVATE INLINE FLT_OR_DBL
344sc_int_exp_cb_bp_stack_comparative(int                    i,
345                                   int                    j,
346                                   int                    k,
347                                   int                    l,
348                                   struct sc_int_exp_dat  *data)
349{
350  return sc_int_exp_cb_bp_comparative(i, j, k, l, data) *
351         sc_int_exp_cb_stack_comparative(i, j, k, l, data);
352}
353
354
355PRIVATE INLINE FLT_OR_DBL
356sc_int_exp_cb_bp_local_stack(int                    i,
357                             int                    j,
358                             int                    k,
359                             int                    l,
360                             struct sc_int_exp_dat  *data)
361{
362  return sc_int_exp_cb_bp_local(i, j, k, l, data) *
363         sc_int_exp_cb_stack(i, j, k, l, data);
364}
365
366
367PRIVATE INLINE FLT_OR_DBL
368sc_int_exp_cb_bp_local_stack_comparative(int                    i,
369                                         int                    j,
370                                         int                    k,
371                                         int                    l,
372                                         struct sc_int_exp_dat  *data)
373{
374  return sc_int_exp_cb_bp_local_comparative(i, j, k, l, data) *
375         sc_int_exp_cb_stack_comparative(i, j, k, l, data);
376}
377
378
379PRIVATE INLINE FLT_OR_DBL
380sc_int_exp_cb_bp_user(int                   i,
381                      int                   j,
382                      int                   k,
383                      int                   l,
384                      struct sc_int_exp_dat *data)
385{
386  return sc_int_exp_cb_bp(i, j, k, l, data) *
387         sc_int_exp_cb_user(i, j, k, l, data);
388}
389
390
391PRIVATE INLINE FLT_OR_DBL
392sc_int_exp_cb_bp_user_comparative(int                   i,
393                                  int                   j,
394                                  int                   k,
395                                  int                   l,
396                                  struct sc_int_exp_dat *data)
397{
398  return sc_int_exp_cb_bp_comparative(i, j, k, l, data) *
399         sc_int_exp_cb_user_comparative(i, j, k, l, data);
400}
401
402
403PRIVATE INLINE FLT_OR_DBL
404sc_int_exp_cb_bp_local_user(int                   i,
405                            int                   j,
406                            int                   k,
407                            int                   l,
408                            struct sc_int_exp_dat *data)
409{
410  return sc_int_exp_cb_bp_local(i, j, k, l, data) *
411         sc_int_exp_cb_user(i, j, k, l, data);
412}
413
414
415PRIVATE INLINE FLT_OR_DBL
416sc_int_exp_cb_bp_local_user_comparative(int                   i,
417                                        int                   j,
418                                        int                   k,
419                                        int                   l,
420                                        struct sc_int_exp_dat *data)
421{
422  return sc_int_exp_cb_bp_local_comparative(i, j, k, l, data) *
423         sc_int_exp_cb_user_comparative(i, j, k, l, data);
424}
425
426
427PRIVATE INLINE FLT_OR_DBL
428sc_int_exp_cb_stack_user(int                    i,
429                         int                    j,
430                         int                    k,
431                         int                    l,
432                         struct sc_int_exp_dat  *data)
433{
434  return sc_int_exp_cb_stack(i, j, k, l, data) *
435         sc_int_exp_cb_user(i, j, k, l, data);
436}
437
438
439PRIVATE INLINE FLT_OR_DBL
440sc_int_exp_cb_stack_user_comparative(int                    i,
441                                     int                    j,
442                                     int                    k,
443                                     int                    l,
444                                     struct sc_int_exp_dat  *data)
445{
446  return sc_int_exp_cb_stack_comparative(i, j, k, l, data) *
447         sc_int_exp_cb_user_comparative(i, j, k, l, data);
448}
449
450
451PRIVATE INLINE FLT_OR_DBL
452sc_int_exp_cb_up_bp_stack(int                   i,
453                          int                   j,
454                          int                   k,
455                          int                   l,
456                          struct sc_int_exp_dat *data)
457{
458  return sc_int_exp_cb_up(i, j, k, l, data) *
459         sc_int_exp_cb_bp(i, j, k, l, data) *
460         sc_int_exp_cb_stack(i, j, k, l, data);
461}
462
463
464PRIVATE INLINE FLT_OR_DBL
465sc_int_exp_cb_up_bp_stack_comparative(int                   i,
466                                      int                   j,
467                                      int                   k,
468                                      int                   l,
469                                      struct sc_int_exp_dat *data)
470{
471  return sc_int_exp_cb_up_comparative(i, j, k, l, data) *
472         sc_int_exp_cb_bp_comparative(i, j, k, l, data) *
473         sc_int_exp_cb_stack_comparative(i, j, k, l, data);
474}
475
476
477PRIVATE INLINE FLT_OR_DBL
478sc_int_exp_cb_up_bp_local_stack(int                   i,
479                                int                   j,
480                                int                   k,
481                                int                   l,
482                                struct sc_int_exp_dat *data)
483{
484  return sc_int_exp_cb_up(i, j, k, l, data) *
485         sc_int_exp_cb_bp_local(i, j, k, l, data) *
486         sc_int_exp_cb_stack(i, j, k, l, data);
487}
488
489
490PRIVATE INLINE FLT_OR_DBL
491sc_int_exp_cb_up_bp_local_stack_comparative(int                   i,
492                                            int                   j,
493                                            int                   k,
494                                            int                   l,
495                                            struct sc_int_exp_dat *data)
496{
497  return sc_int_exp_cb_up_comparative(i, j, k, l, data) *
498         sc_int_exp_cb_bp_local_comparative(i, j, k, l, data) *
499         sc_int_exp_cb_stack_comparative(i, j, k, l, data);
500}
501
502
503PRIVATE INLINE FLT_OR_DBL
504sc_int_exp_cb_up_bp_user(int                    i,
505                         int                    j,
506                         int                    k,
507                         int                    l,
508                         struct sc_int_exp_dat  *data)
509{
510  return sc_int_exp_cb_up(i, j, k, l, data) *
511         sc_int_exp_cb_bp(i, j, k, l, data) *
512         sc_int_exp_cb_user(i, j, k, l, data);
513}
514
515
516PRIVATE INLINE FLT_OR_DBL
517sc_int_exp_cb_up_bp_user_comparative(int                    i,
518                                     int                    j,
519                                     int                    k,
520                                     int                    l,
521                                     struct sc_int_exp_dat  *data)
522{
523  return sc_int_exp_cb_up_comparative(i, j, k, l, data) *
524         sc_int_exp_cb_bp_comparative(i, j, k, l, data) *
525         sc_int_exp_cb_user_comparative(i, j, k, l, data);
526}
527
528
529PRIVATE INLINE FLT_OR_DBL
530sc_int_exp_cb_up_bp_local_user(int                    i,
531                               int                    j,
532                               int                    k,
533                               int                    l,
534                               struct sc_int_exp_dat  *data)
535{
536  return sc_int_exp_cb_up(i, j, k, l, data) *
537         sc_int_exp_cb_bp_local(i, j, k, l, data) *
538         sc_int_exp_cb_user(i, j, k, l, data);
539}
540
541
542PRIVATE INLINE FLT_OR_DBL
543sc_int_exp_cb_up_bp_local_user_comparative(int                    i,
544                                           int                    j,
545                                           int                    k,
546                                           int                    l,
547                                           struct sc_int_exp_dat  *data)
548{
549  return sc_int_exp_cb_up_comparative(i, j, k, l, data) *
550         sc_int_exp_cb_bp_local_comparative(i, j, k, l, data) *
551         sc_int_exp_cb_user_comparative(i, j, k, l, data);
552}
553
554
555PRIVATE INLINE FLT_OR_DBL
556sc_int_exp_cb_up_stack_user(int                   i,
557                            int                   j,
558                            int                   k,
559                            int                   l,
560                            struct sc_int_exp_dat *data)
561{
562  return sc_int_exp_cb_up(i, j, k, l, data) *
563         sc_int_exp_cb_stack(i, j, k, l, data) *
564         sc_int_exp_cb_user(i, j, k, l, data);
565}
566
567
568PRIVATE INLINE FLT_OR_DBL
569sc_int_exp_cb_up_stack_user_comparative(int                   i,
570                                        int                   j,
571                                        int                   k,
572                                        int                   l,
573                                        struct sc_int_exp_dat *data)
574{
575  return sc_int_exp_cb_up_comparative(i, j, k, l, data) *
576         sc_int_exp_cb_stack_comparative(i, j, k, l, data) *
577         sc_int_exp_cb_user_comparative(i, j, k, l, data);
578}
579
580
581PRIVATE INLINE FLT_OR_DBL
582sc_int_exp_cb_bp_stack_user(int                   i,
583                            int                   j,
584                            int                   k,
585                            int                   l,
586                            struct sc_int_exp_dat *data)
587{
588  return sc_int_exp_cb_bp(i, j, k, l, data) *
589         sc_int_exp_cb_stack(i, j, k, l, data) *
590         sc_int_exp_cb_user(i, j, k, l, data);
591}
592
593
594PRIVATE INLINE FLT_OR_DBL
595sc_int_exp_cb_bp_stack_user_comparative(int                   i,
596                                        int                   j,
597                                        int                   k,
598                                        int                   l,
599                                        struct sc_int_exp_dat *data)
600{
601  return sc_int_exp_cb_bp_comparative(i, j, k, l, data) *
602         sc_int_exp_cb_stack_comparative(i, j, k, l, data) *
603         sc_int_exp_cb_user_comparative(i, j, k, l, data);
604}
605
606
607PRIVATE INLINE FLT_OR_DBL
608sc_int_exp_cb_bp_local_stack_user(int                   i,
609                                  int                   j,
610                                  int                   k,
611                                  int                   l,
612                                  struct sc_int_exp_dat *data)
613{
614  return sc_int_exp_cb_bp_local(i, j, k, l, data) *
615         sc_int_exp_cb_stack(i, j, k, l, data) *
616         sc_int_exp_cb_user(i, j, k, l, data);
617}
618
619
620PRIVATE INLINE FLT_OR_DBL
621sc_int_exp_cb_bp_local_stack_user_comparative(int                   i,
622                                              int                   j,
623                                              int                   k,
624                                              int                   l,
625                                              struct sc_int_exp_dat *data)
626{
627  return sc_int_exp_cb_bp_local_comparative(i, j, k, l, data) *
628         sc_int_exp_cb_stack_comparative(i, j, k, l, data) *
629         sc_int_exp_cb_user_comparative(i, j, k, l, data);
630}
631
632
633PRIVATE INLINE FLT_OR_DBL
634sc_int_exp_cb_up_bp_stack_user(int                    i,
635                               int                    j,
636                               int                    k,
637                               int                    l,
638                               struct sc_int_exp_dat  *data)
639{
640  return sc_int_exp_cb_up(i, j, k, l, data) *
641         sc_int_exp_cb_bp(i, j, k, l, data) *
642         sc_int_exp_cb_stack(i, j, k, l, data) *
643         sc_int_exp_cb_user(i, j, k, l, data);
644}
645
646
647PRIVATE INLINE FLT_OR_DBL
648sc_int_exp_cb_up_bp_stack_user_comparative(int                    i,
649                                           int                    j,
650                                           int                    k,
651                                           int                    l,
652                                           struct sc_int_exp_dat  *data)
653{
654  return sc_int_exp_cb_up_comparative(i, j, k, l, data) *
655         sc_int_exp_cb_bp_comparative(i, j, k, l, data) *
656         sc_int_exp_cb_stack_comparative(i, j, k, l, data) *
657         sc_int_exp_cb_user_comparative(i, j, k, l, data);
658}
659
660
661PRIVATE INLINE FLT_OR_DBL
662sc_int_exp_cb_up_bp_local_stack_user(int                    i,
663                                     int                    j,
664                                     int                    k,
665                                     int                    l,
666                                     struct sc_int_exp_dat  *data)
667{
668  return sc_int_exp_cb_up(i, j, k, l, data) *
669         sc_int_exp_cb_bp_local(i, j, k, l, data) *
670         sc_int_exp_cb_stack(i, j, k, l, data) *
671         sc_int_exp_cb_user(i, j, k, l, data);
672}
673
674
675PRIVATE INLINE FLT_OR_DBL
676sc_int_exp_cb_up_bp_local_stack_user_comparative(int                    i,
677                                                 int                    j,
678                                                 int                    k,
679                                                 int                    l,
680                                                 struct sc_int_exp_dat  *data)
681{
682  return sc_int_exp_cb_up_comparative(i, j, k, l, data) *
683         sc_int_exp_cb_bp_local_comparative(i, j, k, l, data) *
684         sc_int_exp_cb_stack_comparative(i, j, k, l, data) *
685         sc_int_exp_cb_user_comparative(i, j, k, l, data);
686}
687
688
689PRIVATE INLINE FLT_OR_DBL
690sc_int_exp_cb_ext_up(int                    i,
691                     int                    j,
692                     int                    k,
693                     int                    l,
694                     struct sc_int_exp_dat  *data)
695{
696  int         u1, u2, u3;
697  FLT_OR_DBL  sc;
698
699  sc  = 1.;
700  u1  = i - 1;
701  u2  = k - j - 1;
702  u3  = data->n - l;
703
704  if (u1 > 0)
705    sc *= data->up[1][u1];
706
707  if (u2 > 0)
708    sc *= data->up[j + 1][u2];
709
710  if (u3 > 0)
711    sc *= data->up[l + 1][u3];
712
713  return sc;
714}
715
716
717PRIVATE INLINE FLT_OR_DBL
718sc_int_exp_cb_ext_up_comparative(int                    i,
719                                 int                    j,
720                                 int                    k,
721                                 int                    l,
722                                 struct sc_int_exp_dat  *data)
723{
724  unsigned int  s;
725  int           u1, u2, u3;
726  FLT_OR_DBL    sc;
727
728  sc = 1.;
729
730  for (s = 0; s < data->n_seq; s++)
731    if (data->up_comparative[s]) {
732      u1  = data->a2s[s][i - 1];
733      u2  = data->a2s[s][k - 1] - data->a2s[s][j];
734      u3  = data->a2s[s][data->n] - data->a2s[s][l];
735
736      if (u1 > 0)
737        sc *= data->up_comparative[s][1][u1];
738
739      if (u2 > 0)
740        sc *= data->up_comparative[s][data->a2s[s][j + 1]][u2];
741
742      if (u3 > 0)
743        sc *= data->up_comparative[s][data->a2s[s][l + 1]][u3];
744    }
745
746  return sc;
747}
748
749
750PRIVATE INLINE FLT_OR_DBL
751sc_int_exp_cb_ext_stack(int                   i,
752                        int                   j,
753                        int                   k,
754                        int                   l,
755                        struct sc_int_exp_dat *data)
756{
757  FLT_OR_DBL sc;
758
759  sc = 1.;
760
761  if ((i == 1) && (j + 1 == k) && (l == data->n)) {
762    sc *= data->stack[i] *
763          data->stack[k] *
764          data->stack[l] *
765          data->stack[j];
766  }
767
768  return sc;
769}
770
771
772PRIVATE INLINE FLT_OR_DBL
773sc_int_exp_cb_ext_stack_comparative(int                   i,
774                                    int                   j,
775                                    int                   k,
776                                    int                   l,
777                                    struct sc_int_exp_dat *data)
778{
779  unsigned int  s;
780  FLT_OR_DBL    sc;
781
782  sc = 1.;
783
784  for (s = 0; s < data->n_seq; s++)
785    if (data->stack_comparative[s]) {
786      if ((data->a2s[s][i] == 1) &&
787          (data->a2s[s][j] == data->a2s[s][k - 1]) &&
788          (data->a2s[s][l] == data->a2s[s][data->n])) {
789        sc *= data->stack_comparative[s][data->a2s[s][i]] *
790              data->stack_comparative[s][data->a2s[s][k]] *
791              data->stack_comparative[s][data->a2s[s][l]] *
792              data->stack_comparative[s][data->a2s[s][j]];
793      }
794    }
795
796  return sc;
797}
798
799
800PRIVATE INLINE FLT_OR_DBL
801sc_int_exp_cb_ext_user(int                    i,
802                       int                    j,
803                       int                    k,
804                       int                    l,
805                       struct sc_int_exp_dat  *data)
806{
807  return data->user_cb(i, j, k, l,
808                       VRNA_DECOMP_PAIR_IL,
809                       data->user_data);
810}
811
812
813PRIVATE INLINE FLT_OR_DBL
814sc_int_exp_cb_ext_user_comparative(int                    i,
815                                   int                    j,
816                                   int                    k,
817                                   int                    l,
818                                   struct sc_int_exp_dat  *data)
819{
820  unsigned int  s;
821  FLT_OR_DBL    sc;
822
823  sc = 1.;
824
825  for (s = 0; s < data->n_seq; s++)
826    if (data->user_cb_comparative[s])
827      sc *= data->user_cb_comparative[s](i, j, k, l,
828                                         VRNA_DECOMP_PAIR_IL,
829                                         data->user_data_comparative[s]);
830
831  return sc;
832}
833
834
835PRIVATE INLINE FLT_OR_DBL
836sc_int_exp_cb_ext_up_stack(int                    i,
837                           int                    j,
838                           int                    k,
839                           int                    l,
840                           struct sc_int_exp_dat  *data)
841{
842  return sc_int_exp_cb_ext_up(i, j, k, l, data) *
843         sc_int_exp_cb_ext_stack(i, j, k, l, data);
844}
845
846
847PRIVATE INLINE FLT_OR_DBL
848sc_int_exp_cb_ext_up_stack_comparative(int                    i,
849                                       int                    j,
850                                       int                    k,
851                                       int                    l,
852                                       struct sc_int_exp_dat  *data)
853{
854  return sc_int_exp_cb_ext_up_comparative(i, j, k, l, data) *
855         sc_int_exp_cb_ext_stack_comparative(i, j, k, l, data);
856}
857
858
859PRIVATE INLINE FLT_OR_DBL
860sc_int_exp_cb_ext_up_user(int                   i,
861                          int                   j,
862                          int                   k,
863                          int                   l,
864                          struct sc_int_exp_dat *data)
865{
866  return sc_int_exp_cb_ext_up(i, j, k, l, data) *
867         sc_int_exp_cb_ext_user(i, j, k, l, data);
868}
869
870
871PRIVATE INLINE FLT_OR_DBL
872sc_int_exp_cb_ext_up_user_comparative(int                   i,
873                                      int                   j,
874                                      int                   k,
875                                      int                   l,
876                                      struct sc_int_exp_dat *data)
877{
878  return sc_int_exp_cb_ext_up_comparative(i, j, k, l, data) *
879         sc_int_exp_cb_ext_user_comparative(i, j, k, l, data);
880}
881
882
883PRIVATE INLINE FLT_OR_DBL
884sc_int_exp_cb_ext_stack_user(int                    i,
885                             int                    j,
886                             int                    k,
887                             int                    l,
888                             struct sc_int_exp_dat  *data)
889{
890  return sc_int_exp_cb_ext_stack(i, j, k, l, data) *
891         sc_int_exp_cb_ext_user(i, j, k, l, data);
892}
893
894
895PRIVATE INLINE FLT_OR_DBL
896sc_int_exp_cb_ext_stack_user_comparative(int                    i,
897                                         int                    j,
898                                         int                    k,
899                                         int                    l,
900                                         struct sc_int_exp_dat  *data)
901{
902  return sc_int_exp_cb_ext_stack_comparative(i, j, k, l, data) *
903         sc_int_exp_cb_ext_user_comparative(i, j, k, l, data);
904}
905
906
907PRIVATE INLINE FLT_OR_DBL
908sc_int_exp_cb_ext_up_stack_user(int                   i,
909                                int                   j,
910                                int                   k,
911                                int                   l,
912                                struct sc_int_exp_dat *data)
913{
914  return sc_int_exp_cb_ext_up(i, j, k, l, data) *
915         sc_int_exp_cb_ext_stack(i, j, k, l, data) *
916         sc_int_exp_cb_ext_user(i, j, k, l, data);
917}
918
919
920PRIVATE INLINE FLT_OR_DBL
921sc_int_exp_cb_ext_up_stack_user_comparative(int                   i,
922                                            int                   j,
923                                            int                   k,
924                                            int                   l,
925                                            struct sc_int_exp_dat *data)
926{
927  return sc_int_exp_cb_ext_up_comparative(i, j, k, l, data) *
928         sc_int_exp_cb_ext_stack_comparative(i, j, k, l, data) *
929         sc_int_exp_cb_ext_user_comparative(i, j, k, l, data);
930}
931
932
933PRIVATE INLINE void
934init_sc_int_exp(vrna_fold_compound_t  *fc,
935                struct sc_int_exp_dat *sc_wrapper)
936{
937  unsigned char sliding_window;
938  unsigned int  s, provides_sc_up, provides_sc_bp, provides_sc_stack, provides_sc_user;
939  vrna_sc_t     *sc, **scs;
940
941  if (fc->exp_matrices)
942    sliding_window = (fc->exp_matrices->type == VRNA_MX_WINDOW) ? 1 : 0;
943  else if ((fc->type == VRNA_FC_TYPE_SINGLE) && (fc->sc))
944    sliding_window = (fc->sc->type == VRNA_SC_WINDOW) ? 1 : 0;
945  else if (fc->hc)
946    sliding_window = (fc->hc->type == VRNA_HC_WINDOW) ? 1 : 0;
947  else
948    sliding_window = 0;
949
950  provides_sc_up    = 0;
951  provides_sc_bp    = 0;
952  provides_sc_stack = 0;
953  provides_sc_user  = 0;
954
955  sc_wrapper->n                     = fc->length;
956  sc_wrapper->n_seq                 = 1;
957  sc_wrapper->a2s                   = NULL;
958  sc_wrapper->idx                   = fc->jindx;
959  sc_wrapper->up                    = NULL;
960  sc_wrapper->up_comparative        = NULL;
961  sc_wrapper->bp                    = NULL;
962  sc_wrapper->bp_comparative        = NULL;
963  sc_wrapper->bp_local              = NULL;
964  sc_wrapper->bp_local_comparative  = NULL;
965  sc_wrapper->stack                 = NULL;
966  sc_wrapper->stack_comparative     = NULL;
967  sc_wrapper->user_cb               = NULL;
968  sc_wrapper->user_cb_comparative   = NULL;
969  sc_wrapper->user_data             = NULL;
970  sc_wrapper->user_data_comparative = NULL;
971
972  sc_wrapper->pair      = NULL;
973  sc_wrapper->pair_ext  = NULL;
974
975  switch (fc->type) {
976    case VRNA_FC_TYPE_SINGLE:
977      sc = fc->sc;
978
979      if (sc) {
980        sc_wrapper->up        = sc->exp_energy_up;
981        sc_wrapper->bp        = (sliding_window) ? NULL : sc->exp_energy_bp;
982        sc_wrapper->bp_local  = (sliding_window) ? sc->exp_energy_bp_local : NULL;
983        sc_wrapper->stack     = sc->exp_energy_stack;
984        sc_wrapper->user_cb   = sc->exp_f;
985        sc_wrapper->user_data = sc->data;
986
987        if (sc->exp_energy_up)
988          provides_sc_up = 1;
989
990        if (sliding_window) {
991          if (sc->exp_energy_bp_local)
992            provides_sc_bp = 1;
993        } else if (sc->exp_energy_bp) {
994          provides_sc_bp = 1;
995        }
996
997        if (sc->exp_energy_stack)
998          provides_sc_stack = 1;
999
1000        if (sc->exp_f)
1001          provides_sc_user = 1;
1002
1003        if (provides_sc_user) {
1004          if (provides_sc_up) {
1005            if (provides_sc_bp) {
1006              if (provides_sc_stack) {
1007                sc_wrapper->pair = (sliding_window) ?
1008                                   &sc_int_exp_cb_up_bp_local_stack_user :
1009                                   &sc_int_exp_cb_up_bp_stack_user;
1010                sc_wrapper->pair_ext = &sc_int_exp_cb_ext_up_stack_user;
1011              } else {
1012                sc_wrapper->pair = (sliding_window) ?
1013                                   &sc_int_exp_cb_up_bp_local_user :
1014                                   &sc_int_exp_cb_up_bp_user;
1015                sc_wrapper->pair_ext = &sc_int_exp_cb_ext_up_user;
1016              }
1017            } else if (provides_sc_stack) {
1018              sc_wrapper->pair      = &sc_int_exp_cb_up_stack_user;
1019              sc_wrapper->pair_ext  = &sc_int_exp_cb_ext_up_stack_user;
1020            } else {
1021              sc_wrapper->pair      = &sc_int_exp_cb_up_user;
1022              sc_wrapper->pair_ext  = &sc_int_exp_cb_ext_up_user;
1023            }
1024          } else if (provides_sc_bp) {
1025            if (provides_sc_stack) {
1026              sc_wrapper->pair = (sliding_window) ?
1027                                 &sc_int_exp_cb_bp_local_stack_user :
1028                                 &sc_int_exp_cb_bp_stack_user;
1029              sc_wrapper->pair_ext = &sc_int_exp_cb_ext_stack_user;
1030            } else {
1031              sc_wrapper->pair = (sliding_window) ?
1032                                 &sc_int_exp_cb_bp_local_user :
1033                                 &sc_int_exp_cb_bp_user;
1034              sc_wrapper->pair_ext = &sc_int_exp_cb_ext_user;
1035            }
1036          } else if (provides_sc_stack) {
1037            sc_wrapper->pair      = &sc_int_exp_cb_stack_user;
1038            sc_wrapper->pair_ext  = &sc_int_exp_cb_ext_stack_user;
1039          } else {
1040            sc_wrapper->pair      = &sc_int_exp_cb_user;
1041            sc_wrapper->pair_ext  = &sc_int_exp_cb_ext_user;
1042          }
1043        } else if (provides_sc_bp) {
1044          if (provides_sc_up) {
1045            if (provides_sc_stack) {
1046              sc_wrapper->pair = (sliding_window) ?
1047                                 &sc_int_exp_cb_up_bp_local_stack :
1048                                 &sc_int_exp_cb_up_bp_stack;
1049              sc_wrapper->pair_ext = &sc_int_exp_cb_ext_up_stack;
1050            } else {
1051              sc_wrapper->pair = (sliding_window) ?
1052                                 &sc_int_exp_cb_up_bp_local :
1053                                 &sc_int_exp_cb_up_bp;
1054              sc_wrapper->pair_ext = &sc_int_exp_cb_ext_up;
1055            }
1056          } else if (provides_sc_stack) {
1057            sc_wrapper->pair = (sliding_window) ?
1058                               &sc_int_exp_cb_bp_local_stack :
1059                               &sc_int_exp_cb_bp_stack;
1060            sc_wrapper->pair_ext = &sc_int_exp_cb_ext_stack;
1061          } else {
1062            sc_wrapper->pair = (sliding_window) ?
1063                               &sc_int_exp_cb_bp_local :
1064                               &sc_int_exp_cb_bp;
1065          }
1066        } else if (provides_sc_up) {
1067          if (provides_sc_stack) {
1068            sc_wrapper->pair      = &sc_int_exp_cb_up_stack;
1069            sc_wrapper->pair_ext  = &sc_int_exp_cb_ext_up_stack;
1070          } else {
1071            sc_wrapper->pair      = &sc_int_exp_cb_up;
1072            sc_wrapper->pair_ext  = &sc_int_exp_cb_ext_up;
1073          }
1074        } else if (provides_sc_stack) {
1075          sc_wrapper->pair      = &sc_int_exp_cb_stack;
1076          sc_wrapper->pair_ext  = &sc_int_exp_cb_ext_stack;
1077        }
1078      }
1079
1080      break;
1081
1082    case VRNA_FC_TYPE_COMPARATIVE:
1083      sc_wrapper->n_seq = fc->n_seq;
1084      sc_wrapper->a2s   = fc->a2s;
1085      scs               = fc->scs;
1086
1087      if (scs) {
1088        sc_wrapper->up_comparative = (FLT_OR_DBL ***)vrna_alloc(
1089          sizeof(FLT_OR_DBL * *) *
1090          fc->n_seq);
1091
1092        sc_wrapper->bp_comparative = (FLT_OR_DBL **)vrna_alloc(
1093          sizeof(FLT_OR_DBL *) *
1094          fc->n_seq);
1095
1096        sc_wrapper->bp_local_comparative = (FLT_OR_DBL ***)vrna_alloc(
1097          sizeof(FLT_OR_DBL * *) *
1098          fc->n_seq);
1099
1100        sc_wrapper->stack_comparative = (FLT_OR_DBL **)vrna_alloc(
1101          sizeof(FLT_OR_DBL *) *
1102          fc->n_seq);
1103
1104        sc_wrapper->user_cb_comparative = (vrna_callback_sc_exp_energy **)vrna_alloc(
1105          sizeof(vrna_callback_sc_exp_energy *) *
1106          fc->n_seq);
1107
1108        sc_wrapper->user_data_comparative = (void **)vrna_alloc(
1109          sizeof(void *) *
1110          fc->n_seq);
1111
1112        for (s = 0; s < fc->n_seq; s++) {
1113          if (scs[s]) {
1114            sliding_window = (scs[s]->type == VRNA_SC_WINDOW) ?
1115                             1 :
1116                             0;
1117            sc_wrapper->up_comparative[s] = scs[s]->exp_energy_up;
1118            sc_wrapper->bp_comparative[s] = (sliding_window) ?
1119                                            NULL :
1120                                            scs[s]->exp_energy_bp;
1121            sc_wrapper->bp_local_comparative[s] = (sliding_window) ?
1122                                                  scs[s]->exp_energy_bp_local :
1123                                                  NULL;
1124            sc_wrapper->stack_comparative[s]      = scs[s]->exp_energy_stack;
1125            sc_wrapper->user_cb_comparative[s]    = scs[s]->exp_f;
1126            sc_wrapper->user_data_comparative[s]  = scs[s]->data;
1127
1128            if (scs[s]->exp_energy_up)
1129              provides_sc_up = 1;
1130
1131            if (sliding_window) {
1132              if (scs[s]->exp_energy_bp_local)
1133                provides_sc_bp = 1;
1134            } else if (scs[s]->exp_energy_bp) {
1135              provides_sc_bp = 1;
1136            }
1137
1138            if (scs[s]->exp_energy_stack)
1139              provides_sc_stack = 1;
1140
1141            if (scs[s]->exp_f)
1142              provides_sc_user = 1;
1143          }
1144        }
1145
1146        if (provides_sc_user) {
1147          if (provides_sc_up) {
1148            if (provides_sc_bp) {
1149              if (provides_sc_stack) {
1150                sc_wrapper->pair = (sliding_window) ?
1151                                   &sc_int_exp_cb_up_bp_local_stack_user_comparative :
1152                                   &sc_int_exp_cb_up_bp_stack_user_comparative;
1153                sc_wrapper->pair_ext = &sc_int_exp_cb_ext_up_stack_user_comparative;
1154              } else {
1155                sc_wrapper->pair = (sliding_window) ?
1156                                   &sc_int_exp_cb_up_bp_local_user_comparative :
1157                                   &sc_int_exp_cb_up_bp_user_comparative;
1158                sc_wrapper->pair_ext = &sc_int_exp_cb_ext_up_user_comparative;
1159              }
1160            } else if (provides_sc_stack) {
1161              sc_wrapper->pair      = &sc_int_exp_cb_up_stack_user_comparative;
1162              sc_wrapper->pair_ext  = &sc_int_exp_cb_ext_up_stack_user_comparative;
1163            } else {
1164              sc_wrapper->pair      = &sc_int_exp_cb_up_user_comparative;
1165              sc_wrapper->pair_ext  = &sc_int_exp_cb_ext_up_user_comparative;
1166            }
1167          } else if (provides_sc_bp) {
1168            if (provides_sc_stack) {
1169              sc_wrapper->pair = (sliding_window) ?
1170                                 &sc_int_exp_cb_bp_local_stack_user_comparative :
1171                                 &sc_int_exp_cb_bp_stack_user_comparative;
1172              sc_wrapper->pair_ext = &sc_int_exp_cb_ext_stack_user_comparative;
1173            } else {
1174              sc_wrapper->pair = (sliding_window) ?
1175                                 &sc_int_exp_cb_bp_local_user_comparative :
1176                                 &sc_int_exp_cb_bp_user_comparative;
1177              sc_wrapper->pair_ext = &sc_int_exp_cb_ext_user_comparative;
1178            }
1179          } else if (provides_sc_stack) {
1180            sc_wrapper->pair      = &sc_int_exp_cb_stack_user_comparative;
1181            sc_wrapper->pair_ext  = &sc_int_exp_cb_ext_stack_user_comparative;
1182          } else {
1183            sc_wrapper->pair      = &sc_int_exp_cb_user_comparative;
1184            sc_wrapper->pair_ext  = &sc_int_exp_cb_ext_user_comparative;
1185          }
1186        } else if (provides_sc_bp) {
1187          if (provides_sc_up) {
1188            if (provides_sc_stack) {
1189              sc_wrapper->pair = (sliding_window) ?
1190                                 &sc_int_exp_cb_up_bp_local_stack_comparative :
1191                                 &sc_int_exp_cb_up_bp_stack_comparative;
1192              sc_wrapper->pair_ext = &sc_int_exp_cb_ext_up_stack_comparative;
1193            } else {
1194              sc_wrapper->pair = (sliding_window) ?
1195                                 &sc_int_exp_cb_up_bp_local_comparative :
1196                                 &sc_int_exp_cb_up_bp_comparative;
1197              sc_wrapper->pair_ext = &sc_int_exp_cb_ext_up_comparative;
1198            }
1199          } else if (provides_sc_stack) {
1200            sc_wrapper->pair = (sliding_window) ?
1201                               &sc_int_exp_cb_bp_local_stack_comparative :
1202                               &sc_int_exp_cb_bp_stack_comparative;
1203            sc_wrapper->pair_ext = &sc_int_exp_cb_ext_stack_comparative;
1204          } else {
1205            sc_wrapper->pair = (sliding_window) ?
1206                               &sc_int_exp_cb_bp_local_comparative :
1207                               &sc_int_exp_cb_bp_comparative;
1208          }
1209        } else if (provides_sc_up) {
1210          if (provides_sc_stack) {
1211            sc_wrapper->pair      = &sc_int_exp_cb_up_stack_comparative;
1212            sc_wrapper->pair_ext  = &sc_int_exp_cb_ext_up_stack_comparative;
1213          } else {
1214            sc_wrapper->pair      = &sc_int_exp_cb_up_comparative;
1215            sc_wrapper->pair_ext  = &sc_int_exp_cb_ext_up_comparative;
1216          }
1217        } else if (provides_sc_stack) {
1218          sc_wrapper->pair      = &sc_int_exp_cb_stack_comparative;
1219          sc_wrapper->pair_ext  = &sc_int_exp_cb_ext_stack_comparative;
1220        }
1221      }
1222
1223      break;
1224  }
1225}
1226
1227
1228PRIVATE INLINE void
1229free_sc_int_exp(struct sc_int_exp_dat *sc_wrapper)
1230{
1231  free(sc_wrapper->up_comparative);
1232  free(sc_wrapper->bp_comparative);
1233  free(sc_wrapper->bp_local_comparative);
1234  free(sc_wrapper->stack_comparative);
1235  free(sc_wrapper->user_cb_comparative);
1236  free(sc_wrapper->user_data_comparative);
1237}
1238