File Coverage

pp-hmmfw.c
Criterion Covered Total %
statement 53 84 63.1
branch 44 184 23.9
condition n/a
subroutine n/a
pod n/a
total 97 268 36.1


line stmt bran cond sub pod time code
1              
2             #line 453 "lib/PDL/PP.pm"
3             /*
4             * THIS FILE WAS GENERATED BY PDL::PP from HMM.pd! Do not modify!
5             */
6              
7             #define PDL_FREE_CODE(trans, destroy, comp_free_code, ntpriv_free_code) \
8             if (destroy) { \
9             comp_free_code \
10             } \
11             if ((trans)->dims_redone) { \
12             ntpriv_free_code \
13             }
14              
15             #include "EXTERN.h"
16             #include "perl.h"
17             #include "XSUB.h"
18             #include "pdl.h"
19             #include "pdlcore.h"
20             #define PDL PDL_HMM
21             extern Core* PDL; /* Structure hold core C functions */
22             #line 23 "pp-hmmfw.c"
23              
24             #include
25              
26             /*#define DEBUG_ALPHA*/
27             /*#define DEBUG_BETA*/
28             /*#define DEBUG_VITERBI*/
29              
30              
31             /* logadd(x,y) = log(exp(x)+exp(y))
32             * + Code from Manning & Schütze (1997), Sec. 9.4, page 337
33             *
34             * LOG_BIG = log(1E31)
35             */
36             #define LOG_BIG 71.3801378828154
37             #define LOG_ZERO -1E+38
38             #define LOG_ONE 0
39             #define LOG_NONE 1
40 52           static inline double logadd1(double x, double y) {
41 52 100         if (y-x > LOG_BIG) return y;
42 32 100         else if (x-y > LOG_BIG) return x;
43             /*else return min(x,y) + log(exp(x-min(x,y)) + exp(y-min(x,y))); */
44 12 50         else if (x
45 12           else return y + log(exp(x-y) + 1);
46             }
47             static inline double logadd0(double x, double y) {
48             return log(exp(x)+exp(y));
49             }
50              
51             /* logdiff(x,y) = log(exp(x)-exp(y))
52             * + adapted from above
53             * + always returns positive (i.e. symmetric difference)
54             */
55             static inline double logdiff1(double x, double y) {
56             if (y-x > LOG_BIG) { return y; }
57             else if (x-y > LOG_BIG) { return x; }
58             /*else { return max(x,y) + log(exp(max(x,y)-max(x,y)) - exp(min(x,y)-max(x,y))); } */
59             /* = max(x,y) + log( 1 - exp(min(x,y)-max(x,y))); } */
60             else if (x>y) { return x + log( 1 - exp(y-x)); }
61             else { return y + log( 1 - exp(x-y)); }
62             }
63             static inline double logdiff0(double x, double y) {
64             return log(x>y ? (exp(x)-exp(y)) : (exp(y)-exp(x)));
65             }
66              
67             /*
68             #define logadd(x,y) logadd0(x,y)
69             #define logdiff(x,y) logdiff0(x,y)
70             */
71              
72             #define logadd(x,y) logadd1(x,y)
73             #define logdiff(x,y) logdiff1(x,y)
74              
75              
76             #line 1857 "lib/PDL/PP.pm"
77             pdl_error pdl_hmmfw_readdata(pdl_trans *__privtrans) {
78             pdl_error PDL_err = {0, NULL, 0};
79             #line 80 "pp-hmmfw.c"
80 13           register PDL_Indx __N_size = __privtrans->ind_sizes[1];
81 13 50         if (!__privtrans->broadcast.incs) return PDL->make_error(PDL_EUSERERROR, "Error in hmmfw:" "broadcast.incs NULL");
82             /* broadcastloop declarations */
83             int __brcloopval;
84             register PDL_Indx __tind0,__tind1; /* counters along dim */
85 13           register PDL_Indx __tnpdls = __privtrans->broadcast.npdls;
86             /* dims here are how many steps along those dims */
87 13           register PDL_Indx __tinc0_a = PDL_BRC_INC(__privtrans->broadcast.incs,__tnpdls,0,0);
88 13           register PDL_Indx __tinc0_b = PDL_BRC_INC(__privtrans->broadcast.incs,__tnpdls,1,0);
89 13           register PDL_Indx __tinc0_pi = PDL_BRC_INC(__privtrans->broadcast.incs,__tnpdls,2,0);
90 13           register PDL_Indx __tinc0_o = PDL_BRC_INC(__privtrans->broadcast.incs,__tnpdls,3,0);
91 13           register PDL_Indx __tinc0_alpha = PDL_BRC_INC(__privtrans->broadcast.incs,__tnpdls,4,0);
92 13           register PDL_Indx __tinc1_a = PDL_BRC_INC(__privtrans->broadcast.incs,__tnpdls,0,1);
93 13           register PDL_Indx __tinc1_b = PDL_BRC_INC(__privtrans->broadcast.incs,__tnpdls,1,1);
94 13           register PDL_Indx __tinc1_pi = PDL_BRC_INC(__privtrans->broadcast.incs,__tnpdls,2,1);
95 13           register PDL_Indx __tinc1_o = PDL_BRC_INC(__privtrans->broadcast.incs,__tnpdls,3,1);
96 13           register PDL_Indx __tinc1_alpha = PDL_BRC_INC(__privtrans->broadcast.incs,__tnpdls,4,1);
97             #define PDL_BROADCASTLOOP_START_hmmfw_readdata PDL_BROADCASTLOOP_START( \
98             readdata, \
99             __privtrans->broadcast, \
100             __privtrans->vtable, \
101             a_datap += __offsp[0]; \
102             b_datap += __offsp[1]; \
103             pi_datap += __offsp[2]; \
104             o_datap += __offsp[3]; \
105             alpha_datap += __offsp[4]; \
106             , \
107             ( ,a_datap += __tinc1_a - __tinc0_a * __tdims0 \
108             ,b_datap += __tinc1_b - __tinc0_b * __tdims0 \
109             ,pi_datap += __tinc1_pi - __tinc0_pi * __tdims0 \
110             ,o_datap += __tinc1_o - __tinc0_o * __tdims0 \
111             ,alpha_datap += __tinc1_alpha - __tinc0_alpha * __tdims0 \
112             ), \
113             ( ,a_datap += __tinc0_a \
114             ,b_datap += __tinc0_b \
115             ,pi_datap += __tinc0_pi \
116             ,o_datap += __tinc0_o \
117             ,alpha_datap += __tinc0_alpha \
118             ) \
119             )
120             #define PDL_BROADCASTLOOP_END_hmmfw_readdata PDL_BROADCASTLOOP_END( \
121             __privtrans->broadcast, \
122             a_datap -= __tinc1_a * __tdims1 + __offsp[0]; \
123             b_datap -= __tinc1_b * __tdims1 + __offsp[1]; \
124             pi_datap -= __tinc1_pi * __tdims1 + __offsp[2]; \
125             o_datap -= __tinc1_o * __tdims1 + __offsp[3]; \
126             alpha_datap -= __tinc1_alpha * __tdims1 + __offsp[4]; \
127             )
128 13           register PDL_Indx __inc_a_N0 = __privtrans->inc_sizes[PDL_INC_ID(__privtrans->vtable,0,0)]; (void)__inc_a_N0;register PDL_Indx __inc_a_N1 = __privtrans->inc_sizes[PDL_INC_ID(__privtrans->vtable,0,1)]; (void)__inc_a_N1;
129 13           register PDL_Indx __inc_alpha_N = __privtrans->inc_sizes[PDL_INC_ID(__privtrans->vtable,4,0)]; (void)__inc_alpha_N;register PDL_Indx __inc_alpha_T = __privtrans->inc_sizes[PDL_INC_ID(__privtrans->vtable,4,1)]; (void)__inc_alpha_T;
130 13           register PDL_Indx __inc_b_N = __privtrans->inc_sizes[PDL_INC_ID(__privtrans->vtable,1,0)]; (void)__inc_b_N;register PDL_Indx __inc_b_M = __privtrans->inc_sizes[PDL_INC_ID(__privtrans->vtable,1,1)]; (void)__inc_b_M;
131 13           register PDL_Indx __inc_o_T = __privtrans->inc_sizes[PDL_INC_ID(__privtrans->vtable,3,0)]; (void)__inc_o_T;
132 13           register PDL_Indx __inc_pi_N = __privtrans->inc_sizes[PDL_INC_ID(__privtrans->vtable,2,0)]; (void)__inc_pi_N;
133             #ifndef PDL_DECLARE_PARAMS_hmmfw_1
134             #define PDL_DECLARE_PARAMS_hmmfw_1(PDL_TYPE_OP,PDL_PPSYM_OP) \
135             PDL_DECLARE_PARAMETER(PDL_TYPE_OP, a, (__privtrans->pdls[0]), 1, PDL_PPSYM_OP) \
136             PDL_DECLARE_PARAMETER(PDL_TYPE_OP, b, (__privtrans->pdls[1]), 1, PDL_PPSYM_OP) \
137             PDL_DECLARE_PARAMETER(PDL_TYPE_OP, pi, (__privtrans->pdls[2]), 1, PDL_PPSYM_OP) \
138             PDL_DECLARE_PARAMETER(PDL_TYPE_OP, o, (__privtrans->pdls[3]), 1, PDL_PPSYM_OP) \
139             PDL_DECLARE_PARAMETER(PDL_TYPE_OP, alpha, (__privtrans->pdls[4]), 1, PDL_PPSYM_OP)
140             #endif
141             #define PDL_IF_BAD(t,f) f
142 13           switch (__privtrans->__datatype) { /* Start generic switch */
143 0           case PDL_F: {
144 0 0         PDL_DECLARE_PARAMS_hmmfw_1(PDL_Float,F)
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
145 0 0         PDL_BROADCASTLOOP_START_hmmfw_readdata {
    0          
    0          
    0          
    0          
    0          
    0          
146             /*-- Initialize: t==0 --*/
147 0           int i,j,t, o_tp1 = (o_datap)[0+(__inc_o_T*(0))];
148 0 0         {/* Open N */ PDL_EXPAND2(register PDL_Indx N=0, __N_stop=(__N_size)); for(; N<__N_stop; N+=1) {
149 0           (alpha_datap)[0+(__inc_alpha_N*(N))+(__inc_alpha_T*(0))] = (pi_datap)[0+(__inc_pi_N*(N))] + (b_datap)[0+(__inc_b_N*(N))+(__inc_b_M*(o_tp1))];
150              
151             #ifdef DEBUG_ALPHA
152             printf("INIT: j=%u,t=0,o=%d: pi(j=%u)=%.2e b(j=%u,o=%d)=%.2e alpha(j=%u,t=0)=%.2e\n",
153             n,o_tp1,
154             n, exp((pi_datap)[0+(__inc_pi_N*(N))]),
155             n,o_tp1 exp((b_datap)[0+(__inc_b_N*(N))+(__inc_b_M*(o_tp1))]),
156             n, exp((alpha_datap)[0+(__inc_alpha_N*(N))+(__inc_alpha_T*(0))])
157             );
158             #endif
159             }} /* Close N */
160              
161             #ifdef DEBUG_ALPHA
162             printf("\n\n");
163             #endif
164              
165             /*-- Loop: time t>0 --*/
166 0 0         for (t=0; t < __privtrans->ind_sizes[2]-1; t++) {
167 0           o_tp1 = (o_datap)[0+(__inc_o_T*(t+1))];
168              
169             /*-- Loop: state_(t+1)==j --*/
170 0 0         for (j=0; j<__privtrans->ind_sizes[1]; j++) {
171 0           PDL_Float alpha_j_tp1 = (PDL_Float)LOG_ZERO;
172              
173              
174             /*-- Loop: state_t==i --*/
175 0 0         for (i=0; i<__privtrans->ind_sizes[1]; i++) {
176 0           alpha_j_tp1 = logadd( (alpha_datap)[0+(__inc_alpha_N*(i))+(__inc_alpha_T*(t))] + (a_datap)[0+(__inc_a_N0*(i))+(__inc_a_N1*(j))], alpha_j_tp1 );
177              
178             #ifdef DEBUG_ALPHA
179             printf("i=%u,j=%u,t=%u,o=%d: alpha(i=%u,t=%u)=%.2e a(i=%u,j=%u)=%.2e b(j=%u,o=%d)=%.2e prod=%.2e sum=%.2e\n",
180             i,j,t,o_tp1,
181             i,t, exp((alpha_datap)[0+(__inc_alpha_N*(i))+(__inc_alpha_T*(t))]),
182             i,j, exp((a_datap)[0+(__inc_a_N0*(i))+(__inc_a_N1*(j))]),
183             j,o_tp1, exp((b_datap)[0+(__inc_b_N*(j))+(__inc_b_M*(o_tp1))]),
184             exp( (alpha_datap)[0+(__inc_alpha_N*(i))+(__inc_alpha_T*(t))] + (a_datap)[0+(__inc_a_N0*(i))+(__inc_a_N1*(j))] ), exp(alpha_j_tp1));
185             #endif
186             }
187              
188             /*-- Storage: alpha(time=t+1, state=j) --*/
189 0           (alpha_datap)[0+(__inc_alpha_N*(j))+(__inc_alpha_T*(t+1))] = alpha_j_tp1 + (b_datap)[0+(__inc_b_N*(j))+(__inc_b_M*(o_tp1))];
190              
191             #ifdef DEBUG_ALPHA
192             printf("----> alpha(j=%u,t=%u)=%.2E\n", j,t+1, exp((alpha_datap)[0+(__inc_alpha_N*(j))+(__inc_alpha_T*(t+1))]));
193             #endif
194             }
195             #ifdef DEBUG_ALPHA
196             printf("\n\n");
197             #endif
198             }
199 0 0         }PDL_BROADCASTLOOP_END_hmmfw_readdata
    0          
200 0           } break;
201 13           case PDL_D: {
202 13 50         PDL_DECLARE_PARAMS_hmmfw_1(PDL_Double,D)
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
203 52 50         PDL_BROADCASTLOOP_START_hmmfw_readdata {
    50          
    50          
    50          
    50          
    100          
    100          
204             /*-- Initialize: t==0 --*/
205 13           int i,j,t, o_tp1 = (o_datap)[0+(__inc_o_T*(0))];
206 39 100         {/* Open N */ PDL_EXPAND2(register PDL_Indx N=0, __N_stop=(__N_size)); for(; N<__N_stop; N+=1) {
207 26           (alpha_datap)[0+(__inc_alpha_N*(N))+(__inc_alpha_T*(0))] = (pi_datap)[0+(__inc_pi_N*(N))] + (b_datap)[0+(__inc_b_N*(N))+(__inc_b_M*(o_tp1))];
208              
209             #ifdef DEBUG_ALPHA
210             printf("INIT: j=%u,t=0,o=%d: pi(j=%u)=%.2e b(j=%u,o=%d)=%.2e alpha(j=%u,t=0)=%.2e\n",
211             n,o_tp1,
212             n, exp((pi_datap)[0+(__inc_pi_N*(N))]),
213             n,o_tp1 exp((b_datap)[0+(__inc_b_N*(N))+(__inc_b_M*(o_tp1))]),
214             n, exp((alpha_datap)[0+(__inc_alpha_N*(N))+(__inc_alpha_T*(0))])
215             );
216             #endif
217             }} /* Close N */
218              
219             #ifdef DEBUG_ALPHA
220             printf("\n\n");
221             #endif
222              
223             /*-- Loop: time t>0 --*/
224 26 100         for (t=0; t < __privtrans->ind_sizes[2]-1; t++) {
225 13           o_tp1 = (o_datap)[0+(__inc_o_T*(t+1))];
226              
227             /*-- Loop: state_(t+1)==j --*/
228 39 100         for (j=0; j<__privtrans->ind_sizes[1]; j++) {
229 26           PDL_Double alpha_j_tp1 = (PDL_Double)LOG_ZERO;
230              
231              
232             /*-- Loop: state_t==i --*/
233 78 100         for (i=0; i<__privtrans->ind_sizes[1]; i++) {
234 52           alpha_j_tp1 = logadd( (alpha_datap)[0+(__inc_alpha_N*(i))+(__inc_alpha_T*(t))] + (a_datap)[0+(__inc_a_N0*(i))+(__inc_a_N1*(j))], alpha_j_tp1 );
235              
236             #ifdef DEBUG_ALPHA
237             printf("i=%u,j=%u,t=%u,o=%d: alpha(i=%u,t=%u)=%.2e a(i=%u,j=%u)=%.2e b(j=%u,o=%d)=%.2e prod=%.2e sum=%.2e\n",
238             i,j,t,o_tp1,
239             i,t, exp((alpha_datap)[0+(__inc_alpha_N*(i))+(__inc_alpha_T*(t))]),
240             i,j, exp((a_datap)[0+(__inc_a_N0*(i))+(__inc_a_N1*(j))]),
241             j,o_tp1, exp((b_datap)[0+(__inc_b_N*(j))+(__inc_b_M*(o_tp1))]),
242             exp( (alpha_datap)[0+(__inc_alpha_N*(i))+(__inc_alpha_T*(t))] + (a_datap)[0+(__inc_a_N0*(i))+(__inc_a_N1*(j))] ), exp(alpha_j_tp1));
243             #endif
244             }
245              
246             /*-- Storage: alpha(time=t+1, state=j) --*/
247 26           (alpha_datap)[0+(__inc_alpha_N*(j))+(__inc_alpha_T*(t+1))] = alpha_j_tp1 + (b_datap)[0+(__inc_b_N*(j))+(__inc_b_M*(o_tp1))];
248              
249             #ifdef DEBUG_ALPHA
250             printf("----> alpha(j=%u,t=%u)=%.2E\n", j,t+1, exp((alpha_datap)[0+(__inc_alpha_N*(j))+(__inc_alpha_T*(t+1))]));
251             #endif
252             }
253             #ifdef DEBUG_ALPHA
254             printf("\n\n");
255             #endif
256             }
257 13 50         }PDL_BROADCASTLOOP_END_hmmfw_readdata
    50          
258 13           } break;
259 0           case PDL_LD: {
260 0 0         PDL_DECLARE_PARAMS_hmmfw_1(PDL_LDouble,E)
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
261 0 0         PDL_BROADCASTLOOP_START_hmmfw_readdata {
    0          
    0          
    0          
    0          
    0          
    0          
262             /*-- Initialize: t==0 --*/
263 0           int i,j,t, o_tp1 = (o_datap)[0+(__inc_o_T*(0))];
264 0 0         {/* Open N */ PDL_EXPAND2(register PDL_Indx N=0, __N_stop=(__N_size)); for(; N<__N_stop; N+=1) {
265 0           (alpha_datap)[0+(__inc_alpha_N*(N))+(__inc_alpha_T*(0))] = (pi_datap)[0+(__inc_pi_N*(N))] + (b_datap)[0+(__inc_b_N*(N))+(__inc_b_M*(o_tp1))];
266              
267             #ifdef DEBUG_ALPHA
268             printf("INIT: j=%u,t=0,o=%d: pi(j=%u)=%.2e b(j=%u,o=%d)=%.2e alpha(j=%u,t=0)=%.2e\n",
269             n,o_tp1,
270             n, exp((pi_datap)[0+(__inc_pi_N*(N))]),
271             n,o_tp1 exp((b_datap)[0+(__inc_b_N*(N))+(__inc_b_M*(o_tp1))]),
272             n, exp((alpha_datap)[0+(__inc_alpha_N*(N))+(__inc_alpha_T*(0))])
273             );
274             #endif
275             }} /* Close N */
276              
277             #ifdef DEBUG_ALPHA
278             printf("\n\n");
279             #endif
280              
281             /*-- Loop: time t>0 --*/
282 0 0         for (t=0; t < __privtrans->ind_sizes[2]-1; t++) {
283 0           o_tp1 = (o_datap)[0+(__inc_o_T*(t+1))];
284              
285             /*-- Loop: state_(t+1)==j --*/
286 0 0         for (j=0; j<__privtrans->ind_sizes[1]; j++) {
287 0           PDL_LDouble alpha_j_tp1 = (PDL_LDouble)LOG_ZERO;
288              
289              
290             /*-- Loop: state_t==i --*/
291 0 0         for (i=0; i<__privtrans->ind_sizes[1]; i++) {
292 0           alpha_j_tp1 = logadd( (alpha_datap)[0+(__inc_alpha_N*(i))+(__inc_alpha_T*(t))] + (a_datap)[0+(__inc_a_N0*(i))+(__inc_a_N1*(j))], alpha_j_tp1 );
293              
294             #ifdef DEBUG_ALPHA
295             printf("i=%u,j=%u,t=%u,o=%d: alpha(i=%u,t=%u)=%.2e a(i=%u,j=%u)=%.2e b(j=%u,o=%d)=%.2e prod=%.2e sum=%.2e\n",
296             i,j,t,o_tp1,
297             i,t, exp((alpha_datap)[0+(__inc_alpha_N*(i))+(__inc_alpha_T*(t))]),
298             i,j, exp((a_datap)[0+(__inc_a_N0*(i))+(__inc_a_N1*(j))]),
299             j,o_tp1, exp((b_datap)[0+(__inc_b_N*(j))+(__inc_b_M*(o_tp1))]),
300             exp( (alpha_datap)[0+(__inc_alpha_N*(i))+(__inc_alpha_T*(t))] + (a_datap)[0+(__inc_a_N0*(i))+(__inc_a_N1*(j))] ), exp(alpha_j_tp1));
301             #endif
302             }
303              
304             /*-- Storage: alpha(time=t+1, state=j) --*/
305 0           (alpha_datap)[0+(__inc_alpha_N*(j))+(__inc_alpha_T*(t+1))] = alpha_j_tp1 + (b_datap)[0+(__inc_b_N*(j))+(__inc_b_M*(o_tp1))];
306              
307             #ifdef DEBUG_ALPHA
308             printf("----> alpha(j=%u,t=%u)=%.2E\n", j,t+1, exp((alpha_datap)[0+(__inc_alpha_N*(j))+(__inc_alpha_T*(t+1))]));
309             #endif
310             }
311             #ifdef DEBUG_ALPHA
312             printf("\n\n");
313             #endif
314             }
315 0 0         }PDL_BROADCASTLOOP_END_hmmfw_readdata
    0          
316 0           } break;
317 0           default: return PDL->make_error(PDL_EUSERERROR, "PP INTERNAL ERROR in hmmfw: unhandled datatype(%d), only handles (FDE)! PLEASE MAKE A BUG REPORT\n", __privtrans->__datatype);
318             }
319             #undef PDL_IF_BAD
320 13           return PDL_err;
321             }
322              
323             static pdl_datatypes pdl_hmmfw_vtable_gentypes[] = { PDL_F, PDL_D, PDL_LD, -1 };
324             static PDL_Indx pdl_hmmfw_vtable_realdims[] = { 2, 2, 1, 1, 2 };
325             static char *pdl_hmmfw_vtable_parnames[] = { "a","b","pi","o","alpha" };
326             static short pdl_hmmfw_vtable_parflags[] = {
327             0,
328             0,
329             0,
330             0,
331             PDL_PARAM_ISCREAT|PDL_PARAM_ISOUT|PDL_PARAM_ISWRITE
332             };
333             static pdl_datatypes pdl_hmmfw_vtable_partypes[] = { -1, -1, -1, -1, -1 };
334             static PDL_Indx pdl_hmmfw_vtable_realdims_starts[] = { 0, 2, 4, 5, 6 };
335             static PDL_Indx pdl_hmmfw_vtable_realdims_ind_ids[] = { 1, 1, 1, 0, 1, 2, 1, 2 };
336             static char *pdl_hmmfw_vtable_indnames[] = { "M","N","T" };
337             pdl_transvtable pdl_hmmfw_vtable = {
338             PDL_TRANS_DO_BROADCAST, 0, pdl_hmmfw_vtable_gentypes, 4, 5, NULL /*CORE21*/,
339             pdl_hmmfw_vtable_realdims, pdl_hmmfw_vtable_parnames,
340             pdl_hmmfw_vtable_parflags, pdl_hmmfw_vtable_partypes,
341             pdl_hmmfw_vtable_realdims_starts, pdl_hmmfw_vtable_realdims_ind_ids, 8,
342             3, pdl_hmmfw_vtable_indnames,
343             NULL, pdl_hmmfw_readdata, NULL,
344             NULL,
345             0,"PDL::HMM::hmmfw"
346             };
347              
348              
349 13           pdl_error pdl_run_hmmfw(pdl *a,pdl *b,pdl *pi,pdl *o,pdl *alpha) {
350 13           pdl_error PDL_err = {0, NULL, 0};
351 13 50         if (!PDL) return (pdl_error){PDL_EFATAL, "PDL core struct is NULL, can't continue",0};
352 13           pdl_trans *__privtrans = PDL->create_trans(&pdl_hmmfw_vtable);
353 13 50         if (!__privtrans) return PDL->make_error_simple(PDL_EFATAL, "Couldn't create trans");
354 13           __privtrans->pdls[0] = a;
355 13           __privtrans->pdls[1] = b;
356 13           __privtrans->pdls[2] = pi;
357 13           __privtrans->pdls[3] = o;
358 13           __privtrans->pdls[4] = alpha;
359 13 50         PDL_RETERROR(PDL_err, PDL->type_coerce(__privtrans));
360 13 50         PDL_RETERROR(PDL_err, PDL->make_trans_mutual(__privtrans));
361 13           return PDL_err;
362             }