/**
   * Function to compute matrix inverse via matrix decomposition.
   *
   * @param in commons-math3 Array2DRowRealMatrix
   * @return matrix block
   * @throws DMLRuntimeException if DMLRuntimeException occurs
   */
  private static MatrixBlock computeMatrixInverse(Array2DRowRealMatrix in)
      throws DMLRuntimeException {
    if (!in.isSquare())
      throw new DMLRuntimeException(
          "Input to inv() must be square matrix -- given: a "
              + in.getRowDimension()
              + "x"
              + in.getColumnDimension()
              + " matrix.");

    QRDecomposition qrdecompose = new QRDecomposition(in);
    DecompositionSolver solver = qrdecompose.getSolver();
    RealMatrix inverseMatrix = solver.getInverse();

    return DataConverter.convertToMatrixBlock(inverseMatrix.getData());
  }
  /**
   * Function to solve a given system of equations.
   *
   * @param in1 matrix object 1
   * @param in2 matrix object 2
   * @return matrix block
   * @throws DMLRuntimeException if DMLRuntimeException occurs
   */
  private static MatrixBlock computeSolve(MatrixObject in1, MatrixObject in2)
      throws DMLRuntimeException {
    Array2DRowRealMatrix matrixInput = DataConverter.convertToArray2DRowRealMatrix(in1);
    Array2DRowRealMatrix vectorInput = DataConverter.convertToArray2DRowRealMatrix(in2);

    /*LUDecompositionImpl ludecompose = new LUDecompositionImpl(matrixInput);
    DecompositionSolver lusolver = ludecompose.getSolver();
    RealMatrix solutionMatrix = lusolver.solve(vectorInput);*/

    // Setup a solver based on QR Decomposition
    QRDecomposition qrdecompose = new QRDecomposition(matrixInput);
    DecompositionSolver solver = qrdecompose.getSolver();
    // Invoke solve
    RealMatrix solutionMatrix = solver.solve(vectorInput);

    return DataConverter.convertToMatrixBlock(solutionMatrix.getData());
  }
 /*  91:    */
 /*  92:    */ public Array2DRowRealMatrix initializeHighOrderDerivatives(
     double h, double[] t, double[][] y, double[][] yDot)
       /*  93:    */ {
   /*  94:259 */ double[][] a = new double[2 * (y.length - 1)][this.c1.length];
   /*  95:260 */ double[][] b = new double[2 * (y.length - 1)][y[0].length];
   /*  96:261 */ double[] y0 = y[0];
   /*  97:262 */ double[] yDot0 = yDot[0];
   /*  98:263 */ for (int i = 1; i < y.length; i++)
   /*  99:    */ {
     /* 100:265 */ double di = t[i] - t[0];
     /* 101:266 */ double ratio = di / h;
     /* 102:267 */ double dikM1Ohk = 1.0D / h;
     /* 103:    */
     /* 104:    */
     /* 105:    */
     /* 106:271 */ double[] aI = a[(2 * i - 2)];
     /* 107:272 */ double[] aDotI = a[(2 * i - 1)];
     /* 108:273 */ for (int j = 0; j < aI.length; j++)
     /* 109:    */ {
       /* 110:274 */ dikM1Ohk *= ratio;
       /* 111:275 */ aI[j] = (di * dikM1Ohk);
       /* 112:276 */ aDotI[j] = ((j + 2) * dikM1Ohk);
       /* 113:    */ }
     /* 114:280 */ double[] yI = y[i];
     /* 115:281 */ double[] yDotI = yDot[i];
     /* 116:282 */ double[] bI = b[(2 * i - 2)];
     /* 117:283 */ double[] bDotI = b[(2 * i - 1)];
     /* 118:284 */ for (int j = 0; j < yI.length; j++)
     /* 119:    */ {
       /* 120:285 */ bI[j] = (yI[j] - y0[j] - di * yDot0[j]);
       /* 121:286 */ yDotI[j] -= yDot0[j];
       /* 122:    */ }
     /* 123:    */ }
   /* 124:294 */ QRDecomposition decomposition =
       new QRDecomposition(new Array2DRowRealMatrix(a, false));
   /* 125:295 */ RealMatrix x =
       decomposition.getSolver().solve(new Array2DRowRealMatrix(b, false));
   /* 126:296 */ return new Array2DRowRealMatrix(x.getData(), false);
   /* 127:    */ }