public void testPosteriorMatrixIterator() throws Exception {
    for (int trial = 0; trial < 100; trial++) {
      this.setup(0);
      Debug.pl(" trial " + trial);
      final float[][][] fMatrix = this.forwardMatrix();
      final float[][][] bMatrix = this.backwardMatrix();
      final float[][][] pM = this.sumForwardBackwardMatrices(fMatrix, bMatrix);
      float total = Float.NEGATIVE_INFINITY;
      for (int i = 0; i < this.stateNumber; i++) {
        total = Maths.logAdd(total, pM[0][0][i]);
      }
      final float[] holdingDiagonalValues = new float[10000];
      final float[] diagonalValues = new float[10000], reverseDiagonalValues = new float[10000];
      final FloatStack floatStack = new FloatStack(10000);
      Arrays.fill(holdingDiagonalValues, Float.NEGATIVE_INFINITY);
      for (int i = 0; i < this.stateNumber; i++) {
        holdingDiagonalValues[this.stateNumber + i] = this.startStates[i];
      }

      final Function_Index fn = this.getExtendedPolygonIterator();
      fn.fn(0);
      final IntStack iS = new IntStack(1000);
      final ForwardBackwardMatrixIter.AlignmentGenerator aG =
          new ForwardBackwardMatrixIter.AlignmentGenerator(
              this.stateNumber, 0, Float.NEGATIVE_INFINITY, floatStack, iS);
      final ForwardBackwardMatrixIter fBMI =
          new ForwardBackwardMatrixIter(
              fn,
              this.stateNumber,
              0,
              0,
              0,
              holdingDiagonalValues,
              diagonalValues,
              reverseDiagonalValues,
              this.endStates,
              this.setCellsForwardsLL,
              this.setCellsBackwardsLL,
              this.setCellsForwardsL,
              this.setCellsForwardsR,
              this.setCellsBackwardsL,
              this.setCellsBackwardsR,
              // setCellsForwards, setCellsBackwards,
              aG.forwards,
              aG.backwards,
              aG.passRunningTotal,
              this.mI,
              new FloatStack(1000),
              50,
              aG.reset);
      final Function_Index_3Args pMIT = ForwardBackwardMatrixIter.cutPointAlignmentGenerator(fBMI);

      Assert.assertTrue(floatStack.empty());
      int diag = 0;
      while (true) {
        diag += 2 + (int) (Math.random() * (this.width - 1 + this.height - 1 - diag));
        if (diag < this.width - 1 + this.height - 1) {
          fBMI.addPolygon(diag);
        } else {
          break;
        }
      }
      final int[] dC = (int[]) pMIT.fn(this.width - 1, this.height - 1, 0);
      final int mark = iS.getMark();
      final float[][][] matrixComputed = new float[this.width][this.height][1];
      while (!iS.empty()) {
        final int x = iS.gen();
        final int y = iS.gen();
        final float w = Float.intBitsToFloat(iS.gen());
        matrixComputed[x][y][0] = w;
      }
      for (int i = 0; i < this.width; i++) {
        for (int j = 0; j < this.height; j++) {
          if ((pM[i][j][0] != Float.NEGATIVE_INFINITY)
              && !((i == 0) && (j == 0))
              && !((i == this.width - 1) && (j == this.height - 1))) {
            Assert.assertEquals(pM[i][j][0] - total, matrixComputed[i][j][0], 0.1);
          }
        }
      }
      for (final Iterator it = this.lLTL.iterator(); it.hasNext(); ) {
        final int[] iA = (int[]) it.next();
        if (matrixComputed[iA[0]][iA[1]][0] != 0) {
          Assert.fail(matrixComputed[iA[0]][iA[1]][0] + " ");
        }
      }
      for (final Iterator it = this.rLTL.iterator(); it.hasNext(); ) {
        final int[] iA = (int[]) it.next();
        if (matrixComputed[iA[0]][iA[1]][0] != 0) {
          Assert.fail(matrixComputed[iA[0]][iA[1]][0] + " ");
        }
      }
    }
  }
 public void testAddTogetherDiagonals() throws Exception {
   for (int trial = 0; trial < 100; trial++) {
     Debug.pl(" trial " + trial);
     this.setup(0);
     final float[][][] fM = this.forwardMatrix();
     final float[][][] bM = this.backwardMatrix();
     final float[][][] pM = this.sumForwardBackwardMatrices(fM, bM);
     int fD = this.r.nextInt(this.height + this.width - 2 - this.minMaxOffset); // inclusive
     Object[] oA = (Object[]) this.polygonClipper.fn(fD);
     final int[] dC = (int[]) oA[2]; // 1];
     oA = (Object[]) this.polygonClipper.fn(this.height + this.width - 2);
     final int[] dC2 = (int[]) oA[2]; // 1];
     float total = Float.NEGATIVE_INFINITY;
     for (int i = 0; i < this.stateNumber; i++) {
       total = Maths.logAdd(total, pM[pM.length - 1][pM[0].length - 1][i]);
     }
     float totalS = Float.NEGATIVE_INFINITY;
     for (int i = 0; i < this.stateNumber; i++) {
       totalS = Maths.logAdd(totalS, pM[0][0][i]);
     }
     Assert.assertEquals(total, totalS, 0.1);
     final float[] forwardDiag = this.getDiagonal(dC[6], dC[7], dC[4], dC[5], fM);
     final float[] backwardDiag =
         this.getBackwardDiagonal(dC2[0], dC2[1], dC2[2], dC2[3], this.width, this.height, bM);
     final int diagLength = (dC2[2] - dC2[0] + 1) * 2 + 1;
     int forwardDiagStartOffset, forwardDiagEndOffset;
     float[] iA;
     if (dC[6] + dC[7] + 2 == dC2[0] + dC2[1]) {
       iA = new float[this.stateNumber];
       System.arraycopy(forwardDiag, this.stateNumber, iA, 0, this.stateNumber);
       forwardDiagStartOffset = 1;
       forwardDiagEndOffset = 1;
     } else {
       forwardDiagStartOffset = (dC[6] - dC[7] - 1) - (dC2[0] - dC2[1] - 1);
       forwardDiagEndOffset = (dC[4] - dC[5] + 1) - (dC2[0] - dC2[1] - 1);
       iA = forwardDiag;
     }
     final int[] lLTA = MatrixIteratorTest.convertLTPoints(this.lLTL);
     final int[] rLTA = MatrixIteratorTest.convertLTPoints(this.rLTL);
     final int x0 = dC[6];
     final int y0 = dC[5];
     final int fDiagC = dC[4] - x0;
     fD = x0 + y0 + fDiagC;
     final boolean isOnForwardLineL =
         ForwardBackwardMatrixIterTest.isOnTheLine(lLTA, fD + 1, Integer.MAX_VALUE);
     final boolean isOnBackwardLineL =
         ForwardBackwardMatrixIterTest.isOnTheLine(lLTA, fD + 2, Integer.MAX_VALUE);
     final boolean isOnForwardLineR =
         ForwardBackwardMatrixIterTest.isOnTheLine(rLTA, fD + 1, Integer.MAX_VALUE);
     final boolean isOnBackwardLineR =
         ForwardBackwardMatrixIterTest.isOnTheLine(rLTA, fD + 2, Integer.MAX_VALUE);
     Assert.assertEquals(
         ForwardBackwardMatrixIter.addTogetherDiagonals(
             iA,
             backwardDiag,
             diagLength,
             forwardDiagStartOffset,
             forwardDiagEndOffset,
             dC2[0],
             dC2[1] + 1,
             this.setCellsForwardsLL,
             this.stateNumber,
             isOnForwardLineL,
             isOnBackwardLineL,
             isOnForwardLineR,
             isOnBackwardLineR),
         total,
         0.1);
   }
 }