;
~FFc           @   s   d  Z  e Z d f  d     YZ d e f d     YZ d e f d     YZ d e f d     YZ d	   Z d
 k l	 Z	 d e e	 f d     YZ
 e
   Z e i Z e i Z d   Z d k l Z l Z l Z l Z l Z f  e e d  Z d   Z d S(   s  Cached prime numbers.

This module provides an object, primes, which masquerades as the infinite list
of all primes, in their proper order.  If you ask it how long it is, it'll be
finite, but if you ask for an element past the `end' you'll still get it (though
you may have to wait).  Ask for its last element and you'll get some prime: ask
whether some bigger prime is in the list and the answer will be yes, none the
less.

Building on that, this module also provides facilities for factorisation and
multiplying back together again:

  prodict(dict) -- product of pow(key, dict[key])

  factorise(numb) -- returns a dictionary, which prodict will map to numb: its
  keys are irreducible (so generally primes, but -1, at least, may also appear).

See also generic integer manipulators in natural.py, combinatorial tools in
permute.py and polynomials in polynomial.py: some day, it'd be fun to do some
stuff with prime polynomials ...

$Id: primes.py,v 1.15 2007/05/06 11:48:08 eddy Exp $
s	   lazyTuplec           B   s   t  Z d  Z e d  Z d   Z d   Z d   Z e Z d   Z	 d   Z
 d   Z d   Z d	   Z d
   Z d   Z d   Z RS(   s   Evaluation on demand of a (possibly infinite) tuple.

    Some of what's in this class should be split out into _Prime, below.
    c         C   s^   | t j o
 g  } n | |  _ y | d } Wn |  i j
 o d } n Xd | |  _ d S(   sN   Initialises a lazy Tuple.

	Optional argument, row, should be a sorted list.
	ii    i   N(   s   rows   Nones   selfs   _item_carriers   tops   _entry_error_s   _ask(   s   selfs   rows   top(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   __init__    s      
	  c         C   sS   t  |  i  } t |  d j  o | d  d | d Sn | d  d | d Sd  S(   Ni   is   ...s   , ...(   s   tuples   selfs   _item_carriers   texts   len(   s   selfs   text(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   __repr__,   s     c         C   s   t  |  i  Sd  S(   N(   s   lens   selfs   _item_carrier(   s   self(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   __len__1   s    c         C   s:   x( | t |  i  j o
 |  i   o q W|  i | Sd  S(   N(   s   keys   lens   selfs   _item_carriers   grow(   s   selfs   key(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   __getitem__4   s     # c         c   s+   d } x t o |  | Vd | } q	 Wd  S(   Ni    i   (   s   is   Trues   self(   s   selfs   i(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   __iter__;   s
     c         C   s6   | d j  p
 | d j  o
 t  n |  i | | !Sd S(   s	   self[i:j]i    N(   s   is   js
   IndexErrors   selfs   _item_carrier(   s   selfs   is   j(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   __getslice__A   s      
c         C   s6   x" | |  i j o
 |  i   o q W| |  i j Sd S(   s3   Is val in self ?

	Override this in base-classes.
	N(   s   vals   selfs   _asks   grows   _item_carrier(   s   selfs   val(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   __contains__G   s
       c         C   s   | |  j o d Sn d Sd  S(   Ni   i    (   s   items   self(   s   selfs   item(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   countO   s     c         C   s)   | |  j o |  i i |  Sn d Sd  S(   Ni(   s   items   selfs   _item_carriers   index(   s   selfs   item(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   indexS   s    c         C   s   |  i d Sd  S(   Ni    (   s   selfs   _item_carrier(   s   self(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   minY   s    c         C   s   |  i d Sd  S(   Ni(   s   selfs   _item_carrier(   s   self(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   max\   s    c         C   s.   |  i } |  i i |  d | |  _ | Sd S(   s   Extend self._item_carrier, return true on success.

	Over-ride this method in derived classes - don't call this one.
	It implements lazy range(infinity).
	i   N(   s   selfs   _asks   results   _item_carriers   append(   s   selfs   result(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   grow_   s
     	(   s   __name__s
   __module__s   __doc__s   Nones   __init__s   __repr__s   __len__s   __getitem__s   __call__s   __iter__s   __getslice__s   __contains__s   counts   indexs   mins   maxs   grow(    (    (    s(   /home/eddy/.sys/py/study/maths/primes.pys	   lazyTuple   s    										s   listc           B   s   t  Z e i Z d   Z RS(   Nc         C   s   |  i |  i | |   Sd  S(   N(   s   selfs	   __class__s   _list__upgetsls   is   j(   s   selfs   is   j(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   __getslice__m   s    (   s   __name__s
   __module__s   lists   __getslice__s   _list__upgetsl(    (    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   listj   s   	s	   risingSetc           B   s/   t  Z e i Z e d  Z e i Z d   Z RS(   Nc         C   s   |  i | p g   d  S(   N(   s   selfs   _risingSet__upinits   val(   s   selfs   val(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   __init__r   s    c         C   s|  |  p |  d | j o | g |  d *nO|  d | j  o |  i |  n-| |  j od t |   d f \ } } x | d | j  o | | d } | | j  o
 | j  n p
 t d  |  | |  | j  o |  | j  n p
 t d  |  | | j  o
 | } n | } |  | | j  o |  | j  n p
 t d  qx W| d | j p
 t d  |  i | |  n d  S(	   Ni    ii   i   s
   arithmetics   prior orders   binary chop misseds   binary chop mis-terminating(	   s   selfs   vals   appends   lens   bots   tops   ats   AssertionErrors   _risingSet__upins(   s   selfs   vals   bots   ats   top(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   insertv   s"       (4 
5(   s   __name__s
   __module__s   lists   __init__s   _risingSet__upinits   Nones   inserts   _risingSet__upins(    (    (    s(   /home/eddy/.sys/py/study/maths/primes.pys	   risingSetp   s   		s   _Primec           B   s   t  Z d  Z d Z e e d  Z d   Z d   Z d   Z d   Z	 d   Z
 d   Z e d	  Z e d
  Z e d  Z d   Z d   Z RS(   sz   List of all primes, generated as needed.

    Needs to use a paged-in-and-out item carrier.  Use that to do cacheing.
    s  

    From Tuple, this inherits ._item_carrier in which we store all the primes
    less than ._ask, which is the next number we're going to check to see if
    it's prime.  Any higher primes we've discovered (usually thanks to
    factorise(), see below) are kept in _sparse (in their correct order, albeit
    probably with gaps).  All currently known primes may be listed as .known().

    self._ask will be an ordinary integer as long as it can, then switch over to
    being a long one.  Entries in .known() will be ordinary integers most of the
    time, unless they are so big they must be long().  However, some entries
    which could be ordinary may still be long().

    c         C   s_   | t j o d g } n | o | i d  n t i |  |  d |  _ t |  |  _	 d  S(   Ni   (
   s   rows   Nones   appends	   lazyTuples   __init__s   selfs   _sqrts	   risingSets   sparses   _sparse(   s   selfs   rows   sparse(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   __init__   s      	c         C   s   d |  i i Sd  S(   Ns   %s()(   s   selfs	   __class__s   __name__(   s   self(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   __repr__   s    c         C   sK   t  |   d j o' d t |  d   d d !|  d f Sn t i |   Sd  S(   Ni   s   (%s, ..., %s)i   i(   s   lens   selfs   strs	   lazyTuples   __repr__(   s   self(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   __str__   s     'c         C   s   |  i |  i Sd  S(   N(   s   selfs   _item_carriers   _sparse(   s   self(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   known   s    c         C   s   |  i Sd S(   s:   Returns a number about which self would like to be asked. N(   s   selfs   _ask(   s   self(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   ask   s     c         C   s  d } xn o| |  i | j p | |  i j o | Sn | |  i j  o t Sn x= |  i | D]. } | | d j o t Sn t |  i  } qb W|  i d } t	 |  | | j o |  i
 |  Sn x< |  i D]1 } | | d j o t Sn | | j o Pq q W|  i   o Pq	 q WxY n oQ |  i   } | | d j o t Sn t	 |  | | j o |  i
 |  Sq#q*Wd  S(   Ni    i   i(   s   seens   nums   selfs   _item_carriers   _sparses   _asks   Nones   ps   lens   longs   _knows	   get_caches   grow(   s   selfs   nums   ps   seen(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   __contains__   s<     $     
   	 
   c         C   s   |  i |  d j  o d |  d |  _ n |  i } x |  d | j  o |  i |  i j o |  i   q5 x |  i D]v } |  i | d j o |  i   Pn | |  i j  o qq n t	 |  | |  i j o |  i   Pqq | d |  _ qq Wq5 W|  i d Sd  S(   Nii   i    (
   s   selfs   _asks   wass   _sparses   _knows   _item_carriers   ps   _Prime__throws   _sqrts   long(   s   selfs   ps   was(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   grow   s&    	  
 
 
c         C   s.   | t |  i f j o d |  i |  _ n d S(   s   Records a non-prime.

	Argument, other, defaults to self._ask: it must not be a prime.  The
	only time it matters is when it's self._ask: which is then stepped
	forward to the next integer. i   N(   s   others   Nones   selfs   _ask(   s   selfs   other(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   __throw   s     c         C   s   | p | |  i j o| |  i i |  i  |  i |  i j o< |  i |  i d j p t d |  i  |  i d |  _ n |  i } d | |  _ nT | |  i j p | |  i j o2 |  i | j p t d |  |  i i |  n | Sd S(   s   Records a prime.

	Argument, other, defaults to self._ask: it must be a prime.  If it is
	self._ask, we append it and advance _ask.  Otherwise, if it isn't
	already in self or _sparse, we add it to _sparse in its proper place.
	i    s$   sparse primes array disordered at %di   s%   missed out a prime, %d, in the searchN(   s   others   selfs   _asks   _item_carriers   appends   _sparses   AssertionErrors   insert(   s   selfs   other(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   _know   s     (	!c         C   sW  | t j o
 h  } n" | } | i d d  o | Sn | d j  o) | i d d  d d | d <| } n | d t |  o t d | f  n | d j o | i   d | d <n| d j od } x n o x |  i
   | D] } |  i | |  \ } } | o | | i | d  | | <n | | j  o= | d j p | |  i d d j p t d | | f  Pq q Wt |   } |  i   o q n Pq Wx | d j o |  i   } |  i | |  \ } } | o | | | <n | d j o qt |  | | j o! |  i |  d | | <d } q| d j p t  qWn | Sd S(	   s  Factorises an integer.

	Argument, num, is an integer to be factorised.
	It may be long, but not real.

	Optional argument:

	    gather -- dictionary to which to add results, or None (the default)
	              to use a fresh empty dictionary: this is what factorise()
	              returns.

	The result of factorise() is always a dictionary: its prodict() is num,
	its keys are primes, -1 or 0 and its values are positive integers.  The
	key -1 is present precisely if num is negative, in which case its
	multiplicity is 1 (not, for instance, 3 or 5).  The key 0 only appears
	when num is 0, in which case the result is {0: 1}.  Note that 1 =
	prodict({}) so I don't need to make a special case of 1 ;^)

	If num is a positive integer, factorise(num) is a dictionary whose keys
	are its prime factors: the value for each key is its multiplicity as a
	factor of num.  Thus, prodict(factorise(num)) is num.

	Zero is a special case (because it is a multiple of every number): its
	given factorisation is { 0: 1 }.  Negative values are factorised as the
	factorisation of the corresponding positive value, with one extra key,
	-1, with multiplicity 1.

	If you want to know the factorisation of the product of a sequence of
	integers, do it by using gather to collect up their several
	factorisations: it's much easier to factorise each of them in turn than
	to factorise their product !

	    out = {}
	    for num in sequence: factorise(num, out)

	See also: Factorise() (which is packaging) and prodict().
	i    ii   i   l    s!   Trying to factorise a non-integers.   all primes less than p have already been triedN(   s   gathers   Nones   results   gets   nums   abss	   TypeErrors   clears   seens   selfs   knowns   ps   _Prime__reduces   counts   _item_carriers   AssertionErrors   lens	   get_caches   grows   longs   _know(   s   selfs   nums   gathers   counts   ps   results   seen(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys	   factorise  sX    %  
 
   8	    

c         C   sT   d } x= | | d j o+ |  i |  | d | | f \ } } q	 W| | f Sd S(   s9   Returns c, m with pow(p,c) * m == n and m coprime with p.i    i   N(   s   cs   ns   ps   selfs   _Prime__throw(   s   selfs   ns   ps   c(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   __reduceo  s      c         C   s   t  Sd S(   s3  Hook-in point for cacheing of primes.

	If you can update self._item_carrier from a cache of some kind, do it
	now.  If you can't, return None, or leave it to this base method to do
	so for you.  On a successful update, return some true value: calling
	code can use this to decide whether to try again ...
	N(   s   None(   s   self(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys	   get_cachex  s     (   s   __name__s
   __module__s   __doc__s   _private_doc_s   Nones   __init__s   __repr__s   __str__s   knowns   asks   __contains__s   grows   _Prime__throws   _knows	   factorises   _Prime__reduces	   get_cache(    (    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   _Prime   s    							
`		c         C   s   d } d } d } x | D] } x\ | | j oN y d | d } | d } Wq" t j
 o d | d } | d } q" Xq" W| | } | d j o |  i d  | } n |  i d	 | d
  q Wd S(   s  Writes a sequence of numbers to a file tidily.

    Arguments:

      file -- a file handle, to which to .write() the tabulated numbers

      block -- a sequence of integers (or long integers)

    Begins each line with a space, separates numbers with comma and space,
    limits lines to 80 characters in width (thus only allowing one number per
    line once they are more than 38 characters each).  Ends in a stray comma,
    which python won't mind when it loads the array, but no newline.

    The tabulation algorithm assumes that each entry in block is bigger than all
    previous (specifically, it has at least as many digits), and that entries
    which don't need to be long aren't.  Breaking these assumptions will cause
    no harm beyond making the table messier. iP   i	   i   i
   i   l   
 i   s   
s    s   ,N(   s   acrosss   clicks   steps   blocks   items   OverflowErrors   files   write(   s   files   blocks   acrosss   items   steps   click(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   _tabulate_block  s&       

(   s   Lazys   cachePrimesc           B   s   t  Z e i Z e e e e d  Z d   Z e d  Z [ d d  Z d f  d     YZ	 e	 d  Z
 [	 d	   Z d
   Z d   Z d   Z d e d  Z RS(   Nc         C   su   |  i | |  | t j o d k l } | d } n | |  _ | t j	 o | |  _
 n d |  _ d |  _ d  Sd  S(   N(   s   __path__i    i   (   s   selfs   _cachePrimes__upinits   rows   sparses	   moduledirs   Nones   study.mathss   __path__s   _cachePrimes__prime_module_dirs   cachedirs   prime_cache_dirs   _cachePrimes__steps   _cachePrimes__high_water(   s   selfs   rows   sparses	   moduledirs   cachedirs   __path__(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   __init__  s    			c         C   sg   y | i |   } Wn | i j
 o t Sn Xd  k } | i | i  o t Sn t	 |  d   d  S(   Ns   exists but is not a directory(
   s   oss   stats   noms   sts   errors   Trues   S_ISDIRs   st_modes   Falses	   TypeError(   s   noms   oss   stats   st(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys	   nosuchdir  s      		 c         C   sJ   d  k  } | i i |  i d  } | | |  o | i |  n | Sd  S(   Ns   primes(   s   oss   paths   joins   selfs   _cachePrimes__prime_module_dirs   anss   nodirs   makedirs(   s   selfs   ignoreds   nodirs   anss   os(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   _lazy_get_prime_cache_dir_  s
    	 s   cc         C   s   y% d  k  }	 |  i } |	 i |  }
 Wn h  Sn Xd  k } | d  } h  } t	 |  } xz |
 D]r } | |  | j o" | d d j o d | | d !j o6 t | | | d !i d   | |	 i i | |  <qa qa W| Sd  S(   Nc         C   sB   d  k  } |  d d j o | i |  d  Sn | i |  d  Sd  S(   Nis   Li    (   s   strings   texts   ss   atols   atoi(   s   texts   ss   string(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys	   _read_int  s    	 is   .pys   -(   s   oss   selfs   prime_cache_dirs   locs   listdirs   rows   strings	   _read_ints   results   lens   stems   langs   names   maps   splits   paths   join(   s   selfs   ignoreds   stems   langs	   _read_ints   strings   names   locs   results   oss   row(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   _lazy_get__caches_  s    		 	 6:s   Dummyc           B   s   t  Z RS(   N(   s   __name__s
   __module__(    (    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   Dummy  s    c         C   s(   |   } | i t | | i  | Sd S(   s4   Imports data from a file, preparatory to _load()ing.N(   s   objects   objs   __dict__s   execfiles   handle(   s   selfs   handles   objects   obj(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys
   _do_import  s
     	c         C   s   d GHt  |  i  } xg |  i i   D]V \ } } | d | j o9 |  i | =| d | j o |  i |  i	 |   Sqz q$ q$ Wt
 Sd S(   s2   Returns true if it got anything out of the caches.s   Getting cachei    iN(   s   lens   selfs   _item_carriers   sizes   _cachess   itemss   names   pairs   _loads
   _do_imports   None(   s   selfs   names   pairs   size(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys	   get_cache  s      
 "c         C   s
  t  |  i  } y | i t  | i  | i j p
 t d  | i | j p t d | i | f  | | i j p t d | | i f  x | i	 D]v } | |  i |  i j o q n t o> x; |  i |  i D]% } | | p t d | | f  q Wn |  i |  q WWn* t j
 o } t d | | i   n Xt o8 |  i | i } | | i t  |   j p
 t d  n | i |  i | i )x6 |  i o |  i d |  i j o |  i d |  _ qW|  i o |  i d |  i d	 j  p t d
 |  i d  d Sd S(   se  Loads data that's been imported from a file.

	Argument, found, is the module object as which the file was imported: it
	should have integer attributes, found.at and found.to and list
	attributes found.sparse and found.block, with each member of sparse
	greater than any member of block, and at+len(block)==to.  The given
	block is used as self[at:to], while entries in sparse are added to
	_sparse in their right order.

	The bits of the file we'll examine are variables in the global scope
	with names 'at', 'to', 'sparse' and 'block'.  Most of this function
	checks things, the actual loading is quite brief ! s   inconsistent load-files;   new slice, [%d:], does not meet up with what we have, [:%d]s-   mis-ordered loading of cache-files (%d > %d).s#   alleged prime, %d, has a factor, %ds#   cache-file lacks necessary variables5   new block of primes doesn't match what I know alreadyi    i   is'   sparse prime, %d, missed in "full" listN(   s   lens   selfs   _item_carriers   sizes   founds   tos   blocks   ats   AssertionErrors   sparses   items   _sparses   checkings   ps   _knows   AttributeErrors   whats   argss   test(   s   selfs   founds   whats   ps   items   tests   size(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   _load  s4     *''
   '( !;c         C   s   d |  i d Sd  S(   Ni   i(   s   selfs   _item_carrier(   s   selfs   ig(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   _lazy_get__ask_4  s    c         C   s[   y3 x, |  i |  i d j  o |  i d |  _ q WWn t j
 o n X|  i |  i Sd  S(   Ni   i   (   s   selfs   _cachePrimes__steps   _cachePrimes__high_waters   OverflowError(   s   self(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys
   _next_high7  s      c      	   C   s.  d k  } | i i |  i |  } | d } |  i   } x | t	 |  i
  j  o | |  i d | d } | p | i i |  o t | d  } zY | i d d |  i d | d	 |  i d
 g  t | |  i
 |  i | ! | i d  Wd | i   X| i | |  n | |  _ |  i   } q: Wd S(   sj  Records `most' of what the primes module knows in files for later reference.

	Arguments are all optional:

	  name -- name-stem for cache files. Default is 'c'.

	  force -- flag, default is false.  Normally, persist() trusts files
	  already in the cache and doesn't bother re-writing them: set force to
	  some true value to make all the files be written anew.

	Updates the cache.  Each cache file contains a sub-list of the known
	primes: small primes are recorded in files with 1024 entries, but
	subsequent sub-lists are longer (by a factor of 2 whenever the
	chunk-size gets bigger than an eighth of the number of primes in all
	earlier cache files).  Each cache-file's name expresses the range of
	indices it contains: this information is also present in the cache-file,
	along with the current value of _sparse.  The block of primes stored in
	the file is formatted to be readable on an 80-column display.  The data
	are stored in the file under the names

	  at -- index, in self, of first prime in block

	  to -- index, in self, of first prime after block

	  sparse -- current _sparse list

	  block -- self[at:to]
	Ns   .tmps   -s   .pys   ws)   """Persistence data for primes module."""s   
at = s   
to = s
   
sparse = s
   
block = [s   
]
(   s   oss   paths   joins   selfs   prime_cache_dirs   names   tmpfiles
   _next_highs   news   lens   _item_carriers   _cachePrimes__high_waters   outfiles   forces   existss   opens   files
   writeliness   _sparses   _tabulate_blocks   writes   closes   rename(   s   selfs   names   forces   tmpfiles   outfiles   files   news   os(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   persist>  s(     		
 .	(   s   __name__s
   __module__s   _Primes   __init__s   _cachePrimes__upinits   Nones	   nosuchdirs   _lazy_get_prime_cache_dir_s   _lazy_get__caches_s   Dummys
   _do_imports	   get_caches   _loads   _lazy_get__ask_s
   _next_highs   persist(    (    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   cachePrimes  s   				<		c         C   s/   t  d   t t |  i   |  i    d  Sd S(   s\  Returns the product of a factorisation dictionary.

    Argument, dict, is a dictionary whose keys are multipliable and whose values
    are powers to which one may sensibly raise these keys.  The result is the
    same as would result from

	answer = 1
	for key, val in dict.items():
	    answer = answer * pow(key, val)
	return answer

    This implementation uses reduce() and map().  This might be more efficient
    than doing it as above, but I don't know.  It's only really here to give me
    a handy way to do the inverse of factorise(), above.

    See also, in module basEddy.quantity: adddict, subdict and scaledict.  They
    and this may one day migrate elsewhere to be together.  We get:
	* prodict(adddict(a,b)) = prodict(a) * prodict(b),
	* prodict(subdict(a,b)) = prodict(a) / prodict(b),
	* prodict(scaledict(d,n)) = pow(prodict(d), n).
    c         C   s   |  | S(   N(   s   as   b(   s   as   b(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   <lambda>  s    i   N(   s   reduces   maps   pows   dicts   keyss   values(   s   dict(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   prodict}  s     (   s	   TupleTypes   ListTypes	   FloatTypes   IntTypes   LongTypec         C   s  | t j o
 h  } n y= t |   d j o
 |  } n |  d } | d | d  f Wn t t t t f j
 o |  p
 |  d j o
 |  } n t
 i   } t |  t j oV y t |  } Wn t j
 o t |  } n X| | j o t d  n | } n t
 i | |  } nQ X| } xF | D]> } y | | Wq(t j
 o t | d t | | <q(Xq(W| o t
 i   n | Sd S(   s  Factorises an integer or each integer in a tuple.

	Optional arguments:

	  args -- an integer, a tuple thereof or (if omitted) the empty tuple.

	  gather -- dictionary to which to add results, or None (the default) to
	  use a fresh empty dictionary: this is what Factorise() returns.

          cache -- flag, default is True.  By default, Factorise() will do a
	  primes.persist() when it is finished: this will slow you down when it
	  happens (writing a cache file can take a while once you know a lot of
	  primes).  Set cache to some false value to suppress this (and remember
	  to run primes.persist() at the end of your session).

	If args is a non-empty tuple, this returns a dictionary whose keys are
	the entries in the tuple, mapped to values which are what you get by
	passing the key to Factorise().  If args is the empty tuple, Factorise
	acts as if it'd been given the smallest natural number that the primes
	module doesn't yet know about.  If args is an integer, Factorise()
	behaves as primes.factorise(), so prodict(Factorise(())) will be this
	`least unknown', but it'll be known by the time you've evaluated that.

	See also: prodict() and primes.factorise().
	i   i    s   Factorising a float !s   cacheN(   s   gathers   Nones   lens   argss   seqs	   TypeErrors   KeyErrors
   IndexErrors   AttributeErrors   nums   primess   asks   types	   FloatTypes   ints   vals   OverflowErrors   longs	   factorises   results	   Factorises   caches   persist(   s   argss   gathers   caches   vals   seqs   nums   result(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys	   Factorise  s>      
 

 
   
   c         C   sD  |  d j  o |  }  h  d d <} n h  } t i |   } t | i    | d <x | i   D] \ } } | } | i   } x t |  D] } | d | } x_ | D]W \ }
 } y |
 | }	 Wn# t j
 o t |
  | }	 n Xt | |
 |  | |	 <q Wy | | } Wq t j
 o t |  | } q Xq Wq_ W| Sd S(   s  Returns a dictionary whose keys are the factors of num.

    The value this dictionary associates with any factor is the factor's
    multiplicity as a factor of num, except for the key 1 (for which this is
    ill-defined) which gets the maximum of all the values in the dictionary.
    Thus, where defined, pow(k, factors(n)[k]) is a factor of n: for k not equal
    to 1, furthermore, pow(k, 1+factors(n)[k]) is not a factor of n.  Notice
    that factors(n)[n] = 1.

    If num is negative, -1 is listed with multiplicity 1, as is its product with
    each positive factor.  This is not wholly satisfactory, but it's not quite
    clear what's saner. i    ii   N(   s   nums   results   primess	   factorises   facts   maxs   valuess   itemss   keys   vals   qs   ranges   is   tops   ks   vs   rs   OverflowErrors   longs   min(   s   nums   vals   is   tops   vs   qs   results   keys   itemss   rs   ks   fact(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   factors  s4            N(   s   __doc__s   Nones   checkings	   lazyTuples   lists	   risingSets   _Primes   _tabulate_blocks   study.value.lazys   Lazys   cachePrimess   primess	   factorises   __contains__s   is_primes   prodicts   typess	   TupleTypes   ListTypes	   FloatTypes   IntTypes   LongTypes   Trues	   Factorises   factors(   s	   risingSets   _tabulate_blocks	   lazyTuples	   FloatTypes   checkings	   TupleTypes   factorss   lists   Lazys   _Primes   is_primes   prodicts	   Factorises   ListTypes   cachePrimess   primess	   factorises   LongTypes   IntType(    (    s(   /home/eddy/.sys/py/study/maths/primes.pys   ?   s   O	)				%=