COOPY » Guide
version 0.6.5
|
00001 #include <stdio.h> 00002 #include <coopy/Viterbi.h> 00003 #include <coopy/Dbg.h> 00004 00005 //#include <iostream> 00006 //using namespace std; 00007 00008 //#define DBG_LEVEL 100 00009 //#define DBG(x) if (DBG_LEVEL>=(x)) 00010 00011 using namespace coopy::store; 00012 using namespace coopy::cmp; 00013 00014 void Viterbi::setSize(int states, int sequence_length) { 00015 K = states; 00016 T = sequence_length; 00017 cost.resize(K,T); 00018 src.resize(K,T,-1); 00019 path.resize(1,T,-1); 00020 reset(); 00021 } 00022 00023 00024 void Viterbi::assertMode(int n_mode) { 00025 switch (n_mode) { 00026 case 0: 00027 if (mode==1) 00028 { 00029 index++; 00030 } 00031 mode = 0; 00032 break; 00033 case 1: 00034 if (mode==0) 00035 { 00036 //assert(index<T); 00037 00038 // Zeroing is now implicit. 00039 // The absence of a cell(x,y) should imply: 00040 // cost(x,y) = 0 00041 // src(x,y) = -1 00042 /* 00043 for (int i=0; i<K; i++) 00044 { 00045 cost(i,index) = 0; 00046 src(i,index) = -1; 00047 } 00048 */ 00049 } 00050 mode = 1; 00051 break; 00052 default: 00053 mode = n_mode; 00054 break; 00055 } 00056 } 00057 00058 void Viterbi::addTransition(int s0, int s1, float c) { 00059 bool resize = false; 00060 if (s0>=K) { 00061 K = s0+1; 00062 resize = true; 00063 } 00064 if (s1>=K) { 00065 K = s1+1; 00066 resize = true; 00067 } 00068 if (resize) { 00069 cost.nonDestructiveResize(K,T); 00070 src.nonDestructiveResize(K,T,-1); 00071 path.nonDestructiveResize(1,T,-1); 00072 } 00073 path_valid = 0; 00074 assertMode(1); 00075 if (index>=T) { 00076 T=index+1; 00077 //printf("RESIZE! index %d T %d\n", index, T); 00078 cost.nonDestructiveResize(K,T); 00079 src.nonDestructiveResize(K,T,-1); 00080 path.nonDestructiveResize(1,T,-1); 00081 } 00082 int sourced = 0; 00083 if (index>0) 00084 { 00085 c += cost(s0,index-1); 00086 sourced = (src(s0,index-1)!=-1); 00087 } 00088 else 00089 { 00090 sourced = 1; 00091 } 00092 00093 if (sourced) 00094 { 00095 if (c<cost(s1,index)||src(s1,index)==-1) 00096 { 00097 //cout << "Setting " << s1 << "," << index << " to " 00098 //<< s0 << endl; 00099 cost(s1,index) = c; 00100 src(s1,index) = s0; 00101 } 00102 else 00103 { 00104 //cout << "Rejecting " << s1 << "," << index << " to " 00105 //<< s0 << endl; 00106 } 00107 } 00108 } 00109 00110 void Viterbi::calculatePath() { 00111 if (!path_valid) 00112 { 00113 endTransitions(); 00114 float best = 0; 00115 int bestj = -1; 00116 if (index<=0) { 00117 // declare victory and exit 00118 path_valid = 1; 00119 return; 00120 } 00121 for (int j=0; j<K; j++) 00122 { 00123 //DBG(50) cout << "j=" << j << " and bestj is " << bestj 00124 // << " and src(j,index-1)=" << src(j,index-2) 00125 // << endl; 00126 if ((cost(j,index-1)<best||bestj==-1)&&src(j,index-1)!=-1) 00127 { 00128 best = cost(j,index-1); 00129 bestj = j; 00130 } 00131 } 00132 best_cost = best; 00133 00134 for (int i=index-1; i>=0; i--) 00135 { 00136 path(0,i) = bestj; 00137 //DBG(50) cout << "i=" << i << " and bestj is " << bestj << endl; 00138 COOPY_ASSERT(bestj!=-1); 00139 COOPY_ASSERT(bestj>=0&&bestj<K); 00140 bestj = src(bestj,i); 00141 } 00142 path_valid = 1; 00143 } 00144 } 00145 00146 void Viterbi::showPath() { 00147 calculatePath(); 00148 for (int i=0; i<index; i++) 00149 { 00150 if (path(0,i)==-1) 00151 { 00152 printf("*"); 00153 } 00154 else 00155 { 00156 printf("%d",path(0,i)); 00157 } 00158 if (K>=10) 00159 { 00160 printf(" "); 00161 } 00162 } 00163 printf(" costs %g\n", getCost()); 00164 } 00165 00166