public OptVector Solve( OptVector[] A, OptVector b, OptVector startX, int nIter) { OptVector[] normA = A; OptVector normb = b; if (!OptVector.Equals(A, OptVector.Transpose(A))) { OptVector[] At = OptVector.Transpose(A); normA = OptVector.Mult(At, A); normb = OptVector.Mult(At, b); } OptVector rNew = normb - OptVector.Mult(normA, startX); OptVector p = rNew; OptVector x = new OptVector(startX); double r2Old = rNew * rNew; double alpha = 1.0; double beta = 1.0; for (int i = 0; i < nIter; i++) { alpha = GetAlpha(normA, p, r2Old); x = x + alpha * p; rNew = rNew - alpha * OptVector.Mult(normA, p); double r2New = rNew * rNew; if (r2New < Precision) { return(x); } beta = GetBeta(r2New, r2Old); p = rNew + beta * p; r2Old = r2New; } return(x); }
public OptVector Solve( OptVector[] A, OptVector b, OptVector startX, int nIter) { OptVector[] symmA = A; OptVector normb = b; //Symmetrize matrix if (CheckSymmetry) { OptVector[] At = OptVector.Transpose(A); if (!OptVector.Equals(A, At)) { symmA = OptVector.Mult(At, A); normb = OptVector.Mult(At, b); } } OptVector v0 = new OptVector(b.Count); OptVector v1 = normb - OptVector.Mult(symmA, startX); double beta1 = v1.Length(); double betaN = 0.0; double n = beta1; double c0 = 1.0; double c1 = 1.0; double s0 = 0.0; double s1 = 0.0; OptVector w0 = new OptVector(v1.Count); OptVector w_1 = new OptVector(v1.Count); OptVector x = new OptVector(startX); for (int i = 0; i < nIter; i++) { //Calculate Lanczos Vectors OptVector v = (1.0 / beta1) * v1; OptVector Av = OptVector.Mult(symmA, v); double alpha = v * Av; v1 = Av - alpha * v - beta1 * v0; betaN = v1.Length(); //Calculate QR factors double lambda = c1 * alpha - c0 * s1 * beta1; double p1 = Math.Sqrt(lambda * lambda + betaN * betaN); double p2 = s1 * alpha + c0 * c1 * beta1; double p3 = s0 * beta1; //Calculate New Givens Rotations c0 = c1; c1 = lambda / p1; s0 = s1; s1 = betaN / p1; //Update Solution OptVector w = (1.0 / p1) * (v - p3 * w_1 - p2 * w0); x = x + c1 * n * w; n = -s1 * n; residual = Math.Abs(n); if (residual < precisionConst) { break; } beta1 = betaN; v0 = v; w_1 = w0; w0 = w; } return(x); }