comparison vamp-sdk/hostext/PluginSummarisingAdapter.cpp @ 187:ed8aa954e72f

* Segmentation work for summarisation
author cannam
date Fri, 12 Sep 2008 16:27:07 +0000
parents 8311695c13f9
children 5a6446a2346a
comparison
equal deleted inserted replaced
186:8311695c13f9 187:ed8aa954e72f
87 typedef std::map<int, OutputAccumulator> OutputAccumulatorMap; 87 typedef std::map<int, OutputAccumulator> OutputAccumulatorMap;
88 OutputAccumulatorMap m_accumulators; // output number -> accumulator 88 OutputAccumulatorMap m_accumulators; // output number -> accumulator
89 89
90 typedef std::map<RealTime, OutputAccumulator> SegmentAccumulatorMap; 90 typedef std::map<RealTime, OutputAccumulator> SegmentAccumulatorMap;
91 typedef std::map<int, SegmentAccumulatorMap> OutputSegmentAccumulatorMap; 91 typedef std::map<int, SegmentAccumulatorMap> OutputSegmentAccumulatorMap;
92 OutputSegmentAccumulatorMap m_segmentedAccumulators; 92 OutputSegmentAccumulatorMap m_segmentedAccumulators; // output -> segmented
93 93
94 typedef std::map<int, RealTime> OutputTimestampMap; 94 typedef std::map<int, RealTime> OutputTimestampMap;
95 OutputTimestampMap m_prevTimestamps; // output number -> timestamp 95 OutputTimestampMap m_prevTimestamps; // output number -> timestamp
96 OutputTimestampMap m_prevDurations; // output number -> durations 96 OutputTimestampMap m_prevDurations; // output number -> durations
97 97
156 PluginSummarisingAdapter::getRemainingFeatures() 156 PluginSummarisingAdapter::getRemainingFeatures()
157 { 157 {
158 return m_impl->getRemainingFeatures(); 158 return m_impl->getRemainingFeatures();
159 } 159 }
160 160
161 void
162 PluginSummarisingAdapter::setSummarySegmentBoundaries(const SegmentBoundaries &b)
163 {
164 m_impl->setSummarySegmentBoundaries(b);
165 }
166
161 Plugin::FeatureList 167 Plugin::FeatureList
162 PluginSummarisingAdapter::getSummaryForOutput(int output, 168 PluginSummarisingAdapter::getSummaryForOutput(int output,
163 SummaryType type, 169 SummaryType type,
164 AveragingMethod avg) 170 AveragingMethod avg)
165 { 171 {
204 std::cerr << "WARNING: Cannot call PluginSummarisingAdapter::process() or getRemainingFeatures() after one of the getSummary methods" << std::endl; 210 std::cerr << "WARNING: Cannot call PluginSummarisingAdapter::process() or getRemainingFeatures() after one of the getSummary methods" << std::endl;
205 } 211 }
206 FeatureSet fs = m_plugin->getRemainingFeatures(); 212 FeatureSet fs = m_plugin->getRemainingFeatures();
207 accumulate(fs, m_lastTimestamp, true); 213 accumulate(fs, m_lastTimestamp, true);
208 return fs; 214 return fs;
215 }
216
217 void
218 PluginSummarisingAdapter::Impl::setSummarySegmentBoundaries(const SegmentBoundaries &b)
219 {
220 m_boundaries = b;
221 std::cerr << "PluginSummarisingAdapter::setSummarySegmentBoundaries: boundaries are:" << std::endl;
222 for (SegmentBoundaries::const_iterator i = m_boundaries.begin();
223 i != m_boundaries.end(); ++i) {
224 std::cerr << *i << " ";
225 }
226 std::cerr << std::endl;
209 } 227 }
210 228
211 Plugin::FeatureList 229 Plugin::FeatureList
212 PluginSummarisingAdapter::Impl::getSummaryForOutput(int output, 230 PluginSummarisingAdapter::Impl::getSummaryForOutput(int output,
213 SummaryType type, 231 SummaryType type,
475 RealTime &start, 493 RealTime &start,
476 RealTime &end) 494 RealTime &end)
477 { 495 {
478 std::cerr << "findSegmentBounds: t = " << t << std::endl; 496 std::cerr << "findSegmentBounds: t = " << t << std::endl;
479 497
480 SegmentBoundaries::const_iterator i = std::lower_bound 498 SegmentBoundaries::const_iterator i = std::upper_bound
481 (m_boundaries.begin(), m_boundaries.end(), t); 499 (m_boundaries.begin(), m_boundaries.end(), t);
482 500
483 start = RealTime::zeroTime; 501 start = RealTime::zeroTime;
484 end = m_lastTimestamp; 502 end = m_lastTimestamp;
485 503
486 if (i != m_boundaries.end()) { 504 if (i != m_boundaries.end()) {
487 505
488 start = *i; 506 end = *i;
489 507
490 if (++i != m_boundaries.end()) { 508 if (i != m_boundaries.begin()) {
491 end = *i; 509 start = *--i;
492 } 510 }
493 } 511 }
494 512
495 std::cerr << "findSegmentBounds: " << t << " is in segment " << start << " -> " << end << std::endl; 513 std::cerr << "findSegmentBounds: " << t << " is in segment " << start << " -> " << end << std::endl;
496 } 514 }
505 i != m_accumulators.end(); ++i) { 523 i != m_accumulators.end(); ++i) {
506 524
507 int output = i->first; 525 int output = i->first;
508 OutputAccumulator &source = i->second; 526 OutputAccumulator &source = i->second;
509 527
528 //!!! This is basically nonsense if the results have no values
529 //!!! (i.e. their times and counts are the only things of
530 //!!! interest) but perhaps it's the user's problem if they
531 //!!! ask for segmentation in that case
532
510 for (int n = 0; n < source.results.size(); ++n) { 533 for (int n = 0; n < source.results.size(); ++n) {
511 534
512 // This result spans source.results[n].time to 535 // This result spans source.results[n].time to
513 // source.results[n].time + source.results[n].duration. 536 // source.results[n].time + source.results[n].duration.
514 // We need to dispose it into segments appropriately 537 // We need to dispose it into segments appropriately
515 538
516 RealTime resultStart = source.results[n].time; 539 RealTime resultStart = source.results[n].time;
517 RealTime resultEnd = resultStart + source.results[n].duration; 540 RealTime resultEnd = resultStart + source.results[n].duration;
541
542 std::cerr << "output: " << output << ", result start = " << resultStart << ", end = " << resultEnd << std::endl;
518 543
519 RealTime segmentStart = RealTime::zeroTime; 544 RealTime segmentStart = RealTime::zeroTime;
520 RealTime segmentEnd = resultEnd - RealTime(1, 0); 545 RealTime segmentEnd = resultEnd - RealTime(1, 0);
521 546
522 while (segmentEnd < resultEnd) { 547 while (segmentEnd < resultEnd) {
586 void 611 void
587 PluginSummarisingAdapter::Impl::reduce() 612 PluginSummarisingAdapter::Impl::reduce()
588 { 613 {
589 accumulateFinalDurations(); 614 accumulateFinalDurations();
590 615
591 RealTime segmentStart = RealTime::zeroTime; //!!! 616 for (OutputSegmentAccumulatorMap::iterator i =
592 617 m_segmentedAccumulators.begin();
593 for (OutputAccumulatorMap::iterator i = m_accumulators.begin(); 618 i != m_segmentedAccumulators.end(); ++i) {
594 i != m_accumulators.end(); ++i) {
595 619
596 int output = i->first; 620 int output = i->first;
597 OutputAccumulator &accumulator = i->second; 621 SegmentAccumulatorMap &segments = i->second;
598 622
599 int sz = accumulator.results.size(); 623 for (SegmentAccumulatorMap::iterator j = segments.begin();
600 624 j != segments.end(); ++j) {
601 double totalDuration = 0.0; 625
602 //!!! is this right? 626 RealTime segmentStart = j->first;
603 if (sz > 0) { 627 OutputAccumulator &accumulator = j->second;
604 totalDuration = toSec(accumulator.results[sz-1].time + 628
605 accumulator.results[sz-1].duration); 629 int sz = accumulator.results.size();
630
631 double totalDuration = 0.0;
632 //!!! is this right?
633 if (sz > 0) {
634 totalDuration = toSec(accumulator.results[sz-1].time +
635 accumulator.results[sz-1].duration);
636 }
637
638 for (int bin = 0; bin < accumulator.bins; ++bin) {
639
640 // work on all values over time for a single bin
641
642 OutputBinSummary summary;
643
644 summary.count = sz;
645
646 summary.minimum = 0.f;
647 summary.maximum = 0.f;
648
649 summary.median = 0.f;
650 summary.mode = 0.f;
651 summary.sum = 0.f;
652 summary.variance = 0.f;
653
654 summary.median_c = 0.f;
655 summary.mode_c = 0.f;
656 summary.mean_c = 0.f;
657 summary.variance_c = 0.f;
658
659 if (sz == 0) continue;
660
661 std::vector<ValueDurationFloatPair> valvec;
662
663 for (int k = 0; k < sz; ++k) {
664 while (accumulator.results[k].values.size() <
665 accumulator.bins) {
666 accumulator.results[k].values.push_back(0.f);
667 }
668 }
669
670 for (int k = 0; k < sz; ++k) {
671 float value = accumulator.results[k].values[bin];
672 valvec.push_back(ValueDurationFloatPair
673 (value,
674 toSec(accumulator.results[k].duration)));
675 }
676
677 std::sort(valvec.begin(), valvec.end());
678
679 summary.minimum = valvec[0].value;
680 summary.maximum = valvec[sz-1].value;
681
682 if (sz % 2 == 1) {
683 summary.median = valvec[sz/2].value;
684 } else {
685 summary.median = (valvec[sz/2].value + valvec[sz/2 + 1].value) / 2;
686 }
687
688 double duracc = 0.0;
689 summary.median_c = valvec[sz-1].value;
690
691 for (int k = 0; k < sz; ++k) {
692 duracc += valvec[k].duration;
693 if (duracc > totalDuration/2) {
694 summary.median_c = valvec[k].value;
695 break;
696 }
697 }
698
699 std::cerr << "median_c = " << summary.median_c << std::endl;
700 std::cerr << "median = " << summary.median << std::endl;
701
702 std::map<float, int> distribution;
703
704 for (int k = 0; k < sz; ++k) {
705 summary.sum += accumulator.results[k].values[bin];
706 distribution[accumulator.results[k].values[bin]] += 1;
707 }
708
709 int md = 0;
710
711 for (std::map<float, int>::iterator di = distribution.begin();
712 di != distribution.end(); ++di) {
713 if (di->second > md) {
714 md = di->second;
715 summary.mode = di->first;
716 }
717 }
718
719 distribution.clear();
720
721 std::map<float, double> distribution_c;
722
723 for (int k = 0; k < sz; ++k) {
724 distribution_c[accumulator.results[k].values[bin]]
725 += toSec(accumulator.results[k].duration);
726 }
727
728 double mrd = 0.0;
729
730 for (std::map<float, double>::iterator di = distribution_c.begin();
731 di != distribution_c.end(); ++di) {
732 if (di->second > mrd) {
733 mrd = di->second;
734 summary.mode_c = di->first;
735 }
736 }
737
738 distribution_c.clear();
739
740 if (totalDuration > 0.0) {
741
742 double sum_c = 0.0;
743
744 for (int k = 0; k < sz; ++k) {
745 double value = accumulator.results[k].values[bin]
746 * toSec(accumulator.results[k].duration);
747 sum_c += value;
748 }
749
750 std::cerr << "mean_c = " << sum_c << " / " << totalDuration << " = "
751 << sum_c / totalDuration << " (sz = " << sz << ")" << std::endl;
752
753 summary.mean_c = sum_c / totalDuration;
754
755 for (int k = 0; k < sz; ++k) {
756 double value = accumulator.results[k].values[bin]
757 * toSec(accumulator.results[k].duration);
758 summary.variance_c +=
759 (value - summary.mean_c) * (value - summary.mean_c);
760 }
761
762 summary.variance_c /= summary.count;
763 }
764
765 float mean = summary.sum / summary.count;
766
767 std::cerr << "mean = " << summary.sum << " / " << summary.count << " = "
768 << summary.sum / summary.count << std::endl;
769
770 for (int k = 0; k < sz; ++k) {
771 float value = accumulator.results[k].values[bin];
772 summary.variance += (value - mean) * (value - mean);
773 }
774 summary.variance /= summary.count;
775
776 m_summaries[output][segmentStart][bin] = summary;
777 }
606 } 778 }
607 779 }
608 for (int bin = 0; bin < accumulator.bins; ++bin) { 780
609 781 m_segmentedAccumulators.clear();
610 // work on all values over time for a single bin
611
612 OutputBinSummary summary;
613
614 summary.count = sz;
615
616 summary.minimum = 0.f;
617 summary.maximum = 0.f;
618
619 summary.median = 0.f;
620 summary.mode = 0.f;
621 summary.sum = 0.f;
622 summary.variance = 0.f;
623
624 summary.median_c = 0.f;
625 summary.mode_c = 0.f;
626 summary.mean_c = 0.f;
627 summary.variance_c = 0.f;
628
629 if (sz == 0) continue;
630
631 std::vector<ValueDurationFloatPair> valvec;
632
633 for (int k = 0; k < sz; ++k) {
634 while (accumulator.results[k].values.size() <
635 accumulator.bins) {
636 accumulator.results[k].values.push_back(0.f);
637 }
638 }
639
640 for (int k = 0; k < sz; ++k) {
641 float value = accumulator.results[k].values[bin];
642 valvec.push_back(ValueDurationFloatPair
643 (value,
644 toSec(accumulator.results[k].duration)));
645 }
646
647 std::sort(valvec.begin(), valvec.end());
648
649 summary.minimum = valvec[0].value;
650 summary.maximum = valvec[sz-1].value;
651
652 if (sz % 2 == 1) {
653 summary.median = valvec[sz/2].value;
654 } else {
655 summary.median = (valvec[sz/2].value + valvec[sz/2 + 1].value) / 2;
656 }
657
658 double duracc = 0.0;
659 summary.median_c = valvec[sz-1].value;
660
661 for (int k = 0; k < sz; ++k) {
662 duracc += valvec[k].duration;
663 if (duracc > totalDuration/2) {
664 summary.median_c = valvec[k].value;
665 break;
666 }
667 }
668
669 std::cerr << "median_c = " << summary.median_c << std::endl;
670 std::cerr << "median = " << summary.median << std::endl;
671
672 std::map<float, int> distribution;
673
674 for (int k = 0; k < sz; ++k) {
675 summary.sum += accumulator.results[k].values[bin];
676 distribution[accumulator.results[k].values[bin]] += 1;
677 }
678
679 int md = 0;
680
681 for (std::map<float, int>::iterator di = distribution.begin();
682 di != distribution.end(); ++di) {
683 if (di->second > md) {
684 md = di->second;
685 summary.mode = di->first;
686 }
687 }
688
689 distribution.clear();
690
691 std::map<float, double> distribution_c;
692
693 for (int k = 0; k < sz; ++k) {
694 distribution_c[accumulator.results[k].values[bin]]
695 += toSec(accumulator.results[k].duration);
696 }
697
698 double mrd = 0.0;
699
700 for (std::map<float, double>::iterator di = distribution_c.begin();
701 di != distribution_c.end(); ++di) {
702 if (di->second > mrd) {
703 mrd = di->second;
704 summary.mode_c = di->first;
705 }
706 }
707
708 distribution_c.clear();
709
710 if (totalDuration > 0.0) {
711
712 double sum_c = 0.0;
713
714 for (int k = 0; k < sz; ++k) {
715 double value = accumulator.results[k].values[bin]
716 * toSec(accumulator.results[k].duration);
717 sum_c += value;
718 }
719
720 std::cerr << "mean_c = " << sum_c << " / " << totalDuration << " = "
721 << sum_c / totalDuration << " (sz = " << sz << ")" << std::endl;
722
723 summary.mean_c = sum_c / totalDuration;
724
725 for (int k = 0; k < sz; ++k) {
726 double value = accumulator.results[k].values[bin]
727 * toSec(accumulator.results[k].duration);
728 summary.variance_c +=
729 (value - summary.mean_c) * (value - summary.mean_c);
730 }
731
732 summary.variance_c /= summary.count;
733 }
734
735 float mean = summary.sum / summary.count;
736
737 std::cerr << "mean = " << summary.sum << " / " << summary.count << " = "
738 << summary.sum / summary.count << std::endl;
739
740 for (int k = 0; k < sz; ++k) {
741 float value = accumulator.results[k].values[bin];
742 summary.variance += (value - mean) * (value - mean);
743 }
744 summary.variance /= summary.count;
745
746 m_summaries[output][segmentStart][bin] = summary;
747 }
748 }
749
750 m_accumulators.clear(); 782 m_accumulators.clear();
751 } 783 }
752 784
753 785
754 } 786 }