// H^j(x) part of the formula
        // which is H^j(x) = (x-xj)*l2j(x)
        // the jIndex is the j of the formula (surprise!!!)
        // and x is the argument of the function
        private double HchapeaujX(int jIndex, double x)
        {
            // the (x-xj) part
            double leftPart = (x - interpolationSamples[samplesXIndex, jIndex]);

            // the l2j(x) part
            double rightPart = Math.Pow(LagrangeMethod.langrangeForX(jIndex, x, interpolationSamples), 2);

            return(leftPart * rightPart);
        }
        // Hj(x) part of the formula
        // which is Hj(x) = [1-2(x-xj)*l'j(xj)]*l2j(x)
        // the jIndex is the j of the formula (surprise!!!)
        // and x is the argument of the function
        private double HjX(int jIndex, double x)
        {
            // the [1-2(x-xj)*l'j(xj)] part
            double leftPart = 0;

            // the l'j(xj) part
            double lagDerivative = LagrangeDiffrentiationMethod.lagrangeDerivative(jIndex, interpolationSamples[samplesXIndex, jIndex], interpolationSamples);

            leftPart = (1 - (2 * (x - interpolationSamples[samplesXIndex, jIndex]) * lagDerivative));

            // the l2j(x) part
            double rightPart = Math.Pow(LagrangeMethod.langrangeForX(jIndex, x, interpolationSamples), 2);

            return(leftPart * rightPart);
        }
        private string HjStringForX(int jIndex)
        {
            double currentXi = interpolationSamples[samplesXIndex, jIndex];

            // the [1-2(x-xj)*l'j(xj)] part


            // build Hj(x) string

            // first the [1-2(x-xj)*l'j(xj)]
            // note that the Hj(x) formula can be changed from
            // [1-2(x-xj)*l'j(xj)]*l2j(x) to [a*x - b]* l2j(x)
            // where a = 2 * l'j(xj) and b = a * xj + 1
            double        a             = 2 * LagrangeDiffrentiationMethod.lagrangeDerivative(jIndex, interpolationSamples[samplesXIndex, jIndex], interpolationSamples);
            double        b             = a * currentXi + 1;
            char          bInversedSign = b >= 0 ? '-' : '+';
            StringBuilder builder       = new StringBuilder("[" + UIDoubleAbs(a) + "x " + bInversedSign + " " + UIDoubleAbs(b) + "]");


            // the l2j(x) part
            builder.Append("(" + LagrangeMethod.langrangeString(jIndex, interpolationSamples) + ")^2");

            return(builder.ToString());
        }
        // H^j(x) part of the formula
        // which is H^j(x) = (x-xj)*l2j(x)
        // the jIndex is the j of the formula (surprise!!!)
        // and x is the argument of the function
        private string HchapeaujStringForX(int jIndex)
        {
            double currentXi             = interpolationSamples[samplesXIndex, jIndex];
            char   currentXiReversedSign = currentXi >= 0 ? '-' : '+';


            // the (x-xj) part
            StringBuilder builder = new StringBuilder();

            if (UIDoubleAbs(currentXi) == 0)
            {
                builder.Append("(x)");
            }

            else
            {
                builder.Append("(x " + currentXiReversedSign + " " + UIDoubleAbs(currentXi) + ")");
            }

            // the l2j(x) part
            builder.Append("[" + LagrangeMethod.langrangeString(jIndex, interpolationSamples) + "]^2");

            return(builder.ToString());
        }