private void SubdivideSegment(float from, float to, int level)
    {
        //Profiler.BeginSample( "Approximation" );
        var coefficients = CalculateChebyshefCoefficients(maxDegree, from, to);
        var error        = 0f;

        for (var i = desiredDegree; i < maxDegree; ++i)
        {
            error += Mathf.Abs(coefficients[i]);
        }

        if (error < maxError || level > maxLevel)
        {
            //Profiler.BeginSample( "Compose" );
            var approximation = new ChebyshevApproximation();
            approximation.CopyCoefficients(f, from, to, desiredDegree, coefficients, 0, desiredDegree);
            //Profiler.EndSample();

            //Profiler.BeginSample( "Insertion" );
            approximations.Add(approximation);
            //Profiler.EndSample();
        }
        else
        {
            var mid = (from + to) * 0.5f;

            SubdivideSegment(from, mid, level + 1);
            SubdivideSegment(mid, to, level + 1);
        }
        //Profiler.EndSample();
    }
        private void DrawChebyshevTable()
        {
            float[] xValues = new float[]
            {
                -3.2f, -2.1f, 0.4f, 0.7f, 2.0f, 2.5f, 2.777f
            };
            float[] yValues = new float[]
            {
                10.0f, -2.0f, 0, -7.0f, 7.0f, 0, 0
            };

            float a = xValues[0];
            float b = xValues[xValues.Length - 1];

            var coefs = ChebyshevApproximation.Approximate(xValues, yValues, 0);

            coefs = ChebyshevApproximation.Approximate(xValues, yValues, 1);
            MnkK1Plotter.ItemsSource = GeneratePoints(coefs, a, b);

            coefs = ChebyshevApproximation.Approximate(xValues, yValues, 2);
            MnkK2Plotter.ItemsSource = GeneratePoints(coefs, a, b);

            coefs = ChebyshevApproximation.Approximate(xValues, yValues, 3);
            MnkK3Plotter.ItemsSource = GeneratePoints(coefs, a, b);

            coefs = ChebyshevApproximation.Approximate(xValues, yValues, 4);
            MnkK4Plotter.ItemsSource = GeneratePoints(coefs, a, b);

            coefs = ChebyshevApproximation.Approximate(xValues, yValues, 5);
            MnkK5Plotter.ItemsSource = GeneratePoints(coefs, a, b);

            coefs = ChebyshevApproximation.Approximate(xValues, yValues, 6);
            MnkK6Plotter.ItemsSource = GeneratePoints(coefs, a, b);
        }
        private void DrawChebyshevFunc()
        {
            var coefs = ChebyshevApproximation.Approximate(a, b, 1, ApproximatedFunction);

            MnkK1Plotter.ItemsSource = GeneratePoints(coefs, a, b);

            coefs = ChebyshevApproximation.Approximate(a, b, 2, ApproximatedFunction);
            MnkK2Plotter.ItemsSource = GeneratePoints(coefs, a, b);

            coefs = ChebyshevApproximation.Approximate(a, b, 3, ApproximatedFunction);
            MnkK3Plotter.ItemsSource = GeneratePoints(coefs, a, b);

            coefs = ChebyshevApproximation.Approximate(a, b, 4, ApproximatedFunction);
            MnkK4Plotter.ItemsSource = GeneratePoints(coefs, a, b);

            coefs = ChebyshevApproximation.Approximate(a, b, 5, ApproximatedFunction);
            MnkK5Plotter.ItemsSource = GeneratePoints(coefs, a, b);

            coefs = ChebyshevApproximation.Approximate(a, b, 6, ApproximatedFunction);
            MnkK6Plotter.ItemsSource = GeneratePoints(coefs, a, b);

            coefs = ChebyshevApproximation.Approximate(a, b, 7, ApproximatedFunction);
            MnkK7Plotter.ItemsSource = GeneratePoints(coefs, a, b);

            coefs = ChebyshevApproximation.Approximate(a, b, 8, ApproximatedFunction);
            MnkK8Plotter.ItemsSource = GeneratePoints(coefs, a, b);

            coefs = ChebyshevApproximation.Approximate(a, b, 9, ApproximatedFunction);
            MnkK9Plotter.ItemsSource = GeneratePoints(coefs, a, b);
        }
        private static float[] GenerateX(float a, float b, float step)
        {
            int pointCount = ChebyshevApproximation.CalculateRank(a, b, step);
            var result     = new float[pointCount];

            for (int i = 0; i < pointCount; i++)
            {
                result[i] = a + i * step;
            }
            return(result);
        }
        private List <Point> GeneratePoints(float[] coefficients, float a, float b)
        {
            var points = new List <Point>();

            for (float i = a; i <= b; i += 0.001f)
            {
                float x = ChebyshevApproximation.Squish(i, a, b);
                float y = ChebyshevApproximation.Evaluate(coefficients, x);
                points.Add(new Point(i, y));
            }

            return(points);
        }
        public void ApproximateTableValues()
        {
            float[] xValues = new float[]
            {
                -3.2f, -2.1f, 0.4f, 0.7f, 2.0f, 2.5f, 2.777f
            };
            float[] yValues = new float[]
            {
                10.0f, -2.0f, 0, -7.0f, 7.0f, 0, 0
            };
            var polynom = ChebyshevApproximation.Approximate(xValues, yValues, xValues.Length - 1);

            Assert.That(polynom.Length == xValues.Length);
        }
        private void DrawBasePoints(FittingFunction fittingFunction)
        {
            var points  = new List <Point>();
            var xValues = ChebyshevApproximation.GenerateX(a, b, step);

            for (int i = 0; i < xValues.Length; i++)
            {
                points.Add(new Point(xValues[i], fittingFunction(xValues[i])));
            }

            RealDataPlotFor1.ItemsSource = RealDataPlotFor2.ItemsSource = RealDataPlotFor3.ItemsSource
                                                                              = RealDataPlotFor4.ItemsSource = RealDataPlotFor5.ItemsSource = RealDataPlotFor6.ItemsSource
                                                                                                                                                  = RealDataPlotFor7.ItemsSource = RealDataPlotFor8.ItemsSource = RealDataPlotFor9.ItemsSource
                                                                                                                                                                                                                      = points;
        }
        public void Approximate()
        {
            float a       = -2.0f;
            float b       = 2.0f;
            float step    = 0.5f;
            int   rank    = ChebyshevApproximation.CalculateRank(a, b, step);
            var   polynom = ChebyshevApproximation.Approximate(a, b, rank, myFunc);

            List <float> results = new List <float>();
            var          xApprox = GenerateX(a, b, 0.0001f);

            for (float i = a; i <= b; i += 0.0001f)
            {
                float x = ChebyshevApproximation.Squish(i, a, b);
                results.Add(ChebyshevApproximation.Evaluate(polynom, x));
            }
            Assert.That(polynom.Length == rank + 1);
        }
        public void CompareTableAndFunc()
        {
            float a       = -2.0f;
            float b       = 2.0f;
            float step    = 0.5f;
            int   rank    = ChebyshevApproximation.CalculateRank(a, b, step);
            var   xValues = GenerateX(a, b, step);
            var   yValues = new float[rank];

            for (int i = 0; i < rank; i++)
            {
                yValues[i] = (float)myFunc(xValues[i]);
            }

            var expectedCoefficients = new Matrix(ChebyshevApproximation.Approximate(a, b, rank - 1, myFunc));

            var actualCoefficients = new Matrix(ChebyshevApproximation.Approximate(xValues, yValues, xValues.Length - 1));

            Assert.That(actualCoefficients.NearEquals(expectedCoefficients, (float)Math.PI + 0.2f), $"Expected: {expectedCoefficients.ToString()}, actual {actualCoefficients.ToString()}");
        }
        private void DemoTable_Chebyshev_Click(object sender, RoutedEventArgs e)
        {
            CleanDataSources();
            float[] xValues = new float[]
            {
                0, 3.3f, 6.6f, 9.9f
            };
            float[] yValues = new float[]
            {
                2.1f, 5.9f, 2.4f, 3.4f
            };


            var coefs = ChebyshevApproximation.Approximate(
                xValues,
                yValues,
                1
                );

            MnkK1Plotter.ItemsSource = GeneratePoints(coefs, xValues[0], xValues[xValues.Length - 1]);

            coefs = ChebyshevApproximation.Approximate(
                xValues,
                yValues,
                2
                );

            MnkK2Plotter.ItemsSource = GeneratePoints(coefs, xValues[0], xValues[xValues.Length - 1]);

            coefs = ChebyshevApproximation.Approximate(
                xValues,
                yValues,
                3
                );

            MnkK3Plotter.ItemsSource = GeneratePoints(coefs, xValues[0], xValues[xValues.Length - 1]);


            DrawBasePoints(xValues, yValues);
        }
        private void DrawMSE_Func()
        {
            var rank    = ChebyshevApproximation.CalculateRank(a, b, step);
            var xValues = new Libs.Matrix(ChebyshevApproximation.GenerateX(a, b, step));
            var yValues = new Libs.Matrix(new float[rank, 1]);

            for (int j = 0; j < yValues.Height; j++)
            {
                yValues[j, 0] = (float)ApproximatedFunction(xValues[0, j]);
            }

            var coefs = MeanSquaredErrorApproximation.Approximate(xValues, yValues, 1);

            MnkK1Plotter.ItemsSource = GeneratePoints(coefs);

            coefs = MeanSquaredErrorApproximation.Approximate(xValues, yValues, 2);
            MnkK2Plotter.ItemsSource = GeneratePoints(coefs);

            coefs = MeanSquaredErrorApproximation.Approximate(xValues, yValues, 3);
            MnkK3Plotter.ItemsSource = GeneratePoints(coefs);

            coefs = MeanSquaredErrorApproximation.Approximate(xValues, yValues, 4);
            MnkK4Plotter.ItemsSource = GeneratePoints(coefs);

            coefs = MeanSquaredErrorApproximation.Approximate(xValues, yValues, 5);
            MnkK5Plotter.ItemsSource = GeneratePoints(coefs);

            coefs = MeanSquaredErrorApproximation.Approximate(xValues, yValues, 6);
            MnkK6Plotter.ItemsSource = GeneratePoints(coefs);

            coefs = MeanSquaredErrorApproximation.Approximate(xValues, yValues, 7);
            MnkK7Plotter.ItemsSource = GeneratePoints(coefs);

            coefs = MeanSquaredErrorApproximation.Approximate(xValues, yValues, 8);
            MnkK8Plotter.ItemsSource = GeneratePoints(coefs);

            coefs = MeanSquaredErrorApproximation.Approximate(xValues, yValues, 9);
            MnkK9Plotter.ItemsSource = GeneratePoints(coefs);
        }
    private void SubdivideSegment( float from, float to, int level )
    {
        //Profiler.BeginSample( "Approximation" );
        var coefficients = CalculateChebyshefCoefficients( maxDegree, from, to );
        var error = 0f;

        for ( var i = desiredDegree; i < maxDegree; ++i ) {
            error += Mathf.Abs( coefficients[i] );
        }

        if ( error < maxError || level > maxLevel ) {
            //Profiler.BeginSample( "Compose" );
            var approximation = new ChebyshevApproximation();
            approximation.CopyCoefficients( f, from, to, desiredDegree, coefficients, 0, desiredDegree );
            //Profiler.EndSample();

            //Profiler.BeginSample( "Insertion" );
            approximations.Add( approximation );
            //Profiler.EndSample();
        } else {
            var mid = ( from + to ) * 0.5f;

            SubdivideSegment( from, mid, level + 1 );
            SubdivideSegment( mid, to, level + 1 );
        }
        //Profiler.EndSample();
    }