/**
   * Computes the density function <SPAN CLASS="MATH"><I>f</I> (<I>x</I>)</SPAN>, with <SPAN
   * CLASS="MATH"><I>&#955;</I><SUB>i</SUB> =</SPAN> <TT>lambda[<SPAN CLASS="MATH"><I>i</I> -
   * 1</SPAN>]</TT>, <SPAN CLASS="MATH"><I>i</I> = 1,&#8230;, <I>k</I></SPAN>.
   *
   * @param lambda rates of the hypoexponential distribution
   * @param x value at which the density is evaluated
   * @return density at <SPAN CLASS="MATH"><I>x</I></SPAN>
   */
  public static double density(double[] lambda, double x) {
    testLambda(lambda);
    if (x < 0) return 0;
    DoubleMatrix2D Ax = buildMatrix(lambda, x);
    DoubleMatrix2D M = DMatrix.expBidiagonal(Ax);

    int k = lambda.length;
    return lambda[k - 1] * M.getQuick(0, k - 1);
  }
  /**
   * Computes the complementary distribution <SPAN CLASS="MATH">bar(F)(<I>x</I>)</SPAN>, with <SPAN
   * CLASS="MATH"><I>&#955;</I><SUB>i</SUB> =</SPAN> <TT>lambda[<SPAN CLASS="MATH"><I>i</I> -
   * 1</SPAN>]</TT>, <SPAN CLASS="MATH"><I>i</I> = 1,&#8230;, <I>k</I></SPAN>.
   *
   * @param lambda rates of the hypoexponential distribution
   * @param x value at which the complementary distribution is evaluated
   * @return complementary distribution at <SPAN CLASS="MATH"><I>x</I></SPAN>
   */
  public static double barF(double[] lambda, double x) {
    testLambda(lambda);
    if (x <= 0.0) return 1.0;
    if (x >= Double.MAX_VALUE) return 0.0;
    DoubleMatrix2D M = buildMatrix(lambda, x);
    M = DMatrix.expBidiagonal(M);

    // prob is first row of final matrix
    int k = lambda.length;
    double sum = 0;
    for (int j = 0; j < k; j++) sum += M.getQuick(0, j);
    return sum;
  }