using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _03_1_Aproksymacja
{
  public class Poli
  {
    public double[] x;
    public double[] y;
    //stopień wielomianu
    public int m;
    //ilosć punktów == x.Length == y.Length
    public int n;
    //współczyniki wielomianu
    public double[] a;
    //
    public double[,] A;
    //kolumna wyrazów wolnych
    public double[] b;

    public double Y(double x0)
    {
      double r = 0;
      double dx = 1;
      for (int i = 0; i <= m; i++)
      {
        r = r + dx * a[i];
        dx = dx * x0;
      }
      return r;
    }

    public void WyznaczA()
    {
      A = new double[m + 1, m + 1];
      b = new double[m + 1];
      double[] rx = new double[n];
      double[] ry = new double[n];
      for (int i = 0; i < n; i++)
      {
        rx[i] = 1;
        ry[i] = y[i];
      }

      for (int j = 0; j <= m; j++)
      {
        int i = 0;
        double sum = 0;
        for (int k = 0; k < n; k++)
          sum = sum + rx[k];
        A[i, j] = sum;

        int i2 = i;
        int j2 = j;
        while ((j2 - 1) >= 0)
        {
          i2 = i2 + 1;
          j2 = j2 - 1;
          A[i2, j2] = sum;
        }

        double sumb = 0;
        for (int k = 0; k < n; k++)
          sumb += ry[k];
        b[j] = sumb;

        for (int k = 0; k < n; k++)
        {
          rx[k] = rx[k] * x[k];
          ry[k] = ry[k] * x[k];
        }
      }

      for (int i = 1; i <= m; i++)
      {
        int j = m;
        double sum = 0;
        for (int k = 0; k < n; k++)
          sum = sum + rx[k];
        A[i, j] = sum;

        int i2 = i;
        int j2 = j;
        while ((i2 + 1) <= m)
        {
          i2 = i2 + 1;
          j2 = j2 - 1;
          A[i2, j2] = sum;
        }

        for (int k = 0; k < n; k++)
          rx[k] = rx[k] * x[k];
      }

      Matrix<double> Am = DenseMatrix.OfArray(A);
      Vector<double> bm = DenseVector.OfArray(b);
      Vector<double> am = Am.Solve(bm);
      a = am.AsArray();
    }

    public double PoliczDlaX(double x0)
    {
      double sum = 0;
      double rx = 1;
      for (int i = 0; i <= m; i++)
      {
        sum = sum + a[i] * rx;
        rx = rx * x0;
      }
      return sum;
    }

  }
}
