chaine 3.13.1__cp313-cp313-win32.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of chaine might be problematic. Click here for more details.

Files changed (68) hide show
  1. chaine/__init__.py +2 -0
  2. chaine/_core/crf.cp313-win32.pyd +0 -0
  3. chaine/_core/crf.cpp +19854 -0
  4. chaine/_core/crf.pyx +271 -0
  5. chaine/_core/crfsuite/COPYING +27 -0
  6. chaine/_core/crfsuite/README +183 -0
  7. chaine/_core/crfsuite/include/crfsuite.h +1077 -0
  8. chaine/_core/crfsuite/include/crfsuite.hpp +649 -0
  9. chaine/_core/crfsuite/include/crfsuite_api.hpp +406 -0
  10. chaine/_core/crfsuite/include/os.h +65 -0
  11. chaine/_core/crfsuite/lib/cqdb/COPYING +28 -0
  12. chaine/_core/crfsuite/lib/cqdb/include/cqdb.h +518 -0
  13. chaine/_core/crfsuite/lib/cqdb/src/cqdb.c +639 -0
  14. chaine/_core/crfsuite/lib/cqdb/src/lookup3.c +1271 -0
  15. chaine/_core/crfsuite/lib/cqdb/src/main.c +184 -0
  16. chaine/_core/crfsuite/lib/crf/src/crf1d.h +354 -0
  17. chaine/_core/crfsuite/lib/crf/src/crf1d_context.c +788 -0
  18. chaine/_core/crfsuite/lib/crf/src/crf1d_encode.c +1020 -0
  19. chaine/_core/crfsuite/lib/crf/src/crf1d_feature.c +382 -0
  20. chaine/_core/crfsuite/lib/crf/src/crf1d_model.c +1085 -0
  21. chaine/_core/crfsuite/lib/crf/src/crf1d_tag.c +582 -0
  22. chaine/_core/crfsuite/lib/crf/src/crfsuite.c +500 -0
  23. chaine/_core/crfsuite/lib/crf/src/crfsuite_internal.h +233 -0
  24. chaine/_core/crfsuite/lib/crf/src/crfsuite_train.c +302 -0
  25. chaine/_core/crfsuite/lib/crf/src/dataset.c +115 -0
  26. chaine/_core/crfsuite/lib/crf/src/dictionary.c +127 -0
  27. chaine/_core/crfsuite/lib/crf/src/holdout.c +83 -0
  28. chaine/_core/crfsuite/lib/crf/src/json.c +1497 -0
  29. chaine/_core/crfsuite/lib/crf/src/json.h +120 -0
  30. chaine/_core/crfsuite/lib/crf/src/logging.c +85 -0
  31. chaine/_core/crfsuite/lib/crf/src/logging.h +49 -0
  32. chaine/_core/crfsuite/lib/crf/src/params.c +370 -0
  33. chaine/_core/crfsuite/lib/crf/src/params.h +84 -0
  34. chaine/_core/crfsuite/lib/crf/src/quark.c +180 -0
  35. chaine/_core/crfsuite/lib/crf/src/quark.h +46 -0
  36. chaine/_core/crfsuite/lib/crf/src/rumavl.c +1178 -0
  37. chaine/_core/crfsuite/lib/crf/src/rumavl.h +144 -0
  38. chaine/_core/crfsuite/lib/crf/src/train_arow.c +409 -0
  39. chaine/_core/crfsuite/lib/crf/src/train_averaged_perceptron.c +237 -0
  40. chaine/_core/crfsuite/lib/crf/src/train_l2sgd.c +491 -0
  41. chaine/_core/crfsuite/lib/crf/src/train_lbfgs.c +323 -0
  42. chaine/_core/crfsuite/lib/crf/src/train_passive_aggressive.c +442 -0
  43. chaine/_core/crfsuite/lib/crf/src/vecmath.h +360 -0
  44. chaine/_core/crfsuite/swig/crfsuite.cpp +1 -0
  45. chaine/_core/crfsuite_api.pxd +67 -0
  46. chaine/_core/liblbfgs/COPYING +22 -0
  47. chaine/_core/liblbfgs/README +71 -0
  48. chaine/_core/liblbfgs/include/lbfgs.h +745 -0
  49. chaine/_core/liblbfgs/lib/arithmetic_ansi.h +142 -0
  50. chaine/_core/liblbfgs/lib/arithmetic_sse_double.h +303 -0
  51. chaine/_core/liblbfgs/lib/arithmetic_sse_float.h +312 -0
  52. chaine/_core/liblbfgs/lib/lbfgs.c +1531 -0
  53. chaine/_core/tagger_wrapper.hpp +58 -0
  54. chaine/_core/trainer_wrapper.cpp +32 -0
  55. chaine/_core/trainer_wrapper.hpp +26 -0
  56. chaine/crf.py +505 -0
  57. chaine/logging.py +214 -0
  58. chaine/optimization/__init__.py +10 -0
  59. chaine/optimization/metrics.py +129 -0
  60. chaine/optimization/spaces.py +394 -0
  61. chaine/optimization/trial.py +103 -0
  62. chaine/optimization/utils.py +119 -0
  63. chaine/training.py +184 -0
  64. chaine/typing.py +18 -0
  65. chaine/validation.py +43 -0
  66. chaine-3.13.1.dist-info/METADATA +348 -0
  67. chaine-3.13.1.dist-info/RECORD +68 -0
  68. chaine-3.13.1.dist-info/WHEEL +4 -0
@@ -0,0 +1,788 @@
1
+ /*
2
+ * CRF1d context (forward-backward, viterbi, etc).
3
+ *
4
+ * Copyright (c) 2007-2010, Naoaki Okazaki
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are met:
9
+ * * Redistributions of source code must retain the above copyright
10
+ * notice, this list of conditions and the following disclaimer.
11
+ * * Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ * * Neither the names of the authors nor the names of its contributors
15
+ * may be used to endorse or promote products derived from this
16
+ * software without specific prior written permission.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
22
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ */
30
+
31
+ /* $Id$ */
32
+
33
+ #ifdef HAVE_CONFIG_H
34
+ #include <config.h>
35
+ #endif /*HAVE_CONFIG_H*/
36
+
37
+ #include <os.h>
38
+
39
+ #include <float.h>
40
+ #include <math.h>
41
+ #include <stdio.h>
42
+ #include <stdlib.h>
43
+
44
+ #include <crfsuite.h>
45
+
46
+ #include "crf1d.h"
47
+ #include "vecmath.h"
48
+
49
+ crf1d_context_t *crf1dc_new(int flag, int L, int T)
50
+ {
51
+ int ret = 0;
52
+ crf1d_context_t *ctx = NULL;
53
+
54
+ ctx = (crf1d_context_t *)calloc(1, sizeof(crf1d_context_t));
55
+ if (ctx != NULL)
56
+ {
57
+ ctx->flag = flag;
58
+ ctx->num_labels = L;
59
+
60
+ ctx->trans = (floatval_t *)calloc(L * L, sizeof(floatval_t));
61
+ if (ctx->trans == NULL)
62
+ goto error_exit;
63
+
64
+ if (ctx->flag & CTXF_MARGINALS)
65
+ {
66
+ ctx->exp_trans = (floatval_t *)_aligned_malloc((L * L + 4) * sizeof(floatval_t), 16);
67
+ if (ctx->exp_trans == NULL)
68
+ goto error_exit;
69
+ ctx->mexp_trans = (floatval_t *)calloc(L * L, sizeof(floatval_t));
70
+ if (ctx->mexp_trans == NULL)
71
+ goto error_exit;
72
+ }
73
+
74
+ if (ret = crf1dc_set_num_items(ctx, T))
75
+ {
76
+ goto error_exit;
77
+ }
78
+
79
+ /* T gives the 'hint' for maximum length of items. */
80
+ ctx->num_items = 0;
81
+ }
82
+
83
+ return ctx;
84
+
85
+ error_exit:
86
+ crf1dc_delete(ctx);
87
+ return NULL;
88
+ }
89
+
90
+ int crf1dc_set_num_items(crf1d_context_t *ctx, int T)
91
+ {
92
+ const int L = ctx->num_labels;
93
+
94
+ ctx->num_items = T;
95
+
96
+ if (ctx->cap_items < T)
97
+ {
98
+ free(ctx->backward_edge);
99
+ free(ctx->mexp_state);
100
+ _aligned_free(ctx->exp_state);
101
+ free(ctx->scale_factor);
102
+ free(ctx->row);
103
+ free(ctx->beta_score);
104
+ free(ctx->alpha_score);
105
+ free(ctx->state);
106
+
107
+ ctx->alpha_score = (floatval_t *)calloc(T * L, sizeof(floatval_t));
108
+ if (ctx->alpha_score == NULL)
109
+ return CRFSUITEERR_OUTOFMEMORY;
110
+ ctx->beta_score = (floatval_t *)calloc(T * L, sizeof(floatval_t));
111
+ if (ctx->beta_score == NULL)
112
+ return CRFSUITEERR_OUTOFMEMORY;
113
+ ctx->scale_factor = (floatval_t *)calloc(T, sizeof(floatval_t));
114
+ if (ctx->scale_factor == NULL)
115
+ return CRFSUITEERR_OUTOFMEMORY;
116
+ ctx->row = (floatval_t *)calloc(L, sizeof(floatval_t));
117
+ if (ctx->row == NULL)
118
+ return CRFSUITEERR_OUTOFMEMORY;
119
+
120
+ if (ctx->flag & CTXF_VITERBI)
121
+ {
122
+ ctx->backward_edge = (int *)calloc(T * L, sizeof(int));
123
+ if (ctx->backward_edge == NULL)
124
+ return CRFSUITEERR_OUTOFMEMORY;
125
+ }
126
+
127
+ ctx->state = (floatval_t *)calloc(T * L, sizeof(floatval_t));
128
+ if (ctx->state == NULL)
129
+ return CRFSUITEERR_OUTOFMEMORY;
130
+
131
+ if (ctx->flag & CTXF_MARGINALS)
132
+ {
133
+ ctx->exp_state = (floatval_t *)_aligned_malloc((T * L + 4) * sizeof(floatval_t), 16);
134
+ if (ctx->exp_state == NULL)
135
+ return CRFSUITEERR_OUTOFMEMORY;
136
+ ctx->mexp_state = (floatval_t *)calloc(T * L, sizeof(floatval_t));
137
+ if (ctx->mexp_state == NULL)
138
+ return CRFSUITEERR_OUTOFMEMORY;
139
+ }
140
+
141
+ ctx->cap_items = T;
142
+ }
143
+
144
+ return 0;
145
+ }
146
+
147
+ void crf1dc_delete(crf1d_context_t *ctx)
148
+ {
149
+ if (ctx != NULL)
150
+ {
151
+ free(ctx->backward_edge);
152
+ free(ctx->mexp_state);
153
+ _aligned_free(ctx->exp_state);
154
+ free(ctx->state);
155
+ free(ctx->scale_factor);
156
+ free(ctx->row);
157
+ free(ctx->beta_score);
158
+ free(ctx->alpha_score);
159
+ free(ctx->mexp_trans);
160
+ _aligned_free(ctx->exp_trans);
161
+ free(ctx->trans);
162
+ }
163
+ free(ctx);
164
+ }
165
+
166
+ void crf1dc_reset(crf1d_context_t *ctx, int flag)
167
+ {
168
+ const int T = ctx->num_items;
169
+ const int L = ctx->num_labels;
170
+
171
+ if (flag & RF_STATE)
172
+ {
173
+ veczero(ctx->state, T * L);
174
+ }
175
+ if (flag & RF_TRANS)
176
+ {
177
+ veczero(ctx->trans, L * L);
178
+ }
179
+
180
+ if (ctx->flag & CTXF_MARGINALS)
181
+ {
182
+ veczero(ctx->mexp_state, T * L);
183
+ veczero(ctx->mexp_trans, L * L);
184
+ ctx->log_norm = 0;
185
+ }
186
+ }
187
+
188
+ void crf1dc_exp_state(crf1d_context_t *ctx)
189
+ {
190
+ const int T = ctx->num_items;
191
+ const int L = ctx->num_labels;
192
+
193
+ veccopy(ctx->exp_state, ctx->state, L * T);
194
+ vecexp(ctx->exp_state, L * T);
195
+ }
196
+
197
+ void crf1dc_exp_transition(crf1d_context_t *ctx)
198
+ {
199
+ const int L = ctx->num_labels;
200
+
201
+ veccopy(ctx->exp_trans, ctx->trans, L * L);
202
+ vecexp(ctx->exp_trans, L * L);
203
+ }
204
+
205
+ void crf1dc_alpha_score(crf1d_context_t *ctx)
206
+ {
207
+ int i, t;
208
+ floatval_t sum, *cur = NULL;
209
+ floatval_t *scale = &ctx->scale_factor[0];
210
+ const floatval_t *prev = NULL, *trans = NULL, *state = NULL;
211
+ const int T = ctx->num_items;
212
+ const int L = ctx->num_labels;
213
+
214
+ /* Compute the alpha scores on nodes (0, *).
215
+ alpha[0][j] = state[0][j]
216
+ */
217
+ cur = ALPHA_SCORE(ctx, 0);
218
+ state = EXP_STATE_SCORE(ctx, 0);
219
+ veccopy(cur, state, L);
220
+ sum = vecsum(cur, L);
221
+ *scale = (sum != 0.) ? 1. / sum : 1.;
222
+ vecscale(cur, *scale, L);
223
+ ++scale;
224
+
225
+ /* Compute the alpha scores on nodes (t, *).
226
+ alpha[t][j] = state[t][j] * \sum_{i} alpha[t-1][i] * trans[i][j]
227
+ */
228
+ for (t = 1; t < T; ++t)
229
+ {
230
+ prev = ALPHA_SCORE(ctx, t - 1);
231
+ cur = ALPHA_SCORE(ctx, t);
232
+ state = EXP_STATE_SCORE(ctx, t);
233
+
234
+ veczero(cur, L);
235
+ for (i = 0; i < L; ++i)
236
+ {
237
+ trans = EXP_TRANS_SCORE(ctx, i);
238
+ vecaadd(cur, prev[i], trans, L);
239
+ }
240
+ vecmul(cur, state, L);
241
+ sum = vecsum(cur, L);
242
+ *scale = (sum != 0.) ? 1. / sum : 1.;
243
+ vecscale(cur, *scale, L);
244
+ ++scale;
245
+ }
246
+
247
+ /* Compute the logarithm of the normalization factor here.
248
+ norm = 1. / (C[0] * C[1] ... * C[T-1])
249
+ log(norm) = - \sum_{t = 0}^{T-1} log(C[t]).
250
+ */
251
+ ctx->log_norm = -vecsumlog(ctx->scale_factor, T);
252
+ }
253
+
254
+ void crf1dc_beta_score(crf1d_context_t *ctx)
255
+ {
256
+ int i, t;
257
+ floatval_t *cur = NULL;
258
+ floatval_t *row = ctx->row;
259
+ const floatval_t *next = NULL, *state = NULL, *trans = NULL;
260
+ const int T = ctx->num_items;
261
+ const int L = ctx->num_labels;
262
+ const floatval_t *scale = &ctx->scale_factor[T - 1];
263
+
264
+ /* Compute the beta scores at (T-1, *). */
265
+ cur = BETA_SCORE(ctx, T - 1);
266
+ vecset(cur, *scale, L);
267
+ --scale;
268
+
269
+ /* Compute the beta scores at (t, *). */
270
+ for (t = T - 2; 0 <= t; --t)
271
+ {
272
+ cur = BETA_SCORE(ctx, t);
273
+ next = BETA_SCORE(ctx, t + 1);
274
+ state = EXP_STATE_SCORE(ctx, t + 1);
275
+
276
+ veccopy(row, next, L);
277
+ vecmul(row, state, L);
278
+
279
+ /* Compute the beta score at (t, i). */
280
+ for (i = 0; i < L; ++i)
281
+ {
282
+ trans = EXP_TRANS_SCORE(ctx, i);
283
+ cur[i] = vecdot(trans, row, L);
284
+ }
285
+ vecscale(cur, *scale, L);
286
+ --scale;
287
+ }
288
+ }
289
+
290
+ void crf1dc_marginals(crf1d_context_t *ctx)
291
+ {
292
+ int i, j, t;
293
+ const int T = ctx->num_items;
294
+ const int L = ctx->num_labels;
295
+
296
+ /*
297
+ Compute the model expectations of states.
298
+ p(t,i) = fwd[t][i] * bwd[t][i] / norm
299
+ = (1. / C[t]) * fwd'[t][i] * bwd'[t][i]
300
+ */
301
+ for (t = 0; t < T; ++t)
302
+ {
303
+ floatval_t *fwd = ALPHA_SCORE(ctx, t);
304
+ floatval_t *bwd = BETA_SCORE(ctx, t);
305
+ floatval_t *prob = STATE_MEXP(ctx, t);
306
+ veccopy(prob, fwd, L);
307
+ vecmul(prob, bwd, L);
308
+ vecscale(prob, 1. / ctx->scale_factor[t], L);
309
+ }
310
+
311
+ /*
312
+ Compute the model expectations of transitions.
313
+ p(t,i,t+1,j)
314
+ = fwd[t][i] * edge[i][j] * state[t+1][j] * bwd[t+1][j] / norm
315
+ = (fwd'[t][i] / (C[0] ... C[t])) * edge[i][j] * state[t+1][j] * (bwd'[t+1][j] / (C[t+1] ... C[T-1])) * (C[0] * ... * C[T-1])
316
+ = fwd'[t][i] * edge[i][j] * state[t+1][j] * bwd'[t+1][j]
317
+ The model expectation of a transition (i -> j) is the sum of the marginal
318
+ probabilities p(t,i,t+1,j) over t.
319
+ */
320
+ for (t = 0; t < T - 1; ++t)
321
+ {
322
+ floatval_t *fwd = ALPHA_SCORE(ctx, t);
323
+ floatval_t *state = EXP_STATE_SCORE(ctx, t + 1);
324
+ floatval_t *bwd = BETA_SCORE(ctx, t + 1);
325
+ floatval_t *row = ctx->row;
326
+
327
+ /* row[j] = state[t+1][j] * bwd'[t+1][j] */
328
+ veccopy(row, bwd, L);
329
+ vecmul(row, state, L);
330
+
331
+ for (i = 0; i < L; ++i)
332
+ {
333
+ floatval_t *edge = EXP_TRANS_SCORE(ctx, i);
334
+ floatval_t *prob = TRANS_MEXP(ctx, i);
335
+ for (j = 0; j < L; ++j)
336
+ {
337
+ prob[j] += fwd[i] * edge[j] * row[j];
338
+ }
339
+ }
340
+ }
341
+ }
342
+
343
+ floatval_t crf1dc_marginal_point(crf1d_context_t *ctx, int l, int t)
344
+ {
345
+ floatval_t *fwd = ALPHA_SCORE(ctx, t);
346
+ floatval_t *bwd = BETA_SCORE(ctx, t);
347
+ return fwd[l] * bwd[l] / ctx->scale_factor[t];
348
+ }
349
+
350
+ floatval_t crf1dc_marginal_path(crf1d_context_t *ctx, const int *path, int begin, int end)
351
+ {
352
+ int t;
353
+ /*
354
+ Compute the marginal probability of a (partial) path.
355
+ a = path[begin], b = path[begin+1], ..., y = path[end-2], z = path[end-1]
356
+ fwd[begin][a] = (fwd'[begin][a] / (C[0] ... C[begin])
357
+ bwd[end-1][z] = (bwd'[end-1][z] / (C[end-1] ... C[T-1]))
358
+ norm = 1 / (C[0] * ... * C[T-1])
359
+ p(a, b, ..., z)
360
+ = fwd[begin][a] * edge[a][b] * state[begin+1][b] * ... * edge[y][z] * state[end-1][z] * bwd[end-1][z] / norm
361
+ = fwd'[begin][a] * edge[a][b] * state[begin+1][b] * ... * edge[y][z] * state[end-1][z] * bwd'[end-1][z] * (C[begin+1] * ... * C[end-2])
362
+ */
363
+ floatval_t *fwd = ALPHA_SCORE(ctx, begin);
364
+ floatval_t *bwd = BETA_SCORE(ctx, end - 1);
365
+ floatval_t prob = fwd[path[begin]] * bwd[path[end - 1]] / ctx->scale_factor[begin];
366
+
367
+ for (t = begin; t < end - 1; ++t)
368
+ {
369
+ floatval_t *state = EXP_STATE_SCORE(ctx, t + 1);
370
+ floatval_t *edge = EXP_TRANS_SCORE(ctx, path[t]);
371
+ prob *= (edge[path[t + 1]] * state[path[t + 1]] * ctx->scale_factor[t]);
372
+ }
373
+
374
+ return prob;
375
+ }
376
+
377
+ #if 0
378
+ /* Sigh, this was found to be slower than the forward-backward algorithm. */
379
+
380
+ #define ADJACENCY(ctx, i) \
381
+ (&MATRIX(ctx->adj, ctx->num_labels, 0, i))
382
+
383
+ void crf1dc_marginal_without_beta(crf1d_context_t* ctx)
384
+ {
385
+ int i, j, t;
386
+ floatval_t *prob = NULL;
387
+ floatval_t *row = ctx->row;
388
+ const floatval_t *fwd = NULL;
389
+ const int T = ctx->num_items;
390
+ const int L = ctx->num_labels;
391
+
392
+ /*
393
+ Compute marginal probabilities of states at T-1
394
+ p(T-1,j) = fwd'[T-1][j]
395
+ */
396
+ fwd = ALPHA_SCORE(ctx, T-1);
397
+ prob = STATE_MEXP(ctx, T-1);
398
+ veccopy(prob, fwd, L);
399
+
400
+ /*
401
+ Repeat the following computation for t = T-1,T-2, ..., 1.
402
+ 1) Compute p(t-1,i,t,j) using p(t,j)
403
+ 2) Compute p(t,i) using p(t-1,i,t,j)
404
+ */
405
+ for (t = T-1;0 < t;--t) {
406
+ fwd = ALPHA_SCORE(ctx, t-1);
407
+ prob = STATE_MEXP(ctx, t);
408
+
409
+ veczero(ctx->adj, L*L);
410
+ veczero(row, L);
411
+
412
+ /*
413
+ Compute adj[i][j] and row[j].
414
+ adj[i][j] = fwd'[t-1][i] * edge[i][j]
415
+ row[j] = \sum_{i} adj[i][j]
416
+ */
417
+ for (i = 0;i < L;++i) {
418
+ floatval_t *adj = ADJACENCY(ctx, i);
419
+ floatval_t *edge = EXP_TRANS_SCORE(ctx, i);
420
+ vecaadd(adj, fwd[i], edge, L);
421
+ vecadd(row, adj, L);
422
+ }
423
+
424
+ /*
425
+ Find z such that z * \sum_{i] adj[i][j] = p(t,j).
426
+ Thus, z = p(t,j) / row[j]; we overwrite row with z.
427
+ */
428
+ vecinv(row, L);
429
+ vecmul(row, prob, L);
430
+
431
+ /*
432
+ Apply the partition factor z (row[j]) to adj[i][j].
433
+ */
434
+ for (i = 0;i < L;++i) {
435
+ floatval_t *adj = ADJACENCY(ctx, i);
436
+ vecmul(adj, row, L);
437
+ }
438
+
439
+ /*
440
+ Now that adj[i][j] presents p(t-1,i,t,j),
441
+ accumulate model expectations of transitions.
442
+ */
443
+ for (i = 0;i < L;++i) {
444
+ floatval_t *adj = ADJACENCY(ctx, i);
445
+ floatval_t *prob = TRANS_MEXP(ctx, i);
446
+ vecadd(prob, adj, L);
447
+ }
448
+
449
+ /*
450
+ Compute the marginal probability of states at t-1.
451
+ p(t-1,i) = \sum_{j} p(t-1,i,t,j)
452
+ */
453
+ prob = STATE_MEXP(ctx, t-1);
454
+ for (i = 0;i < L;++i) {
455
+ floatval_t *adj = ADJACENCY(ctx, i);
456
+ prob[i] = vecsum(adj, L);
457
+ }
458
+ }
459
+ }
460
+ #endif
461
+
462
+ floatval_t crf1dc_score(crf1d_context_t *ctx, const int *labels)
463
+ {
464
+ int i, j, t;
465
+ floatval_t ret = 0;
466
+ const floatval_t *state = NULL, *cur = NULL, *trans = NULL;
467
+ const int T = ctx->num_items;
468
+ const int L = ctx->num_labels;
469
+
470
+ /* Stay at (0, labels[0]). */
471
+ i = labels[0];
472
+ state = STATE_SCORE(ctx, 0);
473
+ ret = state[i];
474
+
475
+ /* Loop over the rest of items. */
476
+ for (t = 1; t < T; ++t)
477
+ {
478
+ j = labels[t];
479
+ trans = TRANS_SCORE(ctx, i);
480
+ state = STATE_SCORE(ctx, t);
481
+
482
+ /* Transit from (t-1, i) to (t, j). */
483
+ ret += trans[j];
484
+ ret += state[j];
485
+ i = j;
486
+ }
487
+ return ret;
488
+ }
489
+
490
+ floatval_t crf1dc_lognorm(crf1d_context_t *ctx)
491
+ {
492
+ return ctx->log_norm;
493
+ }
494
+
495
+ floatval_t crf1dc_viterbi(crf1d_context_t *ctx, int *labels)
496
+ {
497
+ int i, j, t;
498
+ int *back = NULL;
499
+ floatval_t max_score, score, *cur = NULL;
500
+ int argmax_score;
501
+ const floatval_t *prev = NULL, *state = NULL, *trans = NULL;
502
+ const int T = ctx->num_items;
503
+ const int L = ctx->num_labels;
504
+
505
+ /*
506
+ This function assumes state and trans scores to be in the logarithm domain.
507
+ */
508
+
509
+ /* Compute the scores at (0, *). */
510
+ cur = ALPHA_SCORE(ctx, 0);
511
+ state = STATE_SCORE(ctx, 0);
512
+ for (j = 0; j < L; ++j)
513
+ {
514
+ cur[j] = state[j];
515
+ }
516
+
517
+ /* Compute the scores at (t, *). */
518
+ for (t = 1; t < T; ++t)
519
+ {
520
+ prev = ALPHA_SCORE(ctx, t - 1);
521
+ cur = ALPHA_SCORE(ctx, t);
522
+ state = STATE_SCORE(ctx, t);
523
+ back = BACKWARD_EDGE_AT(ctx, t);
524
+
525
+ /* Compute the score of (t, j). */
526
+ for (j = 0; j < L; ++j)
527
+ {
528
+ max_score = -FLOAT_MAX;
529
+ argmax_score = -1;
530
+ for (i = 0; i < L; ++i)
531
+ {
532
+ /* Transit from (t-1, i) to (t, j). */
533
+ trans = TRANS_SCORE(ctx, i);
534
+ score = prev[i] + trans[j];
535
+
536
+ /* Store this path if it has the maximum score. */
537
+ if (max_score < score)
538
+ {
539
+ max_score = score;
540
+ argmax_score = i;
541
+ }
542
+ }
543
+ /* Backward link (#t, #j) -> (#t-1, #i). */
544
+ if (argmax_score >= 0)
545
+ back[j] = argmax_score;
546
+ /* Add the state score on (t, j). */
547
+ cur[j] = max_score + state[j];
548
+ }
549
+ }
550
+
551
+ /* Find the node (#T, #i) that reaches EOS with the maximum score. */
552
+ max_score = -FLOAT_MAX;
553
+ prev = ALPHA_SCORE(ctx, T - 1);
554
+ /* Set a score for T-1 to be overwritten later. Just in case we don't
555
+ end up with something beating -FLOAT_MAX. */
556
+ labels[T - 1] = 0;
557
+ for (i = 0; i < L; ++i)
558
+ {
559
+ if (max_score < prev[i])
560
+ {
561
+ max_score = prev[i];
562
+ labels[T - 1] = i; /* Tag the item #T. */
563
+ }
564
+ }
565
+
566
+ /* Tag labels by tracing the backward links. */
567
+ for (t = T - 2; 0 <= t; --t)
568
+ {
569
+ back = BACKWARD_EDGE_AT(ctx, t + 1);
570
+ labels[t] = back[labels[t + 1]];
571
+ }
572
+
573
+ /* Return the maximum score (without the normalization factor subtracted). */
574
+ return max_score;
575
+ }
576
+
577
+ static void check_values(FILE *fp, floatval_t cv, floatval_t tv)
578
+ {
579
+ if (fabs(cv - tv) < 1e-9)
580
+ {
581
+ fprintf(fp, "OK (%f)\n", cv);
582
+ }
583
+ else
584
+ {
585
+ fprintf(fp, "FAIL: %f (%f)\n", cv, tv);
586
+ }
587
+ }
588
+
589
+ void crf1dc_debug_context(FILE *fp)
590
+ {
591
+ int y1, y2, y3;
592
+ floatval_t norm = 0;
593
+ const int L = 3;
594
+ const int T = 3;
595
+ crf1d_context_t *ctx = crf1dc_new(CTXF_MARGINALS, L, T);
596
+ floatval_t *trans = NULL, *state = NULL;
597
+ floatval_t scores[3][3][3];
598
+ int labels[3];
599
+
600
+ /* Initialize the state scores. */
601
+ state = EXP_STATE_SCORE(ctx, 0);
602
+ state[0] = .4;
603
+ state[1] = .5;
604
+ state[2] = .1;
605
+ state = EXP_STATE_SCORE(ctx, 1);
606
+ state[0] = .4;
607
+ state[1] = .1;
608
+ state[2] = .5;
609
+ state = EXP_STATE_SCORE(ctx, 2);
610
+ state[0] = .4;
611
+ state[1] = .1;
612
+ state[2] = .5;
613
+
614
+ /* Initialize the transition scores. */
615
+ trans = EXP_TRANS_SCORE(ctx, 0);
616
+ trans[0] = .3;
617
+ trans[1] = .1;
618
+ trans[2] = .4;
619
+ trans = EXP_TRANS_SCORE(ctx, 1);
620
+ trans[0] = .6;
621
+ trans[1] = .2;
622
+ trans[2] = .1;
623
+ trans = EXP_TRANS_SCORE(ctx, 2);
624
+ trans[0] = .5;
625
+ trans[1] = .2;
626
+ trans[2] = .1;
627
+
628
+ ctx->num_items = ctx->cap_items;
629
+ crf1dc_alpha_score(ctx);
630
+ crf1dc_beta_score(ctx);
631
+
632
+ /* Compute the score of every label sequence. */
633
+ for (y1 = 0; y1 < L; ++y1)
634
+ {
635
+ floatval_t s1 = EXP_STATE_SCORE(ctx, 0)[y1];
636
+ for (y2 = 0; y2 < L; ++y2)
637
+ {
638
+ floatval_t s2 = s1;
639
+ s2 *= EXP_TRANS_SCORE(ctx, y1)[y2];
640
+ s2 *= EXP_STATE_SCORE(ctx, 1)[y2];
641
+ for (y3 = 0; y3 < L; ++y3)
642
+ {
643
+ floatval_t s3 = s2;
644
+ s3 *= EXP_TRANS_SCORE(ctx, y2)[y3];
645
+ s3 *= EXP_STATE_SCORE(ctx, 2)[y3];
646
+ scores[y1][y2][y3] = s3;
647
+ }
648
+ }
649
+ }
650
+
651
+ /* Compute the partition factor. */
652
+ norm = 0.;
653
+ for (y1 = 0; y1 < L; ++y1)
654
+ {
655
+ for (y2 = 0; y2 < L; ++y2)
656
+ {
657
+ for (y3 = 0; y3 < L; ++y3)
658
+ {
659
+ norm += scores[y1][y2][y3];
660
+ }
661
+ }
662
+ }
663
+
664
+ /* Check the partition factor. */
665
+ fprintf(fp, "Check for the partition factor... ");
666
+ check_values(fp, exp(ctx->log_norm), norm);
667
+
668
+ /* Compute the sequence probabilities. */
669
+ for (y1 = 0; y1 < L; ++y1)
670
+ {
671
+ for (y2 = 0; y2 < L; ++y2)
672
+ {
673
+ for (y3 = 0; y3 < L; ++y3)
674
+ {
675
+ floatval_t logp;
676
+
677
+ labels[0] = y1;
678
+ labels[1] = y2;
679
+ labels[2] = y3;
680
+ logp = crf1dc_score(ctx, labels) - crf1dc_lognorm(ctx);
681
+
682
+ fprintf(fp, "Check for the sequence %d-%d-%d... ", y1, y2, y3);
683
+ check_values(fp, exp(logp), scores[y1][y2][y3] / norm);
684
+ }
685
+ }
686
+ }
687
+
688
+ /* Compute the marginal probability at t=0 */
689
+ for (y1 = 0; y1 < L; ++y1)
690
+ {
691
+ floatval_t a, b, c, s = 0.;
692
+ for (y2 = 0; y2 < L; ++y2)
693
+ {
694
+ for (y3 = 0; y3 < L; ++y3)
695
+ {
696
+ s += scores[y1][y2][y3];
697
+ }
698
+ }
699
+
700
+ a = ALPHA_SCORE(ctx, 0)[y1];
701
+ b = BETA_SCORE(ctx, 0)[y1];
702
+ c = 1. / ctx->scale_factor[0];
703
+
704
+ fprintf(fp, "Check for the marginal probability (0,%d)... ", y1);
705
+ check_values(fp, a * b * c, s / norm);
706
+ }
707
+
708
+ /* Compute the marginal probability at t=1 */
709
+ for (y2 = 0; y2 < L; ++y2)
710
+ {
711
+ floatval_t a, b, c, s = 0.;
712
+ for (y1 = 0; y1 < L; ++y1)
713
+ {
714
+ for (y3 = 0; y3 < L; ++y3)
715
+ {
716
+ s += scores[y1][y2][y3];
717
+ }
718
+ }
719
+
720
+ a = ALPHA_SCORE(ctx, 1)[y2];
721
+ b = BETA_SCORE(ctx, 1)[y2];
722
+ c = 1. / ctx->scale_factor[1];
723
+
724
+ fprintf(fp, "Check for the marginal probability (1,%d)... ", y2);
725
+ check_values(fp, a * b * c, s / norm);
726
+ }
727
+
728
+ /* Compute the marginal probability at t=2 */
729
+ for (y3 = 0; y3 < L; ++y3)
730
+ {
731
+ floatval_t a, b, c, s = 0.;
732
+ for (y1 = 0; y1 < L; ++y1)
733
+ {
734
+ for (y2 = 0; y2 < L; ++y2)
735
+ {
736
+ s += scores[y1][y2][y3];
737
+ }
738
+ }
739
+
740
+ a = ALPHA_SCORE(ctx, 2)[y3];
741
+ b = BETA_SCORE(ctx, 2)[y3];
742
+ c = 1. / ctx->scale_factor[2];
743
+
744
+ fprintf(fp, "Check for the marginal probability (2,%d)... ", y3);
745
+ check_values(fp, a * b * c, s / norm);
746
+ }
747
+
748
+ /* Compute the marginal probabilities of transitions. */
749
+ for (y1 = 0; y1 < L; ++y1)
750
+ {
751
+ for (y2 = 0; y2 < L; ++y2)
752
+ {
753
+ floatval_t a, b, s, t, p = 0.;
754
+ for (y3 = 0; y3 < L; ++y3)
755
+ {
756
+ p += scores[y1][y2][y3];
757
+ }
758
+
759
+ a = ALPHA_SCORE(ctx, 0)[y1];
760
+ b = BETA_SCORE(ctx, 1)[y2];
761
+ s = EXP_STATE_SCORE(ctx, 1)[y2];
762
+ t = EXP_TRANS_SCORE(ctx, y1)[y2];
763
+
764
+ fprintf(fp, "Check for the marginal probability (0,%d)-(1,%d)... ", y1, y2);
765
+ check_values(fp, a * t * s * b, p / norm);
766
+ }
767
+ }
768
+
769
+ for (y2 = 0; y2 < L; ++y2)
770
+ {
771
+ for (y3 = 0; y3 < L; ++y3)
772
+ {
773
+ floatval_t a, b, s, t, p = 0.;
774
+ for (y1 = 0; y1 < L; ++y1)
775
+ {
776
+ p += scores[y1][y2][y3];
777
+ }
778
+
779
+ a = ALPHA_SCORE(ctx, 1)[y2];
780
+ b = BETA_SCORE(ctx, 2)[y3];
781
+ s = EXP_STATE_SCORE(ctx, 2)[y3];
782
+ t = EXP_TRANS_SCORE(ctx, y2)[y3];
783
+
784
+ fprintf(fp, "Check for the marginal probability (1,%d)-(2,%d)... ", y2, y3);
785
+ check_values(fp, a * t * s * b, p / norm);
786
+ }
787
+ }
788
+ }