void doConstrainedMaxCScores(List<String> sentence,Grammar grammar,SophisticatedLexicon lexicon){
  numSubStatesArray=grammar.numSubStates;
  maxcScore=new double[length][length + 1][numStates];
  maxcSplit=new int[length][length + 1][numStates];
  maxcChild=new int[length][length + 1][numStates];
  maxcLeftChild=new int[length][length + 1][numStates];
  maxcRightChild=new int[length][length + 1][numStates];
  double threshold=1.0e-2;
  double logNormalizer=iScorePostU[0][length][0][0];
  double thresh2=threshold * logNormalizer;
  for (int diff=1; diff <= length; diff++) {
    for (int start=0; start < (length - diff + 1); start++) {
      int end=start + diff;
      Arrays.fill(maxcSplit[start][end],-1);
      Arrays.fill(maxcChild[start][end],-1);
      Arrays.fill(maxcLeftChild[start][end],-1);
      Arrays.fill(maxcRightChild[start][end],-1);
      if (diff > 1) {
        for (int pState=0; pState < numSubStatesArray.length; pState++) {
          if (oScorePostU[start][end][pState] == null) {
            continue;
          }
          BinaryRule[] parentRules=grammar.splitRulesWithP(pState);
          int nParentStates=numSubStatesArray[pState];
          for (int i=0; i < parentRules.length; i++) {
            BinaryRule r=parentRules[i];
            int lState=r.leftChildState;
            int rState=r.rightChildState;
            int narrowR=narrowRExtent[start][lState];
            boolean iPossibleL=(narrowR < end);
            if (!iPossibleL) {
              continue;
            }
            int narrowL=narrowLExtent[end][rState];
            boolean iPossibleR=(narrowL >= narrowR);
            if (!iPossibleR) {
              continue;
            }
            int min1=narrowR;
            int min2=wideLExtent[end][rState];
            int min=(min1 > min2 ? min1 : min2);
            if (min > narrowL) {
              continue;
            }
            int max1=wideRExtent[start][lState];
            int max2=narrowL;
            int max=(max1 < max2 ? max1 : max2);
            if (min > max) {
              continue;
            }
            double[][][] scores=r.getScores2();
            int nLeftChildStates=numSubStatesArray[lState];
            int nRightChildStates=numSubStatesArray[rState];
            for (int split=min; split <= max; split++) {
              double ruleScore=0;
              if (iScorePostU[start][split][lState] == null)               continue;
              if (iScorePostU[split][end][rState] == null)               continue;
              for (int lp=0; lp < nLeftChildStates; lp++) {
                double lIS=iScorePostU[start][split][lState][lp];
                if (lIS < thresh2)                 continue;
                for (int rp=0; rp < nRightChildStates; rp++) {
                  if (scores[lp][rp] == null)                   continue;
                  double rIS=iScorePostU[split][end][rState][rp];
                  if (rIS < thresh2)                   continue;
                  for (int np=0; np < nParentStates; np++) {
                    double pOS=oScorePostU[start][end][pState][np];
                    if (pOS < thresh2)                     continue;
                    double ruleS=scores[lp][rp][np];
                    if (ruleS == 0)                     continue;
                    ruleScore+=(pOS * ruleS * lIS* rIS) / logNormalizer;
                  }
                }
              }
              double scale=1.0;
              double leftChildScore=maxcScore[start][split][lState];
              double rightChildScore=maxcScore[split][end][rState];
              double gScore=ruleScore * leftChildScore * rightChildScore* scale;
              if (gScore > maxcScore[start][end][pState]) {
                maxcScore[start][end][pState]=gScore;
                maxcSplit[start][end][pState]=split;
                maxcLeftChild[start][end][pState]=lState;
                maxcRightChild[start][end][pState]=rState;
              }
            }
          }
        }
      }
 else {
        for (int tag=0; tag < numSubStatesArray.length; tag++) {
          if (allowedSubStates[start][end][tag] == null)           continue;
          int nTagStates=numSubStatesArray[tag];
          String word=sentence.get(start);
          if (grammar.isGrammarTag(tag))           continue;
          double[] lexiconScoreArray=lexicon.score(word,(short)tag,start,false,false);
          double lexiconScores=0;
          for (int tp=0; tp < nTagStates; tp++) {
            double pOS=oScorePostU[start][end][tag][tp];
            if (pOS < thresh2)             continue;
            double ruleS=lexiconScoreArray[tp];
            lexiconScores+=(pOS * ruleS) / logNormalizer;
          }
          double scale=1.0;
          maxcScore[start][end][tag]=lexiconScores * scale;
        }
      }
      double[] maxcScoreStartEnd=new double[numStates];
      for (int i=0; i < numStates; i++) {
        maxcScoreStartEnd[i]=maxcScore[start][end][i];
      }
      for (int pState=0; pState < numSubStatesArray.length; pState++) {
        if (oScorePostU[start][end][pState] == null) {
          continue;
        }
        UnaryRule[] unaries=grammar.getClosedSumUnaryRulesByParent(pState);
        int nParentStates=numSubStatesArray[pState];
        for (int r=0; r < unaries.length; r++) {
          UnaryRule ur=unaries[r];
          int cState=ur.childState;
          if ((pState == cState))           continue;
          if (iScorePostU[start][end][cState] == null)           continue;
          double[][] scores=ur.getScores2();
          int nChildStates=numSubStatesArray[cState];
          double ruleScore=0;
          for (int cp=0; cp < nChildStates; cp++) {
            double cIS=iScorePreU[start][end][cState][cp];
            if (cIS < thresh2)             continue;
            if (scores[cp] == null)             continue;
            for (int np=0; np < nParentStates; np++) {
              double pOS=oScorePreU[start][end][pState][np];
              if (pOS < thresh2)               continue;
              double ruleS=scores[cp][np];
              if (ruleS == 0)               continue;
              ruleScore+=(pOS * ruleS * cIS) / logNormalizer;
            }
          }
          double scale=1.0;
          double childScore=maxcScore[start][end][cState];
          double gScore=ruleScore / unaryPenalty * childScore * scale;
          if (gScore > maxcScoreStartEnd[pState]) {
            maxcScoreStartEnd[pState]=gScore;
            maxcChild[start][end][pState]=cState;
          }
        }
      }
      maxcScore[start][end]=maxcScoreStartEnd;
    }
  }
}

void doConstrainedMaxCScores ( List < String > sentence , Grammar grammar , SophisticatedLexicon lexicon ) { numSubStatesArray = grammar . numSubStates ; maxcScore = new double [ length ] [ length + 1 ] [ numStates ] ; maxcSplit = new int [ length ] [ length + 1 ] [ numStates ] ; maxcChild = new int [ length ] [ length + 1 ] [ numStates ] ; maxcLeftChild = new int [ length ] [ length + 1 ] [ numStates ] ; maxcRightChild = new int [ length ] [ length + 1 ] [ numStates ] ; double threshold = 1.0e-2 ; double logNormalizer = iScorePostU [ 0 ] [ length ] [ 0 ] [ 0 ] ; double thresh2 = threshold * logNormalizer ; for ( int diff = 1 ; diff <= length ; diff ++ ) { for ( int start = 0 ; start < ( length - diff + 1 ) ; start ++ ) { int end = start + diff ; Arrays . fill ( maxcSplit [ start ] [ end ] , - 1 ) ; Arrays . fill ( maxcChild [ start ] [ end ] , - 1 ) ; Arrays . fill ( maxcLeftChild [ start ] [ end ] , - 1 ) ; Arrays . fill ( maxcRightChild [ start ] [ end ] , - 1 ) ; if ( diff > 1 ) { for ( int pState = 0 ; pState < numSubStatesArray . length ; pState ++ ) { if ( oScorePostU [ start ] [ end ] [ pState ] == null ) { continue ; } BinaryRule [ ] parentRules = grammar . splitRulesWithP ( pState ) ; int nParentStates = numSubStatesArray [ pState ] ; for ( int i = 0 ; i < parentRules . length ; i ++ ) { BinaryRule r = parentRules [ i ] ; int lState = r . leftChildState ; int rState = r . rightChildState ; int narrowR = narrowRExtent [ start ] [ lState ] ; boolean iPossibleL = ( narrowR < end ) ; if ( ! iPossibleL ) { continue ; } int narrowL = narrowLExtent [ end ] [ rState ] ; boolean iPossibleR = ( narrowL >= narrowR ) ; if ( ! iPossibleR ) { continue ; } int min1 = narrowR ; int min2 = wideLExtent [ end ] [ rState ] ; int min = ( min1 > min2 ? min1 : min2 ) ; if ( min > narrowL ) { continue ; } int max1 = wideRExtent [ start ] [ lState ] ; int max2 = narrowL ; int max = ( max1 < max2 ? max1 : max2 ) ; if ( min > max ) { continue ; } double [ ] [ ] [ ] scores = r . getScores2 ( ) ; int nLeftChildStates = numSubStatesArray [ lState ] ; int nRightChildStates = numSubStatesArray [ rState ] ; for ( int split = min ; split <= max ; split ++ ) { double ruleScore = 0 ; if ( iScorePostU [ start ] [ split ] [ lState ] == null ) continue ; if ( iScorePostU [ split ] [ end ] [ rState ] == null ) continue ; for ( int lp = 0 ; lp < nLeftChildStates ; lp ++ ) { double lIS = iScorePostU [ start ] [ split ] [ lState ] [ lp ] ; if ( lIS < thresh2 ) continue ; for ( int rp = 0 ; rp < nRightChildStates ; rp ++ ) { if ( scores [ lp ] [ rp ] == null ) continue ; double rIS = iScorePostU [ split ] [ end ] [ rState ] [ rp ] ; if ( rIS < thresh2 ) continue ; for ( int np = 0 ; np < nParentStates ; np ++ ) { double pOS = oScorePostU [ start ] [ end ] [ pState ] [ np ] ; if ( pOS < thresh2 ) continue ; double ruleS = scores [ lp ] [ rp ] [ np ] ; if ( ruleS == 0 ) continue ; ruleScore += ( pOS * ruleS * lIS * rIS ) / logNormalizer ; } } } double scale = 1.0 ; double leftChildScore = maxcScore [ start ] [ split ] [ lState ] ; double rightChildScore = maxcScore [ split ] [ end ] [ rState ] ; double gScore = ruleScore * leftChildScore * rightChildScore * scale ; if ( gScore > maxcScore [ start ] [ end ] [ pState ] ) { maxcScore [ start ] [ end ] [ pState ] = gScore ; maxcSplit [ start ] [ end ] [ pState ] = split ; maxcLeftChild [ start ] [ end ] [ pState ] = lState ; maxcRightChild [ start ] [ end ] [ pState ] = rState ; } } } } } else { for ( int tag = 0 ; tag < numSubStatesArray . length ; tag ++ ) { if ( allowedSubStates [ start ] [ end ] [ tag ] == null ) continue ; int nTagStates = numSubStatesArray [ tag ] ; String word = sentence . get ( start ) ; if ( grammar . isGrammarTag ( tag ) ) continue ; double [ ] lexiconScoreArray = lexicon . score ( word , ( short ) tag , start , false , false ) ; double lexiconScores = 0 ; for ( int tp = 0 ; tp < nTagStates ; tp ++ ) { double pOS = oScorePostU [ start ] [ end ] [ tag ] [ tp ] ; if ( pOS < thresh2 ) continue ; double ruleS = lexiconScoreArray [ tp ] ; lexiconScores += ( pOS * ruleS ) / logNormalizer ; } double scale = 1.0 ; maxcScore [ start ] [ end ] [ tag ] = lexiconScores * scale ; } } double [ ] maxcScoreStartEnd = new double [ numStates ] ; for ( int i = 0 ; i < numStates ; i ++ ) { maxcScoreStartEnd [ i ] = maxcScore [ start ] [ end ] [ i ] ; } for ( int pState = 0 ; pState < numSubStatesArray . length ; pState ++ ) { if ( oScorePostU [ start ] [ end ] [ pState ] == null ) { continue ; } UnaryRule [ ] unaries = grammar . getClosedSumUnaryRulesByParent ( pState ) ; int nParentStates = numSubStatesArray [ pState ] ; for ( int r = 0 ; r < unaries . length ; r ++ ) { UnaryRule ur = unaries [ r ] ; int cState = ur . childState ; if ( ( pState == cState ) ) continue ; if ( iScorePostU [ start ] [ end ] [ cState ] == null ) continue ; double [ ] [ ] scores = ur . getScores2 ( ) ; int nChildStates = numSubStatesArray [ cState ] ; double ruleScore = 0 ; for ( int cp = 0 ; cp < nChildStates ; cp ++ ) { double cIS = iScorePreU [ start ] [ end ] [ cState ] [ cp ] ; if ( cIS < thresh2 ) continue ; if ( scores [ cp ] == null ) continue ; for ( int np = 0 ; np < nParentStates ; np ++ ) { double pOS = oScorePreU [ start ] [ end ] [ pState ] [ np ] ; if ( pOS < thresh2 ) continue ; double ruleS = scores [ cp ] [ np ] ; if ( ruleS == 0 ) continue ; ruleScore += ( pOS * ruleS * cIS ) / logNormalizer ; } } double scale = 1.0 ; double childScore = maxcScore [ start ] [ end ] [ cState ] ; double gScore = ruleScore / unaryPenalty * childScore * scale ; if ( gScore > maxcScoreStartEnd [ pState ] ) { maxcScoreStartEnd [ pState ] = gScore ; maxcChild [ start ] [ end ] [ pState ] = cState ; } } } maxcScore [ start ] [ end ] = maxcScoreStartEnd ; } } }
assumes that inside and outside scores ( sum version , not viterbi ) have been computed . in particular , the narrowrextent and other arrays need not be updated .
