Changeset 7633:2a522c38737a


Ignore:
Timestamp:
12/13/07 16:36:42 (6 years ago)
Author:
William Stein <wstein@…>
Branch:
default
Message:

trac #1500 - solve_mod command, that solves equations modulo n.

Location:
sage/calculus
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • sage/calculus/all.py

    r7386 r7633  
    1 from equations import SymbolicEquation, forget, assume, assumptions, solve 
     1from equations import (SymbolicEquation, 
     2                       forget, assume, assumptions, 
     3                       solve, solve_mod) 
    24 
    35from calculus import (SymbolicExpressionRing, 
  • sage/calculus/equations.py

    r7438 r7633  
    524524 
    525525        INPUT: 
    526             x -- a SymbolicVariable object (if not given, the first in the expression is used) 
    527             multiplicities -- (default: False) if True, also returns the multiplicities 
    528                           of each solution, in order.  
    529             solution_dict -- (default: False) if True, return the solution as a dictionary rather than an equation. 
    530             explicit_solution -- (default: False); if True, require that all solutions 
    531                 returned be explicit (rather than implicit) 
    532         OUTPUT: 
    533             A list of SymbolicEquations with the variable to solve for on the 
    534             left hand side. 
     526            x -- a SymbolicVariable object (if not given, the first in 
     527                 the expression is used) 
     528 
     529            multiplicities -- (default: False) if True, also returns 
     530                          the multiplicities of each solution, in order. 
     531 
     532            solution_dict -- (default: False) if True, return the 
     533                        solution as a dictionary rather than an equation. 
     534             
     535            explicit_solution -- (default: False); if True, require 
     536                that all solutions returned be explicit (rather than 
     537                implicit) OUTPUT: A list of SymbolicEquations with the 
     538                variable to solve for on the left hand side. 
    535539 
    536540        EXAMPLES: 
     
    781785    return Sequence(v, universe=objs, cr_str=True) 
    782786 
     787 
     788############################################################ 
     789# Solving modulo N 
     790 
     791def solve_mod(eqns, modulus): 
     792    """ 
     793    Return all solutions to an equation or lists of equations modulo  
     794    the given integer modulus.  Each equation must involve only  
     795    polynomials in 1 or many variables.  
     796 
     797    The solutions are returned as n-tuples, where n is the  
     798    number of variables appearing anywhere in the given equations.   
     799    The variables are in alphabetical order.  
     800 
     801 
     802    INPUT: 
     803        eqns -- equation or list of equations 
     804        modulus -- an integer  
     805 
     806    EXAMPLES: 
     807        sage: var('x,y') 
     808        (x, y) 
     809        sage: solve_mod([x^2 + 2 == x, x^2 + y == y^2], 14) 
     810        [(2, 4), (6, 4), (9, 4), (13, 4)] 
     811        sage: solve_mod([x^2 == 1, 4*x  == 11], 15) 
     812        [(14,)] 
     813 
     814    Fermat's equation modulo 3 with exponent 5: 
     815        sage: var('x,y,z') 
     816        (x, y, z) 
     817        sage: solve_mod([x^5 + y^5 == z^5], 3) 
     818        [(0, 0, 0), (0, 1, 1), (0, 2, 2), (1, 0, 1), (1, 1, 2), (1, 2, 0), (2, 0, 2), (2, 1, 0), (2, 2, 1)] 
     819         
     820    WARNING: 
     821        Currently this naively enumerates all possible solutions. 
     822        The interface is good, but the algorithm is horrible if the 
     823        modulus is at all large!   Sage *does* have the ability to do 
     824        something much faster in certain cases at least by using 
     825        the Chinese Remainder Theorem, Groebner basis, linear algebra 
     826        techniques, etc.  But for a lot of toy problems this function 
     827        as is might be useful.  At least it establishes an interface. 
     828    """ 
     829    from sage.rings.all import Integer, Integers, MPolynomialRing 
     830    from calculus import is_SymbolicExpression 
     831    from sage.misc.all import cartesian_product_iterator 
     832     
     833    if not isinstance(eqns, (list, tuple)): 
     834        eqns = [eqns] 
     835    modulus = Integer(modulus) 
     836    if modulus < 1: 
     837         raise ValueError, "the modulus must be a positive integer" 
     838    vars = list(set(sum([list(e.variables()) for e in eqns], []))) 
     839    vars.sort() 
     840    n = len(vars) 
     841    R = Integers(modulus) 
     842    S = MPolynomialRing(R, len(vars), vars) 
     843    eqns_mod = [S(eq) if is_SymbolicExpression(eq) else \ 
     844                  S(eq.lhs() - eq.rhs()) for eq in eqns] 
     845    ans = [] 
     846    for t in cartesian_product_iterator([R]*len(vars)): 
     847        is_soln = True 
     848        for e in eqns_mod: 
     849            if e(t) != 0: 
     850                is_soln = False 
     851                break 
     852        if is_soln: 
     853            ans.append(t) 
     854 
     855    return ans 
Note: See TracChangeset for help on using the changeset viewer.