public RingPolynomial(IntPolynomial p1)
 {
     for (int i = 0; i < p1.size; i++)
     {
         this.Add(p1[i]);
     }
 }
        public static RingDecomposeList HenselLifting(IntPolynomial f, RingDecomposeList fFactorization, List <RingPolynomial> GCDCoeffs, int liftingDegree)
        {
            IntPolynomial hasSquares;

            IntPolynomial.GCD(f, f.Derivative(), out hasSquares);
            IntPolynomial SquareFreef = (f / hasSquares).Quotient;
            BigInteger    squareCoeff = hasSquares[hasSquares.size - 1];

            SquareFreef *= squareCoeff;

            BigInteger p = RingBint.mod;

            BigInteger           OriginalCoeff = SquareFreef[SquareFreef.size - 1];
            List <IntPolynomial> LiftingList   = new List <IntPolynomial>();

            for (int i = 0; i < fFactorization.CountUniq; i++)
            {
                LiftingList.Add(new IntPolynomial(fFactorization[i]));
            }
            LiftingList[0] *= OriginalCoeff;

            for (int t = 1; t < liftingDegree; t++)
            {
                IntPolynomial multiplyFactor = new IntPolynomial {
                    1
                };
                for (int i = 0; i < LiftingList.Count; i++)
                {
                    multiplyFactor *= new IntPolynomial(LiftingList[i]);
                }

                var            temp = SquareFreef - multiplyFactor;
                RingPolynomial d    = new RingPolynomial(temp / BigInteger.Pow(p, t));


                for (int i = 0; i < fFactorization.CountUniq; i++)
                {
                    RingPolynomial CurrUniqPoly = fFactorization[i];
                    if (i == 0)
                    {
                        CurrUniqPoly *= fFactorization.polyCoef;
                    }
                    RingPolynomial Gc = (d * GCDCoeffs[i] / CurrUniqPoly).Reminder;
                    SetModContext(p, t + 1);
                    LiftingList[i] = LiftingList[i] + new IntPolynomial(Gc) * BigInteger.Pow(p, t);
                    SetModContext(p);
                }
                Program.Log("Разложение поднято до " + BigInteger.Pow(p, t + 1));
            }
            SetModContext(p, liftingDegree);
            RingDecomposeList liftigRes = new RingDecomposeList();

            for (int i = 0; i < LiftingList.Count; i++)
            {
                liftigRes.Add(new RingPolynomial(LiftingList[i]));
            }
            liftigRes.polyCoef = OriginalCoeff;
            return(liftigRes);
        }
Esempio n. 3
0
        static bool IntPolynomialFactorisationTest(string mode = "easy")
        {
            IntPolynomial     f = prepareIntPolyForFactor(mode);
            RingDecomposeList fFactorisation;
            var LiftedFactorisation = f.FactorIntPolynomialOverBigModule(out fFactorisation);

            RingPolynomial res = new RingPolynomial {
                1
            };

            Program.Log();
            Program.Log("Получена факторизация:");
            for (int i = 0; i < LiftedFactorisation.CountUniq; i++)
            {
                for (int j = 0; j < fFactorisation.divisors[i].count; j++)
                {
                    RingPolynomial currPoly;
                    if (i == 0 && j == 0)
                    {
                        currPoly = LiftedFactorisation[i] * LiftedFactorisation.polyCoef;
                    }
                    else
                    {
                        currPoly = LiftedFactorisation[i];
                    }

                    currPoly.Print('g');
                    res *= currPoly;
                }
            }
            Program.Log();

            Program.Log("Проверка на соответствие исходному многочлену произведения:");
            Program.recDepth++;
            Program.Log("Исходный многочлен");
            f.Print();
            Program.Log("Результат перемножения факторизации:");
            res.Print();
            Program.recDepth--;

            IntPolynomial resInt = new IntPolynomial(res);

            if (f == resInt)
            {
                Program.Log("Верно!");
                return(true);
            }
            else
            {
                Program.Log("Неверно...");
                return(false);
            }
        }
Esempio n. 4
0
        static IntPolynomial prepareIntPolyForFactor(string mode)
        {
            int minCoef    = 1;
            int maxCoef    = 1;
            int minNumMult = 1;
            int maxNumMult = 1;
            int minSize    = 1;
            int maxSize    = 1;

            switch (mode)
            {
            case "easy":
                minCoef    = 1;
                maxCoef    = 6;
                minNumMult = 3;
                maxNumMult = 3;
                minSize    = 2;
                maxSize    = 2;
                break;

            case "medium":
                minCoef    = 1;
                maxCoef    = 10;
                minNumMult = 3;
                maxNumMult = 3;
                minSize    = 3;
                maxSize    = 3;
                break;

            case "post-medium":
                minCoef    = 1;
                maxCoef    = 5;
                minNumMult = 4;
                maxNumMult = 5;
                minSize    = 3;
                maxSize    = 5;
                break;

            case "hard":
                minCoef    = 1;
                maxCoef    = 5;
                minNumMult = 10;
                maxNumMult = 10;
                minSize    = 2;
                maxSize    = 5;
                break;

            case "ultra":
                minCoef    = 1;
                maxCoef    = 5;
                minNumMult = 10;
                maxNumMult = 30;
                minSize    = 2;
                maxSize    = 15;
                break;
            }
            Random rnd = new Random();

            IntPolynomial f = new IntPolynomial {
                rnd.Next(minCoef, maxCoef)
            };
            int NumCoeffs = rnd.Next(minNumMult, maxNumMult);

            for (int i = 0; i < NumCoeffs; i++)
            {
                IntPolynomial temp = new IntPolynomial {
                    rnd.Next(minCoef, maxCoef)
                };
                int SizeCoeff = rnd.Next(minSize, maxSize);
                for (int j = 0; j < SizeCoeff; j++)
                {
                    temp[j] = (BigInteger)rnd.Next(minCoef, maxCoef);
                }
                f *= temp;
            }

            return(f);
        }
Esempio n. 5
0
        static void LiftingTest()
        {
            IntPolynomial f = new IntPolynomial {
                1, 2, 3
            } *new IntPolynomial {
                1, 2
            };

            IntPolynomial squares;

            IntPolynomial.GCD(f, f.Derivative(), out squares);
            IntPolynomial SquareFreef = (f / squares).Quotient;
            BigInteger    mod         = IntPolynomial.SelectAppropriateMod(f, SquareFreef);

            RingPolynomial.SetModContext(mod);
            Console.WriteLine("Выбранный модуль кольца: " + mod + "\n");

            RingPolynomial f_inring      = new RingPolynomial(f);
            var            factorization = f_inring.BerlekampFactor();
            var            GCDfactor     = RingPolynomial.GetGCDCoefficientForHensel(factorization);
            RingPolynomial allGCDResult  = new RingPolynomial {
                0
            };

            List <RingPolynomial> factorsOfCoeff = new List <RingPolynomial>();

            for (int i = 0; i < factorization.CountUniq; i++)
            {
                factorsOfCoeff.Add(new RingPolynomial {
                    1
                });
            }
            for (int i = 0; i < factorization.CountUniq; i++)
            {
                for (int j = 0; j < factorization.CountUniq; j++)
                {
                    if (i != j)
                    {
                        factorsOfCoeff[i] *= factorization[j];
                        Console.Write("(" + factorization[j] + ")*");
                    }
                }
                if (i != 0)
                {
                    factorsOfCoeff[i] *= factorization.polyCoef;
                }
                allGCDResult += factorsOfCoeff[i] * GCDfactor[i];
                Console.Write("(" + GCDfactor[i] + ")\n");
            }
            allGCDResult.Print();

            // после поднятия mod уже увеличился
            var liftedDecomposition = RingPolynomial.HenselLifting(f, factorization, GCDfactor, 20);

            RingPolynomial checkLiftedDecomposition = new RingPolynomial {
                1
            };


            for (int i = 0; i < liftedDecomposition.CountUniq; i++)
            {
                for (int j = 0; j < factorization.divisors[i].count; j++)
                {
                    if (i == 0 && j == 0)
                    {
                        (liftedDecomposition[i] * f[f.size - 1]).Print();
                        checkLiftedDecomposition *= (liftedDecomposition[i] * f[f.size - 1]);
                    }
                    else
                    {
                        liftedDecomposition[i].Print();
                        checkLiftedDecomposition *= liftedDecomposition[i];
                    }
                }
            }
            Program.Log("Проверяем декомпозицию поднятую:");
            checkLiftedDecomposition.Print('r');
            f.Print();
        }
        static void Main(string[] args)
        {
            Console.ForegroundColor = ConsoleColor.White;

            Console.WriteLine("Выберите пример (1 - НОД, 2 - Берлекамп, 3 - Гензель)");

            int chosen_example = Console.Read() - '0';

            if (chosen_example == 1)
            {
                int mod = 13;
                RingPolynomial.SetModContext(mod);

                Console.WriteLine("Выбран НОД.");
                Console.WriteLine("1) НОД полиномов над R[x]: (Расширенный алгоритм Евклида)");
                Polynomial f_r = new Polynomial {
                    1, 1, 1
                } *new Polynomial {
                    (decimal)0.5, 1, 1
                } *new Polynomial {
                    2, 1
                };
                f_r.Print('f');
                Polynomial g_r = new Polynomial {
                    1, 1
                } *new Polynomial {
                    7, 7, 7
                } *new Polynomial {
                    3, 1
                };
                g_r.Print('g');
                Console.WriteLine("Их НОД и коэффициенты:");
                Polynomial gcd_r;

                Polynomial.GCDResult coeffs = Polynomial.GCD(f_r, g_r, out gcd_r);

                Console.WriteLine(gcd_r + " = (" + coeffs.Coef1 + ")*(" + f_r + ") + (" + coeffs.Coef2 + ")*(" + g_r + ")");

                Console.WriteLine("---------------------------------------------------------");

                Console.WriteLine("2) НОД полиномов над Zp[x]: (Расширенный алгоритм Евклида), модуль p = " + mod);
                RingPolynomial f_p = new RingPolynomial {
                    2, 1, 1
                } *new RingPolynomial {
                    5, 1
                } *new RingPolynomial {
                    2, 1
                };
                f_p.Print('f');
                RingPolynomial g_p = new RingPolynomial {
                    1, 1
                } *new RingPolynomial {
                    14, 7, 7
                } *new RingPolynomial {
                    3, 1
                };
                g_p.Print('g');
                Console.WriteLine("Их НОД и коэффициенты:");
                RingPolynomial gcd_p;

                RingPolynomial.GCDResult coeffs_p = RingPolynomial.GCD(f_p, g_p, out gcd_p);

                Console.WriteLine(gcd_p + " = (" + coeffs_p.Coef1 + ")*(" + f_p + ") + (" + coeffs_p.Coef2 + ")*(" + g_p + ")");

                Console.WriteLine("---------------------------------------------------------");

                Console.WriteLine("3) НОД полиномов над Z[x]: (алгоритм Евклида с псевдоделением)");
                IntPolynomial f_z = new IntPolynomial {
                    1, 1
                } *new IntPolynomial {
                    5, 1
                } *new IntPolynomial {
                    2, 1
                };
                f_z.Print('f');
                IntPolynomial g_z = new IntPolynomial {
                    1, 1
                } *new IntPolynomial {
                    2, 7, 7
                } *new IntPolynomial {
                    3, 1
                } *new IntPolynomial {
                    2, 1
                };
                g_z.Print('g');
                Console.WriteLine("Их НОД:");
                IntPolynomial gcd_z;
                IntPolynomial.GCD(f_z, g_z, out gcd_z);

                Console.WriteLine(gcd_z);
            }
            else if (chosen_example == 2)
            {
                int mod = 7;
                RingPolynomial.SetModContext(mod);
                Console.WriteLine("Выбран алгоритм Берклемпа факторизации многочлена. Модуль кольца равен: " + mod);
                RingPolynomial f = new RingPolynomial {
                    2, 1
                } *new RingPolynomial {
                    5, 1
                } *new RingPolynomial {
                    25, 10
                } *new RingPolynomial {
                    3, 1
                } *new RingPolynomial {
                    1, 1, 1
                };

                var LiftedFactorisation = f.BerlekampFactor();

                RingPolynomial res = new RingPolynomial {
                    1
                };
                Program.Log("Получена факторизация:");
                for (int i = 0; i < LiftedFactorisation.CountUniq; i++)
                {
                    for (int j = 0; j < LiftedFactorisation.divisors[i].count; j++)
                    {
                        RingPolynomial currPoly;
                        if (i == 0 && j == 0)
                        {
                            currPoly = LiftedFactorisation[i] * LiftedFactorisation.polyCoef;
                        }
                        else
                        {
                            currPoly = LiftedFactorisation[i];
                        }

                        currPoly.Print('g');
                        res *= currPoly;
                    }
                }

                Program.Log("Проверка на соответствие исходному многочлену произведения:");
                Program.recDepth++;
                Program.Log("Исходный многочлен");
                f.Print();
                Program.Log("Результат перемножения факторизации:");
                res.Print();
                Program.recDepth--;

                if (f == res)
                {
                    Program.Log("Верно!");
                }
                else
                {
                    Program.Log("Неверно...");
                }
            }
            else if (chosen_example == 3)
            {
                IntPolynomial f = new IntPolynomial {
                    1, 2
                } *new IntPolynomial {
                    1, 4
                } *new IntPolynomial {
                    1, 4
                } *new IntPolynomial {
                    1, 5
                } *new IntPolynomial {
                    1, 3, 4, 2, 3, 4, 6
                };

                IntPolynomial hasSquares;
                IntPolynomial.GCD(f, f.Derivative(), out hasSquares);
                IntPolynomial SquareFreef = (f / hasSquares).Quotient;

                Console.WriteLine("Выбран алгоритм Гензеля подъема многочленов.");

                Console.WriteLine("Поиск подходящего модуля кольца: ");
                BigInteger mod = IntPolynomial.SelectAppropriateMod(f, SquareFreef);
                Console.WriteLine("Найденный модуль: " + mod);

                RingPolynomial.SetModContext(mod);

                Console.WriteLine("Изначальный многочлен над Z[x]");
                f.Print();
                RingPolynomial f_inring = new RingPolynomial(f);
                Console.WriteLine("Разложение его над Z" + mod + "[x]:");
                var            factorization = f_inring.BerlekampFactor();
                var            GCDfactor     = RingPolynomial.GetGCDCoefficientForHensel(factorization);
                RingPolynomial allGCDResult  = new RingPolynomial {
                    0
                };

                List <RingPolynomial> factorsOfCoeff = new List <RingPolynomial>();
                Console.WriteLine("Подбор коэффициентов для представления единицы в алгоритме Гензеля:");
                Console.WriteLine("Отдельные слагаемые с коэффициентами:");
                for (int i = 0; i < factorization.CountUniq; i++)
                {
                    factorsOfCoeff.Add(new RingPolynomial {
                        1
                    });
                }
                for (int i = 0; i < factorization.CountUniq; i++)
                {
                    for (int j = 0; j < factorization.CountUniq; j++)
                    {
                        if (i != j)
                        {
                            factorsOfCoeff[i] *= factorization[j];
                            Console.Write("(" + factorization[j] + ")*");
                        }
                    }
                    if (i != 0)
                    {
                        factorsOfCoeff[i] *= factorization.polyCoef;
                    }
                    allGCDResult += factorsOfCoeff[i] * GCDfactor[i];
                    Console.Write("(" + GCDfactor[i] + ")\n");
                }
                Console.WriteLine("Проверка их суммы на равенство 1:");
                allGCDResult.Print();

                // после поднятия mod уже увеличился
                var            liftedDecomposition      = RingPolynomial.HenselLifting(f, factorization, GCDfactor, 4);
                RingPolynomial checkLiftedDecomposition = new RingPolynomial {
                    1
                };

                Console.WriteLine("Поднятая факторизация:");
                for (int i = 0; i < liftedDecomposition.CountUniq; i++)
                {
                    for (int j = 0; j < factorization.divisors[i].count; j++)
                    {
                        if (i == 0 && j == 0)
                        {
                            (liftedDecomposition[i] * f[f.size - 1]).Print();
                            checkLiftedDecomposition *= (liftedDecomposition[i] * f[f.size - 1]);
                        }
                        else
                        {
                            liftedDecomposition[i].Print();
                            checkLiftedDecomposition *= liftedDecomposition[i];
                        }
                    }
                }
                Program.Log("Проверяем декомпозицию поднятую:");
                checkLiftedDecomposition.Print('r');
                f.Print();
            }

            Console.Read();
        }
        public static RingDecomposeList HenselLiftingUntilTheEnd(IntPolynomial f, RingDecomposeList fFactorization, List <RingPolynomial> GCDCoeffs)
        {
            IntPolynomial hasSquares;

            IntPolynomial.GCD(f, f.Derivative(), out hasSquares);
            IntPolynomial SquareFreef = (f / hasSquares).Quotient;
            BigInteger    squareCoeff = hasSquares[hasSquares.size - 1];

            SquareFreef *= squareCoeff;

            BigInteger p = RingBint.mod;

            BigInteger OriginalCoeff = f[f.size - 1];
            BigInteger biggestCoeff  = SquareFreef[0];

            for (int i = 1; i < SquareFreef.size; i++)
            {
                if (SquareFreef[i] > biggestCoeff)
                {
                    biggestCoeff = SquareFreef[i];
                }
            }
            List <IntPolynomial> LiftingList = new List <IntPolynomial>();

            for (int i = 0; i < fFactorization.CountUniq; i++)
            {
                LiftingList.Add(new IntPolynomial(fFactorization[i]));
            }
            LiftingList[0] *= OriginalCoeff;
            bool Decomposed = false;

            int        t       = 1;
            BigInteger currMod = p;

            while (!Decomposed)
            {
                currMod = BigInteger.Pow(p, t + 1);
                IntPolynomial multiplyFactor = new IntPolynomial {
                    1
                };
                for (int i = 0; i < LiftingList.Count; i++)
                {
                    multiplyFactor *= LiftingList[i];
                }

                var            temp = SquareFreef - multiplyFactor;
                RingPolynomial d    = new RingPolynomial(temp / BigInteger.Pow(p, t));


                for (int i = 0; i < fFactorization.CountUniq; i++)
                {
                    RingPolynomial CurrUniqPoly = new RingPolynomial(fFactorization[i]);
                    if (i == 0)
                    {
                        CurrUniqPoly *= fFactorization.polyCoef;
                    }
                    RingPolynomial Gc = ((d * GCDCoeffs[i]) / CurrUniqPoly).Reminder;
                    SetModContext(p, t + 1);
                    LiftingList[i] = LiftingList[i] + new IntPolynomial(Gc) * BigInteger.Pow(p, t);
                    SetModContext(p);
                }
                t++;
                Program.Log("Разложение поднято до " + currMod);
                if (currMod > biggestCoeff)
                {
                    SetModContext(p, t);
                    RingPolynomial res = new RingPolynomial {
                        1
                    };
                    RingPolynomial FirstWithoutCoeff = new RingPolynomial(LiftingList[0]) / LiftingList[0][LiftingList[0].degree];
                    for (int u = 0; u < fFactorization.CountUniq; u++)
                    {
                        for (int j = 0; j < fFactorization.divisors[u].count; j++)
                        {
                            if (j != 0 && u == 0)
                            {
                                res *= FirstWithoutCoeff;
                            }
                            else
                            {
                                res *= new RingPolynomial(LiftingList[u]);
                            }
                        }
                    }
                    IntPolynomial resInt = new IntPolynomial(res);
                    if (f == resInt)
                    {
                        Decomposed = true;
                    }
                }
            }

            SetModContext(p, t);
            RingDecomposeList liftigRes = new RingDecomposeList();

            for (int i = 0; i < LiftingList.Count; i++)
            {
                liftigRes.Add(new RingPolynomial(LiftingList[i]));
            }
            liftigRes.polyCoef = OriginalCoeff;
            return(liftigRes);
        }