📄 hrec.c
字号:
bx=LAdd(bx,wt+px); } } } return bx;}/* Version of POutP that caches outp values with frame id */static LogFloat cPOutP(PSetInfo *psi,Observation *obs,StateInfo *si,int id){ PreComp *pre; LogFloat outp; StreamElem *se; Vector w; int s,S; if (si->sIdx>0 && si->sIdx<=pri->psi->nsp) pre=pri->psi->sPre+si->sIdx; else pre=NULL;#ifdef SANITY if (pre==NULL) HError(8520,"cPOutP: State has no PreComp attached");#endif if (pre->id!=id) { if (psi->mixShared==FALSE){ outp=POutP(psi->hset,obs,si); } else { S=obs->swidth[0]; if (S==1 && si->weights==NULL){ outp=cSOutP(psi->hset,1,obs,si->pdf+1,id); } else { outp=0.0; se=si->pdf+1; w=si->weights; for (s=1;s<=S;s++,se++){ outp+=w[s]*cSOutP(psi->hset,s,obs,se,id); } } } pre->outp=outp; pre->id=id; } return(pre->outp);}/* Move align record to (head of) YES referenced list */static void MoveAlignYesRef(Align *align){ align->link->knil=align->knil; align->knil->link=align->link; align->link=pri->aYesRef.link; align->knil=&pri->aYesRef; align->link->knil=align->knil->link=align;}/* Add reference to align record. *//* Moves record to YES referenced list when necessary */static void RefAlign(Align *align){ if (align->usage==0) { MoveAlignYesRef(align);#ifdef SANITY pri->anlen--;pri->aylen++;#endif } align->usage++;}/* Remove reference to align record, moving to */ /* (tail of) NO referenced list when necessary. */static void DeRefAlign(Align *align){#ifdef SANITY if (align->usage<0) HError(8591,"DeRefAlign: Align not referenced");#endif align->usage--; if (align->usage==0) { align->link->knil=align->knil; align->knil->link=align->link; align->knil=pri->aNoTail.knil; align->link=&pri->aNoTail; align->link->knil=align->knil->link=align;#ifdef SANITY pri->anlen++;pri->aylen--;#endif }}/* Allocate new align record and add to NOT referenced list */static Align *NewNRefAlign(NetNode *node,int state,double like, int frame,Align *prev){ Align *align; align=(Align*) New(&pri->alignHeap,0); align->link=pri->aNoRef.link; align->knil=&pri->aNoRef; align->link->knil=align->knil->link=align; align->usage=0; align->used=FALSE; align->node=node; align->state=state; align->like=like; align->frame=frame; if ((align->prev=prev)!=NULL) RefAlign(prev); pri->nalign++;#ifdef SANITY pri->anlen++;#endif return(align);}/* Remove and free align record from NO referenced list */static void UnlinkAlign(Align *align){ align->link->knil=align->knil; align->knil->link=align->link;#ifdef SANITY if (align->usage!=0) HError(8591,"UnlinkAlign: Freeing referenced align record"); align->link=align->knil=NULL; align->node=NULL;align->prev=0; align->usage=0;pri->anlen--;#endif Dispose(&pri->alignHeap,align); pri->nalign--;}static void StepHMM1(NetNode *node) /* Model internal propagation NBEST */{ NetInst *inst; HMMDef *hmm; Token tok,max; TokenSet *res,cmp,*cur; Align *align; int i,j,k,N,endi; LogFloat outp; Matrix trP; short **seIndex; inst=node->inst; max=null_token; hmm=node->info.hmm; N=hmm->numStates; trP=hmm->transP; seIndex=pri->psi->seIndexes[hmm->tIdx]; for (j=2,res=pri->psi->sBuf+2;j<N;j++,res++) { /* Emitting states first */ i=seIndex[j][0]; endi=seIndex[j][1]; cur=inst->state+i-1; res->tok=cur->tok; res->n=cur->n; for (k=0;k<cur->n;k++) res->set[k]=cur->set[k]; res->tok.like+=trP[i][j]; for (i++,cur++;i<=endi;i++,cur++) { cmp.tok=cur->tok; cmp.tok.like+=trP[i][j]; if (res->n==0) { if (cmp.tok.like > res->tok.like) res->tok=cmp.tok; } else TokSetMerge(res,&cmp.tok,cur); } if (res->tok.like>pri->genThresh) { /* State pruning */ outp=cPOutP(pri->psi,pri->obs,hmm->svec[j].info,pri->id); res->tok.like+=outp; if (res->tok.like>max.like) max=res->tok; if (pri->states) { if (res->tok.align==NULL?TRUE: res->tok.align->state!=j || res->tok.align->node!=node) { align=NewNRefAlign(node,j, res->tok.like-outp-res->tok.lm*pri->scale, pri->frame-1,res->tok.align); res->tok.align=align; } } } else { res->tok=null_token; res->n=((pri->nToks>1)?1:0); } } /* Null entry state ready for external propagation */ /* And copy tokens from buffer to instance */ for (i=1,res=pri->psi->sBuf+1,cur=inst->state; i<N;i++,res++,cur++) { cur->n=res->n; cur->tok=res->tok; for (k=0;k<res->n;k++) cur->set[k]=res->set[k]; } /* Set up pruning limits */ if (max.like>pri->genMaxTok.like) { pri->genMaxTok=max; pri->genMaxNode=node; } inst->max=max.like; i=seIndex[N][0]; /* Exit state (ignoring tee trP) */ endi=seIndex[N][1]; res=inst->exit; cur=inst->state+i-1; res->n=cur->n; res->tok=cur->tok; for (k=0;k<cur->n;k++) res->set[k]=cur->set[k]; res->tok.like+=trP[i][N]; for (i++,cur++;i<=endi;i++,cur++) { cmp.tok=cur->tok; cmp.tok.like+=trP[i][N]; if (res->n==0) { if (cmp.tok.like > res->tok.like) res->tok=cmp.tok; } else TokSetMerge(res,&cmp.tok,cur); } if (res->tok.like>LSMALL){ tok.like=res->tok.like+inst->wdlk; if (tok.like > pri->wordMaxTok.like) { pri->wordMaxTok=tok; pri->wordMaxNode=node; } if (!node_tr0(node) && pri->models) { align=NewNRefAlign(node,-1, res->tok.like-res->tok.lm*pri->scale, pri->frame,res->tok.align); res->tok.align=align; } } else { inst->exit->tok=null_token; inst->exit->n=((pri->nToks>1)?1:0); }}/* Tee transition propagation - may be repeated */static void StepHMM2(NetNode *node) { NetInst *inst; HMMDef *hmm; TokenSet cmp,*res,*cur; Align *align; int N; inst=node->inst; hmm=node->info.hmm; N=hmm->numStates; cur=inst->state; res=inst->exit; cmp.tok=cur->tok; cmp.tok.like+=hmm->transP[1][N]; if (res->n==0) { if (cmp.tok.like>res->tok.like) res->tok=cmp.tok; } else TokSetMerge(res,&cmp.tok,cur); if (pri->models) { align=NewNRefAlign(node,-1, res->tok.like-res->tok.lm*pri->scale, pri->frame,res->tok.align); res->tok.align=align; }}static Path *NewNRefPath(void){ Path *path; path=(Path*) New(&pri->pathHeap,0); path->link=pri->pNoRef.link; path->knil=&pri->pNoRef; path->link->knil=path->knil->link=path; path->chain=NULL; path->used=FALSE; pri->npth++;#ifdef SANITY pri->pnlen++;#endif return(path);}static void MovePathYesRef(Path *path){ path->link->knil=path->knil; path->knil->link=path->link; path->link=pri->pYesRef.link; path->knil=&pri->pYesRef; path->link->knil=path->knil->link=path;}static void RefPath(Path *path){ if (path->usage==0) { MovePathYesRef(path);#ifdef SANITY pri->pnlen--;pri->pylen++;#endif } path->usage++;} static void DeRefPathPrev(Path *path){ Path *pth; NxtPath tmp,*cur; tmp.prev=path->prev; tmp.chain=path->chain; for (cur=&tmp;cur!=NULL;cur=cur->chain) { if ((pth=cur->prev)!=NULL) {#ifdef SANITY if (pth->usage<=0) HError(8591,"DeRefPathPrev: Path not referenced");#endif pth->usage--; if (pth->usage==0) { pth->link->knil=pth->knil; pth->knil->link=pth->link; pth->link=pri->pNoRef.link; pth->knil=&pri->pNoRef; pth->link->knil=pth->knil->link=pth;#ifdef SANITY pri->pnlen++;pri->pylen--;#endif } } }} static void UnlinkPath(Path *path){ NxtPath *pth,*nth; path->link->knil=path->knil; path->knil->link=path->link; for (pth=path->chain;pth!=NULL;pth=nth) { nth=pth->chain; Dispose(&pri->rPthHeap,pth); }#ifdef SANITY path->link=path->knil=NULL; /* path->pron=NULL;*/ path->prev=0; path->usage=0;pri->pnlen--; path->chain=NULL; path->frame=-1;#endif Dispose(&pri->pathHeap,path); pri->npth--;}static void CollectPaths(void){ NetInst *inst; TokenSet *cur; int i,k,n; Path *path,*plink; Align *align,*alink; for (inst=pri->head.link;inst!=NULL;inst=inst->link) if (inst->node!=NULL) { if (node_hmm(inst->node)) n=inst->node->info.hmm->numStates-1; else n=1; for (i=1,cur=inst->state;i<=n;i++,cur++) { path=cur->tok.path; if (path && !path->used) { if (path->usage!=0) MovePathYesRef(path); path->used=TRUE; }#ifdef SANITY if (path!=NULL && cur->n>0 && cur->tok.path!=cur->set[0].path) HError(8590,"CollectPaths: Top path mismatch in state %d",i);#endif for (k=1;k<cur->n;k++) { path=cur->set[k].path; if (path && !path->used) { if (path->usage!=0) MovePathYesRef(path); path->used=TRUE; } } align=cur->tok.align; if (align && !align->used) { if (align->usage!=0) MoveAlignYesRef(align); align->used=TRUE; } } path=inst->exit->tok.path; if (path && !path->used) { if (path->usage!=0) MovePathYesRef(path); path->used=TRUE; }#ifdef SANITY if (path!=0 && inst->exit->n>0 && inst->exit->tok.path!=inst->exit->set[0].path) HError(8590,"CollectPaths: Top path mismatch in state N");#endif for (k=1;k<inst->exit->n;k++) { path=inst->exit->set[k].path; if (path && !path->used) { if (path->usage!=0) MovePathYesRef(path); path->used=TRUE; } } align=inst->exit->tok.align; if (align && !align->used) { if (align->usage!=0) MoveAlignYesRef(align); align->used=TRUE; } } for (path=pri->pNoRef.link;path->link!=NULL;path=plink) { if (!path->used) { if (path->align!=NULL) DeRefAlign(path->align); DeRefPathPrev(path); plink=path->link; UnlinkPath(path); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -