예제 #1
0
 def all_generators(self):
     """Return an iterator on all field's generators"""
     sz = len(self) - 1
     loopends = [sz // f for f in factor(sz)]
     one = self.one()
     for x in self:
         if one not in x.multi_pows(loopends):
             yield x
예제 #2
0
def same_divisor_count(i, div_factor_diff, equal, factorcounts, bounds):
    # remove 0 entries and do bounds check
    for k, c in div_factor_diff.items():
        if c==0: del div_factor_diff[k]
        else:
            if i==len(bounds) or abs(c) > bounds[i][k]:
                return 0
    if i==len(factorcounts):
        assert len(div_factor_diff) == 0
        return 2 if equal else 1
    key = (i, frozenset(div_factor_diff.items()), equal)
    if key in _mem:
        return _mem[key]
    ret = 0
    for j in xrange(factorcounts[i]+1):
        newequal = (equal and j == factorcounts[i]-j)
        af, bf = factor(j+1, primes), factor(factorcounts[i]-j+1, primes)
        div_factor_diff.update(bf)
        div_factor_diff.subtract(af)
        ret += same_divisor_count(i+1, div_factor_diff, newequal, factorcounts, bounds)
        div_factor_diff.subtract(bf)
        div_factor_diff.update(af)
    _mem[key] = ret
    return ret
예제 #3
0
def GF(q, n=1):
    factors = factor(q)
    assert len(
        factors) == 1 and q > 1, "Cannot create GF with non prime power %d" % q
    p = factors[0]
    if q == p:
        if n == 1:
            return Zmod(p)
        else:
            return Extension(p, n)
    else:
        log = 1
        while q > p:
            q = q // p
            log += 1
        f = Extension(p, log)
        if n == 1:
            return f
        else:
            return Extension(f, n)
예제 #4
0
def main():
    """Solves this problem

    Calculates the sum of the factors of all numbers under 10000.  
    Then checks each result for amicable numbers.  
    Nothing very special in terms of calculations.

    Returns:
        Integer: Solution to this problem
    """

    dn = {}
    for i in range(1, 10000):
        dn[i] = sum(factor(i))

    amicable = set()
    for k, v in dn.items():
        if k != v and v in dn and dn[v] == k:
            amicable.add(k)

    return sum(amicable)
예제 #5
0
    def _is_irreducible_coefs(cls, F, coef):
        """Rabin irreducibility test"""
        zero, one = F.zero(), F.one()
        if cls._is_zero_coefs(zero, coef):
            return False

        # Make polynomial monic
        if coef[-1] != one:
            inverse = coef[-1]**(-1)
            coef = cls._scalar_mult_coefs(zero, coef, inverse)
        modulo = lambda pol: cls._divmod_coefs(zero, pol, coef)[1]

        deg = cls._deg_coefs(coef)
        deg_factors = factor(deg)
        pows = [deg // f for f in reversed(deg_factors)]
        pows.append(deg)  # Calculate `x^(q^deg)` as well

        # Calc (x^q mod f) and then its powers, make irreducibility tests on the fly
        q = len(F)
        cur_val = modulo([zero] * q + [one])
        cur_exp = 1
        minus_x = [zero, -one]
        for d in pows:
            # Calc next power
            exp = d - cur_exp
            cur_val = cls._pow_coefs(F, cur_val, int(q**exp), coef)
            cur_exp = d
            pol = cls._add_coefs(zero, cur_val, minus_x)  # x^(q^d) - x

            # Do test for current power (except for last power)
            if d < deg:
                gcd = cls._gcd_coefs(zero, pol, coef)
                if gcd != [one]:
                    return False

        # Final test on `x^(q^deg) - x`
        if cls._is_zero_coefs(zero, modulo(pol)):
            return True
        # else:
        return False
예제 #6
0
    def generator(self):
        """Find a generator for F"""
        if self._g is not None:
            return self._g

        sz = len(self) - 1
        if sz == 1:
            self._g = self.one()
            return self._g

        # Check g**((n-1)/p) for all factors p of n-1
        # g is a generator if and only if none of these powers are `one`
        one = self.one()
        loopends = [sz // f for f in factor(sz)]
        found = False
        while not found:
            g = self.rand(nonzero=True)
            res = g.multi_pows(loopends)
            if one not in res:
                found = True
        self._g = g
        return g
예제 #7
0
def main():
    """Solves this problem

    There are probably better solutions to this.  
    Step 1: Calculate all abundant numbers < 28124  
    Step 2: Sum ALL combinations of these and place into a SET (important)  
    Step 3: Check each number < 28124 if it is in the set above and sum the values that aren't  

    Note: This relies HEAVILY on attributes of sets to quickly index values

    Returns:
        Integer: Solution to this problem
    """

    # Step 1: Calculate all abundant numbers < 28124
    abundant = []
    for i in range(12, 28124):
        if sum(factor(i)) > i:
            abundant.append(i)

    # Step 2: Calculate all possible sums of the abundant numbers < 28124
    sums = set()
    for i in abundant:
        for j in abundant:
            s = i + j
            # This is faster than adding every combination - YMMV
            if s > 28123:
                break
            sums.add(s)

    # Step 3: Check each number if it was produced via two abundant numbers
    non_abundant = 0
    for n in range(1, 28124):
        if n not in sums:
            non_abundant += n

    return non_abundant
예제 #8
0
def td_solve(ss,
             block_list,
             unknowns,
             targets,
             H_U=None,
             H_U_factored=None,
             monotonic=False,
             returnindividual=False,
             tol=1E-8,
             maxit=30,
             noisy=True,
             save=False,
             use_saved=False,
             **kwargs):
    """Solves for GE nonlinear perfect foresight paths for SHADE model, given shocks in kwargs.

    Use a quasi-Newton method with the Jacobian H_U mapping unknowns to targets around steady state.
    
    Parameters
    ----------
    ss              : dict, all steady-state information
    block_list      : list, blocks in model (SimpleBlocks or HetBlocks)
    unknowns        : list, unknowns of SHADE DAG, the 'U' in H(U, Z)
    targets         : list, targets of SHADE DAG, the 'H' in H(U, Z)
    H_U             : [optional] array (nU*nU), Jacobian of targets with respect to unknowns
    H_U_factored    : [optional] tuple, LU decomposition of H_U, save time by supplying this from utils.factor()
    monotonic       : [optional] bool, flag indicating HetBlock policy for some k' is monotonic in state k
                                                                        (allows more efficient interpolation)
    returnindividual: [optional] bool, flag to return individual outcomes from HetBlock.td
    tol             : [optional] scalar, for convergence of Newton's method we require |H|<tol
    maxit           : [optional] int, maximum number of iterations of Newton's method
    noisy           : [optional] bool, flag to print largest absolute error for each target
    save            : [optional] bool, flag for saving Jacobians inside HetBlocks during calc of H_U
    use_saved       : [optional] bool, flag for using saved Jacobians inside HetBlocks during calc of H_U
    kwargs          : dict, all shocked Z go here, must all have same length T

    Returns
    ----------
    results : dict, return paths for all aggregate variables, plus individual outcomes of HetBlock if returnindividual
    """
    # check to make sure that kwargs are valid shocks
    for x in unknowns + targets:
        if x in kwargs:
            raise ValueError(
                f'Shock {x} in td_solve cannot also be an unknown or target!')

    # infer T from a single shocked Z in kwargs
    for v in kwargs.values():
        T = v.shape[0]
        break

    # initialize guess for unknowns to steady state length T
    Us = {k: np.full(T, ss[k]) for k in unknowns}
    Uvec = jac.pack_vectors(Us, unknowns, T)

    # obtain H_U_factored if we don't have it already
    if H_U_factored is None:
        if H_U is None:
            # not even H_U is supplied, get it (costly if there are HetBlocks)
            H_U = jac.get_H_U(block_list,
                              unknowns,
                              targets,
                              T,
                              ss,
                              save=save,
                              use_saved=use_saved)
        H_U_factored = utils.factor(H_U)

    # do a topological sort once to avoid some redundancy
    sort = utils.block_sort(block_list)

    # iterate until convergence
    for it in range(maxit):
        results = td_map(ss, block_list, sort, monotonic, returnindividual,
                         **kwargs, **Us)
        errors = {k: np.max(np.abs(results[k])) for k in targets}
        if noisy:
            print(f'On iteration {it}')
            for k in errors:
                print(f'   max error for {k} is {errors[k]:.2E}')
        if all(v < tol for v in errors.values()):
            break
        else:
            # update guess U by -H_U^(-1) times errors H
            Hvec = jac.pack_vectors(results, targets, T)
            Uvec -= utils.factored_solve(H_U_factored, Hvec)
            Us = jac.unpack_vectors(Uvec, unknowns, T)
    else:
        raise ValueError(f'No convergence after {maxit} backward iterations!')

    return results
예제 #9
0
 def __init__(self, p):
     FF.__init__(self, p)
     assert p > 1 and factor(p) == [p], "%r must be a prime integer!" % p
예제 #10
0
def factor_consequtive(x):
	factors = utils.factor(x, primes)
	counts = Counter(factors)
	for k in counts:
		yield k ** counts[k]
예제 #11
0
factors of N! in decreasing order of multiplicity.

Last trick is a counting trick: if a<b and a and b have same number of factors,
note that we will double count this case if we do not have some extra
bookkeeping. Instead of tracking whether a<b in the dp (which is hard), we
track whether a==b in the dp (which is much easier), and if the have the same
number of factors in the end, we add 2 to the total instead of 1. Since we have
now double-counted all the cases, the final answer is achieved halving.
"""

N = 100
# we need to factor largest multiplicity of anything <= 100 (+1), which will never exceed 100 itself
primes = np.nonzero(sieve(N))[0]
factors = Counter()
for i in xrange(2, N+1):
    factors.update(factor(i, primes))

_mem = {}
def same_divisor_count(i, div_factor_diff, equal, factorcounts, bounds):
    # remove 0 entries and do bounds check
    for k, c in div_factor_diff.items():
        if c==0: del div_factor_diff[k]
        else:
            if i==len(bounds) or abs(c) > bounds[i][k]:
                return 0
    if i==len(factorcounts):
        assert len(div_factor_diff) == 0
        return 2 if equal else 1
    key = (i, frozenset(div_factor_diff.items()), equal)
    if key in _mem:
        return _mem[key]
예제 #12
0
def draw_grid(name):

    N = 100
    
    width = math.log(N, 2)
    dwg = svgwrite.Drawing(
        filename=name, 
        debug=True
    )
    
    limitItems = defaultdict(list)
    limitCurrent = 0

    def coord(i, j):
        return math.log(i,2)+math.log(j,2), math.log(i,2)
    
    def getLineWidth(p, j):
        k = 1.5/p
        return k / j
    
    def getPointRadius(j):
        return 0.6/j
    
    def getColor(index):
        h = getHue(index)
        col = colorsys.hsv_to_rgb( h, 0.7, 0.9 )
        return "#%02x%02x%02x" % tuple( map( lambda f: int(f*0xFF), col ) )
        
    scale = 100
    def scalePoint(c): return (c[0]+0.5)*scale, (c[1]+0.5)*scale
    
    def line(c0,c1, w, stroke):
        if c1[0] > width: c1 = (width, c1[1])
        limitItems[limitCurrent].append(dwg.line(start=scalePoint(c0), end=scalePoint(c1), stroke='white', stroke_width= w*1.2*scale))
        limitItems[limitCurrent].append(dwg.line(start=scalePoint(c0), end=scalePoint(c1), stroke=stroke, stroke_width= w*scale))
    
    def point(c,r, fill, i):
        limitItems[limitCurrent].append(dwg.circle(center=scalePoint(c), r= r*scale, fill= fill))
        #
        minsize = 0.035
        s = r*1.8 + minsize
        c = (c[0], c[1] + s*0.35)
        #c = (c[0], c[1] + (i%3)*minsize)
        if getPointRadius(i) <= minsize:
            c = (c[0], c[1] + (i%3-1)*minsize)
        limitItems[limitCurrent].append(dwg.text(`i`, scalePoint(c), font_size= s*scale, font_family= "Arial", style="text-anchor:middle;text-align:center"))

        
    
    ns = range(1, N+1)
    ps = list(itertools.takewhile(lambda p: p <= N, primes()))

    limitCurrent = 1
    point(coord(1, 1), getPointRadius(1), getColor(0), 1)

    #for pi,p in enumerate(ps):  # ji limit
    for pi,p in enumerate([2,3,5,7]):  # ji limit
        
        limitCurrent = p
        fillColor = getColor(pi)

        # verticals
        for j in ns:
            if j>1 and max(factor(j))==p:
                c0 = coord(1, j)
                c1 = coord(j, 1)
                line(c0,c1, getLineWidth(p, j), fillColor)

        # horizontals
        for i in ns:
            for j in ps:
                if i==1 or max(factor(i*j))==p:
                    if j<=p and i*(j-1)<=N:
                        c0 = coord(i, j-1)
                        c1 = coord(i, j)
                        line(c0,c1, getLineWidth(p, j*i), fillColor)
        
        # points
        for j in ns:
            if j>1 and max(factor(j))==p:
                for i in getAllDivisors(j):
                    jj = j/i
                    c0 = coord(i, jj)
                    point(c0, getPointRadius(jj*i), fillColor, jj)
                    
        

    for l in sorted(limitItems.keys())[::-1]:
        group = dwg.add(dwg.g(id='limit'+`l`))
        for i in limitItems[l]:
            group.add(i)
    
    dwg.save()