private float wittenBell(int[] ngram,int ngramOrder){
  int end=ngram.length;
  double p=p0;
  int MAX_QCOUNT=getCount(ngram,ngram.length - 1,ngram.length,maxQ);
  if (MAX_QCOUNT == 0)   return (float)p;
  double pML=Math.log(unQuantize(MAX_QCOUNT)) - numTokens;
  p=logAdd(p,(lambda0 + pML));
  if (ngram.length == 1) {
    return (float)p;
  }
  for (int i=end - 2; i >= end - ngramOrder && i >= 0; i--) {
    int historyCnt=getCount(ngram,i,end,MAX_QCOUNT);
    if (historyCnt == 0) {
      return (float)p;
    }
    int historyTypesAfter=getTypesAfter(ngram,i,end,historyCnt);
    double HC=unQuantize(historyCnt);
    double HTA=1 + unQuantize(historyTypesAfter);
    double lambda=Math.log(HTA) - Math.log(HTA + HC);
    double oneMinusLambda=Math.log(HC) - Math.log(HTA + HC);
    p+=oneMinusLambda;
    int wordCount=getCount(ngram,i + 1,end,historyTypesAfter);
    double WC=unQuantize(wordCount);
    if (WC == 0)     return (float)p;
    p=logAdd(p,lambda + Math.log(WC) - Math.log(HC));
    MAX_QCOUNT=wordCount;
  }
  return (float)p;
}

private float wittenBell ( int [ ] ngram , int ngramOrder ) { int end = ngram . length ; double p = p0 ; int MAX_QCOUNT = getCount ( ngram , ngram . length - 1 , ngram . length , maxQ ) ; if ( MAX_QCOUNT == 0 ) return ( float ) p ; double pML = Math . log ( unQuantize ( MAX_QCOUNT ) ) - numTokens ; p = logAdd ( p , ( lambda0 + pML ) ) ; if ( ngram . length == 1 ) { return ( float ) p ; } for ( int i = end - 2 ; i >= end - ngramOrder && i >= 0 ; i -- ) { int historyCnt = getCount ( ngram , i , end , MAX_QCOUNT ) ; if ( historyCnt == 0 ) { return ( float ) p ; } int historyTypesAfter = getTypesAfter ( ngram , i , end , historyCnt ) ; double HC = unQuantize ( historyCnt ) ; double HTA = 1 + unQuantize ( historyTypesAfter ) ; double lambda = Math . log ( HTA ) - Math . log ( HTA + HC ) ; double oneMinusLambda = Math . log ( HC ) - Math . log ( HTA + HC ) ; p += oneMinusLambda ; int wordCount = getCount ( ngram , i + 1 , end , historyTypesAfter ) ; double WC = unQuantize ( wordCount ) ; if ( WC == 0 ) return ( float ) p ; p = logAdd ( p , lambda + Math . log ( WC ) - Math . log ( HC ) ) ; MAX_QCOUNT = wordCount ; } return ( float ) p ; }
calculates the linearly - interpolated witten - bell probability for a given ngram . this is calculated as : p ( w | h ) = pml ( w | h ) l ( h ) - ( 1 - l ( h ) ) p ( w | h ' ) where : w is a word and h is a history h ' is the history h with the first word removed pml is the maximum - likelihood estimate of the probability l ( . ) is lambda , the interpolation factor , which depends only on the history h : l ( h ) = s ( h ) / s ( h ) + c ( h ) where s ( . ) is the observed number of distinct types after h , and c is the observed number of counts of h in the training corpus . < p > in fact this model calculates the probability starting from the lowest order and working its way up , to take advantage of the one - sided error rate inherent in using a bloom filter data structure .
