📄 hnet.c
字号:
tail=SubLatList(sub->lat,tail,depth+1); } if (tail!=NULL) for (sub=lat->subList;sub!=NULL;sub=sub->next) { if (sub->lat->chain!=NULL) continue; /* Done it already */#if 0 /* Algorithm sanity check only needed once */ { Lattice *cur; /* Quick sanity check */ cur=tail->chain; /* Actual lattice == last in list */ for (cur=cur->chain;cur!=tail->chain;cur=cur->chain) if (sub->lat==cur || sub->lat->subLatId==cur->subLatId || sub->lat->subLatId==NULL) break; if (cur!=tail->chain) /* Match */ HError(8253,"Match"); }#endif sub->lat->chain=tail->chain; tail->chain=sub->lat; tail=sub->lat; } return(tail);}/* Lattices often need to be sorted before output */static Lattice *slat; /* Used by qsort cmp routines *//* QSCmpNodes: order on time, then score if times equal */static int QSCmpNodes(const void *v1,const void *v2){ int s1,s2; double tdiff,sdiff; s1=*((int*)v1);s2=*((int*)v2); tdiff=slat->lnodes[s1].time-slat->lnodes[s2].time; sdiff=slat->lnodes[s1].score-slat->lnodes[s2].score; if (tdiff==0.0) { if (sdiff==0.0) return(s1-s2); else if (sdiff>0.0) return(1); else return(-1); } else if (tdiff>0.0) return(1); else return(-1);}/* QSCmpArcs: order on end node order, then start node order */static int QSCmpArcs(const void *v1,const void *v2){ int s1,s2,j,k; s1=*((int*)v1);s2=*((int*)v2); j=slat->larcs[s1].end->n-slat->larcs[s2].end->n; k=slat->larcs[s1].start->n-slat->larcs[s2].start->n; if (k==0 && j==0) return(s1-s2); else if (j==0) return(k); else return(j);}/* OutputIntField: output integer as text or binary */static void OutputIntField(char field,int val,Boolean bin, char *form,FILE *file){ fprintf(file,"%c%c",field,bin?'~':'='); if (bin) WriteInt(file,&val,1,TRUE); else fprintf(file,form,val); fprintf(file," ");}/* OutputFloatField: output float as text or binary */static void OutputFloatField(char field,float val,Boolean bin, char *form,FILE *file){ fprintf(file,"%c%c",field,bin?'~':'='); if (bin) WriteFloat(file,&val,1,TRUE); else fprintf(file,form,val); fprintf(file," ");}/* OutputAlign: output models aligned with this arc */static void OutputAlign(LArc *la,int format,FILE *file){ int i; LAlign *lal; fprintf(file,"d=:"); for(i=0,lal=la->lAlign;i<la->nAlign;i++,lal++) { fprintf(file,"%s",lal->label->name); if (format&HLAT_ALDUR) fprintf(file,",%.2f",lal->dur); if (format&HLAT_ALLIKE) fprintf(file,",%.2f",lal->like); fprintf(file,":"); }}/* convert log likelihoods from/to external represnation with specified base. internal representation is ALWAYS natural logs, i.e. base e base = 0.0 no logs base = 1.0 natural logs (no conversion required)*/#define ConvLogLikeFromBase(base, ll) ((base) == 0.0 ? log(ll) : \ (base) == 1.0 ? (ll) : (ll) * log(base))#define ConvLogLikeToBase(base, ll) ((base) == 0.0 ? exp(ll) : \ ((base) == 1.0 ? (ll) : (ll) / log(base)))/* WriteOneLattice: Write a single lattice to file */ReturnStatus WriteOneLattice(Lattice *lat,FILE *file,LatFormat format){ int i, *order, *rorder, st, en; LNode *ln = NULL; LArc *la; /* Rather than return an error assume labels on nodes !! */ order=(int *) New(&gstack, sizeof(int)*(lat->nn<lat->na ? lat->na+1 : lat->nn+1)); rorder=(int *) New(&gstack, sizeof(int)*lat->nn); if (lat->subLatId) fprintf(file,"SUBLAT=%s\n",lat->subLatId->name); fprintf(file,"N=%-4d L=%-5d\n",lat->nn,lat->na); for (i=0;i<lat->nn;i++) order[i]=i; if (!(lat->format&HLAT_SHARC) && !(format&HLAT_NOSORT)) { slat=lat; qsort(order,lat->nn,sizeof(int),QSCmpNodes); } if ((format&HLAT_TIMES) || !(format&HLAT_ALABS)) { for (i=0;i<lat->nn;i++) { ln=lat->lnodes+order[i]; rorder[order[i]]=i; ln->n = i; OutputIntField('I',i,format&HLAT_LBIN,"%-4d",file); if (format&HLAT_TIMES) OutputFloatField('t',ln->time / lat->tscale,format&HLAT_LBIN,"%-5.2f",file); if (!(format&HLAT_ALABS)) { if (ln->word==lat->voc->subLatWord && ln->sublat!=NULL) fprintf(file,"L=%-19s ", ReWriteString(ln->sublat->lat->subLatId->name, NULL,ESCAPE_CHAR)); else if (ln->word!=NULL) { fprintf(file,"W=%-19s ", ReWriteString(ln->word->wordName->name, NULL,ESCAPE_CHAR)); if ((format&HLAT_PRON) && ln->v>=0) OutputIntField('v',ln->v,format&HLAT_LBIN,"%-2d",file); if ((format&HLAT_TAGS) && ln->tag!=NULL) fprintf(file,"s=%-19s ", ReWriteString(ln->tag,NULL,ESCAPE_CHAR)); } else fprintf(file,"W=%-19s ","!NULL"); } fprintf(file,"\n"); } } else for (i=0; i < lat->nn; i++) rorder[order[i]]=i; for (i=0;i<lat->na;i++) order[i]=i; if (!(lat->format&HLAT_SHARC) && !(format&HLAT_NOSORT)) { slat=lat; qsort(order,lat->na,sizeof(int),QSCmpArcs); } for (i=0;i<lat->na;i++) { la=NumbLArc(lat,order[i]); OutputIntField('J',i,format&HLAT_LBIN,"%-5d",file); st=rorder[la->start-lat->lnodes]; en=rorder[la->end-lat->lnodes]; OutputIntField('S',st,format&HLAT_LBIN,"%-4d",file); OutputIntField('E',en,format&HLAT_LBIN,"%-4d",file); if (format&HLAT_ALABS) { if (la->end->word!=NULL) fprintf(file,"W=%-19s ", ReWriteString(la->end->word->wordName->name, NULL,ESCAPE_CHAR)); else fprintf(file,"W=%-19s ","!NULL"); if ((format&HLAT_PRON) && ln->v>=0) OutputIntField('v',la->end->v,format&HLAT_LBIN,"%-2d",file); } if (!(lat->format&HLAT_SHARC) && (format&HLAT_ACLIKE)) OutputFloatField ('a', ConvLogLikeToBase(lat->logbase, la->aclike), format&HLAT_LBIN, "%-9.2f", file); if (format&HLAT_LMLIKE) { if (lat->net==NULL) OutputFloatField('l', ConvLogLikeToBase(lat->logbase, la->lmlike*lat->lmscale+lat->wdpenalty), format&HLAT_LBIN,"%-8.2f",file); else OutputFloatField('l',ConvLogLikeToBase(lat->logbase, la->lmlike), format&HLAT_LBIN, "%-7.3f", file); } if (!(lat->format&HLAT_SHARC) && (format&HLAT_PRLIKE)) OutputFloatField('r', ConvLogLikeToBase(lat->logbase, la->prlike), format&HLAT_LBIN, "%-6.2f", file); if (!(lat->format&HLAT_SHARC) && (format&HLAT_ALIGN) && la->nAlign>0) OutputAlign(la,format,file); fprintf(file,"\n"); } if (lat->subLatId) fprintf(file,".\n\n"); Dispose(&gstack,order); slat=NULL; return(SUCCESS);}/* EXPORT->WriteLattice: Write lattice to file */ReturnStatus WriteLattice(Lattice *lat,FILE *file,LatFormat format){ LabId id; Lattice *list; fprintf(file,"VERSION=%s\n",L_VERSION); if (lat->utterance!=NULL) fprintf(file,"UTTERANCE=%s\n",lat->utterance); if (lat->net!=NULL) { fprintf(file,"lmname=%s\nlmscale=%-6.2f wdpenalty=%-6.2f\n", lat->net,lat->lmscale,lat->wdpenalty); } if (format&HLAT_PRLIKE) fprintf(file,"prscale=%-6.2f\n",lat->prscale); if (format&HLAT_ACLIKE) fprintf(file,"acscale=%-6.2f\n",lat->acscale); if (lat->vocab!=NULL) fprintf(file,"vocab=%s\n",lat->vocab); if (lat->hmms!=NULL) fprintf(file,"hmms=%s\n",lat->hmms); if (lat->logbase != 1.0) fprintf(file,"base=%f\n",lat->logbase); if (lat->tscale != 1.0) fprintf(file,"tscale=%f\n",lat->tscale); /* First write all subsidiary sublattices */ if (lat->subList!=NULL && !(format&HLAT_NOSUBS)) { /* Set all chain fields to NULL */ lat->chain=NULL; SubLatList(lat,NULL,1); /* Set chain fields to make linked list */ lat->chain=lat; list=SubLatList(lat,lat,1); /* Disconnect loop */ list->chain=NULL; for (list=lat->chain;list!=NULL;list=list->chain) { if (list->subLatId==NULL){ HRError(8253,"WriteLattice: Sublats must be labelled"); return(FAIL); } if(WriteOneLattice(list,file,format)<SUCCESS){ return(FAIL); } } } id=lat->subLatId; lat->subLatId=NULL; if(WriteOneLattice(lat,file,format)<SUCCESS){ return(FAIL); } lat->subLatId=id; return(SUCCESS);}/* ------------------------ Lattice Input ------------------------- */typedef enum {UNK_FIELD, STR_FIELD, INT_FIELD, FLT_FIELD} LatFieldType;/* CheckStEndNodes: lattice must only have one start and one end node */static ReturnStatus CheckStEndNodes(Lattice *lat){ int i,st,en; NodeId ln; st=en=0; for(i=0,ln=lat->lnodes;i<lat->nn;i++,ln++){ if (ln->pred==NARC) ++st; if (ln->foll==NARC) ++en; } if (st != 1){ HRError(-8252,"CheckStEndNodes: lattice has %d start nodes",st); return(FAIL); } if (en != 1){ HRError(-8252,"CheckStEndNodes: lattice has %d end nodes",en); return(FAIL); } return(SUCCESS);}/* GetNextFieldName: put field name into buf and delimiter into del */static char *GetNextFieldName(char *buf, char *del, Source *src){ int ch,i; char *ptr; buf[0]=0; ch=GetCh(src); while (isspace(ch) && ch!='\n') ch=GetCh(src); if (ch==EOF) { ptr=NULL; } else if (ch=='\n') { buf[0]='\n';buf[1]=0;ptr=buf; } else if (!isalnum(ch) && ch != '.') { if (ch!='#') HError(8250,"GetNextFieldName: Field name expected"); while (ch!='\n' && ch!=EOF) ch=GetCh(src); buf[0]='\n';buf[1]=0;ptr=buf; } else if (ch != '.') { i=0; while(isalnum(ch)) { buf[i++]=ch; ch=GetCh(src); if (ch==EOF) HError(8250,"GetNextFieldName: EOF whilst reading field name"); } buf[i]=0; if (ch!='=' && ch!='~') HError(8250,"GetNextFieldName: Field delimiter expected %s|%c|",buf,ch); *del=ch; ptr=buf; } else { buf[0]='.';buf[1]=0;ptr=buf; } return(ptr);} /* GetFieldValue: into buf and return type */static LatFieldType GetFieldValue(char *buf, Source *src, int buflen){ static char tmp[MAXSTRLEN*10]; int ch; ch=GetCh(src); if (isspace(ch) || ch==EOF) HError(8250,"GetFieldValue: Field value expected"); UnGetCh(ch,src); if (buf==NULL) ReadStringWithLen(src,tmp,MAXSTRLEN*10); else if(!buflen) ReadString(src,buf); else ReadStringWithLen(src,buf,buflen); if (src->wasQuoted) return(STR_FIELD); else return(UNK_FIELD);}/* ParseNumber: if buf is number convert it and return in rval */static LatFieldType ParseNumber(double *rval,char *buf){ char *ptr; double val; LatFieldType type; type=STR_FIELD; if (isdigit((int) buf[0]) || ((buf[0]=='-' || buf[0]=='+') && isdigit((int) buf[1]))) { val=strtod(buf,&ptr); if (ptr != buf) { type=INT_FIELD; if (strchr(buf,'.') != NULL) { type=FLT_FIELD; *rval=val; } else *rval=val; } } return(type);}/* GetIntField: return integer field */static int GetIntField(char ntype,char del,char *vbuf,Source *src){ int vtype,iv; double rv; int fldtype; if (del=='=') { if ((vtype=GetFieldValue(vbuf,src,0))==STR_FIELD) HError(8250,"GetIntField: %c field expects numeric value (%s)", ntype,vbuf); if ((fldtype = ParseNumber(&rv,vbuf))!=INT_FIELD) HError(8250,"GetIntField: %c field expects integer value (%s==%d)", ntype,vbuf,fldtype); } else { if (!ReadInt(src,&iv,1,TRUE)) HError(8250,"GetIntField: Could not read integer for %c field",ntype); rv=iv; } return((int)rv);}/* GetFltField: return float field */static double GetFltField(char ntype,char del,char *vbuf,Source *src){ int vtype; double rv; float fv; if (del=='=') { if ((vtype=GetFieldValue(vbuf,src,0))==STR_FIELD) HError(8250,"GetFltField: %c field expects numeric value (%s)",ntype,vbuf); if (ParseNumber(&rv,vbuf)==STR_FIELD) HError(8250,"GetFltField: %c field expects numeric value (%s)",ntype,vbuf); } else { if (!(ReadFloat(src,&fv,1,TRUE))) HError(8250,"GetFltField: Could not read float for %c field",ntype); rv=fv; } return(rv);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -