Edinburgh Speech Tools  2.1-release
EST_relation_compare.cc
Go to the documentation of this file.
1 /*************************************************************************/
2 /* */
3 /* Centre for Speech Technology Research */
4 /* University of Edinburgh, UK */
5 /* Copyright (c) 1995,1996 */
6 /* All Rights Reserved. */
7 /* */
8 /* Permission is hereby granted, free of charge, to use and distribute */
9 /* this software and its documentation without restriction, including */
10 /* without limitation the rights to use, copy, modify, merge, publish, */
11 /* distribute, sublicense, and/or sell copies of this work, and to */
12 /* permit persons to whom this work is furnished to do so, subject to */
13 /* the following conditions: */
14 /* 1. The code must retain the above copyright notice, this list of */
15 /* conditions and the following disclaimer. */
16 /* 2. Any modifications must be clearly marked as such. */
17 /* 3. Original authors' names are not deleted. */
18 /* 4. The authors' names are not used to endorse or promote products */
19 /* derived from this software without specific prior written */
20 /* permission. */
21 /* */
22 /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
23 /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
24 /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
25 /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
26 /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
27 /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
28 /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
29 /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
30 /* THIS SOFTWARE. */
31 /* */
32 /*************************************************************************/
33 /* Author : Paul Taylor and Simon King */
34 /* Date : June 1995 */
35 /*-----------------------------------------------------------------------*/
36 /* Stream class auxiliary routines */
37 /* */
38 /*=======================================================================*/
39 
40 #include <iostream>
41 #include <fstream>
42 #include <cmath>
43 #include "EST_types.h"
44 #include "EST_FMatrix.h"
46 #include "EST_Token.h"
47 #include "EST_string_aux.h"
50 #include "EST_io_aux.h"
51 
52 using namespace std;
53 
55 {
56  return ((start(&b) < a.F("end")) && (start(&a) < b.F("end")));
57 }
58 
59 // WATCH - this uses what should be private access to Keyval class.
61 {
62  EST_Litem *ptr;
63 
64  for (ptr = a.list.head(); ptr != 0; ptr= ptr->next())
65  {
66  if (a.val(ptr) == -1)
67  continue;
68  if (b.val(a.val(ptr)) == a.key(ptr))
69 // cout << "ok\n";
70  continue;
71  else
72  a.change_key(ptr, -1);
73  }
74  for (ptr = b.list.head(); ptr != 0; ptr= ptr->next())
75  {
76  if (b.val(ptr) == -1)
77  continue;
78  if (a.val(b.val(ptr)) == b.key(ptr))
79 // cout << "ok\n";
80  continue;
81  else
82  a.change_key(ptr, -1);
83  }
84 }
85 
87 {
88  (void)u;
89  (void)a;
90  (void)b;
91 #if 0
92  EST_Item *a_ptr;
93  EST_Litem *i_ptr;
94  int i;
95 
96  for (i = 0, a_ptr = a.head(); a_ptr != 0; a_ptr = a_ptr->next(), ++i)
97  {
98  if (a_ptr->f("pos")==1)
99  {
100  u.add_item(a_ptr->addr(), -1);
101  for (i_ptr = a_ptr->link(b.stream_name())->head(); i_ptr != 0;
102  i_ptr = i_ptr->next())
103  u.change_val(a_ptr->addr(), a_ptr->link(b.stream_name())->item(i_ptr));
104  }
105  }
106 #endif
107 }
108 
110 {
111  EST_Item *a_ptr, *b_ptr;
112 
113  for (a_ptr = a.head(); a_ptr != 0; a_ptr = a_ptr->next())
114  if (a_ptr->f("pos")==1)
115  for (b_ptr = b.head(); b_ptr != 0; b_ptr = b_ptr->next())
116  {
117  if ((b_ptr->f("pos")==1)
118  &&(close_enough(*a_ptr, *b_ptr)))
119  {
120 // cout << "linked\n";
121 #if 0
122  link(*a_ptr, *b_ptr);
123 #endif
124  }
125  }
126 
127 // if ((b.pos(b_ptr->name()))
128 // &&(close_enough(*a_ptr, *b_ptr)))
129 // link(*a_ptr, *b_ptr);
130 }
131 
132 void compare_labels(EST_Relation &reflab, EST_Relation &testlab)
133 {
134  EST_II_KVL uref, utest;
135 
136  relation_match(reflab, testlab); // many-to-many mapping
137 
138  cout << "Ref\n" << reflab;
139  cout << "Test\n" << testlab;
140 
141  function_match(uref, reflab, testlab); // one-to-many mapping
142  function_match(utest, testlab, reflab); // one-to-many mapping
143 
144  cout << "Ref\n" << reflab;
145  cout << "Test\n" << testlab;
146  cout << "Keyval REF\n" << uref;
147  cout << "Keyval TEST\n" << utest;
148 
149 // cout << "Keyval REF\n" << uref;
150 // cout << "Keyval TEST\n" << utest;
151 
152  monotonic_match(uref, utest); // one-to-one mapping
153 
154  reassign_links(reflab, uref, testlab.name());
155  reassign_links(testlab, utest, reflab.name());
156  cout << "Keyval REF\n" << uref;
157  cout << "Keyval TEST\n" << utest;
158 
159 // temporary !!!
160 
161  cout.setf(ios::left,ios::adjustfield);
162 
163  cout << "Total: ";
164  cout.width(10);
165  cout << uref.length();
166  cout << "Deletions: ";
167  cout.width(10);
168  cout << insdel(uref);
169  cout << "Insertions: ";
170  cout.width(10);
171  cout<< insdel(utest) << endl;
172 }
173 
175 {
176  EST_Item *a_ptr;
177  int i = 0;
178  for (a_ptr = a.head(); a_ptr != 0; a_ptr = a_ptr->next())
179  if (a_ptr->f("pos") == 1)
180  {
181  if (n == i)
182  return a_ptr;
183  ++i;
184  }
185  return 0;
186 }
187 
188 // measures amount of total overlap between segments
190 {
191  float s, e;
192 
193  s = fabs(start(&ref) - start(&test));
194  e = fabs(ref.F("end") - test.F("end"));
195 
196  return (s + e) / duration(&ref);
197 }
198 
199 // Only penalises a test segment that extends beyond the boundaries of
200 // a ref segment
202 {
203  float s, e;
204 
205  s = (start(&test) < start(&ref)) ? start(&ref) - start(&test) : 0;
206  e = (ref.F("end") < test.F("end")) ?
207  test.F("end") - ref.F("end") : 0;
208 
209  return (s + e) / duration(&ref);
210 }
211 
213 {
214  float val = 1000.0;
215  ssize_t i, pos=0;
216 
217  for (i = 0; i < m.num_rows(); ++i)
218  if ((m(i, j) > -0.01) && (m(i, j) < val))
219  {
220  val = m(i, j);
221  pos = i;
222  }
223 
224  return pos;
225 }
226 
228 {
229  float val = 1000.0;
230  ssize_t i;
231  for (ssize_t j = 0; j < m.num_columns(); ++j)
232  {
233  val = 1000.0;
234  for (i = 0; i < m.num_rows(); ++i)
235  if (m(i, j) < val)
236  val = m(i, j);
237  for (i = 0; i < m.num_rows(); ++i)
238  if (m(i, j) > val)
239  m(i, j) = -1.0;
240  }
241 }
242 
244 {
245  float val;
246  ssize_t i, j;
247 
248  for (i = 0; i < m.num_rows(); ++i)
249  {
250  val = 1000.0;
251  for (j = 0; j < m.num_columns(); ++j)
252  if ((m(i, j) < val) && (m(i, j) > -0.01))
253  val = m(i, j);
254  for (j = 0; j < m.num_columns(); ++j)
255  if (m(i, j) > val)
256  m(i, j) = -1.0;
257  }
258 }
259 
261 {
262  ssize_t i, j;
263 
264  for (i = 0; i < m.num_rows(); ++i)
265  for (j = 0; j < m.num_columns(); ++j)
266  if (m(i, j) > max)
267  m(i, j) = -1.0;
268 
269 }
270 
272 {
273  ssize_t i, j;
274  int n = 0;
275 
276  for (i = 0; i < m.num_rows(); ++i)
277  for (j = 0; j < m.num_columns(); ++j)
278  if (m(i, j) > -1.0)
279  ++n;
280 
281  return (m.num_rows() - n);
282 }
283 
285 {
286  ssize_t i, j;
287  ssize_t n = 0;
288  EST_Item *s;
289 
290  for (i = 0; i < m.num_rows(); ++i)
291  {
292  s = nthpos(ref_lab, i);
293 // cout << s->name() << ": f:" << s->f("minor")<< endl;
294  if (s->f("minor") == 1)
295  ++n;
296  else
297  for (j = 0; j < m.num_columns(); ++j)
298  if (m(i, j) > -1.0)
299  ++n;
300  }
301  return (m.num_rows() - n);
302 }
303 
305 {
306  ssize_t i, j;
307  ssize_t n = 0;
308 
309  for (j = 0; j < m.num_columns(); ++j)
310  for (i = 0; i < m.num_rows(); ++i)
311  if (m(i, j) > -1.0)
312  ++n;
313 
314  return (m.num_columns() - n);
315 }
316 
318 {
319  ssize_t i, j;
320  ssize_t n = 0;
321  EST_Item *s;
322 
323  for (j = 0; j < m.num_columns(); ++j)
324  {
325  s = nthpos(ref_lab, j);
326 // cout << s->name() << ": f:" << s->f("minor")<< endl;
327  if (s->f("minor") == 1)
328  ++n;
329  else
330  for (i = 0; i < m.num_rows(); ++i)
331  if (m(i, j) > -1.0)
332  ++n;
333  }
334 
335  return (m.num_columns() - n);
336 }
337 
338 ssize_t lowest_pos(float const * const m, ssize_t n)
339 {
340  float val = 1000.0;
341  ssize_t i, pos=0;
342 
343  for (i = 0; i < n; ++i)
344  if (m[i] < val)
345  {
346  val = m[i];
347  pos = i;
348  }
349 
350  return pos;
351 }
352 
353 void threshold_labels(EST_Relation &reflab, float t)
354 {
355  (void)reflab;
356  (void)t;
357 #if 0
358  EST_Item *r_ptr;
359  float score=0.0;
360  int a;
361 
362  for (r_ptr = reflab.head(); r_ptr != 0; r_ptr = r_ptr->next())
363  if (r_ptr->f("pos")==1)
364  {
365  // REORG - temp comment
366 // score = atof(r_ptr->fields());
367  cout << "score is" << score << endl;
368 
369  a = r_ptr->rlink("blank").first();
370  cout << "score is" << score << " address: " << a << endl;
371  if (score > t)
372  cout << "delete\n";
373  }
374 #endif
375 }
376 
377 /* Check through relations of each ref label, and make there aren't
378 multiple ref labels related to the same test label. If this is
379 discovered, compare scores of all the relevant labels and delete the
380 relations of all but the lowest.
381 
382 At this stage, each ref label should have one and only one relation to the
383 test labels.
384 */
385 
387 {
388  (void)reflab;
389 #if 0
390  EST_Item *r_ptr, *s_ptr, *t_ptr;;
391  EST_Litem *p;
392  int a, pos, i;
393  EST_TList<int> la;
394  float *score;
395  score = new float[reflab.length()];
396 
397  for (r_ptr = reflab.head(); r_ptr != 0; r_ptr = r_ptr->next())
398  if (r_ptr->f("pos")==1)
399  {
400  la.clear(); // clear list and add address of current ref label
401  la.append(r_ptr->addr());
402  a = r_ptr->rlink("test").first();
403  cout << a << endl;
404 
405  // check remainer of ref labels and add any that have same
406  // relations address as r_ptr.
407  for (s_ptr = r_ptr->next(); s_ptr != 0; s_ptr = s_ptr->next())
408  if (s_ptr->f("pos")==1)
409  if (s_ptr->rlink("test").first() == a)
410  la.append(s_ptr->addr());
411 
412  cout << "la: " << la;
413  if (la.length() > 1) // true if the are multiple relations
414  {
415  // find scores of all relevant labels
416  for (i = 0, p = la.head(); p!= 0; p = p->next(), ++i)
417  {
418  t_ptr = reflab.item(la.item(p));
419 
420  // REORG - temp comment
421 // score[i] = atof(reflab.item(la.item(p))->fields());
422  }
423  pos = lowest_pos(score, i); // find position of lowest score
424 
425  cout << "best is " << pos << endl;
426  // delete relations of all but lowest score
427  for (i = 0, p = la.head(); p!= 0; p = p->next(), ++i)
428  if (i != pos)
429  {
430  t_ptr = reflab.item(la.item(p));
431  t_ptr->rlink("test").clear();
432  }
433  }
434  }
435 #endif
436 
437 }
438 
439 /* Compare 2 sets of labels by matrix method. This involves making a M
440 (number of test labels) x N (number of ref labels) matrix, and
441 calculating the distance from each label in the test set to each label
442 in the reference set. The lowest score for each reference is then
443 recorded. A test is carried out to make sure that no two reference
444 labels point to the same test label. Then any ref label above a
445 certain distance is classified as incorrect. The numbers of insertions
446 and deletions are then calculated. */
447 
448 EST_FMatrix matrix_compare(EST_Relation &reflab, EST_Relation &testlab, int method,
449  float t, int v)
450 {
451  ssize_t i, j;
452  int num_ref, num_test;
453  EST_Item *r_ptr, *t_ptr;
454  EST_String fns;
455  (void)v;
456 
457  num_ref = num_test = 0;
458 
459  // calculate size of matrix, based on *significant* labels
460  for (r_ptr = testlab.head(); r_ptr != 0; r_ptr = r_ptr->next())
461  if (r_ptr->f("pos")==1)
462  ++num_test;
463 
464  for (r_ptr = reflab.head(); r_ptr != 0; r_ptr = r_ptr->next())
465  if (r_ptr->f("pos")==1)
466  ++num_ref;
467 
468  EST_FMatrix m(num_test, num_ref);
469 
470  if ((m.num_rows() == 0) || (m.num_columns() == 0))
471  return m; // nothing to analyse, hence empty matrix
472 
473  // fill matrix values by comparing each test with each reference
474  // reference is columns, test is rows
475 
476  for (i = 0, t_ptr = testlab.head(); t_ptr != 0; t_ptr = t_ptr->next())
477  if (t_ptr->f("pos")==1)
478  {
479  for (j = 0, r_ptr = reflab.head(); r_ptr != 0; r_ptr = r_ptr->next())
480  if (r_ptr->f("pos")==1)
481  {
482  if (method == 1)
483  m(i, j) = label_distance1(*r_ptr, *t_ptr);
484  else if (method == 2)
485  m(i, j) = label_distance2(*r_ptr, *t_ptr);
486  else
487  cerr << "Unknown comparision method" << method << endl;
488  ++j;
489  }
490  ++i;
491  }
492 
493 // cout << "orig M\n";
494 // print_matrix_scores(reflab, testlab, m);
497  matrix_ceiling(m, t);
498  /* This loop had the r_ptr->set_field_name already commented, so it is useless:
499  // for each ref label, find closest matching test label.
500  for (j = 0, r_ptr = reflab.head(); r_ptr != 0; r_ptr = r_ptr->next())
501  {
502  if (r_ptr->f("pos")==1)
503  {
504  pos = lowest_pos(m, j);
505  // REORG - temp comment
506 // r_ptr->set_field_names(r_ptr->fields() +ftoString(m(pos, j)));
507  ++j;
508  }
509  }*/
510  return m;
511 }
512 
514  &tlist, EST_FMatrix &m, EST_String rpos,
515  EST_String tpos, int method, float t, int v)
516 {
517  EST_Litem *pr, *pt;
518  EST_String filename;
519  EST_Relation reflab, testlab;
520  EST_StrList rposlist, tposlist, rminorlist, tminorlist;
521  float ra, rc, mra, mrc;
522 
523  StringtoStrList(rpos, rposlist);
524  StringtoStrList(tpos, tposlist);
525  StringtoStrList("m l mrb mfb lrb lfb", rminorlist);
526  StringtoStrList("m l mrb mfb lrb lfb", tminorlist);
527 
528  int tot, del, ins, ltot, ldel, lins, lmdel, mdel, lmins, mins;
529  tot = del = ins = mdel = mins = 0;
530 
531  for (pt = tlist.head(); pt; pt = pt->next())
532  {
533  pr = RelationList_ptr_extract(rlist, tlist(pt).name(), TRUE);
534  if (pr != 0)
535  {
536  reflab = rlist(pr);
537  testlab = tlist(pt);
538 
539 /* convert_to_broad(reflab, rposlist);
540  convert_to_broad(testlab, tposlist);
541  convert_to_broad(reflab, rminorlist, "minor");
542  convert_to_broad(testlab, tminorlist, "minor");
543 */
544 
545 // cout << "ref\n" << reflab;
546 // cout << "test\n" << testlab;
547 
548 // cout << "features\n";
549 // print_stream_features(reflab);
550 
551  m = matrix_compare(reflab, testlab, method, t, v);
552 
553  ltot = m.num_columns();
554  ldel = matrix_deletions(m);
555  lmdel = major_matrix_deletions(m, reflab);
556  lins = matrix_insertions(m);
557  lmins = major_matrix_insertions(m, testlab);
558 
559  print_results(reflab, testlab, m, ltot, ldel, lins, v);
560 // cout << "Major Deletions: " << lmdel << endl << endl;;
561 
562  tot += ltot;
563  del += ldel;
564  mdel += lmdel;
565  ins += lins;
566  mins += lmins;
567  }
568  }
569 
570  if (tot != 0) {
571  rc = float(tot - del)/(float)tot * 100.0;
572  ra = float(tot - del -ins)/(float)tot *100.0;
573  mrc = float(tot - mdel)/(float)tot * 100.0;
574  mra = float(tot - mdel - mins)/(float)tot *100.0;
575  } else {
576  rc = NAN;
577  ra = NAN;
578  mrc = NAN;
579  mra = NAN;
580  }
581 
582  if (v)
583  {
584  cout << "Total " << tot << " del: " << del << " ins: " << ins << endl;
585  cout << "Total " << tot << " major del " << mdel << " major ins" << mins << endl;
586  }
587  cout << "Correct " << rc << "% Accuracy " << ra << "%" << endl;
588  cout << "Major Correct " << mrc << "% Accuracy " << mra << "%" << endl;
589 }
590 
592 {
593  int i;
594  EST_Item *s;
595 
596  // reference
597  if (ref)
598  {
599  for (i = 0, s = e.head(); s; s = s->next())
600  if ((int)s->f("pos"))
601  {
602  if (column_hit(m, i) >= 0)
603  s->set("hit", 1);
604  else
605  s->set("hit", 0);
606  ++i;
607  }
608  }
609  else
610  for (i = 0, s = e.head(); s; s = s->next())
611  if ((int)s->f("pos"))
612  {
613  if (row_hit(m, i) >= 0)
614  s->set("hit", 1);
615  else
616  s->set("hit", 0);
617  ++i;
618  }
619 }
620 
622 {
623  int n = 0;
624  EST_Litem *ptr;
625 
626  for (ptr = a.list.head(); ptr != 0; ptr= ptr->next())
627  if (a.val(ptr) == -1)
628  ++n;
629  return n;
630 }
631 
633  EST_II_KVL &uref, EST_II_KVL &utest)
634 {
635  // many-to-many mapping
636  (void)ref;
637  (void)test;
638  (void)name;
639  (void)uref;
640  (void)utest;
641 #if 0
642  relation_match(ref.stream(name), test.stream(name));
643 
644  // one-to-many mapping
645  function_match(uref, ref.stream(name), test.stream(name));
646  function_match(utest, test.stream(name), ref.stream(name));
647 
648  monotonic_match(uref, utest); // one-to-one mapping
649 
650  // temporary !!!
651  // reassign_links(ref.stream(name), uref, name);
652  // reassign_links(test.stream(name), utest, name);
653 
654  // cout << "Keyval REF\n" << uref;
655  // cout << "Keyval TEST\n" << utest;
656 #endif
657  return 0;
658 }
659 
661 {
662  (void)a;
663  (void)b;
664  (void)ua;
665  (void)ub;
666 
667 #if 0
668  EST_Item *a_ptr, *b_ptr;
669 
670  for (a_ptr = a.head(); a_ptr != 0; a_ptr = a_ptr->next())
671  {
672  a_ptr->link(b.stream_name())->clear();
673  if ((a_ptr->f("pos")==1) && (ua.val(a_ptr->addr()) != -1))
674  a_ptr->make_link(b.stream_name(), ua.val(a_ptr->addr()));
675  }
676  for (b_ptr = b.head(); b_ptr != 0; b_ptr = b_ptr->next())
677  {
678  b_ptr->link(a.stream_name())->clear();
679  if ((b_ptr->f("pos")==1) && (ub.val(b_ptr->addr()) != -1))
680  b_ptr->make_link(a.stream_name(), ub.val(b_ptr->addr()));
681  }
682 #endif
683 }
684 
686 {
687  (void)a;
688  (void)u;
689  (void)stream_type;
690 #if 0
691  EST_Item *a_ptr;
692 
693  for (a_ptr = a.head(); a_ptr != 0; a_ptr = a_ptr->next())
694  {
695  a_ptr->link(stream_type)->clear();
696  if ((a_ptr->f("pos")==1) && (u.val(a_ptr->addr()) != -1))
697  a_ptr->make_link(stream_type, u.val(a_ptr->addr()));
698  }
699 #endif
700 }
701 
702 
704  EST_II_KVL &lref, EST_II_KVL &ltest)
705 
706 {
707  int b, c, d, v;
708  (void)lref; // unused parameter
709  (void)a_ptr;
710 
711 // v = a_ptr->addr();
712  v = 0;
713  b = f2.val(v);
714  c = (b == -1) ? -1: ltest.val(b);
715  d = (c == -1) ? -1: f1.val(c);
716 
717  return d;
718 
719  // c = ltest.val(f2.val(v));
720  // d = f1.val(ltest.val(f2.val(v)));
721 }
722 
723 // REF TEST
724 // f1
725 // S -----------> S
726 // ^ ^
727 // lr | | lt
728 // | f2 |
729 // E -----------> E
730 //
731 // For a given element in E(ref), "e", if
732 // lr(e) == f1(lt(f2(e)))
733 // Then ei has been recognised fully.
734 
736 {
737  (void)ref;
738  (void)test;
739  (void)op;
740 #if 0
741  EST_II_KVL f2, inv_f2, inv_f1, f1, lref, ltest;
742 
743  compare_labels(ref, test, "Event", f2, inv_f2);
744  compare_labels(ref, test, "Syllable", f1, inv_f1);
745 
746  if (op.present("print_syllable") && op.present("print_map"))
747  {
748  cout << "Syllable mapping from ref to test\n" << f1;
749  cout << "Syllable mapping from test to ref\n" << inv_f1;
750  }
751  if (op.present("print_event") && op.present("print_map"))
752  {
753  cout << "Event mapping from ref to test\n" << f2;
754  cout << "Event mapping from test to ref\n" << inv_f2;
755  }
756 
757  if (op.present("print_syllable") && op.present("print_ins"))
758  cout << "Syllable_insertions: " << insdel(inv_f1) << endl;
759  if (op.present("print_syllable") && op.present("print_del"))
760  cout << "Syllable_deletions: " << insdel(f1) << endl;
761 
762  if (op.present("print_event") && op.present("print_ins"))
763  cout << "Event_insertions: " << insdel(inv_f2) << endl;
764  if (op.present("print_event") && op.present("print_del"))
765  cout << "Event_deletions: " << insdel(f2) << endl;
766 
767  // cout << "Ref\n" << ref.stream("Event") << ref.stream("Syllable");
768  // cout << "Test\n" << test.stream("Event") << test.stream("Syllable");
769 
770  function_match(lref, ref.stream("Event"), ref.stream("Syllable"));
771  function_match(ltest, test.stream("Event"), test.stream("Syllable"));
772 
773  if (op.present("print_functions"))
774  {
775  cout << "Lref\n" << lref;
776  cout << "Ltest\n" << ltest;
777  cout << "f1\n" << f1;
778  cout << "f2\n" << f2;
779  }
780 
781  EST_Item *a_ptr;
782  int correct, n_ev, n_syl;
783 
784  correct = n_ev = n_syl = 0;
785  for (a_ptr = ref.stream("Event").head(); a_ptr != 0; a_ptr = a_ptr->next())
786  if (a_ptr->f("pos")==1)
787  {
788  ++n_ev;
789  if (lref.val(a_ptr->addr())
790  == commutate(a_ptr, f1, f2, lref, ltest))
791  ++correct;
792  }
793  for (a_ptr = ref.stream("Syllable").head();a_ptr != 0; a_ptr = a_ptr->next())
794  if (a_ptr->f("pos")==1)
795  ++n_syl;
796 
797  if (op.present("print_syllable") && op.present("print_total"))
798  cout << "Number_of_Syllables: " << n_syl << endl;
799  if (op.present("print_event") && op.present("print_total"))
800  cout << "Number_of_Events: " << n_ev << endl;
801 
802  if (op.present("print_link"))
803  cout << "Correct_links: " << correct <<endl;
804 
805  if (op.present("print_derivation"))
806  {
807  for (a_ptr = ref.stream("Event").head();a_ptr!= 0; a_ptr = a_ptr->next())
808  {
809  if (a_ptr->f("pos")==1)
810  {
811  cout << "Lr(ei): " << lref.val(a_ptr->addr()) << endl;
812  cout << "f2(ei): " << f2.val(a_ptr->addr()) << endl;
813  cout << "Lt(f2(ei)): " << ltest.val(f2.val(a_ptr->addr()))
814  << endl;
815  cout << "f1(Lt(f2(ei))): "
816  << f1.val(ltest.val(f2.val(a_ptr->addr()))) << endl;
817  }
818  cout << "Event " << *a_ptr;
819  if ( lref.val(a_ptr->addr())
820  == f1.val(ltest.val(f2.val(a_ptr->addr()))))
821  cout << " is correct\n";
822  else
823  cout << " is incorrect\n";
824  }
825  }
826 #endif
827 }
828 
830 {
831  std::ios_base::fmtflags oldsetf = cout.setf(ios::fixed, ios::adjustfield);
832  cout << "Total: ";
833  std::streamsize oldwidth = cout.width(10);
834  cout << m.num_columns();
835  cout << "Deletions: ";
836  cout.width(10);
837  cout << matrix_deletions(m);
838  cout << "Insertions: ";
839  cout.width(10);
840  cout<< matrix_insertions(m) << endl;
841 
842  cout.width(oldwidth);
843  cout.setf(oldsetf);
844 }
845 
847 {
848  ssize_t i, j;
849  EST_Item *r_ptr, *t_ptr;
850 
851  cout << " ";
852  for (r_ptr = ref.head(); r_ptr != 0; r_ptr = r_ptr->next())
853  {
854  if (r_ptr->f("pos")==1)
855  {
856  // cout.width(5);
857  // cout.setf(ios::right);
858  cout << r_ptr->name() << " ";
859  cout.width(6);
860  cout.setf(ios::right);
861  cout<< r_ptr->F("end") << " ";
862  }
863  }
864  cout << endl;
865 
866  for (t_ptr = test.head(), i = 0; i < a.num_rows(); t_ptr = t_ptr->next())
867  {
868  if (t_ptr->f("pos")==1)
869  {
870  cout << t_ptr->name() << " ";
871  for (j = 0; j < a.num_columns(); ++j)
872  {
873  cout.width(10);
874  cout.precision(3);
875  cout.setf(ios::right);
876  cout.setf(ios::fixed, ios::floatfield);
877  cout << a(i, j) << " ";
878  }
879  cout << endl;
880  ++i;
881  }
882  }
883 }
884 
886 {
887  ssize_t i;
888  for (i = 0; i < m.num_columns(); ++i)
889  if (m(r, i) > 0.0)
890  return i;
891 
892  return -1;
893 }
894 
895 // return the row index of the first positive entry in column c
897 {
898  ssize_t i;
899  for (i = 0; i < m.num_rows(); ++i)
900  if (m(i, c) > 0.0)
901  return i;
902 
903  return -1;
904 }
905 
907 {
908  ssize_t c1, c2;
909  c1 = column_hit(m, last);
910  c2 = column_hit(m, current);
911 
912  return c2 - c1 -1;
913 }
914 
915 int num_b_deletions(EST_FMatrix &m, int last, int current)
916 {
917  int c1, c2;
918  c1 = row_hit(m, last);
919  c2 = row_hit(m, current);
920 
921  return c2 - c1 -1;
922 }
923 
924 void print_s_trans(EST_Relation &a, int width)
925 {
926  (void)a;
927  (void)width;
928 // for (int i = 0; i < a.length(); ++i)
929 // {
930  // cout << (int)a.nth(i)->f("pos") << " XX " << a.nth(i)->name() << endl;
931 /* if ((a.nth(i)->f("pos")==1) || (a.nth(i)->name() == " "))
932  {
933  // cout.setf(ios::fixed, ios::floatfield);
934  cout.width(width);
935  cout << a.nth(i)->name() << " ";
936  }
937  }
938 */
939  cout << endl;
940 }
941 
943 {
944  EST_Item *s;
945 
946  for (s = a.head(); s; s = s->next())
947  {
948  if (s->f("pos") == 0)
949  s->set_name(".");
950  else if (s->f("hit") == 1)
951  s->set_name("HIT");
952  else
953  s->set_name("MISS");
954  s->features().clear();
955  }
956 }
957 
959 {
960  EST_Item *a, *n;
961 
962  for (a = lab.head(); a; a = n)
963  {
964  n = a->next();
965  if (!a->f_present("pos"))
966  lab.remove_item(a);
967  }
968 }
969 
970 // Warning this is bugged - slight misalignments occur.
972 {
973  (void)ref;
974  (void)test;
975  (void)m;
976 /* int i, j, n;
977  EST_Relation al, refal, testal;
978  EST_Item *p;
979  EST_Item pos, blank;
980 
981  blank.set_name(" ");
982 
983  pos.f.set("pos", 1);
984  blank.f.set("pos", 0);
985 
986  pos_only(test);
987  pos_only(ref);
988 
989  // first check for empty matrices - indicates all insertions or deletions
990 
991  if ((m.num_columns() == 0) && (m.num_rows() != 0))
992  {
993  cout << "REC: ";
994  print_s_trans(test);
995  return;
996  }
997  else if ((m.num_columns() != 0) && (m.num_rows() == 0))
998  {
999  cout << "LAB: ";
1000  print_s_trans(ref);
1001  return;
1002  }
1003  else if ((m.num_columns() == 0) && (m.num_rows() == 0))
1004  {
1005  cout << "LAB: ";
1006  print_s_trans(ref);
1007  return;
1008  }
1009 
1010  int l;
1011  l = 0;
1012 
1013  // cout << "ref: " << ref.name() << endl << ref;
1014  // cout << "test: " << test.name() << endl << test;
1015 
1016  if (m(0, 0) < 0)
1017  refal.append(blank);
1018 
1019 
1020  pos.set_name(ref.head()->name());
1021  refal.append(pos);
1022  for (i = 1, p = ref.head()->next(); p; p = p->next(), ++i)
1023  {
1024  n = num_b_insertions(m, l, i);
1025 
1026  for (j = 0; j < n; ++j)
1027  refal.append(blank);
1028 
1029  if (n > -0.5)
1030  l = i;
1031  pos.set_name(p->name());
1032 
1033  refal.append(pos);
1034  }
1035 
1036  l = 0;
1037  pos.set_name(test.head()->name());
1038  testal.append(pos);
1039  for (i = 1, p = test.head()->next(); p; p = p->next(), ++i)
1040  {
1041  n = num_b_deletions(m, l, i);
1042 
1043  // cout << *p << "last " << l << " current " << i <<
1044  // " insertions " << n << endl;
1045  for (j = 0; j < n; ++j)
1046  testal.append(blank);
1047 
1048  if (n > -0.5)
1049  l = i;
1050  pos.set_name(p->name());
1051  testal.append(pos);
1052  }
1053 
1054  cout << "LAB: ";
1055  print_s_trans(refal, 3);
1056  cout << "REC: ";
1057  print_s_trans(testal, 3);
1058 */
1059 }
1060 
1062  EST_FMatrix &m, int tot,
1063  int del, int ins, int v)
1064 {
1065  (void) tot;
1066  (void) del;
1067  (void) ins;
1068  if (v == 0)
1069  return;
1070 
1071  // v == 1 prints out total insertions etc
1072 
1073  if (v == 2)
1074  {
1075  cout << basename(ref.name(), "") << endl;
1076  print_i_d_scores(m);
1077  cout << endl;
1078  }
1079  else if (v == 3)
1080  {
1081  cout << basename(ref.name(), "") << endl;
1082  print_aligned_trans(ref, test, m);
1083  print_i_d_scores(m);
1084  cout << endl;
1085  }
1086  else if (v == 4)
1087  {
1088  cout << basename(ref.name(), "") << endl;
1089  print_matrix_scores(ref, test, m);
1090  print_i_d_scores(m);
1091  cout << endl;
1092  }
1093  else if (v == 5)
1094  {
1095  cout << basename(ref.name(), "") << endl;
1096  print_matrix_scores(ref, test, m);
1097  print_aligned_trans(ref, test, m);
1098  print_i_d_scores(m);
1099  cout << endl;
1100  }
1101  else if (v == 6)
1102  {
1103  print_matrix_scores(ref, test, m);
1104  error_location(ref, m, 1);
1105  make_hit_and_miss(ref);
1106  error_location(test, m, 0);
1107  make_hit_and_miss(test);
1108  ref.save("ref.error");
1109  test.save("test.errors");
1110  }
1111  else if (v == 7)
1112  {
1113  error_location(ref, m, 1);
1114  make_hit_and_miss(ref);
1115  error_location(test, m, 0);
1116  make_hit_and_miss(test);
1117  ref.save("ref.error");
1118  test.save("test.error");
1119  }
1120 }
void print_matrix_scores(EST_Relation &ref, EST_Relation &test, EST_FMatrix &a)
EST_Item * head() const
Definition: EST_Relation.h:121
void minimise_matrix_by_column(EST_FMatrix &m)
const K & key(EST_Litem *ptr, int m=1) const
find key, reference by ptr
Definition: EST_TKVL.cc:201
const EST_String name() const
Definition: EST_Item.h:250
Utility IO Function header file.
int change_key(EST_Litem *ptr, const K &rkey)
change name of key pair.
Definition: EST_TKVL.cc:99
EST_Item * first() const
Definition: EST_Item.cc:339
void remove_item(EST_Item *item)
void relation_match(EST_Relation &a, EST_Relation &b)
void reassign_links(EST_Relation &a, EST_Relation &b, EST_II_KVL &ua, EST_II_KVL &ub)
ssize_t num_columns() const
return number of columns
Definition: EST_TMatrix.h:179
ssize_t major_matrix_insertions(EST_FMatrix &m, EST_Relation &ref_lab)
void pos_only(EST_Relation &lab)
void set(const EST_String &name, ssize_t ival)
Definition: EST_Item.h:185
void print_i_d_scores(EST_FMatrix &m)
STATIC void left(STATUS Change)
Definition: editline.c:523
int insdel(EST_II_KVL &a)
STATIC void right(STATUS Change)
Definition: editline.c:538
void threshold_labels(EST_Relation &reflab, float t)
ssize_t lowest_pos(const EST_FMatrix &m, ssize_t j)
ssize_t row_hit(EST_FMatrix &m, ssize_t r)
ssize_t num_rows() const
return number of rows
Definition: EST_TMatrix.h:177
int length() const
int ssize_t
int change_val(const K &rkey, const V &rval)
Definition: EST_TKVL.cc:113
EST_UItem * next()
Definition: EST_UList.h:55
void compare_labels(EST_Relation &reflab, EST_Relation &testlab)
const EST_Val f(const EST_String &name) const
Definition: EST_Item.h:260
float max(float a, float b)
Definition: EST_cluster.cc:143
int num_b_deletions(EST_FMatrix &m, int last, int current)
ssize_t matrix_insertions(EST_FMatrix &m)
void function_match(EST_II_KVL &u, EST_Relation &a, EST_Relation &b)
void print_aligned_trans(EST_Relation &ref, EST_Relation &test, EST_FMatrix &m)
void set_name(const EST_String &name) const
Definition: EST_Item.h:254
void multiple_labels(EST_Relation &reflab)
void print_results(EST_Relation &ref, EST_Relation &test, EST_FMatrix &m, int tot, int del, int ins, int v)
const EST_String & name() const
Definition: EST_Relation.h:118
EST_Item * nthpos(EST_Relation &a, int n)
float F(const EST_String &name) const
Definition: EST_Item.h:135
void StringtoStrList(EST_String s, EST_StrList &l, EST_String sep)
Convert a EST_String to a EST_StrList by separating tokens in s delimited by the separator sep...
int commutate(EST_Item *a_ptr, EST_II_KVL &f1, EST_II_KVL &f2, EST_II_KVL &lref, EST_II_KVL &ltest)
EST_TList< EST_TKVI< K, V > > list
Linked list of key-val pairs. Don&#39;t use this as it will be made private in the future.
Definition: EST_TKVL.h:94
EST_Item * link(int l, EST_Item *n)
ssize_t major_matrix_deletions(EST_FMatrix &m, EST_Relation &ref_lab)
Templated Key-Value list. Objects of type EST_TKVL contain lists which are accessed by a key of type ...
Definition: EST_TKVL.h:73
void matrix_ceiling(EST_FMatrix &m, float max)
EST_Features & features() const
Definition: EST_Item.h:258
void print_s_trans(EST_Relation &a, int width)
const V & val(const K &rkey, bool m=0) const
return value according to key (const)
Definition: EST_TKVL.cc:145
void error_location(EST_Relation &e, EST_FMatrix &m, int ref)
void pr(LISP p)
Definition: slib.cc:1941
ssize_t matrix_deletions(EST_FMatrix &m)
void append(const T &item)
add item onto end of list
Definition: EST_TList.h:196
EST_String basename(EST_String full, EST_String ext="")
This acts like the bourne shell basename command. By default, it strips any leading path from a strin...
Definition: util_io.cc:167
EST_Item * next() const
Definition: EST_Item.h:348
int add_item(const K &rkey, const V &rval, int no_search=0)
add key-val pair to list
Definition: EST_TKVL.cc:248
float start(const EST_Item &item)
Definition: EST_item_aux.cc:52
void multiple_matrix_compare(EST_RelationList &rlist, EST_RelationList &tlist, EST_FMatrix &m, EST_String rpos, EST_String tpos, int method, float t, int v)
void make_hit_and_miss(EST_Relation &a)
int present(const K &rkey) const
Returns true if key is present.
Definition: EST_TKVL.cc:222
float duration(EST_Item *n)
EST_write_status save(const EST_String &filename, bool evaluate_ff=false) const
EST_UItem * head() const
Definition: EST_UList.h:97
EST_Litem * RelationList_ptr_extract(EST_RelationList &mlf, const EST_String &filename, bool base)
void test_labels(EST_Utterance &ref, EST_Utterance &test, EST_Option &op)
int close_enough(EST_Item &a, EST_Item &b)
void monotonic_match(EST_II_KVL &a, EST_II_KVL &b)
#define TRUE
Definition: EST_bool.h:118
float label_distance2(EST_Item &ref, EST_Item &test)
void clear(void)
remove all items in list
Definition: EST_TList.h:244
void minimise_matrix_by_row(EST_FMatrix &m)
float label_distance1(EST_Item &ref, EST_Item &test)
ssize_t column_hit(EST_FMatrix &m, ssize_t c)
EST_FMatrix matrix_compare(EST_Relation &reflab, EST_Relation &testlab, int method, float t, int v)
ssize_t num_b_insertions(EST_FMatrix &m, ssize_t last, ssize_t current)
Utility EST_String Functions header file.
int f_present(const EST_String &name) const
Definition: EST_Item.h:236