Example #1
0
def multiplyDigits( n, exponent = 1, dropZeroes = False ):
    if exponent < 1:
        raise ValueError( 'multiplyDigits( ) expects a positive integer for \'exponent\'' )
    elif exponent == 1:
        return fprod( getDigits( n, dropZeroes ) )
    else:
        return fprod( [ power( i, exponent ) for i in getDigits( n, dropZeroes ) ] )
Example #2
0
def multiplyDigitList(n, exponent=1, dropZeroes=False):
    if exponent < 1:
        raise ValueError(
            'multiplyDigitList( ) expects a positive integer for \'exponent\'')

    if exponent == 1:
        return fprod(getDigitList(n, dropZeroes))

    return fprod([power(i, exponent) for i in getDigitList(n, dropZeroes)])
Example #3
0
def _crt( a, b, m, n ):
    d = getGCD( m, n )

    if fmod( fsub( a, b ), d ) != 0:
        return None

    x = floor( fdiv( m, d ) )
    y = floor( fdiv( n, d ) )
    z = floor( fdiv( fmul( m, n ), d ) )
    p, q, r = getExtendedGCD( x, y )

    return fmod( fadd( fprod( [ b, p, x ] ), fprod( [ a, q, y ] ) ), z )
def hyper1(As, Bs, N, M):
    with mpmath.extraprec(mpmath.mp.prec):
        s = t = 1
        for j in range(1, N):
            t *= fprod(a + j - 1 for a in As) / fprod(b + j - 1 for b in Bs)
            s += t
        if M > 0:
            s2 = 0
            g = sum(As) - sum(Bs)
            for (j, c) in enumerate(gammaprod_series(As, Bs, M)):
                s2 += c * mpmath.zeta(-(g - j), N)
            s += s2 * mpmath.gammaprod(Bs, As)
    return s
def hyper1(As, Bs, N, M):
    with mpmath.extraprec(mpmath.mp.prec):
        s = t = 1
        for j in range(1, N):
            t *= fprod(a + j - 1 for a in As) / fprod(b + j - 1 for b in Bs)
            s += t
        if M > 0:
            s2 = 0
            g = sum(As) - sum(Bs)
            for (j, c) in enumerate(gammaprod_series(As, Bs, M)):
                s2 += c * mpmath.zeta(-(g - j), N)
            s += s2 * mpmath.gammaprod(Bs, As)
    return s
Example #6
0
 def _proda_jni_mpmath(self):
     if self._proda_jni_cache_mpmath is None:
         idx = np.arange(self.N)
         self._proda_jni_cache_mpmath = np.array([
             mp.fprod(ai - self.a[idx != i]) for i, ai in enumerate(self.a)
         ])
     return self._proda_jni_cache_mpmath
Example #7
0
def calculateWindChill( measurement1, measurement2 ):
    validUnitTypes = [
        [ 'velocity', 'temperature' ],
    ]

    arguments = matchUnitTypes( [ measurement1, measurement2 ], validUnitTypes )

    if not arguments:
        raise ValueError( '\'wind_chill\' requires velocity and temperature measurements' )

    wind_speed = arguments[ 'velocity' ].convert( 'miles/hour' ).value
    temperature = arguments[ 'temperature' ].convert( 'degrees_F' ).value

    if wind_speed < 3:
        raise ValueError( '\'wind_chill\' is not defined for wind speeds less than 3 mph' )

    if temperature > 50:
        raise ValueError( '\'wind_chill\' is not defined for temperatures over 50 degrees fahrenheit' )

    result = fsum( [ 35.74, fmul( temperature, 0.6215 ), fneg( fmul( 35.75, power( wind_speed, 0.16 ) ) ),
                   fprod( [ 0.4275, temperature, power( wind_speed, 0.16 ) ] ) ] )

    # in case someone puts in a silly velocity
    if result < -459.67:
        result = -459.67

    return RPNMeasurement( result, 'degrees_F' ).convert( arguments[ 'temperature' ].units )
Example #8
0
def getNthOctagonalTriangularNumber( n ):
    sign = power( -1, real( n ) )

    return nint( floor( fdiv( fmul( fsub( 7, fprod( [ 2, sqrt( 6 ), sign ] ) ),
                                    power( fadd( sqrt( 3 ), sqrt( 2 ) ),
                                           fsub( fmul( 4, real_int( n ) ), 2 ) ) ),
                              96 ) ) )
Example #9
0
def Ptrue(Qp, I, R, S, Q, b, replacement=True):
    """
    Returns the probability of testing with replacement,
    in which tested individuals can be retested on the same day.
    
    Args
    ----
    Qp (int): number of positive tests.
    I (int): number of infecteds.
    R (int): number of recovered.
    S (int): number of suceptibles.
    Q (int): number of tests.
    b (float): biased-testing factor.
    replacement (boolean): testing with/without replacement.
    
    """

    if replacement:
        f0 = (I + R) / (S + I + R)
        Ptrue = binomial(Q, Qp) * power(f0 * exp(b), Qp) * power(
            1 - f0, Q - Qp)
        Ptrue /= power(1 + (exp(b) - 1) * f0, Q)

    else:
        product = [(I + R - k) / (S - Q + Qp - k) for k in range(Qp)]

        Ptrue = binomial(Q, Qp) * fprod(product) * exp(Qp*b) * \
                1/hyp2f1( -I - R, -Q, S - Q + 1, exp(b) )

    return Ptrue
Example #10
0
def calculateWindChillOperator( measurement1, measurement2 ):
    '''
    https://www.ibiblio.org/units/dictW.html
    '''

    validUnitTypes = [
        [ 'velocity', 'temperature' ],
    ]

    arguments = matchUnitTypes( [ measurement1, measurement2 ], validUnitTypes )

    if not arguments:
        raise ValueError( '\'wind_chill\' requires velocity and temperature measurements' )

    windSpeed = arguments[ 'velocity' ].convert( 'miles/hour' ).value
    temperature = arguments[ 'temperature' ].convert( 'degrees_F' ).value

    if windSpeed < 3:
        raise ValueError( '\'wind_chill\' is not defined for wind speeds less than 3 mph' )

    if temperature > 50:
        raise ValueError( '\'wind_chill\' is not defined for temperatures over 50 degrees fahrenheit' )

    result = fsum( [ 35.74, fmul( temperature, 0.6215 ), fneg( fmul( 35.75, power( windSpeed, 0.16 ) ) ),
                     fprod( [ 0.4275, temperature, power( windSpeed, 0.16 ) ] ) ] )

    # in case someone puts in a silly velocity
    if result < -459.67:
        result = -459.67

    return RPNMeasurement( result, 'degrees_F' ).convert( arguments[ 'temperature' ].units )
Example #11
0
 def _displaced_thermal(cls, alpha, nbar, n):
     """
     returns the motional state distribution with the displacement alpha, motional temperature nbar for the state n
     """
     # this is needed because for some inputs (larrge n or small nbar, this term is 0 while the laguerre term is infinite. their product is zero but beyond the floating point precision
     try:
         old_settings = np.seterr(invalid="raise")
         populations = (
             1.0
             / (nbar + 1.0)
             * (nbar / (nbar + 1.0)) ** n
             * laguerre(n, 0, -alpha ** 2 / (nbar * (nbar + 1.0)))
             * np.exp(-alpha ** 2 / (nbar + 1.0))
         )
     except FloatingPointError:
         np.seterr(**old_settings)
         print "precise calculation required", alpha, nbar
         populations = [
             mp.fprod(
                 (
                     1.0 / (nbar + 1.0),
                     mp.power(nbar / (nbar + 1.0), k),
                     mp.laguerre(k, 0, -alpha ** 2 / (nbar * (nbar + 1.0))),
                     mp.exp(-alpha ** 2 / (nbar + 1.0)),
                 )
             )
             for k in n
         ]
         print "done computing populations"
         populations = np.array(populations)
         print "returned array"
     return populations
 def _displaced_thermal(cls, alpha, nbar, n):
     '''
     returns the motional state distribution with the displacement alpha, motional temperature nbar for the state n
     '''
     #this is needed because for some inputs (larrge n or small nbar, this term is 0 while the laguerre term is infinite. their product is zero but beyond the floating point precision
     try:
         old_settings = np.seterr(invalid='raise')
         populations = 1. / (nbar +
                             1.0) * (nbar / (nbar + 1.0))**n * laguerre(
                                 n, 0, -alpha**2 /
                                 (nbar *
                                  (nbar + 1.0))) * np.exp(-alpha**2 /
                                                          (nbar + 1.0))
     except FloatingPointError:
         np.seterr(**old_settings)
         print 'precise calculation required', alpha, nbar
         populations = [
             mp.fprod((1. / (nbar + 1.0), mp.power(nbar / (nbar + 1.0), k),
                       mp.laguerre(k, 0, -alpha**2 / (nbar * (nbar + 1.0))),
                       mp.exp(-alpha**2 / (nbar + 1.0)))) for k in n
         ]
         print 'done computing populations'
         populations = np.array(populations)
         print 'returned array'
     return populations
Example #13
0
def findNthPolygonalNumber( n, k ):
    if real_int( k ) < 3:
        raise ValueError( 'the number of sides of the polygon cannot be less than 3,' )

    return nint( fdiv( fsum( [ sqrt( fsum( [ power( k, 2 ), fprod( [ 8, k, real( n ) ] ),
                                             fneg( fmul( 8, k ) ), fneg( fmul( 16, n ) ), 16 ] ) ),
                               k, -4 ] ), fmul( 2, fsub( k, 2 ) ) ) )
Example #14
0
def getNthMotzkinNumber( n ):
    result = 0

    for j in arange( 0, floor( fdiv( real( n ), 3 ) ) + 1 ):
        result = fadd( result, fprod( [ power( -1, j ), binomial( fadd( n, 1 ), j ),
                                      binomial( fsub( fmul( 2, n ), fmul( 3, j ) ), n ) ] ) )

    return fdiv( result, fadd( n, 1 ) )
Example #15
0
def getNthDecagonalTriangularNumberOperator(n):
    return nint(
        floor(
            fdiv(
                fmul(fadd(9, fprod([4, sqrt(2),
                                    power(-1, fadd(n, 1))])),
                     power(fadd(1, sqrt(2)), fsub(fmul(4, fadd(n, 1)), 6))),
                64)))
Example #16
0
def getNthOctagonalTriangularNumberOperator(n):
    sign = power(-1, n)

    return nint(
        floor(
            fdiv(
                fmul(fsub(7, fprod([2, sqrt(6), sign])),
                     power(fadd(sqrt(3), sqrt(2)), fsub(fmul(4, n), 2))), 96)))
Example #17
0
def L(m, n, d):
    list1 = range(m * n + 1, m * n + m + 1 + 1)
    prod1 = fprod(list1)
    list2 = []
    for k in range(m + 1):
        list2.append(((-1)**(m * n + m + k)) * comb(m, k) / prod0(m, n, k))
    return (1 + d)**(m + 3 / 2) * prod1 / factorial(m) * sqrt(
        factorial(m * n + m) * fsum(list2))
Example #18
0
def getECMFactors( target ):
    from pyecm import factors

    n = int( floor( target ) )

    verbose = g.verbose
    randomSigma = True
    asymptoticSpeed = 10
    processingPower = 1.0

    if n < -1:
        return [ ( -1, 1 ) ] + getECMFactors( fneg( n ) )
    elif n == -1:
        return [ ( -1, 1 ) ]
    elif n == 0:
        return [ ( 0, 1 ) ]
    elif n == 1:
        return [ ( 1, 1 ) ]

    if verbose:
        print( '\nfactoring', n, '(', int( floor( log10( n ) ) ), ' digits)...' )

    if g.factorCache is None:
        loadFactorCache( )

    if n in g.factorCache:
        if verbose and n != 1:
            print( 'cache hit:', n )
            print( )

        return g.factorCache[ n ]

    result = [ ]

    for factor in factors( n, verbose, randomSigma, asymptoticSpeed, processingPower ):
        result.append( factor )

    result = [ int( i ) for i in result ]

    largeFactors = list( collections.Counter( [ i for i in result if i > 65535 ] ).items( ) )
    product = int( fprod( [ power( i[ 0 ], i[ 1 ] ) for i in largeFactors ] ) )

    save = False

    if product not in g.factorCache:
        g.factorCache[ product ] = largeFactors
        save = True

    result = list( collections.Counter( result ).items( ) )

    if n > g.minValueToCache and n not in g.factorCache:
        g.factorCache[ n ] = result
        g.factorCacheIsDirty = True

    if verbose:
        print( )

    return result
Example #19
0
def runYAFU(n):
    fullOut = subprocess.run([
        g.userConfiguration['yafu_path'] + os.sep +
        g.userConfiguration['yafu_binary'], '-xover', '120'
    ],
                             input='factor(' + str(int(n)) + ')\n',
                             encoding='ascii',
                             stdout=subprocess.PIPE,
                             cwd=g.userConfiguration['yafu_path'],
                             check=True).stdout

    #print( 'out', fullOut )

    out = fullOut[fullOut.find('***factors found***'):]

    if len(out) < 2:
        if log10(n) > 40:
            raise ValueError('yafu seems to have crashed trying to factor ' +
                             str(int(n)) + '.\n\nyafu output follows:\n' +
                             fullOut)

        debugPrint(
            'yafu seems to have crashed, switching to built-in factoring code')
        return factorise(int(n))

    result = []

    while True:
        prime = ''

        out = out[out.find('P'):]

        if len(out) < 2:
            break

        out = out[out.find('='):]

        index = 2

        while out[index] >= '0' and out[index] <= '9':
            prime += out[index]
            index += 1

        result.append(mpmathify(prime))

    if not result:
        raise ValueError('yafu seems to have failed.')

    answer = fprod(result)

    if answer != n:
        debugPrint('\nyafu has barfed')
        for i in result:
            n = fdiv(n, i)

        result.extend(runYAFU(n))

    return sorted(result)
Example #20
0
def getNthDecagonalHeptagonalNumber( n ):
    sqrt10 = sqrt( 10 )

    return nint( floor( fdiv( fprod( [ fsub( 11,
                                             fmul( fmul( 2, sqrt10 ),
                                                   power( -1, real_int( n ) ) ) ),
                                       fadd( 1, sqrt10 ),
                                       power( fadd( 3, sqrt10 ),
                                              fsub( fmul( 4, n ), 3 ) ) ] ), 320 ) ) )
Example #21
0
def getNthNonagonalPentagonalNumber( n ):
    sqrt21 = sqrt( 21 )
    sign = power( -1, real_int( n ) )

    return nint( floor( fdiv( fprod( [ fadd( 25, fmul( 4, sqrt21 ) ),
                                       fsub( 5, fmul( sqrt21, sign ) ),
                                       power( fadd( fmul( 2, sqrt( 7 ) ), fmul( 3, sqrt( 3 ) ) ),
                                              fsub( fmul( 4, n ), 4 ) ) ] ),
                              336 ) ) )
Example #22
0
def getNthNonagonalTriangularNumber( n ):
    a = fmul( 3, sqrt( 7 ) )
    b = fadd( 8, a )
    c = fsub( 8, a )

    return nint( fsum( [ fdiv( 5, 14 ),
                         fmul( fdiv( 9, 28 ), fadd( power( b, real_int( n ) ), power( c, n ) ) ),
                         fprod( [ fdiv( 3, 28 ),
                                  sqrt( 7 ),
                                  fsub( power( b, n ), power( c, n ) ) ] ) ] ) )
Example #23
0
File: rpnList.py Project: flawr/rpn
def calculateGeometricMean( args ):
    if isinstance( args, RPNGenerator ):
        return calculateGeometricMean( list( args ) )
    elif isinstance( args, list ):
        if isinstance( args[ 0 ], ( list, RPNGenerator ) ):
            return [ calculateGeometricMean( list( arg ) ) for arg in args ]
        else:
            return root( fprod( args ), len( args ) )
    else:
        return args
Example #24
0
def getNthMenageNumber( n ):
    if n < 0:
        raise ValueError( '\'menage\' requires a non-negative argument' )
    elif n in [ 1, 2 ]:
        return 0
    elif n in [ 0, 3 ]:
        return 1
    else:
        return nsum( lambda k: fdiv( fprod( [ power( -1, k ), fmul( 2, n ), binomial( fsub( fmul( 2, n ), k ), k ),
                                            fac( fsub( n, k ) ) ] ), fsub( fmul( 2, n ), k ) ), [ 0, n ] )
Example #25
0
def getNthDecagonalHeptagonalNumberOperator(n):
    sqrt10 = sqrt(10)

    return nint(
        floor(
            fdiv(
                fprod([
                    fsub(11, fmul(fmul(2, sqrt10), power(-1, n))),
                    fadd(1, sqrt10),
                    power(fadd(3, sqrt10), fsub(fmul(4, n), 3))
                ]), 320)))
Example #26
0
def runYAFU( n ):
    import subprocess

    full_out = subprocess.run( [ g.userConfiguration[ 'yafu_path' ] + os.sep +
                                 g.userConfiguration[ 'yafu_binary' ], str( int( n ) ), '-xover', '120' ],
                             stdout=subprocess.PIPE, cwd=g.userConfiguration[ 'yafu_path' ] ).stdout.decode( 'ascii' )

    #print( 'out', full_out )

    out = full_out[ full_out.find( '***factors found***' ) : ]

    if len( out ) < 2:
        if log10( n ) > 40:
            raise ValueError( 'yafu seems to have crashed trying to factor ' + str( int( n ) ) +
                              '.\n\nyafu output follows:\n' + full_out )
        else:
            debugPrint( 'yafu seems to have crashed, switching to built-in factoring code' )
            from rpn.factorise import factorise
            return factorise( int( n ) )

    result = [ ]

    while True:
        prime = ''

        out = out[ out.find( 'P' ) : ]

        if len( out ) < 2:
            break

        out = out[ out.find( '=' ) : ]

        index = 2

        while out[ index ] >= '0' and out[ index ] <= '9':
            prime += out[ index ]
            index += 1

        result.append( mpmathify( prime ) )

    if not result:
        raise ValueError( 'yafu seems to have failed.' )

    answer = fprod( result )

    if answer != n:
        debugPrint( '\nyafu has barfed' )
        for i in result:
            n = fdiv( n, i )

        result.extend( runYAFU( n ) )

    return sorted( result )
def hyper1_auto(As, Bs, N, M):
    with mpmath.extraprec(mpmath.mp.prec):
        s = t = 1
        good_ratio_hits = 0
        for j in range(1, N):
            s_old = s
            t *= fprod(a + j - 1 for a in As) / fprod(b + j - 1 for b in Bs)
            s += t
            ratio = (s - s_old) / s
            if ratio < mpf(10 ** -18):
                good_ratio_hits += 1
            if good_ratio_hits > 3:
                break
            print float(s)
        if M > 0:
            s2 = 0
            g = sum(As) - sum(Bs)
            for (j, c) in enumerate(gammaprod_series(As, Bs, M)):
                s2 += c * mpmath.zeta(-(g - j), N)
            s += s2 * mpmath.gammaprod(Bs, As)
    return s
Example #28
0
def findPolygonalNumber(n, k):
    return floor(
        fdiv(
            fsum([
                sqrt(
                    fsum([
                        power(k, 2),
                        fprod([8, k, n]),
                        fneg(fmul(8, k)),
                        fneg(fmul(16, n)), 16
                    ])), k, -4
            ]), fmul(2, fsub(k, 2))))
def hyper1_auto(As, Bs, N, M):
    with mpmath.extraprec(mpmath.mp.prec):
        s = t = 1
        good_ratio_hits = 0
        for j in range(1, N):
            s_old = s
            t *= fprod(a + j - 1 for a in As) / fprod(b + j - 1 for b in Bs)
            s += t
            ratio = (s - s_old) / s
            if ratio < mpf(10**-18):
                good_ratio_hits += 1
            if good_ratio_hits > 3:
                break
            print float(s)
        if M > 0:
            s2 = 0
            g = sum(As) - sum(Bs)
            for (j, c) in enumerate(gammaprod_series(As, Bs, M)):
                s2 += c * mpmath.zeta(-(g - j), N)
            s += s2 * mpmath.gammaprod(Bs, As)
    return s
Example #30
0
def getNthSylvester( n ):
    if real( n ) == 1:
        return 2
    elif n == 2:
        return 3
    else:
        list = [ 2, 3 ]

        for i in arange( 2, n ):
            list.append( fprod( list ) + 1 )

    return list[ -1 ]
Example #31
0
def getNthMotzkinNumber( n ):
    '''
    http://oeis.org/A001006

    a(n) = sum((-1)^j*binomial(n+1, j)*binomial(2n-3j, n), j=0..floor(n/3))/(n+1)
    '''
    result = 0

    for j in arange( 0, floor( fdiv( real( n ), 3 ) ) + 1 ):
        result = fadd( result, fprod( [ power( -1, j ), binomial( fadd( n, 1 ), j ),
                                      binomial( fsub( fmul( 2, n ), fmul( 3, j ) ), n ) ] ) )

    return fdiv( result, fadd( n, 1 ) )
Example #32
0
def getAntiprismVolumeOperator(n, k):
    result = getProduct([
        fdiv(
            fprod([
                n,
                sqrt(fsub(fmul(4, cos(cos(fdiv(pi, fmul(n, 2))))), 1)),
                sin(fdiv(fmul(3, pi), fmul(2, n)))
            ]), fmul(12, sin(sin(fdiv(pi, n))))),
        sin(fdiv(fmul(3, pi), fmul(2, n))),
        getPower(k, 3)
    ])

    return result.convert('meter^3')
Example #33
0
def getNthSylvesterNumber(n):
    if n == 1:
        return 2

    if n == 2:
        return 3

    sylvesters = [2, 3]

    for _ in arange(2, n):
        sylvesters.append(fprod(sylvesters) + 1)

    return sylvesters[-1]
Example #34
0
def calculate_RAM_usage(shape):
    """ 
    Calculate a lower bound to the RAM needed to allocate the arrays for efficient_gcf_calculation
    
    8 arrays of shape full of 64-bit floats. 
    There are also some lists whose space is hard to estimate. 
    
    :param shape: see efficient_gcf_calculation
    :param length: see efficient_gcf_calculation
    :return float: RAM usage in bytes
    """
    c = 200.
    return 8. * mp.fprod(shape) * 8. + c * mp.fsum(shape) * 8.
Example #35
0
def getNthNonagonalPentagonalNumberOperator(n):
    sqrt21 = sqrt(21)
    sign = power(-1, n)

    return nint(
        floor(
            fdiv(
                fprod([
                    fadd(25, fmul(4, sqrt21)),
                    fsub(5, fmul(sqrt21, sign)),
                    power(fadd(fmul(2, sqrt(7)), fmul(3, sqrt(3))),
                          fsub(fmul(4, n), 4))
                ]), 336)))
Example #36
0
def getPartitionNumber( n ):
    '''
    This version is, um, less recursive than the original, which I've kept.
    The strategy is to create a list of the smaller partition numbers we need
    to calculate and then start calling them recursively, starting with the
    smallest.  This will minimize the number of recursions necessary, and in
    combination with caching values, will calculate practically any integer
    partition without the risk of a stack overflow.

    I can't help but think this is still grossly inefficient compared to what's
    possible.  It seems that using this algorithm, calculating any integer
    partition ends up necessitating calculating the integer partitions of
    every integer smaller than the original argument.
    '''
    debugPrint( 'partition', int( n ) )

    if real_int( n ) < 0:
        raise ValueError( 'non-negative argument expected' )
    elif n in ( 0, 1 ):
        return 1

    sign = 1
    i = 1
    k = 1

    estimate = log10( fdiv( power( e, fmul( pi, sqrt( fdiv( fmul( 2, n ), 3 ) ) ) ),
                            fprod( [ 4, n, sqrt( 3 ) ] ) ) )
    if mp.dps < estimate + 5:
        mp.dps = estimate + 5

    partitionList = [ ]
    signList = [ ]

    while n - k >= 0:
        partitionList.append( ( fsub( n, k ), sign ) )
        i += 1

        if i % 2:
            sign *= -1

        k = getNthGeneralizedPolygonalNumber( i, 5 )

    partitionList = partitionList[ : : -1 ]

    total = 0

    for partition, sign in partitionList:
        total = fadd( total, fmul( sign, getPartitionNumber( partition ) ) )

    return total
Example #37
0
def makePythagoreanTriple( n, k ):
    if real( n ) < 0 or real( k ) < 0:
        raise ValueError( "'make_pyth_3' requires positive arguments" )

    if n == k:
        raise ValueError( "'make_pyth_3' requires unequal arguments" )

    result = [ ]

    result.append( fprod( [ 2, n, k ] ) )
    result.append( fabs( fsub( fmul( n, n ), fmul( k, k ) ) ) )
    result.append( fadd( fmul( n, n ), fmul( k, k ) ) )

    return sorted( result )
Example #38
0
def getPartitionNumber(n):
    '''
    This version is, um, less recursive than the original, which I've kept.
    The strategy is to create a list of the smaller partition numbers we need
    to calculate and then start calling them recursively, starting with the
    smallest.  This will minimize the number of recursions necessary, and in
    combination with caching values, will calculate practically any integer
    partition without the risk of a stack overflow.

    I can't help but think this is still grossly inefficient compared to what's
    possible.  It seems that using this algorithm, calculating any integer
    partition ends up necessitating calculating the integer partitions of
    every integer smaller than the original argument.
    '''
    debugPrint('partition', int(n))

    if n in (0, 1):
        return 1

    sign = 1
    i = 1
    k = 1

    estimate = log10(
        fdiv(power(e, fmul(pi, sqrt(fdiv(fmul(2, n), 3)))),
             fprod([4, n, sqrt(3)])))
    if mp.dps < estimate + 5:
        mp.dps = estimate + 5

    partitionList = []

    while n - k >= 0:
        partitionList.append((fsub(n, k), sign))
        i += 1

        if i % 2:
            sign *= -1

        k = getNthGeneralizedPolygonalNumber(i, 5)

    partitionList = partitionList[::-1]

    total = 0

    for partition, sign in partitionList:
        total = fadd(total, fmul(sign, getPartitionNumber(partition)))

    return total
Example #39
0
def createDivisorList( seed, factors ):
    result = [ ]

    factor, count = factors[ 0 ]

    for i in range( count + 1 ):
        divisors = [ ]
        divisors.extend( seed )
        divisors.extend( [ factor ] * i )

        if len( factors ) > 1:
            result.extend( createDivisorList( divisors, factors[ 1 : ] ) )
        else:
            result.extend( [ fprod( divisors ) ] )

    return result
Example #40
0
def getNthSchroederNumber( n ):
    if real( n ) == 1:
        return 1

    if n < 0:
        raise ValueError( '\'nth_schroeder\' expects a non-negative argument' )

    n = fsub( n, 1 )

    result = 0

    for k in arange( 0, fadd( n, 1 ) ):
        result = fadd( result, fdiv( fprod( [ power( 2, k ), binomial( n, k ),
                                              binomial( n, fsub( k, 1 ) ) ] ), n ) )

    return result
Example #41
0
def getAntiprismVolume( n, k ):
    if real( n ) < 3:
        raise ValueError( 'the number of sides of the prism cannot be less than 3,' )

    if not isinstance( k, RPNMeasurement ):
        return getAntiprismVolume( n, RPNMeasurement( real( k ), 'meter' ) )

    if k.getDimensions( ) != { 'length' : 1 }:
        raise ValueError( '\'antiprism_volume\' argument 2 must be a length' )

    result = getProduct( [ fdiv( fprod( [ n, sqrt( fsub( fmul( 4, cos( cos( fdiv( pi, fmul( n, 2 ) ) ) ) ), 1 ) ),
                                   sin( fdiv( fmul( 3, pi ), fmul( 2, n ) ) ) ] ),
                           fmul( 12, sin( sin( fdiv( pi, n ) ) ) ) ),
                           sin( fdiv( fmul( 3, pi ), fmul( 2, n ) ) ),
                           getPower( k, 3 ) ] )

    return result.convert( 'meter^3' )
Example #42
0
def makeEulerBrick( _a, _b, _c ):
    a, b, c = sorted( [ real( _a ), real( _b ), real( _c ) ] )

    if fadd( power( a, 2 ), power( b, 2 ) ) != power( c, 2 ):
        raise ValueError( "'euler_brick' requires a pythogorean triple" )

    result = [ ]

    a2 = fmul( a, a )
    b2 = fmul( b, b )
    c2 = fmul( c, c )

    result.append( fabs( fmul( a, fsub( fmul( 4, b2 ), c2 ) ) ) )
    result.append( fabs( fmul( b, fsub( fmul( 4, a2 ), c2 ) ) ) )
    result.append( fprod( [ 4, a, b, c ] ) )

    return sorted( result )
Example #43
0
def getNthMenageNumber(n):
    '''https://oeis.org/A000179'''
    if n == 1:
        return -1

    if n == 2:
        return 0

    if n in [0, 3]:
        return 1

    return nsum(
        lambda k: fdiv(
            fprod([
                power(-1, k),
                fmul(2, n),
                binomial(fsub(fmul(2, n), k), k),
                fac(fsub(n, k))
            ]), fsub(fmul(2, n), k)), [0, n])
Example #44
0
def getNthSchroederNumber(n):
    if n == 1:
        return 1

    n = fsub(n, 1)

    result = 0

    precision = int(fmul(n, 0.8))

    if mp.dps < precision:
        mp.dps = precision

    for k in arange(0, fadd(n, 1)):
        result = fadd(
            result,
            fdiv(fprod([power(2, k),
                        binomial(n, k),
                        binomial(n, fsub(k, 1))]), n))

    return result
Example #45
0
def getProduct( n ):
    if isinstance( n, RPNGenerator ):
        return getProduct( list( n ) )

    if isinstance( n[ 0 ], ( list, RPNGenerator ) ):
        return [ getProduct( arg ) for arg in n ]

    if not n:
        return 0

    if len( n ) == 1:
        return n[ 0 ]

    hasUnits = False

    for item in n:
        if isinstance( item, RPNMeasurement ):
            hasUnits = True
            break

    if hasUnits:
        result = RPNMeasurement( 1 )

        for item in n:
            if isinstance( item, list ):
                return [ getProduct( arg ) for arg in item ]

            result = multiply( result, item )

        return result

    if not n:
        return 0

    if isinstance( n[ 0 ], list ):
        return [ getProduct( item ) for item in n ]

    return fprod( n )
Example #46
0
def getNthMotzkinNumber(n):
    '''
    http://oeis.org/A001006

    a(n) = sum((-1)^j*binomial(n+1, j)*binomial(2n-3j, n), j=0..floor(n/3))/(n+1)
    '''
    precision = int(n)

    if mp.dps < precision:
        mp.dps = precision

    result = 0

    for j in arange(0, floor(fdiv(n, 3)) + 1):
        result = fadd(
            result,
            fprod([
                power(-1, j),
                binomial(fadd(n, 1), j),
                binomial(fsub(fmul(2, n), fmul(3, j)), n)
            ]))

    return fdiv(result, fadd(n, 1))
Example #47
0
    def _displaced_thermal(cls, alpha, nbar, n):
        '''
        returns the motional state distribution with the displacement alpha, motional temperature nbar for the state n
        '''
        #this is needed because for some inputs (larrge n or small nbar, this term is 0 while the laguerre term is infinite. their product is zero but beyond the floating point precision
        try:
            old_settings = np.seterr(invalid='raise')
            populations = 1. / (nbar +
                                1.0) * (nbar / (nbar + 1.0))**n * laguerre(
                                    n, 0, -alpha**2 /
                                    (nbar *
                                     (nbar + 1.0))) * np.exp(-alpha**2 /
                                                             (nbar + 1.0))
        except FloatingPointError:
            np.seterr(**old_settings)

            def fib():
                a, b = 0, 1
                while 1:
                    yield a
                    a, b = b, a + b

            import time
            t1 = time.time()
            print 'precise calculation required', alpha, nbar
            expon_term = mp.exp(-alpha**2 / (nbar + 1.0))
            populations = [
                float(
                    mp.fprod((mp.power(nbar / (nbar + 1.0), k),
                              mp.laguerre(k, 0,
                                          -alpha**2 / (nbar * (nbar + 1.0))),
                              expon))) for k in n
            ]
            populations = np.array(populations) / (nbar + 1)
            print time.time() - t1
            print 'done'
        return populations
Example #48
0
File: rpnList.py Project: flawr/rpn
def getProduct( n ):
    if isinstance( n, RPNGenerator ):
        return getProduct( list( n ) )
    elif isinstance( n[ 0 ], ( list, RPNGenerator ) ):
        return [ getProduct( arg ) for arg in n ]

    if not n:
        return 0
    elif len( n ) == 1:
        return n[ 0 ]

    hasUnits = False

    for item in n:
        if isinstance( item, RPNMeasurement ):
            hasUnits = True
            break

    if hasUnits:
        result = RPNMeasurement( 1, { } )

        for item in n:
            if isinstance( item, list ):
                return [ getProduct( arg ) for arg in item ]

            result = result.multiply( item )

        return result
    else:
        if not n:
            return 0

        if isinstance( n[ 0 ], list ):
            return [ getProduct( item ) for item in n ]
        else:
            return fprod( n )
Example #49
0
 def _displaced_thermal(cls, alpha, nbar, n):
     '''
     returns the motional state distribution with the displacement alpha, motional temperature nbar for the state n
     '''
     #this is needed because for some inputs (larrge n or small nbar, this term is 0 while the laguerre term is infinite. their product is zero but beyond the floating point precision
     try:
         old_settings = np.seterr(invalid='raise')
         populations = 1./ (nbar + 1.0) * (nbar / (nbar + 1.0))**n * laguerre(n, 0 , -alpha**2 / ( nbar * (nbar + 1.0))) * np.exp( -alpha**2 / (nbar + 1.0))
     except FloatingPointError:
         np.seterr(**old_settings)
         def fib():
             a, b = 0, 1
             while 1:
                 yield a
                 a, b = b, a + b
         import time
         t1 = time.time()
         print 'precise calculation required', alpha, nbar
         expon_term = mp.exp(-alpha**2 / (nbar + 1.0))
         populations = [float(mp.fprod((mp.power(nbar / (nbar + 1.0), k), mp.laguerre(k, 0, -alpha**2 / ( nbar * (nbar + 1.0))), expon))) for k in n]
         populations = np.array(populations) / (nbar + 1)
         print time.time() - t1 
         print 'done'
     return populations
Example #50
0
def calculateHeatIndexOperator( measurement1, measurement2 ):
    '''
    https://en.wikipedia.org/wiki/Heat_index#Formula
    '''
    # pylint: disable=invalid-name
    validUnitTypes = [
        [ 'temperature', 'constant' ],
    ]

    arguments = matchUnitTypes( [ measurement1, measurement2 ], validUnitTypes )

    if not arguments:
        raise ValueError( '\'heat_index\' requires a temperature measurement and the relative humidity in percent' )

    T = arguments[ 'temperature' ].convert( 'degrees_F' ).value
    R = arguments[ 'constant' ]

    if T < 80:
        raise ValueError( '\'heat_index\' is not defined for temperatures less than 80 degrees fahrenheit' )

    if R < 0.4 or R > 1.0:
        raise ValueError( '\'heat_index\' requires a relative humidity value ranging from 40% to 100%' )

    R = fmul( R, 100 )

    c1 = -42.379
    c2 = 2.04901523
    c3 = 10.14333127
    c4 = -0.22475541
    c5 = -6.83783e-3
    c6 = -5.481717e-2
    c7 = 1.22874e-3
    c8 = 8.5282e-4
    c9 = -1.99e-6

    heatIndex = fsum( [ c1, fmul( c2, T ), fmul( c3, R ), fprod( [ c4, T, R ] ), fprod( [ c5, T, T ] ),
                        fprod( [ c6, R, R ] ), fprod( [ c7, T, T, R ] ), fprod( [ c8, T, R, R ] ),
                        fprod( [ c9, T, T, R, R ] ) ] )

    return RPNMeasurement( heatIndex, 'fahrenheit' ).convert( arguments[ 'temperature' ].units )
Example #51
0
def calculateHeatIndex( measurement1, measurement2 ):
    validUnitTypes = [
        [ 'temperature', 'constant' ],
    ]

    arguments = matchUnitTypes( [ measurement1, measurement2 ], validUnitTypes )

    if not arguments:
        raise ValueError( '\'heat_index\' requires a temperature measurement and the relative humidity in percent' )

    T = arguments[ 'temperature' ].convert( 'degrees_F' ).value
    R = arguments[ 'constant' ]

    if T < 80:
        raise ValueError( '\'heat_index\' is not defined for temperatures less than 80 degrees fahrenheit' )

    if R < 0.4 or R > 1.0:
        raise ValueError( '\'heat_index\' requires a relative humidity value ranging from 40% to 100%' )

    R = fmul( R, 100 )

    c1 = -42.379
    c2 = 2.04901523
    c3 = 10.14333127
    c4 = -0.22475541
    c5 = -6.83783e-3
    c6 = -5.481717e-2
    c7 = 1.22874e-3
    c8 = 8.5282e-4
    c9 = -1.99e-6

    heatIndex = fsum( [ c1, fmul( c2, T ), fmul( c3, R ), fprod( [ c4, T, R ] ), fprod( [ c5, T, T ] ),
                        fprod( [ c6, R, R ] ), fprod( [ c7, T, T, R ] ), fprod( [ c8, T, R, R ] ),
                        fprod( [ c9, T, T, R, R ] ) ] )

    return RPNMeasurement( heatIndex, 'fahrenheit' ).convert( arguments[ 'temperature' ].units )
Example #52
0
def fm1(m, n):
    list1 = range(m * n + 1, m * n + m + 1 + 1)
    result1 = fprod(list1)
    return An(n)**m * factorial(m) / result1
Example #53
0
def getDivisorCount( n ):
    if n == 1:
        return 1

    factors = getECMFactors( n ) if g.ecm else getFactors( n )
    return fprod( [ i[ 1 ] + 1 for i in factors ] )
Example #54
0
def solveQuarticPolynomial( _a, _b, _c, _d, _e ):
    if mp.dps < 50:
        mp.dps = 50

    # maybe it's really an order-3 polynomial
    if _a == 0:
        return solveCubicPolynomial( _b, _c, _d, _e )

    # degenerate case, just return the two real and two imaginary 4th roots of the
    # constant term divided by the 4th root of a
    elif _b == 0 and _c == 0 and _d == 0:
        e = fdiv( _e, _a )

        f = root( _a, 4 )

        x1 = fdiv( root( fneg( e ), 4 ), f )
        x2 = fdiv( fneg( root( fneg( e ), 4 ) ), f )
        x3 = fdiv( mpc( 0, root( fneg( e ), 4 ) ), f )
        x4 = fdiv( mpc( 0, fneg( root( fneg( e ), 4 ) ) ), f )

        return [ x1, x2, x3, x4 ]

    # otherwise we have a regular quartic to solve
    b = fdiv( _b, _a )
    c = fdiv( _c, _a )
    d = fdiv( _d, _a )
    e = fdiv( _e, _a )

    # we turn the equation into a cubic that we can solve
    f = fsub( c, fdiv( fmul( 3, power( b, 2 ) ), 8 ) )
    g = fsum( [ d, fdiv( power( b, 3 ), 8 ), fneg( fdiv( fmul( b, c ), 2 ) ) ] )
    h = fsum( [ e, fneg( fdiv( fmul( 3, power( b, 4 ) ), 256 ) ),
                fmul( power( b, 2 ), fdiv( c, 16 ) ), fneg( fdiv( fmul( b, d ), 4 ) ) ] )

    y1, y2, y3 = solveCubicPolynomial( 1, fdiv( f, 2 ), fdiv( fsub( power( f, 2 ), fmul( 4, h ) ), 16 ),
                                       fneg( fdiv( power( g, 2 ), 64 ) ) )

    # pick two non-zero roots, if there are two imaginary roots, use them
    if y1 == 0:
        root1 = y2
        root2 = y3
    elif y2 == 0:
        root1 = y1
        root2 = y3
    elif y3 == 0:
        root1 = y1
        root2 = y2
    elif im( y1 ) != 0:
        root1 = y1

        if im( y2 ) != 0:
            root2 = y2
        else:
            root2 = y3
    else:
        root1 = y2
        root2 = y3

    # more variables...
    p = sqrt( root1 )
    q = sqrt( root2 )
    r = fdiv( fneg( g ), fprod( [ 8, p, q ] ) )
    s = fneg( fdiv( b, 4 ) )

    # put together the 4 roots
    x1 = fsum( [ p, q, r, s ] )
    x2 = fsum( [ p, fneg( q ), fneg( r ), s ] )
    x3 = fsum( [ fneg( p ), q, fneg( r ), s ] )
    x4 = fsum( [ fneg( p ), fneg( q ), r, s ] )

    return [ chop( x1 ), chop( x2 ), chop( x3 ), chop( x4 ) ]
Example #55
0
    def apply(self, items, evaluation):
        'Times[items___]'

        items = items.numerify(evaluation).get_sequence()
        leaves = []
        numbers = []

        prec = min_prec(*items)
        is_machine_precision = any(item.is_machine_precision() for item in items)

        # find numbers and simplify Times -> Power
        for item in items:
            if isinstance(item, Number):
                numbers.append(item)
            elif leaves and item == leaves[-1]:
                leaves[-1] = Expression('Power', leaves[-1], Integer(2))
            elif (leaves and item.has_form('Power', 2) and
                  leaves[-1].has_form('Power', 2) and
                  item.leaves[0].same(leaves[-1].leaves[0])):
                leaves[-1].leaves[1] = Expression(
                    'Plus', item.leaves[1], leaves[-1].leaves[1])
            elif (leaves and item.has_form('Power', 2) and
                  item.leaves[0].same(leaves[-1])):
                leaves[-1] = Expression(
                    'Power', leaves[-1],
                    Expression('Plus', item.leaves[1], Integer(1)))
            elif (leaves and leaves[-1].has_form('Power', 2) and
                  leaves[-1].leaves[0].same(item)):
                leaves[-1] = Expression('Power', item, Expression(
                    'Plus', Integer(1), leaves[-1].leaves[1]))
            else:
                leaves.append(item)

        if numbers:
            if prec is not None:
                if is_machine_precision:
                    numbers = [item.to_mpmath() for item in numbers]
                    number = mpmath.fprod(numbers)
                    number = Number.from_mpmath(number)
                else:
                    with mpmath.workprec(prec):
                        numbers = [item.to_mpmath() for item in numbers]
                        number = mpmath.fprod(numbers)
                        number = Number.from_mpmath(number, dps(prec))
            else:
                number = sympy.Mul(*[item.to_sympy() for item in numbers])
                number = from_sympy(number)
        else:
            number = Integer(1)

        if number.same(Integer(1)):
            number = None
        elif number.is_zero:
            return number
        elif number.same(Integer(-1)) and leaves and leaves[0].has_form('Plus', None):
            leaves[0].leaves = [Expression('Times', Integer(-1), leaf)
                                for leaf in leaves[0].leaves]
            number = None

        for leaf in leaves:
            leaf.last_evaluated = None

        if number is not None:
            leaves.insert(0, number)

        if not leaves:
            return Integer(1)
        elif len(leaves) == 1:
            return leaves[0]
        else:
            return Expression('Times', *leaves)
Example #56
0
def solveQuarticPolynomialOperator( _a, _b, _c, _d, _e ):
    # pylint: disable=invalid-name
    '''
    This function applies the quartic formula to solve a polynomial
    with coefficients of a, b, c, d, and e.
    '''
    if mp.dps < 50:
        mp.dps = 50

    # maybe it's really an order-3 polynomial
    if _a == 0:
        return solveCubicPolynomial( _b, _c, _d, _e )

    # degenerate case, just return the two real and two imaginary 4th roots of the
    # constant term divided by the 4th root of a
    if _b == 0 and _c == 0 and _d == 0:
        e = fdiv( _e, _a )

        f = root( _a, 4 )

        x1 = fdiv( root( fneg( e ), 4 ), f )
        x2 = fdiv( fneg( root( fneg( e ), 4 ) ), f )
        x3 = fdiv( mpc( 0, root( fneg( e ), 4 ) ), f )
        x4 = fdiv( mpc( 0, fneg( root( fneg( e ), 4 ) ) ), f )

        return [ x1, x2, x3, x4 ]

    # otherwise we have a regular quartic to solve
    b = fdiv( _b, _a )
    c = fdiv( _c, _a )
    d = fdiv( _d, _a )
    e = fdiv( _e, _a )

    # we turn the equation into a cubic that we can solve
    f = fsub( c, fdiv( fmul( 3, power( b, 2 ) ), 8 ) )
    g = fsum( [ d, fdiv( power( b, 3 ), 8 ), fneg( fdiv( fmul( b, c ), 2 ) ) ] )
    h = fsum( [ e, fneg( fdiv( fmul( 3, power( b, 4 ) ), 256 ) ),
                fmul( power( b, 2 ), fdiv( c, 16 ) ), fneg( fdiv( fmul( b, d ), 4 ) ) ] )

    roots = solveCubicPolynomial( 1, fdiv( f, 2 ), fdiv( fsub( power( f, 2 ), fmul( 4, h ) ), 16 ),
                                  fneg( fdiv( power( g, 2 ), 64 ) ) )
    y1 = roots[ 0 ]
    y2 = roots[ 1 ]
    y3 = roots[ 2 ]

    # pick two non-zero roots, if there are two imaginary roots, use them
    if y1 == 0:
        root1 = y2
        root2 = y3
    elif y2 == 0:
        root1 = y1
        root2 = y3
    elif y3 == 0:
        root1 = y1
        root2 = y2
    elif im( y1 ) != 0:
        root1 = y1

        if im( y2 ) != 0:
            root2 = y2
        else:
            root2 = y3
    else:
        root1 = y2
        root2 = y3

    # more variables...
    p = sqrt( root1 )
    q = sqrt( root2 )
    r = fdiv( fneg( g ), fprod( [ 8, p, q ] ) )
    s = fneg( fdiv( b, 4 ) )

    # put together the 4 roots
    x1 = fsum( [ p, q, r, s ] )
    x2 = fsum( [ p, fneg( q ), fneg( r ), s ] )
    x3 = fsum( [ fneg( p ), q, fneg( r ), s ] )
    x4 = fsum( [ fneg( p ), fneg( q ), r, s ] )

    return [ chop( x1 ), chop( x2 ), chop( x3 ), chop( x4 ) ]
Example #57
0
def solveCubicPolynomial( a, b, c, d ):
    # pylint: disable=invalid-name
    '''
    This function applies the cubic formula to solve a polynomial
    with coefficients of a, b, c and d.
    '''
    if mp.dps < 50:
        mp.dps = 50

    if a == 0:
        return solveQuadraticPolynomial( b, c, d )

    f = fdiv( fsub( fdiv( fmul( 3, c ), a ), fdiv( power( b, 2 ), power( a, 2 ) ) ), 3 )

    g = fdiv( fadd( fsub( fdiv( fmul( 2, power( b, 3 ) ), power( a, 3 ) ),
                          fdiv( fprod( [ 9, b, c ] ), power( a, 2 ) ) ),
                    fdiv( fmul( 27, d ), a ) ), 27 )
    h = fadd( fdiv( power( g, 2 ), 4 ), fdiv( power( f, 3 ), 27 ) )

    # all three roots are the same
    if h == 0:
        x1 = fneg( root( fdiv( d, a ), 3 ) )
        x2 = x1
        x3 = x2
    # two imaginary and one real root
    elif h > 0:
        r = fadd( fneg( fdiv( g, 2 ) ), sqrt( h ) )

        if r < 0:
            s = fneg( root( fneg( r ), 3 ) )
        else:
            s = root( r, 3 )

        t = fsub( fneg( fdiv( g, 2 ) ), sqrt( h ) )

        if t < 0:
            u = fneg( root( fneg( t ), 3 ) )
        else:
            u = root( t, 3 )

        x1 = fsub( fadd( s, u ), fdiv( b, fmul( 3, a ) ) )

        real = fsub( fdiv( fneg( fadd( s, u ) ), 2 ), fdiv( b, fmul( 3, a ) ) )
        imaginary = fdiv( fmul( fsub( s, u ), sqrt( 3 ) ), 2 )

        x2 = mpc( real, imaginary )
        x3 = mpc( real, fneg( imaginary ) )
    # all real roots
    else:
        j = sqrt( fsub( fdiv( power( g, 2 ), 4 ), h ) )
        k = acos( fneg( fdiv( g, fmul( 2, j ) ) ) )

        if j < 0:
            l = fneg( root( fneg( j ), 3 ) )
        else:
            l = root( j, 3 )

        m = cos( fdiv( k, 3 ) )
        n = fmul( sqrt( 3 ), sin( fdiv( k, 3 ) ) )
        p = fneg( fdiv( b, fmul( 3, a ) ) )

        x1 = fsub( fmul( fmul( 2, l ), cos( fdiv( k, 3 ) ) ), fdiv( b, fmul( 3, a ) ) )
        x2 = fadd( fmul( fneg( l ), fadd( m, n ) ), p )
        x3 = fadd( fmul( fneg( l ), fsub( m, n ) ), p )

    return [ chop( x1 ), chop( x2 ), chop( x3 ) ]
Example #58
0
def L1(m, n, d):
    list1 = range(m * n + 1, m * n + m + 1 + 1)
    prod1 = fprod(list1)
    return (1 + d)**2 * 2 * (Bn(n)**n -
                             Bn(n)**(n + 1))**m * prod1 / factorial(m)
Example #59
0
def solveCubicPolynomial( a, b, c, d ):
    if mp.dps < 50:
        mp.dps = 50

    if a == 0:
        return solveQuadraticPolynomial( b, c, d )

    f = fdiv( fsub( fdiv( fmul( 3, c ), a ), fdiv( power( b, 2 ), power( a, 2 ) ) ), 3 )

    g = fdiv( fadd( fsub( fdiv( fmul( 2, power( b, 3 ) ), power( a, 3 ) ),
                          fdiv( fprod( [ 9, b, c ] ), power( a, 2 ) ) ),
                    fdiv( fmul( 27, d ), a ) ), 27 )
    h = fadd( fdiv( power( g, 2 ), 4 ), fdiv( power( f, 3 ), 27 ) )

    # all three roots are the same
    if h == 0:
        x1 = fneg( root( fdiv( d, a ), 3 ) )
        x2 = x1
        x3 = x2
    # two imaginary and one real root
    elif h > 0:
        r = fadd( fneg( fdiv( g, 2 ) ), sqrt( h ) )

        if r < 0:
            s = fneg( root( fneg( r ), 3 ) )
        else:
            s = root( r, 3 )

        t = fsub( fneg( fdiv( g, 2 ) ), sqrt( h ) )

        if t < 0:
            u = fneg( root( fneg( t ), 3 ) )
        else:
            u = root( t, 3 )

        x1 = fsub( fadd( s, u ), fdiv( b, fmul( 3, a ) ) )

        real = fsub( fdiv( fneg( fadd( s, u ) ), 2 ), fdiv( b, fmul( 3, a ) ) )
        imaginary = fdiv( fmul( fsub( s, u ), sqrt( 3 ) ), 2 )

        x2 = mpc( real, imaginary )
        x3 = mpc( real, fneg( imaginary ) )
    # all real roots
    else:
        j = sqrt( fsub( fdiv( power( g, 2 ), 4 ), h ) )
        k = acos( fneg( fdiv( g, fmul( 2, j ) ) ) )

        if j < 0:
            l = fneg( root( fneg( j ), 3 ) )
        else:
            l = root( j, 3 )

        m = cos( fdiv( k, 3 ) )
        n = fmul( sqrt( 3 ), sin( fdiv( k, 3 ) ) )
        p = fneg( fdiv( b, fmul( 3, a ) ) )

        x1 = fsub( fmul( fmul( 2, l ), cos( fdiv( k, 3 ) ) ), fdiv( b, fmul( 3, a ) ) )
        x2 = fadd( fmul( fneg( l ), fadd( m, n ) ), p )
        x3 = fadd( fmul( fneg( l ), fsub( m, n ) ), p )

    return [ chop( x1 ), chop( x2 ), chop( x3 ) ]
Example #60
0
def mp_fprod2(a, b):
    return mp.fprod([a, b])