protected static PolynomialDouble ShiftLeft(PolynomialDouble polynomial, int shift)
        {
            if (shift == 0)
            {
                return(polynomial);
            }

            shift = Math.Abs(shift);

            if (shift > polynomial.Length)
            {
                throw new DimensionMismatchException("Polynomial shift is greater than the length of a polynomial");
            }

            var rawResult = new double[polynomial.Length];


            for (int i = 0; i < polynomial.Length + shift; i++)
            {
                rawResult[i] = polynomial.Coefficients[i + shift];
            }

            var result = new PolynomialDouble(rawResult);

            return(result);
        }
 protected static PolynomialDouble Addition(PolynomialDouble polynomial, double scalar)
 {
     return(new PolynomialDouble(
                ElementWiseOperation(
                    polynomial,
                    scalar,
                    (a, b) => a + b
                    )));
 }
 protected static PolynomialDouble Mod(PolynomialDouble polynomial, int scalar)
 {
     return(new PolynomialDouble(
                ElementWiseOperation(
                    polynomial,
                    scalar,
                    (a, b) => a % b
                    )));
 }
        protected static PolynomialDouble Subtraction(PolynomialDouble polynomialLeft, PolynomialDouble polynomialRight)
        {
            var resultLength = Math.Max(polynomialLeft.Length, polynomialRight.Length);
            var rawResult    = new double[resultLength];

            for (int i = 0; i < resultLength; i++)
            {
                rawResult[i] =
                    (i < polynomialLeft.Length ? polynomialLeft.Coefficients[i] : 0.0) -
                    (i < polynomialRight.Length ? polynomialRight.Coefficients[i] : 0.0);
            }

            var result = new PolynomialDouble(rawResult);

            return(result);
        }
        public bool Equals(PolynomialDouble other)
        {
            if (Degree != other.Degree)
            {
                return(false);
            }

            var length = Math.Max(Length, other.Length);

            for (var i = 0; i < length; i++)
            {
                if (Math.Abs(
                        (i < Length ? Coefficients[i] : 0.0) - (i < other.Length ? other.Coefficients[i] : 0.0)
                        ) > Epsilon)
                {
                    return(false);
                }
            }
            return(true);
        }
        protected static PolynomialLongDivisionResult Division(PolynomialDouble polynomialDivident, PolynomialDouble polynomialDivisor)
        {
            if (polynomialDivisor.Degree < 0)
            {
                throw new ArgumentException("Can't divide by empty polynomial");
            }

            if (polynomialDivident.Degree < polynomialDivisor.Degree)
            {
                return(new PolynomialLongDivisionResult
                {
                    Result = new PolynomialDouble(0, 0.0),
                    Mod = polynomialDivident
                });
            }

            var divident = polynomialDivident.Clone();

            var rawResult = new double[polynomialDivident.Length];

            while (divident.Degree >= polynomialDivisor.Degree)
            {
                var degreeDifference = divident.Degree - polynomialDivisor.Degree;
                var divisorShifted   = polynomialDivisor >> (degreeDifference);

                rawResult[degreeDifference] = divident.Coefficients[divident.Degree] / divisorShifted.Coefficients[divident.Degree];

                divisorShifted = divisorShifted * rawResult[degreeDifference];

                divident = divident - divisorShifted;
            }

            var result = new PolynomialLongDivisionResult
            {
                Result = new PolynomialDouble(rawResult),
                Mod    = divident
            };

            return(result);
        }
        protected static PolynomialDouble Multiplication(PolynomialDouble polynomialLeft, PolynomialDouble polynomialRight)
        {
            if (polynomialLeft.IsZero() || polynomialRight.IsZero())
            {
                return(Helper.ZeroPolynomialDouble());
            }

            var resultLength = polynomialLeft.Length + polynomialRight.Length;
            var rawResult    = new double[resultLength];

            for (int i = 0; i < polynomialLeft.Length; i++)
            {
                for (int j = 0; j < polynomialRight.Length; j++)
                {
                    rawResult[i + j] += polynomialLeft.Coefficients[i] * polynomialRight.Coefficients[j];
                }
            }

            var result = new PolynomialDouble(rawResult);

            return(result);
        }