/* UCollectData: Collect data from segStore for each stream s of each state n and store in seqMat[n][s]*/ void UCollectData(Sequence **seqMat) { int i,j,s,numSegs,segLen; long int n; float obsPerState; Observation obs; Ptr p; numSegs = NumSegs(segStore); for (i=1;i<=numSegs;i++) { segLen=SegLength(segStore,i); obsPerState=((float) segLen)/((float) (nStates-2)); if (obsPerState < 1.0) HError(2122,"UCollectData: segment too short[%d]",segLen); for (j=1;j<=segLen;j++) { obs = GetSegObs(segStore,i,j); n = (long int)(((float)(j-1)/obsPerState)+2); for (s=1; s<=nStreams; s++){ if (hset.hsKind==DISCRETEHS){ p = (Ptr)((long int)obs.vq[s]); StoreItem(seqMat[n][s],p); }else StoreItem(seqMat[n][s],obs.fv[s]); } } } }
/* UCollectData: Collect data from segStore for each stream s of each state n and store in seqMat[n][s]*/ void UCollectData(Sequence ***seqMat) { int i,j,k,n,s,numSegs,segLen,order; float obsPerState; Observation obs; Ptr p; numSegs = NumSegs(segStore); for (i=1;i<=numSegs;i++) { segLen=SegLength(segStore,i); obsPerState=((float) segLen)/((float) (nStates-2)); if (obsPerState < 1.0) HError(2122,"UCollectData: segment too short[%d]",segLen); for (j=1;j<=segLen;j++) { obs = GetSegObs(segStore,i,j); n = (int)(((float)(j-1)/obsPerState)+2); for (s=1; s<=nStreams; s++){ if (hset.hsKind==DISCRETEHS){ p = (Ptr)((long)obs.vq[s]); StoreItem(seqMat[n][s][1],p); } else if(hset.msdflag[s]){ order = SpaceOrder(obs.fv[s]); if ((k = IncludeSpace(msdInfo[n][s],order))) StoreItem(seqMat[n][s][k],obs.fv[s]); else if(!ignOutVec) HError(2122,"UCollectData: no space corresponded to order[%d]",order); }else StoreItem(seqMat[n][s][1],obs.fv[s]); } } } }
/* FindBestMixes: for each state/obs pair find most likely mix component */ void FindBestMixes(int segNum, int segLen, IntVec states, IntVec *mixes) { int i,s,m,bestm,M=0; StreamElem *ste; StreamInfo *sti; IntVec smix; Observation obs; Vector v; LogFloat bestP,p; MixtureElem *me; MixPDF *mp; if (trace&T_MIX) printf(" Mixture component alignment\n"); for (i=1; i<=segLen; i++){ ste = hmmLink->svec[states[i]].info->pdf+1; obs = GetSegObs(segStore, segNum, i); if (hset.hsKind == TIEDHS) PrecomputeTMix(&hset, &obs, 0.0, 1); for (s=1; s<=nStreams; s++,ste++){ sti = ste->info; if (hset.hsKind != TIEDHS) M = sti->nMix; smix = mixes[s]; if (hset.hsKind==TIEDHS) /* PrecomputeTMix has already sorted probs */ bestm = hset.tmRecs[s].probs[1].index; else if (M==1) bestm = 1; else{ v = obs.fv[s]; bestP = LZERO; bestm=0; if (trace&T_MIX) printf(" seg %d, stream %d: ",i,s); for (m=1; m<=M; m++){ me = sti->spdf.cpdf+m; mp = me->mpdf; p = MOutP(v,mp); if (p>bestP){ bestP=p; bestm=m; } if (trace&T_MIX) printf(" P(mix[%d])=%.1f",m,p); } if (bestm==0) HError(2125,"FindBestMixes: no best mix"); if (trace&T_MIX) printf(" [best=%d]\n",bestm); } smix[i] = bestm; } } }
/* UpdateCounts: using frames in seg i and alignment in states/mixes */ void UpdateCounts(int segNum, int segLen, IntVec states,IntVec *mixes) { int M=0,i,j,k,s,m,state,last; StreamElem *ste; MixPDF *mp = NULL; WtAcc *wa; MuAcc *ma; VaAcc *va; TrAcc *ta; Vector v; Observation obs; TMixRec *tmRec = NULL; float x,y; last = 1; /* last before 1st emitting state must be 1 */ ta = (TrAcc *)GetHook(hmmLink->transP); for (i=1; i<=segLen; i++){ state = states[i]; if (trace&T_CNT) printf(" Seg %d -> state %d\n",i,state); if (uFlags&(UPMEANS|UPVARS|UPMIXES)){ obs = GetSegObs(segStore, segNum, i); if (hset.hsKind == TIEDHS) PrecomputeTMix(&hset, &obs, 50.0, 0); ste = hmmLink->svec[state].info->pdf+1; for (s=1; s<=nStreams; s++,ste++){ if (hset.hsKind==DISCRETEHS){ m = obs.vq[s]; v = NULL; } else { v = obs.fv[s]; m = mixes[s][i]; } switch(hset.hsKind){ case TIEDHS: tmRec = &(hset.tmRecs[s]); M = tmRec->nMix; break; case PLAINHS: case SHAREDHS: case DISCRETEHS: M = ste->nMix; break; } if (m<1 || m > M) HError(2170,"UpdateCounts: mix/vq idx out of range[%d]",m); if (trace&T_CNT) printf(" stream %d -> mix %d[%d]\n",s,m,M); /* update mixture weight */ if (M>1 && (uFlags&UPMIXES)) { wa = (WtAcc *)ste->hook; wa->occ += 1.0; wa->c[m] += 1.0; if (trace&T_CNT) printf(" mix wt -> %.1f\n",wa->c[m]); } if (hset.hsKind==DISCRETEHS) continue; /* update state/mixture component */ switch(hset.hsKind){ case PLAINHS: case SHAREDHS: mp = ste->spdf.cpdf[m].mpdf; break; case TIEDHS: mp = tmRec->mixes[m]; break; } ma = (MuAcc *)GetHook(mp->mean); va = (VaAcc *)GetHook(mp->cov.var); ma->occ += 1.0; va->occ += 1.0; for (j=1; j<=hset.swidth[s]; j++) { x = v[j] - mp->mean[j]; ma->mu[j] += x; if (uFlags&UPVARS) switch(mp->ckind){ case DIAGC: va->cov.var[j] += x*x; break; case FULLC: for (k=1; k<=j; k++){ y = v[k]-mp->mean[k]; va->cov.inv[j][k] += x*y; } break; default: HError(2124,"UpdateCounts: bad cov kind %d\n", mp->ckind); } } if (trace&T_CNT) { ShowVector(" mean ->",ma->mu,6); if (uFlags&UPVARS) { if (mp->ckind==DIAGC) ShowVector(" var ->",va->cov.var,6); else ShowTriMat(" cov ->",va->cov.inv,6,6); } fflush(stdout); } } } /* update transition probs */ if (uFlags&UPTRANS){ ta->occ[last] += 1.0; ta->tran[last][state] += 1.0; last = state; if (i==segLen){ /* remember final state */ ta->occ[state] += 1.0; ta->tran[state][nStates] += 1.0; } if (trace&T_CNT) { ShowMatrix(" tran ->",ta->tran,6,6); fflush(stdout); } } } }
/* ViterbiAlign: align the segNum'th segment. For each frame k, store aligned state in states and mostly likely mix comp in mixes. Return logP. */ LogFloat ViterbiAlign(int segNum,int segLen, IntVec states, IntVec *mixes) { int currState,prevState,bestPrevState; int segIdx; LogFloat bestP,currP,tranP,prevP; Observation obs; if (trace & T_VIT) printf(" Aligning Segment Number %d\n",segNum); MakeTraceBack(segLen); /* From entry state 1: Column 1 */ obs = GetSegObs(segStore, segNum, 1); if (hset.hsKind == TIEDHS) PrecomputeTMix(&hset, &obs, 50.0, 0); for (currState=2;currState<nStates;currState++) { tranP = hmmLink->transP[1][currState]; if (tranP<LSMALL) lastP[currState] = LZERO; else lastP[currState] = tranP + OutP(&obs,hmmLink,currState); traceBack[1][currState] = 1; } if (trace & T_VIT) ShowP(1,lastP); /* Columns[2] -> Columns[segLen] -- this is the general case */ for (segIdx=2; segIdx<=segLen; segIdx++) { obs = GetSegObs(segStore, segNum, segIdx); if (hset.hsKind == TIEDHS) PrecomputeTMix(&hset, &obs, 50.0, 0); for (currState=2;currState<nStates;currState++) { bestPrevState=2; tranP = hmmLink->transP[2][currState]; prevP = lastP[2]; bestP = (tranP<LSMALL) ? LZERO : tranP+prevP; for (prevState=3;prevState<nStates;prevState++) { tranP = hmmLink->transP[prevState][currState]; prevP = lastP[prevState]; currP = (tranP<LSMALL) ? LZERO : tranP+prevP; if (currP > bestP) { bestPrevState=prevState; bestP=currP; } } if (bestP<LSMALL) currP = thisP[currState] = LZERO; else { currP = OutP(&obs,hmmLink,currState); thisP[currState] = bestP+currP; } if (trace&T_OBP) printf("OutP[s=%d,t=%d] = %f\n",currState,segIdx,currP); traceBack[segIdx][currState]=bestPrevState; } CopyVector(thisP,lastP); if (trace & T_VIT) ShowP(segIdx,lastP); } /* column[segLen]--> exit state(numStates) */ bestPrevState=2; tranP = hmmLink->transP[2][nStates]; prevP = lastP[2]; bestP=(tranP<LSMALL) ? LZERO : tranP+prevP; for (prevState=3;prevState<nStates;prevState++) { tranP = hmmLink->transP[prevState][nStates]; prevP = lastP[prevState]; currP = (tranP<LSMALL) ? LZERO : tranP+prevP; if (currP > bestP) { bestPrevState=prevState; bestP=currP; } } /* bestPrevState now gives last internal state along best state sequence */ if (bestP<LSMALL) HError(2126,"ViterbiAlign: No path found in %d'th segment",segNum); if (trace & T_VIT) { ShowTraceBack(segLen,traceBack); printf(" bestP = %12.5f via state %d\n",bestP,bestPrevState); fflush(stdout); } DoTraceBack(segLen,states,bestPrevState); if (mixes!=NULL) /* ie not DISCRETE */ FindBestMixes(segNum,segLen,states,mixes); ResetHeap( &traceBackStack ); return bestP; }
/* LoadFile: load whole file or segments into segStore */ void LoadFile(char *fn) { BufferInfo info; char labfn[80]; Transcription *trans; long segStIdx,segEnIdx; static int segIdx=1; /* Between call handle on latest seg in segStore */ static int prevSegIdx=1; HTime tStart, tEnd; int i,k,s,ncas,nObs=0,segLen; LLink p; Observation obs; if((pbuf=OpenBuffer(&bufferStack, fn, 10, dff, FALSE_dup, FALSE_dup))==NULL) HError(2150,"LoadFile: Config parameters invalid"); GetBufferInfo(pbuf,&info); CheckData(fn,info); if (firstTime) InitSegStore(&info); if (segId == NULL) { /* load whole parameter file */ nObs = ObsInBuffer(pbuf); tStart = 0.0; tEnd = (info.tgtSampRate * nObs); LoadSegment(segStore, tStart, tEnd, pbuf); segIdx++; } else { /* load segment of parameter file */ MakeFN(fn,labDir,labExt,labfn); trans = LOpen(&transStack,labfn,lff); ncas = NumCases(trans->head,segId); if ( ncas > 0) { for (i=1,nObs=0; i<=ncas; i++) { p = GetCase(trans->head,segId,i); segStIdx = (long)(p->start/info.tgtSampRate); segEnIdx = (long)(p->end/info.tgtSampRate); if (segEnIdx >= ObsInBuffer(pbuf)) segEnIdx = ObsInBuffer(pbuf)-1; if (segEnIdx - segStIdx + 1 >= nStates-2) { LoadSegment(segStore, p->start, p->end, pbuf); if (trace&T_LD1) printf(" loading seg %s %f[%ld]->%f[%ld]\n",segId->name, p->start,segStIdx,p->end,segEnIdx); nObs += SegLength(segStore, segIdx); segIdx++; }else if (trace&T_LD1) printf(" seg %s %f->%f ignored\n",segId->name, p->start,p->end); } } } if (hset.hsKind == DISCRETEHS){ for (k=prevSegIdx; k<segIdx; k++){ segLen = SegLength(segStore, k); for (i=1; i<=segLen; i++){ obs = GetSegObs(segStore, k, i); for (s=1; s<=nStreams; s++){ if( (obs.vq[s] < 1) || (obs.vq[s] > maxMixInS[s])) HError(2150,"LoadFile: Discrete data value [ %d ] out of range in stream [ %d ] in file %s",obs.vq[s],s,fn); } } } prevSegIdx=segIdx; } if (trace&T_LD0) printf(" %d observations loaded from %s\n",nObs,fn); CloseBuffer(pbuf); ResetHeap(&transStack); }