using _04_2_Gauss;
using System;

namespace _06_2_Newton_ulady_rownan
{

  public delegate double FW(double[] x);

  public class NewtonRaphson
  {
    public FW[] funcs;
    public FW[,] fprims;
    public double eps;
    public double[] x0;

    double[,] J;
    double[] B;
    double[] x;
    double[] H;
    int N;

    public int licznik;

    void Init()
    {
      B = new double[N];
      J = new double[N, N];
    }

    public double[] Oblicz()
    {
      N = x0.Length;
      Init();
      licznik = 0;
      x = (double[])x0.Clone();
      do
      {
        licznik++;
        LiczB();
        LiczJ();
        LiczH();
        DodajH2X();
      } while (Norma() > eps);
      return x;
    }
    private void LiczB()
    {
      for (int i = 0; i < N; i++)
        B[i] = -funcs[i](x);
    }
    private void LiczJ()
    {
      for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
          J[i, j] = fprims[i, j](x);
    }
    private void LiczH()
    {
      Gauss g = new Gauss();
      g.A = J;
      g.b = B;
      g.Wybor = MetodaWyboru.Czesciowy;
      H = g.Oblicz();
    }

    private void DodajH2X()
    {
      for (int i = 0; i < N; i++)
        x[i] = x[i] + H[i];
    }

    private double Norma()
    {
      double sum = 0;
      for (int i = 0; i < N; i++)
        sum = sum + H[i] * H[i];
      sum = Math.Sqrt(sum);
      return sum;
    }
  }
}
