25#define VIT_MIN_CAPACITY 7
26#define MAX_LINKCOUNT 300
27#define SUBSTATEVALUE_BITS (8*sizeof(short))
34 explicit SubstateId(
signed char s=-1,
short v=0) : slot(s), value(v) {}
36 bool operator< (
const SubstateId& other)
const {
38 slot < other.slot || (slot == other.slot &&
41 bool operator== (
const SubstateId& other)
const {
42 return slot == other.slot && value == other.value;
44 bool operator> (
const SubstateId& other)
const {
45 return (other < *
this);
47 bool operator!= (
const SubstateId& other)
const {
48 return !operator==(other);
50 bool operator<= (
const SubstateId& other)
const {
51 return !operator>(other);
55 return slot==-1 && value==0;
63 return ((slot+1) << SUBSTATEVALUE_BITS) + value;
65 void set(
int fromId) {
68 slot = ((fromId-value) >> SUBSTATEVALUE_BITS) -1;
71 return SubstateId(slot, numeric_limits<short>::min());
74 return SubstateId(slot, numeric_limits<short>::max());
83 return "(" + itoa(d.slot) +
"/" + itoa(d.value) +
")";
87typedef map<SubstateId, SubstateId> SubstateIdMap;
90#define MEMUSEDBLCOUNT 10
91struct GenericDataType {
93 for (
int i=0; i<MEMUSEDBLCOUNT; i++)
96 void operator+=(
const GenericDataType& other) {
97 for (
int i=0; i<MEMUSEDBLCOUNT; i++)
98 vals[i]+=other.vals[i];
100 double& operator[] (
int i) {
return vals[i]; }
101 double vals[MEMUSEDBLCOUNT];
113 ProjectError(
"Internal error: ViterbiSubmapType has no map!") {}
122 ProjectError(
"Internal error: ViterbiSubmapType is empty!") {}
132enum AlgorithmVariant { doViterbiOnly, doViterbiAndForward, doSampling, doBacktracking };
135inline bool doViterbi(AlgorithmVariant algovar) {
136 return algovar <= doViterbiAndForward;
138inline bool needForwardTable(AlgorithmVariant algovar) {
139 return algovar == doViterbiAndForward || algovar == doSampling;
141inline AlgorithmVariant doViterbi(
bool needForwardTable) {
142 return needForwardTable ? doViterbiAndForward : doViterbiOnly;
161 p(dbl), predMap(pred), succCount(0) {}
166 return !(other < *
this);
169 return !operator<(other);
172 return other < *
this;
193 map<SubstateId,ViterbiSubmapEntry>(other),
197 delete predSubstates;
206 SubstateIdMap* predSubstates;
217 typedef ViterbiSubmapBasetype::iterator iterator;
218 typedef ViterbiSubmapBasetype::const_iterator const_iterator;
222 factor(1), state(st), theMap(0) {}
226 factor(other.factor), state(other.state)
238 factor = other.factor;
245 factor = other.factor * mult;
254 int getMainState()
const {
260 bool inactive()
const {
264 return inactive() || theMap->empty();
266 bool emptypart(
int part) {
267 return inactive() || begin(part) == end(part);
270 return inactive() ? 0 : theMap->size();
276 int linkcount()
const {
277 return inactive() ? 0 : theMap->linkcount;
280 return theMap && theMap->linkcount > 1;
283 SubstateIdMap* getPredSubstateMap()
const;
285 void clearEmptySubstateMap()
const;
290 int eraseAllUnneededSubstates()
const;
293 iterator begin()
const {
294 return theMap->begin();
296 iterator begin(
int slot)
const {
297 return theMap->lower_bound(SubstateId::min(slot));
299 iterator end()
const {
300 return theMap->end();
302 iterator end(
int slot)
const {
303 return theMap->upper_bound(SubstateId::max(slot));
306 return theMap->lower_bound(substate);
308 iterator bound(
signed char slot,
short value)
const {
309 return theMap->lower_bound(
SubstateId(slot,value));
312 const_iterator it = theMap->find(substate);
313 return it==end() ? 0 : it->second.p * factor;
315 iterator insert(iterator where, pair<SubstateId, ViterbiSubmapEntry> what)
const {
317 return theMap->insert(where, what);
326 insert(end(), substate, value, pred);
328 void erase(iterator start, iterator end)
const {
329 theMap->erase(start, end);
332 theMap->erase(substate);
335 return (*theMap)[substate].succCount;
337 short& succCount(iterator it) {
338 return it->second.succCount;
340 const short& succCount(iterator it)
const {
345 return it->second.succCount;
348 return succCount(begin());
350 void eraseAndDecCounts(iterator it)
const;
354 cloneMap(newPredMap, MAX_LINKCOUNT);
357 int eraseUnneededSubstate(
SubstateId substate);
358 void registerPredecessors();
359 void useMaximum(
Double& mainProb);
363 GenericDataType memoryUsage();
364 void dieOnZero()
const;
365 void checkAfterWindow()
const;
367 void checkCounts()
const;
375 theMap = other.theMap;
376 if (theMap) theMap->linkcount++;
380 if (theMap && --(theMap->linkcount)==0)
391inline SubstateIdMap* ViterbiSubmapType::getPredSubstateMap()
const {
394 SubstateIdMap*& result = theMap->predSubstates;
396 result =
new SubstateIdMap;
400inline void ViterbiSubmapType::clearEmptySubstateMap()
const {
401 if (theMap && theMap->predSubstates &&
402 theMap->predSubstates->empty()) {
403 delete theMap->predSubstates;
404 theMap->predSubstates = 0;
410 theMap = other.theMap;
414inline void ViterbiSubmapType::eraseAndDecCounts(iterator it)
const {
417 SubstateId substate = popPredSubstate(it->first);
418 pred->succCount(substate)--;
420 if (pred->succCount(substate) < 0)
429 if (target.p * factor < value) {
430 target.set(value / factor, pred);
436inline void ViterbiSubmapType::cloneMap(
ViterbiSubmapType* newPredMap,
int maxlinkcount) {
439 throw ProjectError(
"SubstateModel::cloneMap: predMap==0!");
441 if (theMap->linkcount > maxlinkcount) {
444 for (iterator it=begin(); it != end(); ++it) {
445 it->second.predMap = newPredMap;
446 it->second.succCount = 0;
451inline void ViterbiSubmapType::getMaxSubstate(
SubstateId& substate,
Double& value)
const {
452 value = 0; substate.set(0);
455 for (iterator it = begin(); it != end(); ++it)
456 if (it->second > value) {
457 substate = it->first;
458 value = it->second.p;
472 state(st), value(v), substate_idx(i) {}
475 signed char substate_idx;
485typedef vector<ViterbiEntryType> ViterbiColumnBasetype;
496 ViterbiColumnBasetype(),
497 subProbs(), idx(0), maxsize(0) {}
503 void erase(
int state);
506 Double get(
int state)
const {
507 return has(state) ? elem(state).value : 0;
510 if (substate.undef())
return get(state);
512 return getSubstates(state).get(substate);
518 Double operator[](
int state)
const {
521 Double& operator[](
int state) {
523 return elem(state).value;
528 bool has(
int state)
const {
530 if (state < 0 || state >= maxsize)
531 throw ProjectError(
"ViterbiColumnType: state out of range");
533 return idx[state] >= 0;
536 return ViterbiColumnBasetype::size();
543 bool hasSubstates(
int state)
const {
544 int idx = getSubstateIdx(state);
545 return idx >= 0 && idx < (int) subProbs.size() && !subProbs[idx].inactive();
554 template <
class Tp,
class FncPtr>
555 void foreachSubstate(Tp p, FncPtr f) {
556 for (
int i=0; i<subProbs.size(); i++)
557 (p->*f)(subProbs[i]);
559 void eraseSubstates(
int state);
560 int eraseUnneededSubstates();
561 int removeEmptySubmaps();
565 int substateCount(
int state)
const {
567 return getSubstates(state).size();
572 int totalSubstateCount()
const {
574 for (
int i=0; i<subProbs.size(); i++) result += subProbs[i].size();
577 map<int,Double> substateCounts()
const {
578 map<int,Double> result;
579 for (
int i=0; i<subProbs.size(); i++)
580 result[subProbs[i].state] = subProbs[i].size();
583 void testIntegrity()
const;
584 void checkAfterWindow()
const {
585 for (
int i=0; i < subProbs.size(); i++)
586 subProbs[i].checkAfterWindow();
588 void showSubstateInfo(ostream& strm)
const;
589 void write(ostream& strm,
const vector<string>&);
590 void write(
const vector<string>&);
592 int getSubmapCapacity() {
595 GenericDataType getSubstateMemoryUsage();
596 void countSubmaps(map<ViterbiSubmapBasetype*,int>& linkcounts);
601 return ViterbiColumnBasetype::operator[](idx[state]);
604 return ViterbiColumnBasetype::operator[](idx[state]);
606 void addState(
int state,
signed char sub_idx=-1);
607 signed char getSubstateIdx(
int state)
const {
608 return has(state) ? elem(state).substate_idx : -1;
610 void eraseSubProbs(
int subidx);
612 vector<ViterbiSubmapType> subProbs;
619inline const ViterbiSubmapType& ViterbiColumnType::getSubstates(
int state)
const {
620 int idx = getSubstateIdx(state);
621 if (idx >= 0 && idx < (
int) subProbs.size()) {
623 if (!result.inactive())
630 int idx = getSubstateIdx(state);
631 if (idx >= 0 && idx < (
int) subProbs.size()) {
633 if (!result.inactive())
639inline void ViterbiColumnType::getMaxSubstate(
int state,
SubstateId& substate,
Double& value)
const {
640 Double mainval = get(state);
643 submap.getMaxSubstate(substate, value);
647 substate.set(0); value = mainval;
650inline int ViterbiColumnType::eraseUnneededSubstates() {
652 for (
unsigned i=0; i<subProbs.size(); i++)
653 result += subProbs[i].eraseAllUnneededSubstates();
657inline int ViterbiColumnType::removeEmptySubmaps() {
659 for (
unsigned i=0; i<subProbs.size(); i++)
660 if (subProbs[i].empty() && !subProbs[i].inactive()) {
661 subProbs[i].deactivate();
667inline void ViterbiColumnType::eraseSubProbs(
int subidx) {
671 if (subidx < (
int) subProbs.size() - 1) {
672 elem(subProbs.back().state).substate_idx = subidx;
673 subProbs[subidx] = subProbs.back();
693 void assign(
int colcount,
int colsize) {
697 for (
int i=0; i<count; i++) {
698 data[i].reset(colsize);
715 for (
int i=0; i<count; i++)
716 result += data[i].capacity();
717 return result / count;
720 return data[i].capacity();
724 for (
int i=0; i<count; i++)
725 result += data[i].size();
726 return result / count;
728 void write(ostream& strm,
const vector<string>& stateNames = vector<string>()) {
729 for (
int i=0; i<count; i++)
730 data[i].write(strm, stateNames);
732 int compare(istream&,
const vector<string>& stateNames = vector<string>());
733 void showSubstateMemoryUsage(
int from = 0,
int to = -1);
762 void reset(){state = TYPE_UNKNOWN; base = predEnd = -INT_MAX;}
763 void resetPredEnd() {predEnd = -INT_MAX;}
772 return (first.probability > second.probability);
785 while (!options.empty())
788 void add(
int state,
int base,
Double probability,
int predEnd = -INT_MAX) {
790 (predEnd == -INT_MAX)? base : predEnd,
792 cumprob += probability;
794 void prepareSampling() {
798 return options.size();
800 void print(ostream& out) {
801 out <<
"options: " << cumprob <<
" | ";
802 for (list<OptionListItem>::iterator it = options.begin(); it != options.end(); ++it){
803 out << it->state <<
" " << it->base <<
" " << (it->probability/cumprob) <<
", ";
810 list<OptionListItem> options;
This class implements a double object with a very large range.
Definition lldouble.hh:31
Options lists are used for sampling; items also in backtracking.
Definition vitmatrix.hh:748
Definition vitmatrix.hh:779
ProjectError()
Definition types.hh:460
Definition vitmatrix.hh:491
An array of Viterbi columns.
Definition vitmatrix.hh:687
Definition vitmatrix.hh:209
exceptions thrown by Viterbi
Definition vitmatrix.hh:111
Definition vitmatrix.hh:120
Definition vitmatrix.hh:33
one entry in the viterbi matrix, including the index for the substate map
Definition vitmatrix.hh:470
Definition vitmatrix.hh:188
Definition vitmatrix.hh:159