class TridiagonalSolver {

  public static double[] solvTriDag(final TridiagonalMatrix aM, final double[] b) {

    ArgumentChecker.notNull(aM, "null matrix");
    ArgumentChecker.notNull(b, "null vector");
    final double[] d = aM.getDiagonal(); //b is modified, so get copy of diagonal
    final int n = d.length;
    ArgumentChecker.isTrue(n == b.length, "vector y wrong length for matrix");
    final double[] y = Arrays.copyOf(b, n);

    final double[] l = aM.getLowerSubDiagonalData();
    final double[] u = aM.getUpperSubDiagonalData();

    final double[] x = new double[n];
    for (int i = 1; i < n; i++) {
      final double m = l[i - 1] / d[i - 1];
      d[i] = d[i] - m * u[i - 1];
      y[i] = y[i] - m * y[i - 1];
    }

    x[n - 1] = y[n - 1] / d[n - 1];

    for (int i = n - 2; i >= 0; i--) {
      x[i] = (y[i] - u[i] * x[i + 1]) / d[i];
    }

    return x;
  }

}