/*************************************************************************** * This file is part of the 'Shout LVCS Recognition toolkit'. * *************************************************************************** * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 by Marijn Huijbregts * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; version 2 of the License. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "standard.h" #include "nbest.h" ///////////////////////////////////////////////////////////////////////////////////////////////////// /// The constructor will create the N-Best list structure. The original WLR strings are flatten. /// For each sentence occurence, the one with the best AM score is retained, duplicates are removed. ///////////////////////////////////////////////////////////////////////////////////////////////////// NBest::NBest(WLRType *path, char **voc, int stS, LanguageModel *lm, double orgLm, double orgTrP) { // Parameter initialisation: admin = NULL; languageModel = lm; vocabulary = voc; startOfSentenceWord = stS; org_LmScale = orgLm; org_transPenalty = orgTrP; int nrOfPaths = 1; // Get the size of the initial NBest matrix: int length = getNBestArraySize(path,&nrOfPaths); length++; // for the extra parameter at the end of each sentence: path to parent and index at parent... // Create the first (temporary) matrix and initialise: NBestType nbestArray[length*nrOfPaths]; for(int a = 0;agetP(nbestArray[keyDest].wordID,hist,hist); } keyDest++; keySource++; } } nbestArray[keyDest].wordID = -5555; } adminLength = 0; /// \todo Do we need to check which duplicate is the best? // Now remove duplicates: for(int a=0;ausedAt = -4; res = fillNBestArray(w->previous,array,nr, emptyNr, length); // Now for myself: if(w->timeStamp >= 0) { if(w->isSil) { array[*nr+res].wordID = startOfSentenceWord; array[*nr+res].LM = 0; array[*nr+res].AM = w->COMBlikelihood - w->previous->COMBlikelihood; } else { int dummy[LM_NGRAM_DEPTH]; array[*nr+res].wordID = languageModel->getLastWordID(w->lmHistory); array[*nr+res].LM = languageModel->getP(array[*nr+res].wordID,w->previous->lmHistory,dummy)*org_LmScale - org_transPenalty; array[*nr+res].AM = (w->COMBlikelihood - w->previous->COMBlikelihood) - array[*nr+res].LM; } res++; array[*nr+res].wordID = -5555; // Now the alternatives: int parentNr = *nr; for(int i=0;inBest[i] != NULL && w->nBest[i]->usedAt != -4) { *nr = *emptyNr; *emptyNr += length; int a = fillNBestArray(w->nBest[i],array,nr,emptyNr,length); array[*nr+a].wordID = -1*(parentNr+res); } } *nr = parentNr; } } return res; } ///////////////////////////////////////////////////////////////////////////////////////////////////// /// This method will determine how many words the longest path in the N-Best list contains and /// how big N is (nrOfPaths, unfiltered) ///////////////////////////////////////////////////////////////////////////////////////////////////// int NBest::getNBestArraySize(WLRType *w, int *nrOfPaths) { int res = 0; if(w != NULL) { res = getNBestArraySize(w->previous,nrOfPaths); if(w->timeStamp >= 0) { res++; w->usedAt = -8; for(int i=0;inBest[i] != NULL && w->nBest[i]->usedAt != -8) { (*nrOfPaths)++; int r2 = getNBestArraySize(w->nBest[i],nrOfPaths); if(r2 > res) { res = r2; } } } } } return res; } ///////////////////////////////////////////////////////////////////////////////////////////////////// /// Sets a reference hypothese. ///////////////////////////////////////////////////////////////////////////////////////////////////// void NBest::setReference(WLRType *w) { reference.nrWords = 0; reference.noSilWords = 0; reference.totAM = 0.0; reference.totLM = 0.0; while(w != NULL) { if(w->timeStamp >= 0) { if(w->isSil) { reference.totAM += (w->COMBlikelihood - w->previous->COMBlikelihood); } else { int dummy[LM_NGRAM_DEPTH]; float lm = languageModel->getP(languageModel->getLastWordID(w->lmHistory),w->previous->lmHistory,dummy)*org_LmScale - org_transPenalty; reference.totLM += lm; reference.totAM += (w->COMBlikelihood - w->previous->COMBlikelihood - lm); reference.noSilWords++; } reference.nrWords++; } w = w->previous; } reference.totLM = (reference.totLM+org_transPenalty*reference.noSilWords)/org_LmScale; } ///////////////////////////////////////////////////////////////////////////////////////////////////// /// Calculates the score of the reference with LM-scale lmScale.. ///////////////////////////////////////////////////////////////////////////////////////////////////// int NBest::getScore(float lmScale, float transPenalty) { for(int i=0;i target && !admin[i].processed) { bestI = i; admin[i].processed = true; } i++; } return (bestI != -1); } ///////////////////////////////////////////////////////////////////////////////////////////////////// /// Print the N-Best hypothesis (N == max) ///////////////////////////////////////////////////////////////////////////////////////////////////// void NBest::print(int max) { int count = 0; for(int i=0;i bestScore && !admin[i].processed) { bestScore = score; bestI = i; } } if(bestI >= 0) { admin[bestI].processed = true; for(int a=0;a