annotate src/AgentFeederMono.h @ 203:aac739775e29 noteagent

Rename file, add labels
author Chris Cannam
date Wed, 04 Jun 2014 12:12:56 +0100
parents 3de7c871d9c8
children
rev   line source
Chris@181 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@181 2
Chris@181 3 /*
Chris@181 4 Silvet
Chris@181 5
Chris@181 6 A Vamp plugin for note transcription.
Chris@181 7 Centre for Digital Music, Queen Mary University of London.
Chris@181 8 This file Copyright 2012 Chris Cannam.
Chris@181 9
Chris@181 10 This program is free software; you can redistribute it and/or
Chris@181 11 modify it under the terms of the GNU General Public License as
Chris@181 12 published by the Free Software Foundation; either version 2 of the
Chris@181 13 License, or (at your option) any later version. See the file
Chris@181 14 COPYING included with this distribution for more information.
Chris@181 15 */
Chris@181 16
Chris@181 17 #ifndef AGENT_FEEDER_MONO_H
Chris@181 18 #define AGENT_FEEDER_MONO_H
Chris@181 19
Chris@181 20 #include "AgentFeeder.h"
Chris@181 21
Chris@181 22 //#define DEBUG_FEEDER 1
Chris@181 23
Chris@181 24 /**
Chris@181 25 * Take a series of observations or estimates (one at a time) and feed
Chris@181 26 * them to a set of agent hypotheses, creating a new candidate agent
Chris@181 27 * for each observation and also testing the observation against the
Chris@181 28 * existing set of hypotheses.
Chris@181 29 *
Chris@181 30 * One satisfied hypothesis is considered to be "accepted" at any
Chris@181 31 * moment (that is, the earliest contemporary hypothesis to have
Chris@181 32 * become satisfied). The series of accepted and completed hypotheses
Chris@181 33 * from construction to the present time can be queried through
Chris@189 34 * retrieveAcceptedHypotheses(), which detaches them from the current
Chris@189 35 * feeder (i.e. hypotheses returned from one call to this function
Chris@189 36 * will not be returned by any subsequent call).
Chris@181 37 *
Chris@181 38 * Call feed() to provide a new observation. Call finish() when all
Chris@181 39 * observations have been provided. The set of hypotheses returned by
Chris@181 40 * getAcceptedHypotheses() will not be complete unless finish() has
Chris@181 41 * been called.
Chris@181 42 */
Chris@181 43 template <typename Hypothesis>
Chris@181 44 class AgentFeederMono : public AgentFeeder
Chris@181 45 {
Chris@189 46 private:
Chris@189 47 typedef std::vector<Hypothesis> Hypotheses;
Chris@189 48
Chris@181 49 public:
Chris@189 50 AgentFeederMono() : m_haveCurrent(false) { }
Chris@181 51
Chris@181 52 virtual void feed(AgentHypothesis::Observation o) {
Chris@181 53
Chris@181 54 #ifdef DEBUG_FEEDER
Chris@181 55 std::cerr << "feed: have observation [value = " << o.value << ", time = " << o.time << "]" << std::endl;
Chris@181 56 #endif
Chris@181 57
Chris@189 58 if (m_haveCurrent) {
Chris@189 59 if (m_current.accept(o)) {
Chris@189 60 return;
Chris@189 61 }
Chris@181 62 if (m_current.getState() == Hypothesis::Expired) {
Chris@189 63 m_accepted.push_back(m_current);
Chris@181 64 #ifdef DEBUG_FEEDER
Chris@181 65 std::cerr << "current has expired, pushing to accepted" << std::endl;
Chris@181 66 #endif
Chris@189 67 m_haveCurrent = false;
Chris@181 68 }
Chris@189 69 }
Chris@181 70
Chris@189 71 bool swallowed = false;
Chris@181 72
Chris@181 73 #ifdef DEBUG_FEEDER
Chris@189 74 std::cerr << "not swallowed by current" << std::endl;
Chris@181 75 #endif
Chris@181 76
Chris@189 77 Hypotheses newCandidates;
Chris@181 78
Chris@189 79 for (typename Hypotheses::iterator i = m_candidates.begin();
Chris@189 80 i != m_candidates.end(); ++i) {
Chris@181 81
Chris@189 82 Hypothesis h = *i;
Chris@181 83
Chris@189 84 if (swallowed) {
Chris@181 85
Chris@189 86 // don't offer: each observation can only belong to one
Chris@189 87 // satisfied hypothesis
Chris@189 88 newCandidates.push_back(h);
Chris@181 89
Chris@189 90 } else {
Chris@181 91
Chris@189 92 if (h.accept(o)) {
Chris@181 93 #ifdef DEBUG_FEEDER
Chris@189 94 std::cerr << "accepted, state is " << h.getState() << std::endl;
Chris@181 95 #endif
Chris@189 96 if (h.getState() == Hypothesis::Satisfied) {
Chris@181 97
Chris@189 98 swallowed = true;
Chris@181 99
Chris@189 100 if (!m_haveCurrent ||
Chris@189 101 m_current.getState() == Hypothesis::Expired ||
Chris@189 102 m_current.getState() == Hypothesis::Rejected) {
Chris@181 103 #ifdef DEBUG_FEEDER
Chris@189 104 std::cerr << "current has ended, updating from candidate" << std::endl;
Chris@181 105 #endif
Chris@189 106 m_current = h;
Chris@189 107 m_haveCurrent = true;
Chris@181 108 } else {
Chris@189 109 newCandidates.push_back(h);
Chris@181 110 }
Chris@189 111
Chris@189 112 } else {
Chris@189 113 newCandidates.push_back(h);
Chris@181 114 }
Chris@181 115 }
Chris@181 116 }
Chris@189 117 }
Chris@181 118
Chris@189 119 if (!swallowed) {
Chris@189 120 Hypothesis h;
Chris@189 121 h.accept(o); // must succeed, as h is new
Chris@189 122 newCandidates.push_back(h);
Chris@181 123 #ifdef DEBUG_FEEDER
Chris@189 124 std::cerr << "not swallowed, creating new hypothesis" << std::endl;
Chris@181 125 #endif
Chris@189 126 }
Chris@181 127
Chris@189 128 // reap rejected/expired hypotheses from candidates list,
Chris@189 129 // and assign back to m_candidates
Chris@189 130
Chris@189 131 m_candidates.clear();
Chris@181 132
Chris@189 133 for (typename Hypotheses::const_iterator i = newCandidates.begin();
Chris@189 134 i != newCandidates.end(); ++i) {
Chris@189 135 Hypothesis h = *i;
Chris@189 136 if (h.getState() != Hypothesis::Rejected &&
Chris@189 137 h.getState() != Hypothesis::Expired) {
Chris@189 138 m_candidates.push_back(h);
Chris@189 139 } else {
Chris@181 140 #ifdef DEBUG_FEEDER
Chris@189 141 std::cerr << "reaping a candidate" << std::endl;
Chris@181 142 #endif
Chris@181 143 }
Chris@181 144 }
Chris@181 145 #ifdef DEBUG_FEEDER
Chris@181 146 std::cerr << "have " << m_candidates.size() << " candidates" << std::endl;
Chris@181 147 #endif
Chris@181 148 }
Chris@181 149
Chris@181 150 virtual void finish() {
Chris@189 151 if (m_haveCurrent &&
Chris@189 152 (m_current.getState() == Hypothesis::Satisfied)) {
Chris@181 153 #ifdef DEBUG_FEEDER
Chris@181 154 std::cerr << "finish: current is satisfied, pushing to accepted" << std::endl;
Chris@181 155 #endif
Chris@189 156 m_accepted.push_back(m_current);
Chris@181 157 }
Chris@181 158 }
Chris@181 159
Chris@189 160 std::set<Hypothesis> retrieveAcceptedHypotheses() {
Chris@189 161 std::set<Hypothesis> hs;
Chris@189 162 #ifdef DEBUG_FEEDER
Chris@189 163 std::cerr << "retrieveAcceptedHypotheses: returning " << m_accepted.size() << " accepted" << std::endl;
Chris@189 164 #endif
Chris@189 165 for (typename Hypotheses::const_iterator i = m_accepted.begin();
Chris@189 166 i != m_accepted.end(); ++i) {
Chris@189 167 hs.insert(*i);
Chris@189 168 }
Chris@187 169 m_accepted.clear();
Chris@189 170 return hs;
Chris@181 171 }
Chris@181 172
Chris@181 173 private:
Chris@181 174 Hypotheses m_candidates;
Chris@181 175 Hypothesis m_current;
Chris@189 176 bool m_haveCurrent;
Chris@181 177 Hypotheses m_accepted;
Chris@181 178 };
Chris@181 179
Chris@181 180 #endif