📄 hhed.c
字号:
{ TriMat w; int size; size = (k>0) ? 3 : 2; w = CreateSTriMat(&hmmHeap,size); w[1][1] = mat[i][i]; w[2][1] = mat[j][i]; w[2][2] = mat[j][j]; if (k>0) { w[1][3] = mat[i][k]; w[2][3] = mat[j][k]; w[3][3] = mat[k][k]; } return w;}/* SplitStreams: split streams of given HMM as per swidth info */void SplitStreams(HMMSet *hset,StateInfo *si,Boolean simple,Boolean first){ int j,s,S,m,M,width,V,next; StreamElem *ste,*oldste; MixtureElem *me,*oldme; MixPDF *mp, *oldmp; Boolean hasN; int epos[4]; int eposIdx; S = hset->swidth[0]; V = hset->vecSize; hasN = HasNulle(hset->pkind); oldste = si->pdf+1; ste = (StreamElem *)New(hset->hmem,S*sizeof(StreamElem)); si->pdf = ste - 1; next = 1; /* start of next slice to take from src vector */ eposIdx = 0; for (j=0; j<3; j++) epos[j] = 0; for (s=1;s<=S;s++,ste++) { width = hset->swidth[s]; M = ste->nMix = oldste->nMix; ste->hook = NULL; me = (MixtureElem *) New(hset->hmem,M*sizeof(MixtureElem)); ste->spdf.cpdf = me-1; oldme=oldste->spdf.cpdf+1; for (m=1; m<=M; m++, me++,oldme++) { oldmp = oldme->mpdf; if (oldmp->nUse>0) HError(2640,"SplitStreams: MixPDF is shared"); if (GetUse(oldmp->mean) > 0) HError(2640,"SplitStreams: Mean is shared"); switch(oldmp->ckind) { case DIAGC: if (GetUse(oldmp->cov.var) > 0) HError(2640,"SplitStreams: variance is shared"); break; case LLTC: case FULLC: if (GetUse(oldmp->cov.inv) > 0) HError(2640,"SplitStreams: covariance is shared"); break; default: HError(2640,"SplitStreams: not implemented for CovKind==%d", oldmp->ckind); break; } me->weight = oldme->weight; mp = (MixPDF *) New(hset->hmem,sizeof(MixPDF)); mp->nUse = 0; mp->hook = NULL; mp->gConst = LZERO; mp->ckind = oldmp->ckind; me->mpdf = mp; if (simple || s<S) { /* straight segmentation of original stream */ if ((trace & (T_SIZ | T_IND)) && first) printf(" Slicing at stream %d, [%d->%d]\n", s,next,next+width-1); mp->mean = SliceVector(oldmp->mean,next,next+width-1); if (mp->ckind == DIAGC) mp->cov.var = SliceVector(oldmp->cov.var,next,next+width-1); else mp->cov.inv = SliceTriMat(oldmp->cov.inv,next,next+width-1); } else { if ((trace & (T_SIZ | T_DET)) && first) printf(" Chopping at stream %d, [%d,%d,%d]\n", s,epos[0],epos[1],epos[2]); mp->mean = ChopVector(oldmp->mean,epos[0],epos[1],epos[2]); if (oldmp->ckind == DIAGC) mp->cov.var = ChopVector(oldmp->cov.var, epos[0],epos[1],epos[2]); else mp->cov.inv = ChopTriMat(oldmp->cov.inv, epos[0],epos[1],epos[2]); } } next += width; if (!simple && !(hasN && s==1)) { /* remember positions of E coefs */ epos[eposIdx++] = next; ++next; } } si->weights = CreateSVector(hset->hmem,S); for (s=1; s<=S; s++) si->weights[s] = 1.0;}/* -------------------- Tying Operations --------------------- *//* TypicalState: extract a typical state from given list ie the state with largest total gConst in stream 1 (indicating broad variances) and as few as possible zero mixture weights*/ILink TypicalState(ILink ilist, LabId macId){ ILink i,imax; LogFloat gsum,gmax; int m,M; StateInfo *si; StreamElem *ste; gmax = LZERO; imax = NULL; for (i=ilist; i!=NULL; i=i->next) { si = ((StateElem *)(i->item))->info; ste = si->pdf+1; M = ste->nMix; gsum = 0; for (m=1; m<=M; m++) if (ste->spdf.cpdf[m].weight>MINMIX) gsum += ste->spdf.cpdf[m].mpdf->gConst; else gsum -= 200.0; /* arbitrary penaltly */ if (gsum>gmax) { gmax = gsum; imax = i; } } if (imax==NULL) { HError(-2638,"TypicalState: No typical state for %s",macId->name); imax=ilist; } return imax;}/* TieState: tie all state info fields in ilist to typical state */void TieState(ILink ilist, LabId macId){ ILink i,ti; StateInfo *si,*tsi; StateElem *se; if (badGC) { FixAllGConsts(hset); /* in case any bad gConsts around */ badGC=FALSE; } if (hset->hsKind==TIEDHS || hset->hsKind==DISCRETEHS) ti=ilist; else ti = TypicalState(ilist,macId); se = (StateElem *) ti->item; tsi = se->info; tsi->nUse = 1; NewMacro(hset,fidx,'s',macId,tsi); for (i=ilist; i!=NULL; i=i->next) { se = (StateElem *)i->item; si = se->info; if (si != tsi) { se->info = tsi; ++tsi->nUse; } }}/* TieTrans: tie all transition matrices in ilist to 1st */void TieTrans(ILink ilist, LabId macId){ ILink i; SMatrix tran; HMMDef *hmm; hmm = ilist->owner; tran = hmm->transP; SetUse(tran,1); NewMacro(hset,fidx,'t',macId,tran); for (i=ilist; i!=NULL; i=i->next) { hmm = i->owner; if (hmm->transP != tran) { hmm->transP = tran; IncUse(tran); } }}/* TieDur: tie all dur vectors in ilist to 1st */void TieDur(ILink ilist, LabId macId){ ILink i; StateInfo *si; SVector v; si = (StateInfo *)ilist->item; if ((v=si->dur)==NULL) HError(2630,"TieDur: Attempt to tie null duration as macro %s", macId->name); SetUse(v,1); NewMacro(hset,fidx,'d',macId,v); for (i=ilist->next; i!=NULL; i=i->next) { si = (StateInfo *)i->item; if (si->dur==NULL) HError(-2630,"TieDur: Attempt to tie null duration to macro %s", macId->name); if (si->dur != v) { si->dur = v; IncUse(v); } }}/* TieWeights: tie all stream weight vectors in ilist to 1st */void TieWeights(ILink ilist, LabId macId){ ILink i; StateInfo *si; SVector v; si = (StateInfo *)ilist->item; v = si->weights; if (v==NULL) HError(2630,"TieWeights: Attempt to tie null stream weights as macro %s", macId->name); SetUse(v,1); NewMacro(hset,fidx,'w',macId,v); for (i=ilist->next; i!=NULL; i=i->next) { si = (StateInfo *)i->item; if (si->weights==NULL) HError(-2630,"TieWeights: Attempt to tie null stream weights to macro %s",macId->name); if (si->weights != v) { si->weights = v; IncUse(v); } }}/* VAdd: add vector b to vector a */void VAdd(Vector a, Vector b){ int k,V; V = VectorSize(a); for (k=1; k<=V; k++) a[k] += b[k];}/* VMax: max vector b to vector a */void VMax(Vector a, Vector b){ int k,V; V = VectorSize(a); for (k=1; k<=V; k++) if (b[k]>a[k]) a[k] = b[k];}/* VNorm: divide vector a by n */void VNorm(Vector a, int n){ int k,V; V = VectorSize(a); for (k=1; k<=V; k++) a[k] /= n;}/* TieMean: tie all mean vectors to average */void TieMean(ILink ilist, LabId macId){ ILink i; MixPDF *mp; Vector tmean; int tSize,vSize; mp = (MixPDF *)ilist->item; tmean = mp->mean; tSize = VectorSize(tmean); SetUse(tmean,1); NewMacro(hset,fidx,'u',macId,tmean); for (i=ilist->next; i!=NULL; i=i->next) { mp = (MixPDF *)i->item; if (mp->mean != tmean) { vSize = VectorSize(mp->mean); if (tSize != vSize) HError(2630,"TieMean: Vector size mismatch %d vs %d", tSize, vSize); VAdd(tmean,mp->mean); mp->mean = tmean; IncUse(tmean); } } VNorm(tmean,GetUse(tmean));}/* TieVar: tie all variance vectors in ilist to max */void TieVar(ILink ilist, LabId macId){ ILink i; MixPDF *mp; Vector tvar; int tSize,vSize; mp = (MixPDF *)ilist->item; tvar = mp->cov.var; tSize = VectorSize(tvar); SetUse(tvar,1); NewMacro(hset,fidx,'v',macId,tvar); for (i=ilist->next; i!=NULL; i=i->next) { mp = (MixPDF *)i->item; if (mp->cov.var!=tvar) { vSize = VectorSize(mp->cov.var); if (tSize != vSize) HError(2630,"TieVar: Vector size mismatch %d vs %d", tSize, vSize); VMax(tvar,mp->cov.var); mp->cov.var = tvar; IncUse(tvar); } } badGC=TRUE; /* gConsts no longer valid */}/* TieInv: tie all invcov mats in ilist to first */void TieInv(ILink ilist, LabId macId){ ILink i; MixPDF *mp; STriMat tinv; int tSize,mSize; mp = (MixPDF *)ilist->item; tinv = mp->cov.inv; tSize = NumRows(mp->cov.inv); SetUse(tinv,1); NewMacro(hset,fidx,'i',macId,tinv); for (i=ilist->next; i!=NULL; i=i->next) { mp = (MixPDF *)i->item; if (mp->cov.inv!=tinv) { mSize = NumRows(mp->cov.inv); if (tSize != mSize) HError(2630,"TieInv: Matrix size mismatch %d vs %d", tSize, mSize); mp->cov.inv = tinv; IncUse(tinv); } } badGC=TRUE; /* gConsts no longer valid */}/* TieXform: tie all xform mats in ilist to first */void TieXform(ILink ilist, LabId macId){ ILink i; MixPDF *mp; SMatrix txform; int tr,tc,mr,mc; mp = (MixPDF *)ilist->item; txform = mp->cov.xform; tr = NumRows(mp->cov.xform); tc = NumCols(mp->cov.xform); SetUse(txform,1); NewMacro(hset,fidx,'x',macId,txform); for (i=ilist->next; i!=NULL; i=i->next) { mp = (MixPDF *)i->item; if (mp->cov.xform!=txform) { mr = NumRows(mp->cov.xform); mc = NumCols(mp->cov.xform); if (tc != mc || tr != mr) HError(2630,"TieXform: Matrix size mismatch"); mp->cov.xform = txform; IncUse(txform); } } badGC=TRUE; /* gConsts no longer valid */}/* TieMix: tie all mix pdf's in ilist to 1st */void TieMix(ILink ilist, LabId macId){ ILink i; MixtureElem *me; MixPDF *tmpdf; me = (MixtureElem *)ilist->item; /* should choose max(Sigma) for */ tmpdf = me ->mpdf; /* consistency with tie states */ tmpdf->nUse = 1; NewMacro(hset,fidx,'m',macId,tmpdf); for (i=ilist->next; i!=NULL; i=i->next) { me = (MixtureElem *)i->item; if (me->mpdf!=tmpdf) { me->mpdf = tmpdf; ++tmpdf->nUse; } }}/* CreateJMixSet: create an array of 'joinSize' mixture elems */MixtureElem * CreateJMixSet(void){ MixtureElem *me; int m; me = (MixtureElem*) New(&hmmHeap,sizeof(MixtureElem)*joinSize); --me; for (m=1;m<=joinSize;m++) { me[m].weight = 0.0; me[m].mpdf = NULL; } return me;}/* AddJMix: add given mixture elem to joinSet inserting it in order of mixture weight */void AddJMix(MixtureElem *me){ int i,j; if (nJoins<joinSize || me->weight > joinSet[nJoins].weight) { if (nJoins == joinSize) /* if full discard last mix */ --nJoins; i = 1; /* find insertion point */ while (me->weight < joinSet[i].weight) i++; for (j=nJoins; j>=i; j--) /* make space */ joinSet[j+1] = joinSet[j]; joinSet[i] = *me; /* insert new mix */ ++nJoins; }}/* RemTop: remove and return top mix in join set */MixtureElem RemTop(void){ int j; MixtureElem me; if (nJoins==0) HError(2691,"RemTop: Attempt to rem top of empty join set"); me = joinSet[1]; for (j=1;j<nJoins;j++) joinSet[j] = joinSet[j+1]; joinSet[nJoins].weight = 0.0; --nJoins; return me;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -