On Nov 9, 2007, at 1:43 PM, John Cremona wrote: > [Hello Robert -- are you in Bristol yet?]
Just got in. > I'm puzzled now. My comment on inefficiency and Steffen's were based > on the code >> for i from 0 <= i <= n/2: >> if (i*i) % n == self.ivalue: >> return self._new_c(i) >> > > but now when I do a.sqrt?? I do not see that code. Steffen, are you > using 2.8.12? This depends on the size of the modulus. There are three types-- IntegerMod_int32, IntegerMod_int64, and IntegerMod_gmp. The 32-bit one has that code, and only for small p. If your modulus is beg enough, a.sqrt?? won't give you that at all. > > John > > > On 09/11/2007, Steffen <[EMAIL PROTECTED]> wrote: >> >> Thx, I am wondering why I did not try the command a.sqrt?? on my own. >> >> However, it seems as the implemented algorithm is not the most >> efficient one. My result from a.sqrt?? from the latest release: >> >> def sqrt(self, extend=True, all=False): >> cdef int_fast32_t i, n = self.__modulus.int32 >> if n > 100: >> moduli = self._parent.factored_order() >> # Unless the modulus is tiny, test to see if we're in the >> really >> # easy case of n prime, n = 3 mod 4. >> if n > 100 and n % 4 == 3 and len(moduli) == 1 and moduli[0] >> [1] == 1: >> if jacobi_int(self.ivalue, self.__modulus.int32) == 1: >> # it's a non-zero square, sqrt(a) = a^(p+1)/4 >> i = mod_pow_int(self.ivalue, (self.__modulus.int32 >> +1)/ >> 4, n) >> if i > n/2: >> i = n-i >> if all: >> return [self._new_c(i), self._new_c(n-i)] >> else: >> return self._new_c(i) >> elif self.ivalue == 0: >> return self >> elif not extend: >> raise ValueError, "self must be a square" >> # Now we use a heuristic to guess whether or not it will >> # be faster to just brute-force search for squares in a c >> loop... >> # TODO: more tuning? >> elif n <= 100 or n / (1 << len(moduli)) < 5000: >> if all: >> return [self._new_c(i) for i from 0 <= i < n if (i*i) >> % n == self.ivalue] >> else: >> for i from 0 <= i <= n/2: >> if (i*i) % n == self.ivalue: >> return self._new_c(i) >> if not extend: >> raise ValueError, "self must be a square" >> # Either it failed but extend was True, or the generic >> algorithm is better >> return IntegerMod_abstract.sqrt(self, extend=extend, all=all) >> >> The easier %4 == 3 case seems to be implemented efficiently, but the >> %4 == 1 not. The algo from Tonelli and Shanks might be a good >> solution >> here. Any thoughts on other/better algorithm? >> >> Steffen >> >> >> >> >> On 9 Nov., 18:24, "John Cremona" <[EMAIL PROTECTED]> wrote: >>> Use the ?? operator to see the algorithm: >>> >>> sage: a=GF(next_prime(10^6)).random_element()^2; >>> sage: a.sqrt?? >>> >>> Type: builtin_function_or_method >>> Base Class: <type 'builtin_function_or_method'> >>> String Form: <built-in method sqrt of >>> sage.rings.integer_mod.IntegerMod_int64 object at 0x99055a4> >>> Namespace: Interactive >>> Source: >>> def sqrt(self, extend=True, all=False): >>> r""" >>> Returns square root or square roots of self modulo n. >>> >>> INPUT: >>> extend -- bool (default: True); if True, return a square >>> root in an extension ring, if necessary. Otherwise, >>> raise a ValueError if the square is not in the >>> base ring. >>> all -- bool (default: False); if True, return *all* >>> square >>> roots of self, instead of just one. >>> >>> ALGORITHM: Calculates the square roots mod $p$ for each >>> of the >>> primes $p$ dividing the order of the ring, then lifts them >>> p-adically and uses the CRT to find a square root mod $n$. >>> >>> See also \code{square_root_mod_prime_power} and >>> \code{square_root_mod_prime} (in this module) for more >>> algorithmic details. >>> >>> EXAMPLES: >>> sage: mod(-1, 17).sqrt() >>> 4 >>> sage: mod(5, 389).sqrt() >>> 86 >>> sage: mod(7, 18).sqrt() >>> 5 >>> sage: a = mod(14, 5^60).sqrt() >>> sage: a*a >>> 14 >>> sage: mod(15, 389).sqrt(extend=False) >>> Traceback (most recent call last): >>> ... >>> ValueError: self must be a square >>> sage: Mod(1/9, next_prime(2^40)).sqrt()^(-2) >>> 9 >>> sage: Mod(1/25, next_prime(2^90)).sqrt()^(-2) >>> 25 >>> >>> sage: a = Mod(3,5); a >>> 3 >>> sage: x = Mod(-1, 360) >>> sage: x.sqrt(extend=False) >>> Traceback (most recent call last): >>> ... >>> ValueError: self must be a square >>> sage: y = x.sqrt(); y >>> sqrt359 >>> sage: y.parent() >>> Univariate Quotient Polynomial Ring in sqrt359 over Ring >>> of integers modulo 360 with modulus x^2 + 1 >>> sage: y^2 >>> 359 >>> >>> We compute all square roots in several cases: >>> sage: R = Integers(5*2^3*3^2); R >>> Ring of integers modulo 360 >>> sage: R(40).sqrt(all=True) >>> [20, 160, 200, 340] >>> sage: [x for x in R if x^2 == 40] # Brute force >>> verification >>> [20, 160, 200, 340] >>> sage: R(1).sqrt(all=True) >>> [1, 19, 71, 89, 91, 109, 161, 179, 181, 199, 251, 269, >>> 271, 289, 341, 359] >>> sage: R(0).sqrt(all=True) >>> [0, 60, 120, 180, 240, 300] >>> >>> sage: R = Integers(5*13^3*37); R >>> Ring of integers modulo 406445 >>> sage: v = R(-1).sqrt(all=True); v >>> [78853, 111808, 160142, 193097, 213348, 246303, >>> 294637, 327592] >>> sage: [x^2 for x in v] >>> [406444, 406444, 406444, 406444, 406444, 406444, >>> 406444, 406444] >>> sage: v = R(169).sqrt(all=True); min(v), -max(v), len(v) >>> (13, 13, 104) >>> sage: all([x^2==169 for x in v]) >>> True >>> >>> Modulo a power of 2: >>> sage: R = Integers(2^7); R >>> Ring of integers modulo 128 >>> sage: a = R(17) >>> sage: a.sqrt() >>> 23 >>> sage: a.sqrt(all=True) >>> [23, 41, 87, 105] >>> sage: [x for x in R if x^2==17] >>> [23, 41, 87, 105] >>> >>> """ >>> if self.is_one(): >>> if all: >>> return list(self.parent().square_roots_of_one()) >>> else: >>> return self >>> >>> if not self.is_square_c(): >>> if extend: >>> >>> and so on! >>> >>> John >>> >>> On 09/11/2007, Steffen <[EMAIL PROTECTED]> wrote: >>> >>> >>> >>> >>> >>>> Hi, I need to find square roots in GF(prime). I did it like this: >>> >>>> y = sqrt(GF(prime)(ySquare)) >>> >>>> So far I am not quite happy with the calculation periods and I >>>> would >>>> like to know which algorithm is used. In my case is prime % 4 == 1, >>>> which is the hardest case to find the square root mod p. I am sage >>>> newbie and probably its again only a command that I cant find. I >>>> tried >>>> sqrt? and similar things, but only got the information that sqrt >>>> is a >>>> symbolic function. Could somebody tell me which algo is >>>> implemented or >>>> better how to find the implemented algo. >>> >>>> Cheers, Steffen >>> >>> -- >>> John Cremona >> >> >>> >> > > > -- > John Cremona > > --~--~---------~--~----~------------~-------~--~----~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://sage.scipy.org/sage/ and http://modular.math.washington.edu/sage/ -~----------~----~----~----~------~----~------~--~---