public static ComplexPolynom MultiplyPol(ComplexPolynom poly, Complex j, string type = "line") { if (type == "line") // (x-j) { ComplexPolynom t = new ComplexPolynom(new List <ComplexMonom> { new ComplexMonom(1, 1), new ComplexMonom(0, -j) }); t = t * poly; return(t); } else if (type == "quadr") // X^2 - 2Re(j)X + |j|^2 { ComplexPolynom t = new ComplexPolynom(new List <ComplexMonom> { new ComplexMonom(2, 1), new ComplexMonom(1, 2 * j.Real), new ComplexMonom(0, j.Magnitude * j.Magnitude) }); t = t * poly; return(t); } else { return(null); } }
/// <summary> /// Параметры кривых полученных комплексным умножением /// </summary> /// <param name="D">Фундаментальный Дискриминант</param> /// <returns></returns> private List <BigInteger[]> GetCurveComplexMultiply(int D) { List <BigInteger[]> paramCurve = new List <BigInteger[]>(); BigInteger g = GetNonQuadr(); if (D == -3) { for (int i = 0; i < 6; i++) { paramCurve.Add(new BigInteger[] { 0, -BigInteger.ModPow(g, i, Number) }); } return(paramCurve); } else if (D == -4) { for (int i = 0; i < 4; i++) { paramCurve.Add(new BigInteger[] { -BigInteger.ModPow(g, i, Number), 0 }); } return(paramCurve); } else { Polynom GilbPolFp; if (GilbertPolynoms.ContainsKey(D)) { ComplexPolynom GilbPol; GilbertPolynoms.TryGetValue(D, out GilbPol); GilbPolFp = GilbPol.GetPolynomReal(Number); } else { ComplexPolynom GilbPol = Extension.GilbertPolynom(D); GilbertPolynoms.Add(D, GilbPol); GilbPolFp = GilbPol.GetPolynomReal(Number); } //--------------------------------------------------------------- //-----------------Получение корня полинома---------------------- BigInteger root; if (GilbPolFp.Degree <= 2) { var roots = GilbPolFp.GetRoots(); if (roots.Count != 0) { root = roots[0]; } else { return(null); } } else { #region Поиск нод //var nod = Polynom.GreatCommonDivisor(GilbPolFp, Polynom.Derivative(GilbPolFp)); //if(nod.Degree!=0 && nod.Degree<3) //{ // var roots = nod.GetRoots(); // if (roots.Count != 0) // root = roots[0]; // else // { // return null; // } //} //else //{ // using (StreamWriter sw = new StreamWriter(new FileStream("polynom.txt", FileMode.Append))) // { // sw.WriteLine("//------------------------------------------------------------------------"); // sw.WriteLine(Number); // sw.WriteLine("D = " + D); // sw.WriteLine(GilbPolFp + " mod " + Number); // sw.WriteLine("//------------------------------------------------------------------------"); // sw.Close(); // } // return null; //} #endregion return(null); } //--------------------------------------------------------------- //------------------Получение параметров------------------------- BigInteger c = root * Extension.Inverse(root - 1728, Number); c = BigInteger.Remainder(c, Number); BigInteger r = BigInteger.Remainder(3 * BigInteger.Negate(c), Number); BigInteger s = BigInteger.Remainder(2 * c, Number); //--------------------------------------------------------------- paramCurve.Add(new BigInteger[] { r, s }); paramCurve.Add(new BigInteger[] { BigInteger.Remainder(r * BigInteger.ModPow(g, 2, Number), Number), BigInteger.Remainder(s * BigInteger.ModPow(g, 3, Number), Number) }); return(paramCurve); //--------------------------------------------------------------- } }
/// <summary> /// Гильбертов многочлен, число классов и множество привиденных форм (a,b,c) дискриминанта D /// </summary> /// <param name="D"></param> /// <returns></returns> public static ComplexPolynom GilbertPolynom(int D) { //-----Инициализация------------------------------------------ ComplexPolynom T = new ComplexPolynom(new List <ComplexMonom> { new ComplexMonom(0, 1) }); int b = D & 0x01; // D mod 2 int k = (int)Math.Sqrt(Math.Abs(D) / 3); int h = 0; // счетчик классов List <BigInteger[]> red = new List <BigInteger[]>(); // Множество примитивных приведенных форм (a,b,c) //----------Основной Цикл по b--------------------------------------- while (b <= k) { int t = (b * b - D); if ((t & 0x03) != 0) { b++; continue; } int m = (b * b - D) / 4; for (int a = 1; a *a <= m; a++) { if (m % a != 0) { continue; } int c = m / a; if (b > a) { continue; } //---------Установки для многочлена------------------------- Complex r = new Complex(-b, Math.Sqrt(Math.Abs(D))); r /= 2 * a; Complex delt1 = Delta(Complex.Exp(4 * Math.PI * r * Complex.ImaginaryOne), 5000); Complex delt2 = Delta(Complex.Exp(2 * Math.PI * r * Complex.ImaginaryOne), 5000); var f = delt1 / delt2; var j = Complex.Pow(256 * f + 1, 3); j /= f; //---------------------------------- if (b == a || c == a || b == 0) { T = ComplexPolynom.MultiplyPol(T, j, "line"); h++; red.Add(new BigInteger[] { a, b, c }); } else { T = ComplexPolynom.MultiplyPol(T, j, "quadr"); h += 2; red.Add(new BigInteger[] { a, b, c }); red.Add(new BigInteger[] { a, -b, c }); } } b++; } return(T); }