public bool Solve() { Iterations = 0; int size = B.Length; // Based on the algorithm in "Matrix Computations" by Golum and Van Loan. R = new double[size]; P = new double[size]; W = new double[size]; if (X == null || UseXAsInitialGuess == false) { if (X == null) { X = new double[size]; } Array.Clear(X, 0, X.Length); Array.Copy(B, R, B.Length); } else { // hopefully is X is a decent initialization... InitializeR(R); } // [RMS] these were inside loop but they are constant! double norm = BufferUtil.Dot(B, B); double root1 = Math.Sqrt(norm); // The first iteration. double rho0 = BufferUtil.Dot(R, R); // [RMS] If we were initialized w/ constraints already satisfied, // then we are done! (happens for example in mesh deformations) if (rho0 < math.MathUtil.ZeroTolerance * root1) { return(true); } Array.Copy(R, P, R.Length); MultiplyF(P, W); double alpha = rho0 / BufferUtil.Dot(P, W); BufferUtil.MultiplyAdd(X, alpha, P); BufferUtil.MultiplyAdd(R, -alpha, W); double rho1 = BufferUtil.Dot(R, R); // The remaining iterations. int iter; for (iter = 1; iter < MaxIterations; ++iter) { double root0 = Math.Sqrt(rho1); if (root0 <= math.MathUtil.ZeroTolerance * root1) { break; } double beta = rho1 / rho0; UpdateP(P, beta, R); MultiplyF(P, W); alpha = rho1 / BufferUtil.Dot(P, W); BufferUtil.MultiplyAdd(X, alpha, P); BufferUtil.MultiplyAdd(R, -alpha, W); rho0 = rho1; rho1 = BufferUtil.Dot(R, R); } //System.Console.WriteLine("{0} iterations", iter); Iterations = iter; return(iter < MaxIterations); }