/// <summary> /// Решение СЛАУ методом локально-оптимальной схемы /// </summary> /// <param name="A">Матрица СЛАУ</param> /// <param name="b">Ветор правой части</param> /// <param name="Initial">Ветор начального приближения</param> /// <param name="Precision">Точность</param> /// <param name="Maxiter">Максимальное число итераций</param> /// <returns>Вектор x - решение СЛАУ Ax=b с заданной точностью</returns> public IVector Solve(IPreconditioner Preconditioner, IMatrix A, IVector b, IVector Initial, double Precision, int Maxiter, ILogger Logger) { Logger.WriteNameSolution("Seidel", Preconditioner.getName()); string start = DateTime.Now.ToString("dd.MM.yyyy hh:mm:ss:fff"); Logger.setMaxIter(Maxiter); IVector x = (IVector)Initial.Clone(); //начальное приблежение IVector r = b.Add(A.Mult(x), 1, -1); //r = b - Ax_0 double residual = r.Norm / b.Norm; // ||b-Ax_0|| / ||b|| for (int i = 0; i < Maxiter && residual > Precision; i++) { x = A.SolveL(b.Add(A.MultU(x, false), 1, -1)); //x_k+1=D_-1 (b-Rx_k) r = b.Add(A.Mult(x), 1, -1); //r = b - Ax residual = r.Norm / b.Norm; // ||b-Ax|| / ||b|| Factory.Residual.Add(residual); Logger.WriteIteration(i, residual); if (double.IsNaN(r.Norm) || double.IsInfinity(r.Norm)) { Logger.WriteSolution(x, Maxiter, b.Add(A.Mult(x), -1, 1).Norm); Logger.WriteTime(start, DateTime.Now.ToString("dd.MM.yyyy hh:mm:ss:fff")); throw new CantSolveException(); } } Logger.WriteSolution(x, Maxiter, b.Add(A.Mult(x), -1, 1).Norm); Logger.WriteTime(start, DateTime.Now.ToString("dd.MM.yyyy hh:mm:ss:fff")); return(x); }
public bool InitMethod(ILinearOperator A, IVector x0, IVector b, bool malloc = false, IFactorization Factorizer = null) { if (malloc) { x = new Vector(x0.Size); } else { x = x0; } xk = x0.Clone(); this.b = b; this.A = A; this.Factorizer = Factorizer; norm_b = b.Norm; currentIter = 0; if (Factorizer != null) { r_prev = Factorizer.LSolve(b.Add(A.Multiply(xk), -1)); r0 = r_prev.Clone(); z = Factorizer.USolve(r_prev.Clone()); } else { r_prev = b.Add(A.Multiply(xk), -1); r0 = r_prev.Clone(); z = r_prev.Clone(); } dotproduct_rr = r_prev.DotProduct(r_prev); dotproduct_rprevr0 = dotproduct_rr; init = true; return(init); }
public bool InitMethod(ILinearOperator A, IVector x0, IVector b, bool malloc = false, IFactorization Factorizer = null) { if (malloc) { x = new Vector(x0.Size); } else { x = x0; } this.x0 = x0; this.b = b; this.A = A; this.Factorizer = Factorizer; norm_b = b.Norm; currentIter = 0; if (Factorizer != null) { r = Factorizer.LSolve(b.Add(A.Multiply(x0), -1)); z = Factorizer.USolve(r); p = Factorizer.LSolve(A.Multiply(z)); } else { r = b.Add(A.Multiply(x0), -1); z = r.Clone(); p = A.Multiply(z); } dotproduct_pp = p.DotProduct(p); init = true; return(init); }
public void Add() { Utils.ProcessInEnv(env => { var res = enc1.Add(enc2, env).Decrypt(env); Compare(vec1.Add(vec2), res); var res_p = enc1.Add(plain2, env).Decrypt(env); Compare(vec1.Add(vec2), res_p); }, Factory); }
public void MakeStep(out int iter, out double residual) { if (!init) { throw new InvalidOperationException("Решатель не инициализирован, выполнение операции невозможно"); } currentIter++; iter = currentIter; Az = A.Multiply(z); coefficient = dotproduct_rr / Az.DotProduct(z); x = x.Add(z, coefficient); r = r.Add(Az, -coefficient); coefficient = dotproduct_rr; dotproduct_rr = r.DotProduct(r); coefficient = dotproduct_rr / coefficient; z = r.Add(z, coefficient); if (Double.IsInfinity(coefficient) || Double.IsNaN(coefficient)) { residual = -1; return; } residual = Math.Sqrt(dotproduct_rr) / norm_b; }
public void MakeStep(out int iter, out double residual) { if (!init) { throw new InvalidOperationException("Решатель не инициализирован, выполнение операции невозможно"); } currentIter++; iter = currentIter; coefficient = p.DotProduct(r) / dotproduct_pp; x = x.Add(z, coefficient); r = r.Add(p, -coefficient); Ar = A.Multiply(r); coefficient = -p.DotProduct(Ar) / dotproduct_pp; z = r.Add(z, coefficient); p = Ar.Add(p, coefficient); dotproduct_pp = p.DotProduct(p); if (Double.IsInfinity(coefficient) || Double.IsNaN(coefficient)) { residual = -1; return; } residual = r.Norm / norm_b; }
public Neuron(int numOfWeights) { var random = new Random(); Weights = new Vector(); for (int i = 0; i < numOfWeights; i++) { Weights.Add(random.NextDouble()); } }
static void Main(string[] args) { Vector a = new Vector(), b = new Vector(), c = new Vector(); IVector ia = a, ib = b, ic = c; Console.WriteLine("interface"); ia.Add(ref b, out c); Console.WriteLine("direct"); a.Add(ref b, out c); }
public void IVector_Add_EqualSize(IVector factory, double[] op1Data, double[] op2Data, double[] expected) { IVector v1 = factory.FromArray(op1Data); IVector v2 = factory.FromArray(op2Data); IVector actual = v1.Add(v2); _out.WriteLine("Length of data"); Assert.Equal(expected.Length, actual.Count); for (int i = 0; i < expected.Length; i++) { _out.WriteLine($"ex: {expected[i]}, ac: {actual[i]}"); Assert.Equal(expected[i], actual[i]); } }
public void MakeStep(out int iter, out double residual) { if (!init) { throw new InvalidOperationException("Решатель не инициализирован, выполнение операции невозможно"); } if (currentIter % 20 == 0) { r_prev = A.LSolve(b.Add(A.Multiply(xk), -1), true); r0 = r_prev.Clone(); z = A.USolve(r_prev.Clone(), true); dotproduct_rr = r_prev.DotProduct(r_prev); dotproduct_rprevr0 = dotproduct_rr; } currentIter++; iter = currentIter; LAUz = A.LSolve(A.Multiply(A.USolve(z, true)), true); var alpha = dotproduct_rprevr0 / (LAUz.DotProduct(r0)); var p = r_prev.Add(LAUz, -alpha); LAUp = A.LSolve(A.Multiply(A.USolve(p, true)), true); var gamma = (LAUp.DotProduct(p)) / (LAUp.DotProduct(LAUp)); xk = xk.Add(z, alpha).Add(p, gamma); r = p.Add(LAUp, -gamma); dotproduct_rkr0 = r.DotProduct(r0); var beta = alpha * dotproduct_rkr0 / (gamma * dotproduct_rprevr0); z = r.Add(z, beta).Add(LAUz, -beta * gamma); dotproduct_rprevr0 = dotproduct_rkr0; r_prev = r; dotproduct_rr = r.DotProduct(r); if (Double.IsNaN(beta) || Double.IsInfinity(beta)) { residual = -1; return; } x = A.USolve(xk, true); residual = Math.Sqrt(dotproduct_rr) / norm_b; }
public void MakeStep(out int iter, out double residual) { if (!init) { throw new InvalidOperationException("Решатель не инициализирован, выполнение операции невозможно"); } currentIter++; //x_k=(L+D)^(-1)*(b-Ux) var x_k = A.LSolve(b.Add(Ux, -1), true); double w = 1.0; double tempResidual = Double.MaxValue; while (w >= 0.1) { ////???????????????? for (int i = 0; i < x.Size; i++) { x_temp[i] = w * x_k[i] + (1 - w) * x[i]; } ////???????????????? Ux = Ux = A.UMult(x_temp, false, 0); //tempResidual = ||b - (Ux+Lx+Dx)|| / ||b|| tempResidual = Ux.Add(A.LMult(x_temp, false, 0)).Add(A.Diagonal.HadamardProduct(x_temp)).Add(b, -1).Norm / norm_b; w -= 0.1; if (tempResidual < lastResidual) { break; } } lastResidual = tempResidual; ////???????????????? for (int i = 0; i < x.Size; i++) { x[i] = x_temp[i]; } ////??????????????? residual = lastResidual; iter = currentIter; }
public void VectorAdditionAndSubtraction() { IVector <DoubleComponent> Point1 = MatrixFactory <DoubleComponent> .CreateVector3D(1, 1, 1); //new Vector3D(); //Point1.Set(1, 1, 1); IVector <DoubleComponent> Point2 = MatrixFactory <DoubleComponent> .CreateVector3D(2, 2, 2); //Point2.Set(2, 2, 2); IVector <DoubleComponent> Point3;; Point3 = Point1.Add(Point2); Assert.IsTrue(Point3.Equals(MatrixFactory <DoubleComponent> .CreateVector3D(3, 3, 3))); Point3 = Point1.Subtract(Point2); Assert.IsTrue(Point3.Equals(MatrixFactory <DoubleComponent> .CreateVector3D(-1, -1, -1))); Point3.AddEquals(Point1); Assert.IsTrue(Point3.Equals(MatrixFactory <DoubleComponent> .CreateVector3D(0, 0, 0))); Point3.AddEquals(Point2); Assert.IsTrue(Point3.Equals(MatrixFactory <DoubleComponent> .CreateVector3D(2, 2, 2))); Point3.SetFrom(MatrixFactory <DoubleComponent> .CreateVector3D(3, -4, 5)); Assert.IsTrue(Point3.GetMagnitude().GreaterThan(7.07) && Point3.GetMagnitude().LessThan(7.08)); IVector <DoubleComponent> InlineOpLeftSide = MatrixFactory <DoubleComponent> .CreateVector3D(5.0f, -3.0f, .0f); IVector <DoubleComponent> InlineOpRightSide = MatrixFactory <DoubleComponent> .CreateVector3D(-5.0f, 4.0f, 1.0f); Assert.IsTrue( InlineOpLeftSide.Add(InlineOpRightSide) .Equals( MatrixFactory <DoubleComponent> .CreateVector3D(.0f, 1.0f, 1.0f) )); Assert.IsTrue( InlineOpLeftSide.Subtract(InlineOpRightSide) .Equals( MatrixFactory <DoubleComponent> .CreateVector3D(10.0f, -7.0f, -1.0f)) ); }
public virtual void Update(double numSecondsPassed) { m_Position.Add(m_Velocity.Multiply(numSecondsPassed)); if (m_Position[0].GreaterThan(GameWidth)) { m_Position[0].SubtractEquals(GameWidth); } if (m_Position[0].LessThan(0)) { m_Position[0].AddEquals(GameWidth); } if (m_Position[1].GreaterThan(GameHeight)) { m_Position[1].SubtractEquals(GameHeight); } if (m_Position[1].LessThan(0)) { m_Position[1].AddEquals(GameHeight); } }
//не предобусловленная система public bool InitMethod(ILinearOperator A, IVector x0, IVector b, bool malloc = false) { if (malloc) { x = new Vector(x0.Size); } else { x = x0; } this.x0 = x0; this.b = b; this.A = A; norm_b = b.Norm; currentIter = 0; r = b.Add(A.Multiply(x0), -1); z = r.Clone(); dotproduct_rr = r.DotProduct(r); init = true; return(init); }
public IMatrix Add(IMatrix rhs) { Debug.Assert(RowCount == rhs.RowCount); Debug.Assert(ColCount == rhs.ColCount); HashSet <int> allRows = new HashSet <int>(); foreach (int k in mInternal.Keys) { allRows.Add(k); } foreach (int k in rhs.RowKeys) { allRows.Add(k); } IMatrix result = this.Zero(mRowKeys, mColKeys, mDefaultVal); foreach (int k in allRows) { IVector row1 = this[k]; IVector row2 = rhs[k]; if (row1 == null) { result[k] = row2.Clone(); } else if (row2 == null) { result[k] = row1.Clone(); } else { result[k] = row1.Add(row2); } } return(result); }
/// this is for a pool layer which is a convolution but with all the weights equal 1 /// the scale of the result is normalized such that it will act as if an average was performed (as opposed to sum) IVector SumOnce(IMatrix m, int[] corner) { IVector agg = null; var res = ProcessInEnv(env => { foreach (var offset in Offsets) { var element = ElementAt(m, corner, offset, InputShape); if (element != null) { var t = agg; agg = (agg == null) ? element : agg.Add(element, env); if (t != null) { t.Dispose(); } } } agg.RegisterScale(agg.Scale * Offsets.Length); return(agg); }); return(res); }
public IVector InitMethod(ILinearOperator A, IVector x0, IVector b, bool malloc = false) { if (malloc) { x = new Vector(x0.Size); } else { x = x0; } xk = x0; this.b = b; this.A = A; norm_b = b.Norm; currentIter = 0; r_prev = A.LSolve(b.Add(A.Multiply(xk), -1), true); r0 = r_prev.Clone(); z = A.USolve(r_prev.Clone(), true); dotproduct_rr = r_prev.DotProduct(r_prev); dotproduct_rprevr0 = dotproduct_rr; init = true; return(x); }
/// <summary> /// Решение СЛАУ методом сопряженных градиентов /// </summary> /// <param name="A">Матрица СЛАУ</param> /// <param name="b">Ветор правой части</param> /// <param name="Initial">Ветор начального приближения</param> /// <param name="Precision">Точность</param> /// <param name="Maxiter">Максимальное число итераций</param> /// <returns>Вектор x - решение СЛАУ Ax=b с заданной точностью</returns> public IVector Solve(IPreconditioner Preconditioner, IMatrix A, IVector b, IVector Initial, double Precision, int Maxiter, ILogger Logger) { Logger.WriteNameSolution("MSG", Preconditioner.getName()); string start = DateTime.Now.ToString("dd.MM.yyyy hh:mm:ss:fff"); Logger.setMaxIter(Maxiter); IVector x = Preconditioner.MultU(Initial); double scalAzZ, scalRR, alpha, beta = 1.0; IVector r = b.Add(A.Mult(Initial), 1, -1); r = Preconditioner.T.SolveL(Preconditioner.SolveL(r)); IVector Az, Atz, z = A.Transpose.Mult(r); z = Preconditioner.T.SolveU(z); r = z.Clone() as IVector; scalRR = r.ScalarMult(r); double normR = Math.Sqrt(scalRR) / b.Norm; for (int iter = 0; iter < Maxiter && normR > Precision && beta > 0; iter++) { Az = Preconditioner.SolveU(z); Atz = A.Mult(Az); Atz = Preconditioner.T.SolveL(Preconditioner.SolveL(Atz)); Az = A.Transpose.Mult(Atz); Az = Preconditioner.T.SolveU(Az); scalAzZ = Az.ScalarMult(z); if (scalAzZ == 0) { Logger.WriteSolution(x, Maxiter, b.Add(A.Mult(x), -1, 1).Norm); Logger.WriteTime(start, DateTime.Now.ToString("dd.MM.yyyy hh:mm:ss:fff")); throw new DivideByZeroException("Division by 0"); } alpha = scalRR / scalAzZ; x.Add(z, 1, alpha, true); r.Add(Az, 1, -alpha, true); beta = scalRR; if (scalRR == 0) { Logger.WriteSolution(x, Maxiter, b.Add(A.Mult(x), -1, 1).Norm); Logger.WriteTime(start, DateTime.Now.ToString("dd.MM.yyyy hh:mm:ss:fff")); throw new DivideByZeroException("Division by 0"); } scalRR = r.ScalarMult(r); beta = scalRR / beta; z = r.Add(z, 1, beta); normR = Math.Sqrt(scalRR) / b.Norm; Factory.Residual.Add(normR); Logger.WriteIteration(iter, normR); if (double.IsNaN(normR) || double.IsInfinity(normR)) { x = Preconditioner.SolveU(x); Logger.WriteSolution(x, Maxiter, b.Add(A.Mult(x), -1, 1).Norm); Logger.WriteTime(start, DateTime.Now.ToString("dd.MM.yyyy hh:mm:ss:fff")); throw new CantSolveException(); } } ; x = Preconditioner.SolveU(x); Logger.WriteSolution(x, Maxiter, b.Add(A.Mult(x), -1, 1).Norm); Logger.WriteTime(start, DateTime.Now.ToString("dd.MM.yyyy hh:mm:ss:fff")); return(x); }
//updates the ANN with information from the sweepers enviroment public bool Update(List <IVector <T> > mines) { //this will store all the inputs for the NN List <T> inputs = new List <T>(); //get List to closest mine IVector <T> vClosestMine = GetClosestMine(mines); //normalise it vClosestMine = vClosestMine.Normalize(); #if false // get the angle to the closest mine Vector3D DeltaToMine = vClosestMine - m_vPosition; Vector2D DeltaToMine2D = new Vector2D(DeltaToMine.x, DeltaToMine.y); Vector2D LookAt2D = new Vector2D(m_vLookAt.x, m_vLookAt.y); double DeltaAngle = LookAt2D.GetDeltaAngle(DeltaToMine2D); inputs.Add(DeltaAngle); inputs.Add(DeltaAngle); inputs.Add(DeltaAngle); inputs.Add(DeltaAngle); #else //add in List to closest mine inputs.Add(vClosestMine[0]); inputs.Add(vClosestMine[1]); //add in sweepers look at List inputs.Add(m_vLookAt[0]); inputs.Add(m_vLookAt[1]); #endif //update the brain and get feedback ///watch the performance here List <double> output = m_ItsBrain.Update(inputs.Select(o => o.ToDouble()).ToList()); //make sure there were no errors in calculating the //output if (output.Count < m_ItsBrain.NumOutputs) { return(false); } //assign the outputs to the sweepers left & right tracks m_lTrack = output[0]; m_rTrack = output[1]; //calculate steering forces double RotForce = m_lTrack - m_rTrack; //clamp rotation RotForce = System.Math.Min(System.Math.Max(RotForce, -m_dMaxTurnRate), m_dMaxTurnRate); m_dRotation += RotForce; m_dSpeed = (m_lTrack + m_rTrack); //update Look At m_vLookAt[0] = M.New <T>((double)-System.Math.Sin(m_dRotation)); m_vLookAt[1] = M.New <T>((double)System.Math.Cos(m_dRotation)); //update position m_vPosition.Add(m_vLookAt.Multiply(m_dSpeed)); //wrap around window limits if (m_vPosition[0].GreaterThan(m_WindowWidth)) { m_vPosition[0] = M.Zero <T>(); } if (m_vPosition[0].LessThan(0)) { m_vPosition[0] = M.New <T>(m_WindowWidth); } if (m_vPosition[1].GreaterThan(m_WindowHeight)) { m_vPosition[1] = M.Zero <T>(); } if (m_vPosition[1].LessThan(0)) { m_vPosition[1] = M.New <T>(m_WindowHeight); } return(true); }
public void DrawLine(IVector <T> Start, IVector <T> End, bool DoAA) { if (Start == End) { return; } Gl.glPushAttrib(Gl.GL_ALL_ATTRIB_BITS); CheckLineImageCache(); ImageGLDisplayListPlugin <T> GLBuffer = ImageGLDisplayListPlugin <T> .GetImageGLDisplayListPlugin(m_LineImageCache); Gl.glEnable(Gl.GL_BLEND); Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA); Gl.glColor4f(0, 0, 0, 1); IVector <T> Normal = (End.Subtract(Start)); Normal = Normal.Normalize(); IVector <T> PerpendicularNormal = Normal.GetPerpendicular(); float Width = 40; if (DoAA) { Width--; } IVector <T> OffsetPos = PerpendicularNormal.Multiply(Width); IVector <T> OffsetNeg = PerpendicularNormal.Multiply(-(Width + 1)); RendererOpenGL <T> .PushOrthoProjection(); Gl.glDisable(Gl.GL_TEXTURE_2D); IVector <T> StartLeft = Start.Add(OffsetPos); IVector <T> StartRight = Start.Add(OffsetNeg); IVector <T> EndLeft = End.Add(OffsetPos); IVector <T> EndRight = End.Add(OffsetNeg); Gl.glBegin(Gl.GL_QUADS); { Gl.glVertex2d(StartLeft[0].ToDouble(), StartLeft[1].ToDouble()); Gl.glVertex2d(EndLeft[0].ToDouble(), EndLeft[1].ToDouble()); Gl.glVertex2d(EndRight[0].ToDouble(), EndRight[1].ToDouble()); Gl.glVertex2d(StartRight[0].ToDouble(), StartRight[1].ToDouble()); } Gl.glEnd(); if (DoAA) { double EdgeWith = 2; //IVector<DoubleComponent> StartLeftAA = StartLeft + PerpendicularNormal * EdgeWith - Normal * EdgeWith; //IVector<DoubleComponent> StartRightAA = StartRight - PerpendicularNormal * EdgeWith - Normal * EdgeWith; //IVector<DoubleComponent> EndLeftAA = EndLeft + PerpendicularNormal * EdgeWith + Normal * EdgeWith; //IVector<DoubleComponent> EndRightAA = EndRight - PerpendicularNormal * EdgeWith + Normal * EdgeWith; IVector <T> StartLeftAA = StartLeft .Add(PerpendicularNormal) .Multiply(EdgeWith) .Subtract(Normal) .Multiply(EdgeWith); IVector <T> StartRightAA = StartRight .Subtract(PerpendicularNormal) .Multiply(EdgeWith) .Subtract(Normal) .Multiply(EdgeWith); IVector <T> EndLeftAA = EndLeft .Add(PerpendicularNormal) .Multiply(EdgeWith) .Add(Normal) .Multiply(EdgeWith); IVector <T> EndRightAA = EndRight .Subtract(PerpendicularNormal) .Multiply(EdgeWith) .Add(Normal) .Multiply(EdgeWith); Gl.glEnable(Gl.GL_TEXTURE_2D); Gl.glBindTexture(Gl.GL_TEXTURE_2D, GLBuffer.GLTextureHandle); Gl.glBegin(Gl.GL_QUADS); { // left edge Gl.glTexCoord2d(0, 0); Gl.glVertex2d(StartLeft[0].ToDouble(), StartLeft[1].ToDouble()); Gl.glVertex2d(EndLeft[0].ToDouble(), EndLeft[1].ToDouble()); Gl.glTexCoord2d(1, 0); Gl.glVertex2d(EndLeftAA[0].ToDouble(), EndLeftAA[1].ToDouble()); Gl.glVertex2d(StartLeftAA[0].ToDouble(), StartLeftAA[1].ToDouble()); // right edge Gl.glTexCoord2d(0, 0); Gl.glVertex2d(StartRight[0].ToDouble(), StartRight[1].ToDouble()); Gl.glVertex2d(EndRight[0].ToDouble(), EndRight[1].ToDouble()); Gl.glTexCoord2d(1, 0); Gl.glVertex2d(EndRightAA[0].ToDouble(), EndRightAA[1].ToDouble()); Gl.glVertex2d(StartRightAA[0].ToDouble(), StartRightAA[1].ToDouble()); // start edge EdgeWith = 20; Gl.glTexCoord2d(0, 0); Gl.glVertex2d(StartLeft[0].ToDouble(), StartLeft[1].ToDouble()); Gl.glVertex2d(StartRight[0].ToDouble(), StartRight[1].ToDouble()); Gl.glTexCoord2d(1, 0); Gl.glVertex2d(StartRightAA[0].ToDouble(), StartRightAA[1].ToDouble()); Gl.glVertex2d(StartLeftAA[0].ToDouble(), StartLeftAA[1].ToDouble()); // end edge Gl.glTexCoord2d(0, 0); Gl.glVertex2d(EndLeft[0].ToDouble(), EndLeft[1].ToDouble()); Gl.glVertex2d(EndRight[0].ToDouble(), EndRight[1].ToDouble()); Gl.glTexCoord2d(1, 0); Gl.glVertex2d(EndRightAA[0].ToDouble(), EndRightAA[1].ToDouble()); Gl.glVertex2d(EndLeftAA[0].ToDouble(), EndLeftAA[1].ToDouble()); } Gl.glEnd(); } RendererOpenGL <T> .PopOrthoProjection(); Gl.glPopAttrib(); }
/// <summary> /// Решение СЛАУ стабилизированным методом бисопряжённых градиентов /// </summary> /// <param name="A">Матрица СЛАУ</param> /// <param name="b">Ветор правой части</param> /// <param name="Initial">Ветор начального приближения</param> /// <param name="Precision">Точность</param> /// <param name="Maxiter">Максимальное число итераций</param> /// <returns>Вектор x - решение СЛАУ Ax=b с заданной точностью</returns> public IVector Solve(IPreconditioner Preconditioner, IMatrix A, IVector b, IVector Initial, double Precision, int Maxiter, ILogger Logger) { Logger.WriteNameSolution("BSGstab", Preconditioner.getName()); string start = DateTime.Now.ToString("dd.MM.yyyy hh:mm:ss:fff"); Logger.setMaxIter(Maxiter); IVector x = (IVector)Initial.Clone(); IVector r = b.Add(A.Mult(Initial), 1, -1); IVector r0 = r.Clone() as IVector; double opo = 1, po = 1, alpha = 1, w = 1, beta, normR; IVector p = new SimpleVector(b.Size); IVector v = new SimpleVector(b.Size); IVector y, h, s, z, t; normR = r.Norm / b.Norm; for (int iter = 0; iter < Maxiter && normR > Precision; iter++) { po = r0.ScalarMult(r); beta = (po / opo) * (alpha / w); p = r.Add(p.Add(v, 1, -w), 1, beta); y = Preconditioner.SolveL(Preconditioner.SolveU(p)); v = A.Mult(y); alpha = po / r0.ScalarMult(v); h = x.Add(y, 1, alpha); s = r.Add(v, 1, -alpha); z = Preconditioner.SolveL(Preconditioner.SolveU(s)); t = A.Mult(z); w = (Preconditioner.SolveL(t).ScalarMult(Preconditioner.SolveL(s))) / (Preconditioner.SolveL(t).ScalarMult(Preconditioner.SolveL(t))); x = h.Add(z, 1, w); r = s.Add(t, 1, -w); opo = po; normR = r.Norm / b.Norm; Factory.Residual.Add(normR); Logger.WriteIteration(iter, normR); if (double.IsNaN(normR) || double.IsInfinity(normR)) { Logger.WriteSolution(x, Maxiter, b.Add(A.Mult(x), -1, 1).Norm); Logger.WriteTime(start, DateTime.Now.ToString("dd.MM.yyyy hh:mm:ss:fff")); throw new CantSolveException(); } } Logger.WriteSolution(x, Maxiter, b.Add(A.Mult(x), -1, 1).Norm); Logger.WriteTime(start, DateTime.Now.ToString("dd.MM.yyyy hh:mm:ss:fff")); return(x); /* * if (b.Norm == 0) * return x; * * double alpha = 0.0, beta = 0.0, gamma = 0.0; * * IVector r0 = b.Add(A.Mult(Initial), 1, -1); //r_0 = f - Ax_0 * r0 = Preconditioner.SolveL(r0);//r_0 = L(-1)(f - Ax_0) * * IVector z = Preconditioner.SolveU(r0);//z_0 = U(-1)r_0 * * IVector r = (IVector)r0.Clone(); // r = r_0 * * IVector p = new SimpleVector(b.Size); * IVector LAUz = new SimpleVector(b.Size); * IVector LAUp = new SimpleVector(b.Size); * * double r_r = 0.0, r_r_1 = 0.0; * * double normR = r.Norm / b.Norm; * * for (int iter = 0; iter < Maxiter && normR > Precision; iter++) * { * r_r = r0.ScalarMult(r);//(r(k-1),r0) * * LAUz = Preconditioner.SolveL(A.Mult(Preconditioner.SolveU(z)));//L(-1)AU(-1)z(k-1) * * alpha = r_r / r0.ScalarMult(LAUz);//alpha = (r(k-1),r0)/(r0,L(-1)AU(-1)z(k-1)) * * p = r.Add(LAUz, 1, -alpha);//pk = r(k-1) - alpha * L(-1)AU(-1)z(k-1) * * LAUp = Preconditioner.SolveL(A.Mult(Preconditioner.SolveU(p)));//L(-1)AU(-1)p(k) * * gamma = p.ScalarMult(LAUp) / LAUp.ScalarMult(LAUp);//gamma = (p(k),L(-1)AU(-1)p(k))/(L(-1)AU(-1)p(k),L(-1)AU(-1)p(k)) * * x.Add(z, 1, alpha, true);//xk = x(k-1) + alpha(k) * z(k-1) * x.Add(p, 1, gamma, true);//xk = x(k-1) + gamma(k) * p(k) * * r_r_1 = r0.ScalarMult(r);//(r(k-1),r0) * * r = p.Add(LAUp, 1, -gamma);//rk = p(k) - gamma(k) * L(-1)AU(-1)p(k) * * r_r = r0.ScalarMult(r);//(r(k), r0) * * beta = (r_r * alpha) / (r_r_1 * gamma);//beta = ((r(k),r0) * alpha(k))/((r(k-1),r0) * omega(k-1)) * * z = r.Add(z, 1, beta);//z(k) = r(k) + beta(k) * z(k-1) * z.Add(LAUz, 1, -beta * gamma, true);//z(k) = z(k) - beta(k) * gamma(k) * L(-1)AU(-1)z(k-1) * * normR = r.Norm / b.Norm; * * Factory.Residual.Add(normR); * Logger.WriteIteration(iter, normR); * } * x = Preconditioner.SolveU(x);//x = U(-1)x * Logger.WriteSolution(x, Maxiter); * Logger.WriteTime(start, DateTime.Now.ToString("dd.MM.yyyy hh:mm:ss:fff")); * return x; */ }
public bool InitMethod(ILinearOperator A, IVector x0, IVector b, bool malloc = false, IFactorization Factorizer = null) { if (malloc) { x = new Vector(x0.Size); } else { x = x0; } xk = x0.Clone(); this.x0 = x0; this.b = b; this.A = A; this.Factorizer = Factorizer; At = A.Transpose; norm_b = b.Norm; currentIter = 0; if (Factorizer != null) { r = Factorizer.UTransposeSolve(At.Multiply(Factorizer.LTransposeSolve(Factorizer.LSolve(b.Add(A.Multiply(x0), -1))))); z = r.Clone(); xk = Factorizer.UMult(x0); } else { r = At.Multiply(b).Add(At.Multiply(A.Multiply(x0)), -1); z = r.Clone(); } dotproduct_rr = r.DotProduct(r); init = true; return(init); }
/// <summary> /// Решение СЛАУ методом локально-оптимальной схемы /// </summary> /// <param name="preconditioner">Матрица СЛАУ</param> /// <param name="b">Ветор правой части</param> /// <param name="Initial">Ветор начального приближения</param> /// <param name="Precision">Точность</param> /// <param name="Maxiter">Максимальное число итераций</param> /// <returns>Вектор x - решение СЛАУ Ax=b с заданной точностью</returns> public IVector Solve(IPreconditioner preconditioner, IMatrix A, IVector b, IVector Initial, double Precision, int Maxiter, ILogger Logger) { Logger.WriteNameSolution("LOS", preconditioner.getName()); string start = DateTime.Now.ToString("dd.MM.yyyy hh:mm:ss:fff"); Logger.setMaxIter(Maxiter); IVector x = Initial.Clone() as IVector; double alpha = 0.0, beta = 0.0; IVector r = b.Add(A.Mult(Initial), 1, -1); //r_0 = f - Ax_0 r = preconditioner.SolveL(r); // r_0 = L^-1 * (f - Ax_0) IVector Ar, z = preconditioner.SolveU(r); // z_0 = U^-1 * r_0 IVector p = preconditioner.SolveL(A.Mult(z)); // p_0 = L^-1 * Az_0 double p_r = 0.0, p_p = 0.0; double scalRR = r.ScalarMult(r); double normR = Math.Sqrt(scalRR) / b.Norm; for (int iter = 0; iter < Maxiter && normR > Precision; iter++) //for (int iter = 0; iter < Maxiter && ; iter++) { p_r = p.ScalarMult(r); //(p_k-1,r_k-1) p_p = p.ScalarMult(p); //(p_k-1,p_k-1) alpha = p_r / p_p; x.Add(z, 1, alpha, true); // x_k = x_k-1 + alfa_k*z_k-1 r.Add(p, 1, -alpha, true); // r_k = r_k-1 - alfa_k*p_k-1 Ar = preconditioner.SolveL(A.Mult(preconditioner.SolveU(r))); //Ar_k = L^-1 * A * U^-1 * r_k //Ar = A.SolveU(r); //Ar = AA.Mult(Ar); //Ar = A.SolveL(Ar); beta = -(p.ScalarMult(Ar) / p_p); z = preconditioner.SolveU(r).Add(z, 1, beta); //z_k = U^-1 * r_k + beta_k*z_k-1 p = Ar.Add(p, 1, beta); // p_k = L^-1 * A * U^-1 * r_k + beta_k*p_k-1 if (scalRR == 0) { Logger.WriteSolution(x, Maxiter, b.Add(A.Mult(x), -1, 1).Norm); Logger.WriteTime(start, DateTime.Now.ToString("dd.MM.yyyy hh:mm:ss:fff")); throw new DivideByZeroException("Division by 0"); } scalRR = r.ScalarMult(r); normR = Math.Sqrt(scalRR) / b.Norm; Factory.Residual.Add(normR); Logger.WriteIteration(iter, normR); if (double.IsNaN(normR) || double.IsInfinity(normR)) { Logger.WriteSolution(x, Maxiter, b.Add(A.Mult(x), -1, 1).Norm); Logger.WriteTime(start, DateTime.Now.ToString("dd.MM.yyyy hh:mm:ss:fff")); throw new CantSolveException(); } } Logger.WriteSolution(x, Maxiter, b.Add(A.Mult(x), -1, 1).Norm); Logger.WriteTime(start, DateTime.Now.ToString("dd.MM.yyyy hh:mm:ss:fff")); return(x); }