/// <summary> /// Solves Ax=b, where A is square and nonsingular. b overwritten with /// solution. Partial pivoting if tol = 1. /// </summary> /// <param name="b">size n, b on input, x on output</param> /// <returns>true if successful, false on error</returns> public bool Solve(Complex[] b) { if (b == null || numFactor == null) { return(false); // check inputs } Complex[] x = new Complex[n]; // get workspace Common.InversePermute(numFactor.pinv, b, x, n); // x = b(p) Triangular.SolveL(numFactor.L, x); // x = L\x Triangular.SolveU(numFactor.U, x); // x = U\x Common.InversePermute(symFactor.q, x, b, n); // b(q) = x return(true); }
/// <summary> /// Solve a least-squares problem (min ||Ax-b||_2, where A is m-by-n with m /// >= n) or underdetermined system (Ax=b, where m < n) /// </summary> /// <param name="b">size max(m,n), b (size m) on input, x(size n) on output</param> /// <returns>true if successful, false on error</returns> public bool Solve(Complex[] b) { Complex[] x; if (b == null) { return(false); // check inputs } if (m >= n) { x = new Complex[symFactor != null ? symFactor.m2 : 1]; // get workspace Common.InversePermute(symFactor.pinv, b, x, m); // x(0:m-1) = b(p(0:m-1) for (int k = 0; k < n; k++) // apply Householder refl. to x { ApplyHouseholder(numFactor.L, k, numFactor.B[k], x); } Triangular.SolveU(numFactor.U, x); // x = R\x Common.InversePermute(symFactor.q, x, b, n); // b(q(0:n-1)) = x(0:n-1) } else { x = new Complex[symFactor != null ? symFactor.m2 : 1]; // get workspace Common.Permute(symFactor.q, b, x, m); // x(q(0:m-1)) = b(0:m-1) Triangular.SolveUt(numFactor.U, x); // x = R'\x for (int k = m - 1; k >= 0; k--) // apply Householder refl. to x { ApplyHouseholder(numFactor.L, k, numFactor.B[k], x); } Common.Permute(symFactor.pinv, x, b, n); // b(0:n-1) = x(p(0:n-1)) } return(true); }