protected double estimateProb(ProbabilityStructure probStructure, TrainerEvent event) { ProbabilityStructure structure = probStructure; if (Debug.level >= 20) { System.err.println(structureClassName + "\n\t" + event); }   int highestCachedLevel = numLevels; int lastLevel = numLevels - 1;  double[] lambdas = structure.lambdas; double[] estimates = structure.estimates;  for (int level = 0; level < numLevels; level++) { Transition transition = structure.getTransition(event, level); Event history = transition.history();   if (useCache) { cacheAccesses[level]++; if (Debug.level >= 21) { System.err.print("level " + level + ": getting cached  P"); } MapToPrimitive.Entry cacheProbEntry = cache[level].getProb(transition); if (cacheProbEntry != null) { if (Debug.level >= 21) { System.err.println(cacheProbEntry); } estimates[level] = cacheProbEntry.getDoubleValue(); cacheHits[level]++; highestCachedLevel = level; break; } else { if (Debug.level >= 21) { System.err.print(transition); System.err.println("=null"); } } } CountsTrio trio = counts[level]; MapToPrimitive.Entry histEntry = trio.history().getEntry(history); double historyCount = (histEntry == null ? 0.0 : histEntry.getDoubleValue(CountsTrio.hist)); double transitionCount = trio.transition().count(transition); double diversityCount = (histEntry == null ? 0.0 : histEntry.getDoubleValue(CountsTrio.diversity));  double lambda, estimate; double fudge = lambdaFudge[level]; double fudgeTerm = lambdaFudgeTerm[level]; if (useSmoothingParams) { MapToPrimitive.Entry smoothingParamEntry = smoothingParams[level].getEntry(history); if (smoothingParamEntry != null && historyCount > 0) { lambda = smoothingParamEntry.getDoubleValue(); estimate = transitionCount / historyCount; } else { if (warnSmoothingHasHistoryNotInTraining && smoothingParamEntry != null) System.err.println(structureClassName + ": warning: smoothing parameter exists for a " + "history not seen in training: " + history); lambda = lambdaPenalty[level]; estimate = 0; } } else if (historyCount == 0) { lambda = lambdaPenalty[level]; estimate = 0; } else {  lambda = ((!deficientEstimation && level == lastLevel) ? 1.0 : historyCount / (historyCount + fudgeTerm + fudge * diversityCount));  estimate = transitionCount / historyCount; }  if (Debug.level >= 20) { for (int i = 0; i < level; i++) System.err.print("  ");  System.err.println(transitionCount + "    " + historyCount + "    " + diversityCount + "    " + lambda + "    " + estimate); }  lambdas[level] = lambda; estimates[level] = estimate;  } double prob = Constants.probImpossible; if (useCache) { prob = (highestCachedLevel == numLevels ? Constants.probImpossible : estimates[highestCachedLevel]); } for (int level = highestCachedLevel - 1; level >= 0; level--) { double lambda = lambdas[level]; double estimate = estimates[level]; prob = lambda * estimate + ((1 - lambda) * prob); if (useCache  && prob > Constants.probImpossible) { Transition transition = structure.transitions[level]; if (Debug.level >= 21) { System.err.println("adding P" + transition + " = " + prob + " to cache at level " + level); }  putInCache: if (!cache[level].containsKey(transition)) { numCacheAdds++; Transition canonTrans = (Transition)canonicalEvents.get(transition); if (canonTrans != null) { cache[level].put(canonTrans, prob); numCanonicalHits++; } else {  Event transHist = transition.history(); Event transFuture = transition.future(); Event hist = (Event)canonicalEvents.get(transHist); if (hist == null) {  hist = transHist.copy();  } else { numCanonicalHits++;  } Event future = (Event)canonicalEvents.get(transFuture); if (future == null) {  future = transFuture.copy();  } else { numCanonicalHits++;  } cache[level].put(new Transition(future, hist), prob);  } } } }   return prob;
public double estimateProb(int id, TrainerEvent event) { if (precomputeProbs) throw new UnsupportedOperationException("precomputed probs are in log-space"); ProbabilityStructure clientStructure = getClientProbStructure(id); return estimateProb(clientStructure, event);
  protected double estimateProb(ProbabilityStructure probStructure,				TrainerEvent event) {    ProbabilityStructure structure = probStructure;    if (Debug.level >= 20) {      System.err.println(structureClassName + "\n\t" + event);    }    /*    if (useCache) {      Double cacheProb = topLevelCache.getProb(event);      if (cacheProb != null)	return cacheProb.doubleValue();    }    */    int highestCachedLevel = numLevels;    int lastLevel = numLevels - 1;    double[] lambdas = structure.lambdas;    double[] estimates = structure.estimates;    //structure.prevHistCount = 0;    for (int level = 0; level < numLevels; level++) {      Transition transition = structure.getTransition(event, level);      Event history = transition.history();      // check cache here!!!!!!!!!!!!      if (useCache) {	cacheAccesses[level]++;	if (Debug.level >= 21) {	  System.err.print("level " + level + ": getting cached  P");	}	MapToPrimitive.Entry cacheProbEntry = cache[level].getProb(transition);	if (cacheProbEntry != null) {	  if (Debug.level >= 21) {	    System.err.println(cacheProbEntry);	  }	  estimates[level] = cacheProbEntry.getDoubleValue();	  cacheHits[level]++;	  highestCachedLevel = level;	  break;	}	else {	  if (Debug.level >= 21) {	    System.err.print(transition);	    System.err.println("=null");	  }	}      }      CountsTrio trio = counts[level];      MapToPrimitive.Entry histEntry = trio.history().getEntry(history);      double historyCount = (histEntry == null ? 0.0 :			     histEntry.getDoubleValue(CountsTrio.hist));      double transitionCount = trio.transition().count(transition);      double diversityCount = (histEntry == null ? 0.0 :			       histEntry.getDoubleValue(CountsTrio.diversity));      double lambda, estimate; //, adjustment = 1.0;      double fudge = lambdaFudge[level];      double fudgeTerm = lambdaFudgeTerm[level];      if (useSmoothingParams) {        MapToPrimitive.Entry smoothingParamEntry =          smoothingParams[level].getEntry(history);        if (smoothingParamEntry != null && historyCount > 0) {          lambda = smoothingParamEntry.getDoubleValue();	  estimate = transitionCount / historyCount;	}	else {	  if (warnSmoothingHasHistoryNotInTraining &&	      smoothingParamEntry != null)	    System.err.println(structureClassName +			       ": warning: smoothing parameter exists for a " +			       "history not seen in training: " + history);	  lambda = lambdaPenalty[level];	  estimate = 0;	}      }      else if (historyCount == 0) {	lambda = lambdaPenalty[level];	estimate = 0;      }      else {	/*	if (structure.prevHistCount <= historyCount)	  adjustment = 1 - structure.prevHistCount / historyCount;	*/	lambda = ((!deficientEstimation && level == lastLevel) ? 1.0 :		  historyCount /		  (historyCount + fudgeTerm + fudge * diversityCount));	  //adjustment * (historyCount / (historyCount + fudge * diversityCount));	estimate = transitionCount / historyCount;      }      if (Debug.level >= 20) {	for (int i = 0; i < level; i++)	  System.err.print("  ");	/*	System.err.println(transitionCount + "    " +			   historyCount + "    " + diversityCount + "    " +			   adjustment + "    " + estimate);	*/	System.err.println(transitionCount + "    " +			   historyCount + "    " + diversityCount + "    " +			   lambda + "    " + estimate);      }      lambdas[level] = lambda;      estimates[level] = estimate;      //structure.prevHistCount = historyCount;    }    double prob = Constants.probImpossible;    if (useCache) {      prob = (highestCachedLevel == numLevels ?	      Constants.probImpossible : estimates[highestCachedLevel]);    }    for (int level = highestCachedLevel - 1; level >= 0; level--) {      double lambda = lambdas[level];      double estimate = estimates[level];      prob = lambda * estimate + ((1 - lambda) * prob);      if (useCache  && prob > Constants.probImpossible) {	Transition transition = structure.transitions[level];	if (Debug.level >= 21) {	  System.err.println("adding P" + transition + " = " + prob +			     " to cache at level " + level);	}	putInCache:	if (!cache[level].containsKey(transition)) {	  numCacheAdds++;	  Transition canonTrans = (Transition)canonicalEvents.get(transition);	  if (canonTrans != null) {	    cache[level].put(canonTrans, prob);	    numCanonicalHits++;	  }	  else {	    // don't want to copy history and future if we don't have to	    Event transHist = transition.history();	    Event transFuture = transition.future();	    Event hist = (Event)canonicalEvents.get(transHist);	    if (hist == null) {	      //break putInCache;	      hist = transHist.copy();	      //System.err.println("no hit: " + hist);	    }	    else {	      numCanonicalHits++;	      //System.err.println("hit: " + hist);	    }	    Event future = (Event)canonicalEvents.get(transFuture);	    if (future == null) {	      //break putInCache;	      future = transFuture.copy();	      //System.err.println("no hit: " + future);	    }	    else {	      numCanonicalHits++;	      //System.err.println("hit: " + future);	    }	    cache[level].put(new Transition(future, hist), prob);	    //cache[level].put(transition.copy(), prob);	  }	}      }    }    /*    if (useCache && prob > Constants.logOfZero) {      if (!topLevelCache.containsKey(event))	topLevelCache.put(event.copy(), prob);    }    */    return prob;  }