def powm1(ctx, x, y):
mag = ctx.mag
one = ctx.one
w = x**y - one
M = mag(w)
# Only moderate cancellation
if M > -8:
return w
# Check for the only possible exact cases
if not w:
if (not y) or (x in (1, -1, 1j, -1j) and ctx.isint(y)):
return w
x1 = x - one
magy = mag(y)
lnx = ctx.ln(x)
# Small y: x^y - 1 ~ log(x)*y + O(log(x)^2 * y^2)
if magy + mag(lnx) < -ctx.prec:
return lnx*y + (lnx*y)**2/2
# TODO: accurately eval the smaller of the real/imag part
return ctx.sum_accurately(lambda: iter([x**y, -1]), 1)
python类log()的实例源码
def _digamma_complex(x):
if not x.imag:
return complex(_digamma_real(x.real))
if x.real < 0.5:
x = 1.0-x
s = pi*cotpi(x)
else:
s = 0.0
while abs(x) < 10.0:
s -= 1.0/x
x += 1.0
x2 = x**-2
t = x2
for c in _psi_coeff:
s -= c*t
if abs(t) < 1e-20:
break
t *= x2
return s + cmath.log(x) - 0.5/x
def ei_taylor(z, _e1=False):
s = t = z
k = 2
while 1:
t = t*z/k
term = t/k
if abs(term) < 1e-17:
break
s += term
k += 1
s += euler
if _e1:
s += log(-z)
else:
if type(z) is float or z.imag == 0.0:
s += math_log(abs(z))
else:
s += cmath.log(z)
return s
def powm1(ctx, x, y):
mag = ctx.mag
one = ctx.one
w = x**y - one
M = mag(w)
# Only moderate cancellation
if M > -8:
return w
# Check for the only possible exact cases
if not w:
if (not y) or (x in (1, -1, 1j, -1j) and ctx.isint(y)):
return w
x1 = x - one
magy = mag(y)
lnx = ctx.ln(x)
# Small y: x^y - 1 ~ log(x)*y + O(log(x)^2 * y^2)
if magy + mag(lnx) < -ctx.prec:
return lnx*y + (lnx*y)**2/2
# TODO: accurately eval the smaller of the real/imag part
return ctx.sum_accurately(lambda: iter([x**y, -1]), 1)
def _digamma_complex(x):
if not x.imag:
return complex(_digamma_real(x.real))
if x.real < 0.5:
x = 1.0-x
s = pi*cotpi(x)
else:
s = 0.0
while abs(x) < 10.0:
s -= 1.0/x
x += 1.0
x2 = x**-2
t = x2
for c in _psi_coeff:
s -= c*t
if abs(t) < 1e-20:
break
t *= x2
return s + cmath.log(x) - 0.5/x
def ei_taylor(z, _e1=False):
s = t = z
k = 2
while 1:
t = t*z/k
term = t/k
if abs(term) < 1e-17:
break
s += term
k += 1
s += euler
if _e1:
s += log(-z)
else:
if type(z) is float or z.imag == 0.0:
s += math_log(abs(z))
else:
s += cmath.log(z)
return s
def powm1(ctx, x, y):
mag = ctx.mag
one = ctx.one
w = x**y - one
M = mag(w)
# Only moderate cancellation
if M > -8:
return w
# Check for the only possible exact cases
if not w:
if (not y) or (x in (1, -1, 1j, -1j) and ctx.isint(y)):
return w
x1 = x - one
magy = mag(y)
lnx = ctx.ln(x)
# Small y: x^y - 1 ~ log(x)*y + O(log(x)^2 * y^2)
if magy + mag(lnx) < -ctx.prec:
return lnx*y + (lnx*y)**2/2
# TODO: accurately eval the smaller of the real/imag part
return ctx.sum_accurately(lambda: iter([x**y, -1]), 1)
def _digamma_complex(x):
if not x.imag:
return complex(_digamma_real(x.real))
if x.real < 0.5:
x = 1.0-x
s = pi*cotpi(x)
else:
s = 0.0
while abs(x) < 10.0:
s -= 1.0/x
x += 1.0
x2 = x**-2
t = x2
for c in _psi_coeff:
s -= c*t
if abs(t) < 1e-20:
break
t *= x2
return s + cmath.log(x) - 0.5/x
def ei_taylor(z, _e1=False):
s = t = z
k = 2
while 1:
t = t*z/k
term = t/k
if abs(term) < 1e-17:
break
s += term
k += 1
s += euler
if _e1:
s += log(-z)
else:
if type(z) is float or z.imag == 0.0:
s += math_log(abs(z))
else:
s += cmath.log(z)
return s
def repay(self, sct):
"""
used only after the activation of CDT contract
repay the loan, which converts SCT to DCt
:param sct: amount of SCT need to be repaid
:return: cdt
"""
# used only after the activation of CDT contract
if not self.is_cdt_active:
return
# repay rate is the same as loan rate
ether = sct * self.CDTL
# update the CDT balance
self.CDTB += ether
# convert SCT to CDT
cdt = sct
# calculate the cash price of CDT
self.CDTP = self.CDTB / (self.CDTS * self.CDT_CRR)
# log CDT contract according to switch
if self.log == self.log_cdt or self.log == self.log_dpt_cdt:
print('repay: ', sct, 'SCT', '+', ether, 'ETH', '=>', cdt, 'CDT')
return cdt
def to_credit(self, dct):
"""
used only after the activation of CDT contract
convert DCT to CDT, those who pay the loan gets the CDT.
market for DCT
:param dct:
:return: cdt
"""
# used only after the activation of CDT contract
if not self.is_cdt_active:
return
# repay rate is the same as loan rate
ether = dct * self.CDTL
# update the CDT balance
self.CDTB += ether
# convert DCT to CDT
cdt = dct
# calculate the cash price of CDT
self.CDTP = self.CDTB / (self.CDTS * self.CDT_CRR)
# log CDT contract according to switch
if self.log == self.log_cdt or self.log == self.log_dpt_cdt:
print('to credit: ', dct, 'DCT', '+', ether, 'ETH', '=>', cdt, 'CDT')
return cdt
def repay(self, sct):
"""
used only after the activation of CDT contract
repay the loan, which converts SCT to DCt
:param sct: amount of SCT need to be repaid
:return: cdt
"""
# used only after the activation of CDT contract
if not self.is_cdt_active:
return
# repay rate is the same as loan rate
ether = sct * self.CDTL
# update the CDT balance
self.CDTB += ether
# convert SCT to CDT
cdt = sct
# calculate the cash price of CDT
self.CDTP = self.CDTB / (self.CDTS * self.CDT_CRR)
# log CDT contract according to switch
if self.log == self.log_cdt or self.log == self.log_dpt_cdt:
print('repay: ', sct, 'SCT', '+', ether, 'ETH', '=>', cdt, 'CDT')
return cdt
def to_credit(self, dct):
"""
used only after the activation of CDT contract
convert DCT to CDT, those who pay the loan gets the CDT.
market for DCT
:param dct:
:return: cdt
"""
# used only after the activation of CDT contract
if not self.is_cdt_active:
return
# repay rate is the same as loan rate
ether = dct * self.CDTL
# update the CDT balance
self.CDTB += ether
# convert DCT to CDT
cdt = dct
# calculate the cash price of CDT
self.CDTP = self.CDTB / (self.CDTS * self.CDT_CRR)
# log CDT contract according to switch
if self.log == self.log_cdt or self.log == self.log_dpt_cdt:
print('to credit: ', dct, 'DCT', '+', ether, 'ETH', '=>', cdt, 'CDT')
return cdt
def to_discredit(self, sct):
"""
used only after the activation of CDT contract
convert SCT to DCT
:param sct: amount of SCT to be converted
:return: dct
"""
# used only after the activation of CDT contract
if not self.is_cdt_active:
return
# convert SCT to DCT minus 0.05 fee
dct = sct * 0.95
# calculate the cash price of CDT
self.CDTP = self.CDTB / (self.CDTS * self.CDT_CRR)
# log CDT contract according to switch
if self.log == self.log_cdt or self.log == self.log_dpt_cdt:
print('discredit:', sct, 'SCT','=>', dct, 'DCT')
return dct
def repay(self, sct):
"""
used only after the activation of CDT contract
repay the loan, which converts SCT to DCt
:param sct: amount of SCT need to be repaid
:return: cdt
"""
# used only after the activation of CDT contract
if not self.is_cdt_active:
return
# repay rate is the same as loan rate
ether = sct * self.CDTL
# update the CDT balance
self.CDTB += ether
# convert SCT to CDT
cdt = sct
# calculate the cash price of CDT
self.CDTP = self.CDTB / (self.CDTS * self.CDT_CRR)
# log CDT contract according to switch
if self.log == self.log_cdt or self.log == self.log_dpt_cdt:
print('repay: ', sct, 'SCT', '+', ether, 'ETH', '=>', cdt, 'CDT')
return cdt
def to_credit(self, dct):
"""
used only after the activation of CDT contract
convert DCT to CDT, those who pay the loan gets the CDT.
market for DCT
:param dct:
:return: cdt
"""
# used only after the activation of CDT contract
if not self.is_cdt_active:
return
# repay rate is the same as loan rate
ether = dct * self.CDTL
# update the CDT balance
self.CDTB += ether
# convert DCT to CDT
cdt = dct
# calculate the cash price of CDT
self.CDTP = self.CDTB / (self.CDTS * self.CDT_CRR)
# log CDT contract according to switch
if self.log == self.log_cdt or self.log == self.log_dpt_cdt:
print('to credit: ', dct, 'DCT', '+', ether, 'ETH', '=>', cdt, 'CDT')
return cdt
def test_cdt(e, a):
"""
test cdt and the interest of DPT
:param e: instance of ERC20 Token
:param a: random action seed
:return:
"""
# The loan is concurrent with deposit and withdraw, but loan has a concrete period.
# assum very 50 DPT action per CDT action period
run_between = 50
# interest rate
interest = 0.08
# random loan amount
loan = random.randint(1, int(e.CDTS.real/1000)+1)
for i in range(run_between):
random_dpt(e, random.random(), 1/3)
# random CDT action
random_cdt(e, a, loan, interest)
# log CDT and DPT instance
log_cdt(e)
log_dpt(e)
# time.sleep(1)
def powm1(ctx, x, y):
mag = ctx.mag
one = ctx.one
w = x**y - one
M = mag(w)
# Only moderate cancellation
if M > -8:
return w
# Check for the only possible exact cases
if not w:
if (not y) or (x in (1, -1, 1j, -1j) and ctx.isint(y)):
return w
x1 = x - one
magy = mag(y)
lnx = ctx.ln(x)
# Small y: x^y - 1 ~ log(x)*y + O(log(x)^2 * y^2)
if magy + mag(lnx) < -ctx.prec:
return lnx*y + (lnx*y)**2/2
# TODO: accurately eval the smaller of the real/imag part
return ctx.sum_accurately(lambda: iter([x**y, -1]), 1)
def _digamma_complex(x):
if not x.imag:
return complex(_digamma_real(x.real))
if x.real < 0.5:
x = 1.0-x
s = pi*cotpi(x)
else:
s = 0.0
while abs(x) < 10.0:
s -= 1.0/x
x += 1.0
x2 = x**-2
t = x2
for c in _psi_coeff:
s -= c*t
if abs(t) < 1e-20:
break
t *= x2
return s + cmath.log(x) - 0.5/x
def ei_taylor(z, _e1=False):
s = t = z
k = 2
while 1:
t = t*z/k
term = t/k
if abs(term) < 1e-17:
break
s += term
k += 1
s += euler
if _e1:
s += log(-z)
else:
if type(z) is float or z.imag == 0.0:
s += math_log(abs(z))
else:
s += cmath.log(z)
return s
def _digamma_complex(x):
if not x.imag:
return complex(_digamma_real(x.real))
if x.real < 0.5:
x = 1.0-x
s = pi*cotpi(x)
else:
s = 0.0
while abs(x) < 10.0:
s -= 1.0/x
x += 1.0
x2 = x**-2
t = x2
for c in _psi_coeff:
s -= c*t
if abs(t) < 1e-20:
break
t *= x2
return s + cmath.log(x) - 0.5/x
def ei_taylor(z, _e1=False):
s = t = z
k = 2
while 1:
t = t*z/k
term = t/k
if abs(term) < 1e-17:
break
s += term
k += 1
s += euler
if _e1:
s += log(-z)
else:
if type(z) is float or z.imag == 0.0:
s += math.log(abs(z))
else:
s += cmath.log(z)
return s
def LOG(df, price='Close'):
"""
Logarithm
"""
log_list = []
i = 0
while i < len(df[price]):
log = cmath.log(df[price][i]).real
log_list.append(ln)
i += 1
return log_list
def test_log():
mp.dps = 15
assert log(1) == 0
for x in [0.5, 1.5, 2.0, 3.0, 100, 10**50, 1e-50]:
assert log(x).ae(math.log(x))
assert log(x, x) == 1
assert log(1024, 2) == 10
assert log(10**1234, 10) == 1234
assert log(2+2j).ae(cmath.log(2+2j))
# Accuracy near 1
assert (log(0.6+0.8j).real*10**17).ae(2.2204460492503131)
assert (log(0.6-0.8j).real*10**17).ae(2.2204460492503131)
assert (log(0.8-0.6j).real*10**17).ae(2.2204460492503131)
assert (log(1+1e-8j).real*10**16).ae(0.5)
assert (log(1-1e-8j).real*10**16).ae(0.5)
assert (log(-1+1e-8j).real*10**16).ae(0.5)
assert (log(-1-1e-8j).real*10**16).ae(0.5)
assert (log(1j+1e-8).real*10**16).ae(0.5)
assert (log(1j-1e-8).real*10**16).ae(0.5)
assert (log(-1j+1e-8).real*10**16).ae(0.5)
assert (log(-1j-1e-8).real*10**16).ae(0.5)
assert (log(1+1e-40j).real*10**80).ae(0.5)
assert (log(1j+1e-40).real*10**80).ae(0.5)
# Huge
assert log(ldexp(1.234,10**20)).ae(log(2)*1e20)
assert log(ldexp(1.234,10**200)).ae(log(2)*1e200)
# Some special values
assert log(mpc(0,0)) == mpc(-inf,0)
assert isnan(log(mpc(nan,0)).real)
assert isnan(log(mpc(nan,0)).imag)
assert isnan(log(mpc(0,nan)).real)
assert isnan(log(mpc(0,nan)).imag)
assert isnan(log(mpc(nan,1)).real)
assert isnan(log(mpc(nan,1)).imag)
assert isnan(log(mpc(1,nan)).real)
assert isnan(log(mpc(1,nan)).imag)
def test_complex_functions():
for x in (list(range(10)) + list(range(-10,0))):
for y in (list(range(10)) + list(range(-10,0))):
z = complex(x, y)/4.3 + 0.01j
assert exp(mpc(z)).ae(cmath.exp(z))
assert log(mpc(z)).ae(cmath.log(z))
assert cos(mpc(z)).ae(cmath.cos(z))
assert sin(mpc(z)).ae(cmath.sin(z))
assert tan(mpc(z)).ae(cmath.tan(z))
assert sinh(mpc(z)).ae(cmath.sinh(z))
assert cosh(mpc(z)).ae(cmath.cosh(z))
assert tanh(mpc(z)).ae(cmath.tanh(z))
def test_aliases():
assert ln(7) == log(7)
assert log10(3.75) == log(3.75,10)
assert degrees(5.6) == 5.6 / degree
assert radians(5.6) == 5.6 * degree
assert power(-1,0.5) == j
assert fmod(25,7) == 4.0 and isinstance(fmod(25,7), mpf)
def test_misc_bugs():
# test that this doesn't raise an exception
mp.dps = 1000
log(1302)
mp.dps = 15
def log10(ctx, x):
return ctx.log(x, 10)
def _mathfun_n(f_real, f_complex):
def f(*args, **kwargs):
try:
return f_real(*(float(x) for x in args))
except (TypeError, ValueError):
return f_complex(*(complex(x) for x in args))
f.__name__ = f_real.__name__
return f
# Workaround for non-raising log and sqrt in Python 2.5 and 2.4
# on Unix system
def math_log(x):
if x <= 0.0:
raise ValueError("math domain error")
return math.log(x)