def test_mev(): output("""\ reim:{$[0>type x;1 0*x;2=count x;x;'`]}; mc:{((x[0]*y 0)-x[1]*y 1;(x[0]*y 1)+x[1]*y 0)}; mmc:{((.qml.mm[x 0]y 0)-.qml.mm[x 1]y 1;(.qml.mm[x 0]y 1)+.qml.mm[x 1]y 0)}; mev_:{[b;x] if[2<>count wv:.qml.mev x;'`length]; if[not all over prec>=abs mmc[flip vc;flip(flip')(reim'')flip x]- flip(w:reim'[wv 0])mc'vc:(flip')(reim'')(v:wv 1);'`check]; / Normalize sign; LAPACK already normalized to real v*:1-2*0>{x a?max a:abs x}each vc[;0]; (?'[prec>=abs w[;1];w[;0];w];?'[b;v;0n])};""") for A in eigenvalue_subjects: if A.rows <= 3: V = [] for w, n, r in A.eigenvects(): w = sp.simplify(sp.expand_complex(w)) if len(r) == 1: r = r[0] r = sp.simplify(sp.expand_complex(r)) r = r.normalized() / sp.sign(max(r, key=abs)) r = sp.simplify(sp.expand_complex(r)) else: r = None V.extend([(w, r)]*n) V.sort(key=lambda (x, _): (-abs(x), -sp.im(x))) else: Am = mp.matrix(A) # extra precision for complex pairs to be equal in sort with mp.extradps(mp.mp.dps): W, R = mp.eig(Am) V = [] for w, r in zip(W, (R.column(i) for i in range(R.cols))): w = mp.chop(w) with mp.extradps(mp.mp.dps): _, S, _ = mp.svd(Am - w*mp.eye(A.rows)) if sum(x == 0 for x in mp.chop(S)) == 1: # nullity 1, so normalized eigenvector is unique r /= mp.norm(r) * mp.sign(max(r, key=abs)) r = mp.chop(r) else: r = None V.append((w, r)) V.sort(key=lambda (x, _): (-abs(x), -x.imag)) W, R = zip(*V) test("mev_[%sb" % "".join("0" if r is None else "1" for r in R), A, (W, [r if r is None else list(r) for r in R]), complex_pair=True)
def convertUnitList( self, other ): if not isinstance( other, list ): raise ValueError( 'convertUnitList expects a list argument' ) result = [ ] nonIntegral = False for i in range( 1, len( other ) ): conversion = g.unitConversionMatrix[ ( other[ i - 1 ].getUnitName( ), other[ i ].getUnitName( ) ) ] if conversion != floor( conversion ): nonIntegral = True if nonIntegral: source = self for count, measurement in enumerate( other ): with extradps( 2 ): conversion = source.convertValue( measurement ) if count < len( other ) - 1: result.append( RPNMeasurement( floor( conversion ), measurement.units ) ) source = RPNMeasurement( chop( frac( conversion ) ), measurement.units ) else: result.append( RPNMeasurement( conversion, measurement.units ) ) return result else: source = self.convert( other[ -2 ] ) with extradps( 2 ): result.append( source.getModulo( other[ -2 ] ).convert( other[ -1 ] ) ) source = source.subtract( result[ -1 ] ) for i in range( len( other ) - 2, 0, -1 ): source = source.convert( other[ i - 1 ] ) with extradps( 2 ): result.append( source.getModulo( other[ i - 1 ] ).convert( other[ i ] ) ) source = source.subtract( result[ -1 ] ) result.append( source ) return result[ : : -1 ]
def pdf(x, k, theta): """ Probability density function for the log-gamma distribution. k is the shape parameter of the gamma distribution. theta is the scale parameter of the log-gamma distribution. """ with mpmath.extradps(5): x = mpmath.mpf(x) k = mpmath.mpf(k) theta = mpmath.mpf(theta) z = x / theta return mpmath.exp(k * z - mpmath.exp(z)) / mpmath.gamma(k) / theta
def cdf(x, a=0, b=1): """ Uniform distribution cumulative distribution function. """ with _mpmath.extradps(5): a, b = _validate(a, b) x = _mpmath.mpf(x) if x < a: return _mpmath.mp.zero elif x > b: return _mpmath.mp.one else: return (x - a) / (b - a)
def sf(x, k, theta): """ Survival function of the log-gamma distribution. k is the shape parameter of the gamma distribution. theta is the scale parameter of the log-gamma distribution. """ with mpmath.extradps(5): x = mpmath.mpf(x) k = mpmath.mpf(k) theta = mpmath.mpf(theta) z = x / theta return mpmath.gammainc(k, mpmath.exp(z), mpmath.inf, regularized=True)
def logpdf(x, k, theta): """ Log of the PDF of the log-gamma distribution. k is the shape parameter of the gamma distribution. theta is the scale parameter of the log-gamma distribution. """ with mpmath.extradps(5): x = mpmath.mpf(x) k = mpmath.mpf(k) theta = mpmath.mpf(theta) z = x / theta return (k * z - mpmath.exp(z)) - mpmath.loggamma(k) - mpmath.log(theta)
def cdf(x, k, loc, scale): """ Cumulative distribution function for the Weibull distribution (for maxima). This is a three-parameter version of the distribution. The more typical two-parameter version has just the parameters k and scale. """ with mpmath.extradps(5): x = mpmath.mpf(x) k, loc, scale = _validate_params(k, loc, scale) if x >= loc: return mpmath.mp.one z = (x - loc) / scale return mpmath.exp(-(-z)**k)
def logpdf(x): """ Natual logarithm of the PDF of the raised cosine distribution. The PDF of the raised cosine distribution is f(x) = (1 + cos(x))/(2*pi) on the interval (-pi, pi) and zero elsewhere. """ with mpmath.extradps(5): if x <= -mpmath.pi or x >= mpmath.pi: return -mpmath.inf return mpmath.log1p(mpmath.cos(x)) - mpmath.log(2 * mpmath.pi)
def invcdf(p, mu=0, sigma=1): """ Inverse of the CDF of the Lévy distribution. """ if p < 0 or p > 1: raise ValueError('p must be in the interval [0, 1]') if sigma <= 0: raise ValueError('sigma must be positive.') with mpmath.extradps(5): p = mpmath.mpf(p) mu = mpmath.mpf(mu) sigma = mpmath.mpf(sigma) return mu + sigma / (2 * _erfcinv(p)**2)
def _norm_delta_cdf(a, b): """ Compute CDF(b) - CDF(a) for the standard normal distribution CDF. The function assumes a <= b. """ with mpmath.extradps(5): if a == b: return mpmath.mp.zero if a > 0: delta = mpmath.ncdf(-a) - mpmath.ncdf(-b) else: delta = mpmath.ncdf(b) - mpmath.ncdf(a) return delta
def var(a, b): """ Variance of the truncated standard normal distribution. """ _validate_params(a, b) with mpmath.extradps(5): a = mpmath.mpf(a) b = mpmath.mpf(b) pa = pdf(a, a, b) pb = pdf(b, a, b) # Avoid the possibility of inf*0: ta = 0 if pa == 0 else a*pa tb = 0 if pb == 0 else b*pb return 1 + ta - tb - (pa - pb)**2
def logpdf(x, nu): """ Logarithm of the PDF for the inverse chi-square distribution. """ _validate_nu(nu) if x <= 0: return mpmath.ninf with mpmath.extradps(5): x = mpmath.mpf(x) nu = mpmath.mpf(nu) hnu = nu/2 logp = (-hnu*mpmath.log(2) + (-hnu - 1)*mpmath.log(x) - 1/(2*x) - mpmath.loggamma(hnu)) return logp
def pdf(x, nu): """ PDF for the inverse chi-square distribution. """ _validate_nu(nu) if x <= 0: return mpmath.mp.zero with mpmath.extradps(5): x = mpmath.mpf(x) nu = mpmath.mpf(nu) hnu = nu/2 p = (mpmath.power(2, -hnu) * x**(-hnu - 1) * mpmath.exp(-1/(2*x)) / mpmath.gamma(hnu)) return p
def invcdf(p, a=0, b=1): """ Uniform distribution inverse CDF. This function is also known as the quantile function or the percent point function. """ with _mpmath.extradps(5): a, b = _validate(a, b) if p < 0 or p > 1: return _mpmath.nan p = _mpmath.mpf(p) x = a + p * (b - a) return x
def pdf(x, nu, sigma): """ PDF for the Rice distribution. """ if x <= 0: return mpmath.mp.zero with mpmath.extradps(5): x = mpmath.mpf(x) nu = mpmath.mpf(nu) sigma = mpmath.mpf(sigma) sigma2 = sigma**2 p = ((x / sigma2) * mpmath.exp(-(x**2 + nu**2) / (2 * sigma2)) * mpmath.besseli(0, x * nu / sigma2)) return p
def pdf(x, k, lam): """ PDF for the noncentral chi-square distribution. """ if x < 0: return mpmath.mp.zero with mpmath.extradps(5): x = mpmath.mpf(x) k = mpmath.mpf(k) lam = mpmath.mpf(lam) p = (mpmath.exp(-(x + lam) / 2) * mpmath.power(x / lam, (k / 2 - 1) / 2) * mpmath.besseli(k / 2 - 1, mpmath.sqrt(lam * x)) / 2) return p
def sf(x, a, b): """ Survival function of the Benktander II distribution. Variable names follow the convention used on wikipedia. """ _validate_ab(a, b) if x < 1: return mpmath.mp.one with mpmath.extradps(5): x = mpmath.mpf(x) a = mpmath.mpf(a) b = mpmath.mpf(b) return x**(b - 1) * mpmath.exp((a / b) * (1 - x**b))
def invsf(p, k, theta, x0): """ Inverse of the survival functin for the log-gamma distribution. k is the shape parameter of the gamma distribution. theta is the scale parameter of the log-gamma distribution. x0 is an initial guess for the quantile. """ with mpmath.extradps(5): p = mpmath.mpf(p) k = mpmath.mpf(k) theta = mpmath.mpf(theta) root = mpmath.findroot(lambda t: sf(t, k, theta) - p, x0) return root
def mom(x): """ Method of moments parameter estimation for the Gumbel-max distribution. x must be a sequence of real numbers. Returns (loc, scale). """ with mpmath.extradps(5): M1 = _mean(x) M2 = _mean([mpmath.mpf(t)**2 for t in x]) scale = mpmath.sqrt(6*(M2 - M1**2))/mpmath.pi loc = M1 - scale*mpmath.euler return loc, scale
def invsf(p, c, beta, scale): """ Inverse survival function of the Gamma-Gompertz distribution. """ with mpmath.extradps(5): if p < 0 or p > 1: return mpmath.mp.nan p = mpmath.mpf(p) beta = mpmath.mpf(beta) c = mpmath.mpf(c) scale = mpmath.mpf(scale) r = mpmath.powm1(p, -1 / c) x = scale * mpmath.log1p(beta * r) return x
def invcdf(p, loc, scale): """ Inverse of the CDF for the Gumbel distribution. """ if scale <= 0: raise ValueError('scale must be positive.') with mpmath.extradps(5): p = mpmath.mpf(p) loc = mpmath.mpf(loc) scale = mpmath.mpf(scale) z = -mpmath.log(-mpmath.log(p)) x = scale*z + loc return x
def cdf(x, c, d, scale): """ Burr type XII distribution cumulative distribution function. Unlike scipy, a location parameter is not included. """ _validate_params(c, d, scale) with mpmath.extradps(5): x = mpmath.mpf(x) c = mpmath.mpf(c) d = mpmath.mpf(d) scale = mpmath.mpf(scale) # TO DO: See if the use of logsf (as in scipy) is worthwhile. return 1 - sf(x, c, d, scale)
def logpmf(k, ntotal, ngood, untilnbad): """ Logarithm of the prob. mass function of the negative hypergeometric distr. """ _validate(ntotal, ngood, untilnbad) if k < 0 or k > ngood: return mpmath.mp.ninf with mpmath.extradps(5): t1 = logbinomial(k + untilnbad - 1, k) t2 = logbinomial(ntotal - untilnbad - k, ngood - k) t3 = logbinomial(ntotal, ngood) return mpmath.fsum([t1, t2, -t3])
def logpdf(x, mu, loc=0, scale=1): """ Logarithm of the PDF for the inverse Gaussian distribution. """ with mpmath.extradps(5): mu, loc, scale = _validate_params(mu, loc, scale) x = mpmath.mpf(x) if x <= loc: return mpmath.ninf z = (x - loc) / scale t = ((z - mu) / mu)**2 logp = (-0.5 * mpmath.log(2 * mpmath.pi) - 1.5 * mpmath.log(z) - t / (2 * z)) return logp
def pmf(k, ntotal, ngood, untilnbad): """ Probability mass function of the negative hypergeometric distribution. """ _validate(ntotal, ngood, untilnbad) if k < 0 or k > ngood: return mpmath.mp.zero with mpmath.extradps(5): b1 = mpmath.binomial(k + untilnbad - 1, k) b2 = mpmath.binomial(ntotal - untilnbad - k, ngood - k) b3 = mpmath.binomial(ntotal, ngood) return b1 * (b2 / b3)
def pdf(x, mu, loc=0, scale=1): """ PDF for the inverse Gaussian distribution. """ with mpmath.extradps(5): mu, loc, scale = _validate_params(mu, loc, scale) x = mpmath.mpf(x) if x <= loc: return mpmath.mp.zero z = (x - loc) / scale den = mpmath.sqrt(2 * mpmath.pi * z**3) t = ((z - mu) / mu)**2 num = mpmath.exp(-t / (2 * z)) return num / den
def var(dfn, dfd, nc): """ Variance of the noncentral F distribution. """ if dfd <= 4: return _mp.mp.nan with _mp.extradps(5): nc = _mp.mpf(nc) dfn = _mp.mpf(dfn) dfd = _mp.mpf(dfd) v = (2 * ((dfn + nc)**2 + (dfn + 2 * nc) * (dfd - 2)) / ((dfd - 2)**2 * (dfd - 4)) * (dfd / dfn)**2) return v
def pdf(x, nu, loc=0, scale=1): """ Probability density function for the Nakagami distribution. """ _validate_params(nu, loc, scale) with mpmath.extradps(5): if x <= loc: return mpmath.mp.zero x = mpmath.mpf(x) nu = mpmath.mpf(nu) loc = mpmath.mpf(loc) scale = mpmath.mpf(scale) z = (x - loc)/scale return (2*nu**nu * z**(2*nu - 1) * mpmath.exp(-nu*z**2) / mpmath.gamma(nu) / scale)
def sf(x, c, beta, scale): """ Cumulative distribution function of the Gamma-Gompertz distribution. """ with mpmath.extradps(5): if x < 0: return mpmath.mp.one x = mpmath.mpf(x) beta = mpmath.mpf(beta) c = mpmath.mpf(c) scale = mpmath.mpf(scale) ex = mpmath.exp(x / scale) p = mpmath.power(beta / (beta - 1 + ex), c) return p
def logbeta(x, y): """ Natural logarithm of beta(x, y). The beta function is Gamma(x) Gamma(y) beta(x, y) = ----------------- Gamma(x + y) where Gamma(z) is the Gamma function. """ with mpmath.extradps(5): return (mpmath.loggamma(x) + mpmath.loggamma(y) - mpmath.loggamma(mpmath.fsum([x, y])))
def sf(x, df): """ Survival function of Student's t distribution. """ if df <= 0: raise ValueError('df must be greater than 0') with mpmath.extradps(5): half = mpmath.mp.one/2 x = mpmath.mpf(x) df = mpmath.mpf(df) h = (df + 1) / 2 p1 = x * mpmath.gamma(h) p2 = mpmath.hyp2f1(half, h, 3*half, -x**2/df) return half - p1*p2/mpmath.sqrt(mpmath.pi*df)/mpmath.gamma(df/2)
def invsf(p, mu=0, b=1): """ Laplace distribution inverse survival function. """ if b <= 0: raise ValueError('b must be positive.') with mpmath.extradps(5): p = mpmath.mpf(p) mu = mpmath.mpf(mu) b = mpmath.mpf(b) if p >= 0.5: q = mu + b * mpmath.log(2 - 2 * p) else: q = mu - b * mpmath.log(2 * p) return q
#!/usr/bin/python """ """ import mpmath as mp import numpy as np import sys mp.mp.dps = 30 a = float(sys.argv[1]) b = float(sys.argv[2]) x_lo = float(sys.argv[3]) n = int (sys.argv[4]) for x in np.logspace(x_lo, 0, n) : x = mp.mpf(x) with mp.extradps(300) : y = mp.betainc(a, b, 0, x, regularized=True) print x, y
def convertValue( self, other, tryReverse=True ): if self.isEquivalent( other ): return self.getValue( ) if self.isCompatible( other ): conversions = [ ] if isinstance( other, list ): result = [ ] source = self for count, measurement in enumerate( other ): with extradps( 1 ): conversion = source.convertValue( measurement ) if count < len( other ) - 1: result.append( RPNMeasurement( floor( conversion ), measurement.getUnits( ) ) ) source = RPNMeasurement( chop( frac( conversion ) ), measurement.getUnits( ) ) else: result.append( RPNMeasurement( conversion, measurement.getUnits( ) ) ) return result units1 = self.getUnits( ) units2 = other.getUnits( ) unit1String = units1.getUnitString( ) unit2String = units2.getUnitString( ) debugPrint( 'unit1String: ', unit1String ) debugPrint( 'unit2String: ', unit2String ) if unit1String == unit2String: return fmul( self.getValue( ), other.getValue( ) ) if unit1String in g.operatorAliases: unit1String = g.operatorAliases[ unit1String ] if unit2String in g.operatorAliases: unit2String = g.operatorAliases[ unit2String ] exponents = { } if not g.unitConversionMatrix: loadUnitConversionMatrix( ) # look for a straight-up conversion unit1NoStar = unit1String.replace( '*', '-' ) unit2NoStar = unit2String.replace( '*', '-' ) debugPrint( 'unit1NoStar: ', unit1NoStar ) debugPrint( 'unit2NoStar: ', unit2NoStar ) if ( unit1NoStar, unit2NoStar ) in g.unitConversionMatrix: value = fmul( self.value, mpmathify( g.unitConversionMatrix[ ( unit1NoStar, unit2NoStar ) ] ) ) elif ( unit1NoStar, unit2NoStar ) in specialUnitConversionMatrix: value = specialUnitConversionMatrix[ ( unit1NoStar, unit2NoStar ) ]( self.value ) else: # otherwise, we need to figure out how to do the conversion conversionValue = mpmathify( 1 ) # if that isn't found, then we need to do the hard work and break the units down newUnits1 = RPNUnits( ) for unit in units1: newUnits1.update( RPNUnits( g.unitOperators[ unit ].representation + "^" + str( units1[ unit ] ) ) ) newUnits2 = RPNUnits( ) for unit in units2: newUnits2.update( RPNUnits( g.unitOperators[ unit ].representation + "^" + str( units2[ unit ] ) ) ) debugPrint( 'units1:', units1 ) debugPrint( 'units2:', units2 ) debugPrint( 'newUnits1:', newUnits1 ) debugPrint( 'newUnits2:', newUnits2 ) debugPrint( ) debugPrint( 'iterating through units:' ) for unit1 in newUnits1: foundConversion = False for unit2 in newUnits2: debugPrint( 'units 1:', unit1, newUnits1[ unit1 ], getUnitType( unit1 ) ) debugPrint( 'units 2:', unit2, newUnits2[ unit2 ], getUnitType( unit2 ) ) if getUnitType( unit1 ) == getUnitType( unit2 ): conversions.append( [ unit1, unit2 ] ) exponents[ ( unit1, unit2 ) ] = units1[ unit1 ] foundConversion = True break if not foundConversion: debugPrint( 'didn\'t find a conversion, try reducing' ) reduced = self.getReduced( ) debugPrint( 'reduced:', self.units, 'becomes', reduced.units ) reducedOther = other.getReduced( ) debugPrint( 'reduced other:', other.units, 'becomes', reducedOther.units ) # check to see if reducing did anything and bail if it didn't... bail out if ( reduced.units == self.units ) and ( reducedOther.units == other.units ): break reduced = reduced.convertValue( reducedOther ) return RPNMeasurement( fdiv( reduced, reducedOther.value ), reducedOther.getUnits( ) ).getValue( ) debugPrint( ) value = conversionValue if not foundConversion: # This is a cheat. The conversion logic has flaws, but if it's possible to do the # conversion in the opposite direction, then we can do that and return the reciprocal. # This allows more conversions without fixing the underlying problems, which will # require some redesign. if tryReverse: return fdiv( 1, other.convertValue( self, False ) ) else: raise ValueError( 'unable to convert ' + self.getUnitString( ) + ' to ' + other.getUnitString( ) ) for conversion in conversions: if conversion[ 0 ] == conversion[ 1 ]: continue # no conversion needed debugPrint( 'unit conversion:', g.unitConversionMatrix[ tuple( conversion ) ] ) debugPrint( 'exponents', exponents ) conversionValue = mpmathify( g.unitConversionMatrix[ tuple( conversion ) ] ) conversionValue = power( conversionValue, exponents[ tuple( conversion ) ] ) debugPrint( 'conversion: ', conversion, conversionValue ) value = fmul( value, conversionValue ) value = fmul( self.value, value ) return value else: if isinstance( other, list ): otherUnit = '[ ' + ', '.join( [ unit.getUnitString( ) for unit in other ] ) + ' ]' else: otherUnit = other.getUnitString( ) raise ValueError( 'incompatible units cannot be converted: ' + self.getUnitString( ) + ' and ' + otherUnit )