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 ) ] )
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)])
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 _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
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 )
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 ) ) )
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
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 )
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
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 ) ) ) )
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 ) )
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)))
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)))
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))
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
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)
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 ) ) )
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 ) ) )
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 ) ) ] ) ] ) )
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
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 ] )
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)))
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
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
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 ]
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 ) )
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')
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]
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.
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)))
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
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 )
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
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
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
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' )
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 )
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])
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
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 )
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))
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
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 )
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
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 )
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 )
def fm1(m, n): list1 = range(m * n + 1, m * n + m + 1 + 1) result1 = fprod(list1) return An(n)**m * factorial(m) / result1
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 ] )
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 ) ]
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)
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 ) ]
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 ) ]
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)
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 ) ]
def mp_fprod2(a, b): return mp.fprod([a, b])