Mpmath庫-學習筆記

FE-有限元鹰發表於2024-07-02

目錄
  • 1. Introduction
    • 1.2 Basic usage of mpmath
    • 1.3 輸出格式化
    • 1.4 輸出的小數點位數
  • 2. BASIC FEATURES
    • 2.1 Arbitrary-precision floating-point (mp)
    • 2.2 Arbitrary-precision interval arithmetic (iv)
    • 2.3 Double-precision arithmetic using Python’s builtin float and complex types (fp)
    • 2.4 基本函式
  • 2.4 實用函式
    • 2.4.1 converion and printing
    • 2.4.2 算術運算
    • 2.4.3 複數相關函式
    • 2.4.4 處理整數和小數
    • 2.4.5 公差和近似比較

Checking that it works

# import mpmath as mp
from mpmath import *
from icecream import ic
mp.dps = 50         # Set precision
print(mpf(2)**mpf('0.5'))

1. Introduction

1.2 Basic usage of mpmath

mpmath的數值型別: mpf(real float),mpc(complex float),matrix

print(mp.dps)
print(mp.cos(3.14))

a1=mpf(4)
a2=mpf('4.0')
ic(a1,a2)
a3=mpf("1.25e6")
ic(a3)
a4=mpf("-inf")
ic(a4)

a5=mpc(1,2)
ic(a5)
a6=mpc(complex(1,20))
ic(a6)

ic(a5.conjugate())  # 共軛複數
ic(a5.real)         # 實部
ic(a5.imag)         # 虛部

Mpmath使用全域性工作精度;它不跟蹤單個數字的精度或準確性。執行算術運算或呼叫mpf()將結果舍入到當前的工作精度。工作精度由一個名為mp的上下文物件控制

print(mp)
# Mpmath settings:
#   mp.prec = 169               [default: 53]
#   mp.dps = 50                 [default: 15]
#   mp.trap_complex = False     [default: False]

# prec---二進位制精度
# dps---十進位制精度
#  prec = 3.33*dps

# 當建立一個新的mpf時,該值最多將與輸入一樣準確
#!!警告: 將mpmath數字與Python浮點數混合使用時要小心
mp.dps = 30
# bad
ic(mpf(10.8))

# good
ic(mpf('10.8'))

# also good
ic(mpf(108)/mpf(10))


# ? 然而,0.5、1.5、0.75、0.125等通常作為輸入是安全的,因為它們可以用Python浮點數精確地表示

1.3 輸出格式化

# 設定 mp.pretty = True 可以輸出更好看的結果

mp.pretty = True
mpf(0.6)
# output: 0.599999999999999977795539507497

mp.pretty = False
mpf(0.6)
# output: mpf('0.599999999999999977795539507496869')

1.4 輸出的小數點位數

use mpmath.nstr() and mpmath.nprint() 函式.預設情況下列印數字的位數由工作精度決定。要指定要顯示的位數,而不改變工作精度,

a=mpf(1)/6.0

mp.nstr(a, 5)
# output: '0.16667'

mp.nprint(a, 10)
# output: '0.1666666667'

2. BASIC FEATURES

mpmath中的高階程式碼是作為“上下文物件”上的方法實現的。上下文實現算術、型別轉換和其他基本操作。上下文還儲存諸如精度之類的設定,並儲存快取資料。提供了一些不同的上下文(具有基本相容的介面),以便高階演算法可以與底層演算法的不同實現一起使用,從而允許不同的特性和速度-精度權衡。

目前,mpmath提供了以下上下文:

  • Arbitrary-precision arithmetic (mp)
  • A faster Cython-based version of mp (used by default in Sage, and currently only available there)
  • Arbitrary-precision interval arithmetic (iv)
  • Double-precision arithmetic using Python’s builtin float and complex types (fp)

2.1 Arbitrary-precision floating-point (mp)

mp支援任意精度,並且支援絕大多數函式,經過充分測試,充分最佳化.

2.2 Arbitrary-precision interval arithmetic (iv)

iv支援區間運算,但是在版本1.3.0中,iv還處於測試階段,只支援少部分函式.

2.3 Double-precision arithmetic using Python’s builtin float and complex types (fp)

儘管mpmath通常是為任意精度算術設計的,但許多高階演算法可以很好地處理普通的Python浮點數和複數,它們使用硬體雙精度(在大多數系統上,這相當於53位精度).mp object的函式會把輸入轉換為mpmath numbers type. fp object則是將輸入轉換為Python的浮點數和複數型別.當需要進行大量的函式求值(數值積分、繪圖等),並且當fp演算法提供足夠的精度時,這可以大大提高mp演算法的速度。

基於以上優勢,可以使用fp.func 進行運算.(使用func 或mp.func 都是mp的函式)

使用fp演算法計算的結果可能比使用等效精度(mp)的mp計算的結果不那麼精確.(mp.prec = 53),因為後者經常使用更高的內部精度。其精度高度依賴於:

  • for some functions, fp almost always gives 14-15 correct digits; for others, results can be accurate to only 2-3 digits or even completely wrong.
  • The recommended use for fp is therefore to speed up large-scale computations where accuracy can be verified in advance on a subset of the input set, or where results can be verified afterwards.
fp.pretty=True
u=fp.rand()

print(u)
# 0.6473090346719316

print(type(u))
# <class 'float'>

m=fp.matrix([[1,2],[3,4]])**2

print(m)
# [ 7.0  10.0]
# [15.0  22.0]

print(type(m))
# <class 'mpmath.matrices.matrices.matrix'>

2.4 基本函式

fp bject 為基本函式 包裝了Python的math和cmath模組。支援實數和複數,並自動為實數輸入生成複數結果(數學會引發異常)

fp.sqrt(5)
# 2.23606797749979

fp.sqrt(-5)
# 2.23606797749979j

fp.sin(fp.pi/2)
# 1.0

fp.power(-2,0.5)
# (8.659560562354934e-17+1.4142135623730951j)

print(type(fp.power(-2,0.5)))
# <class 'complex'>

2.4 實用函式

2.4.1 converion and printing

# mp.mpmathify(x,strings=True)
# 能夠將x轉換為mpf or mpc型別

fp.dps=15
fp.pretty = True

mpmathify(3.5)
# mpf('3.5')

mpmathify(3+4j)
#mpc(real='3.0', imag='4.0')

mpmathify('3.5')
# mpf('3.5')

# mpmath.nstr(x,n=6,**kwargs)
# 將mpf或mpc轉換為具有n位有效數字的十進位制字串
# nprint(x,n=6) 會直接列印nstr()的字串結果

f=mp.mpf(1.53)
print(f)
nprint(f,n=12)
# 1.530000000000000026645352591
# 1.53

2.4.2 算術運算

包括加減乘除、取模、冪運算等。

# ! mpmath.fadd(x, y,**kwargs)
# 實現x+y,返回浮點數結果.可以自定義精度和舍入模式.預設精度是工作精度,
# kwargs中可以設定精度和舍入模式.:
# + prec,dps(int)--設定精度; exact=True--不四捨五入.
# + rounding(str)--設定舍入模式,可選'n'(default)--nearst,'f'--floor,'c'-ceiling,'d'-down,'u'-up.
x=mp.rand()
y=mp.rand()
ic(x,y)
nprint(mp.fadd(x,y,dps=5,rounding='u'))
# ic| x: mpf('0.936352251244129142275205120579475')
#     y: mpf('0.118268786487759443295747691143063')
# 1.05462

# ! mpmath.fsub(x, y,**kwargs)
# 實現x-y,返回浮點數結果.
x=mp.mpf(1.53)
y=mp.mpf(2.87)
print(x-y)
# -1.34000000000000007993605777301
print(mp.fsub(x,y))
# -1.34000000000000007993605777301

# ! mpmath.fneg(x,**kwargs)
# 實現-x,返回浮點數結果.
print(mp.fneg(mp.mpf(2.5)))
# -2.5

# ! mpmath.fmul(x, y,**kwargs)
# 實現x*y,返回浮點數結果.
x=mp.mpf(2.5)
y=mp.mpf(3.14)
print(x*y)
# 7.85000000000000031086244689504
print(mp.fmul(x,y))
# 7.85000000000000031086244689504

a=mp.mpc(2,5)
b=mp.mpc(3,4)
print(a*b)
# (-14.0 + 23.0j)
print(mp.fmul(a,b))
# (-14.0 + 23.0j)

# ! mpmath.fdiv(x, y,**kwargs)
# 實現x/y,返回浮點數結果.
x=mp.mpf(3)
y=mp.mpf(2)
print(x/y)
# 1.5
print(mp.fdiv(x,y))
# 1.5


# ! mpmath.fmod(x,y)
# Converts 𝑦 and 𝑧 to mpmath numbers and returns 𝑦 mod 𝑧. 
# For mpmath numbers, this is equivalent to x % y.
mp.fmod(100,3)
# mpf('1.0')
print(100%3)
# 1

# ! mpmath.fsum(terms,absolute=False,squared=False,**kwargs)
# 計算一個array-like的terms的和.如果len(terms)>2,這會比python內建的sum函式快很多.
# + absolute=True--返回每一項的絕對值的總和.
# + squared=True--返回每一項的平方的總和.
mp.fsum([1,2,3,4,5])
# mpf('15.0')

mp.fsum([1,-2,3,-4,5],absolute=True)
# mpf('15.0')
mp.fsum([1,-2,3,-4,5],absolute=False)
# mpf('3.0')

mp.fsum([1,2,3,4,5],squared=True)
# mpf('55.0')

# ! mpmath.fprod(factors)
# 計算一個array-like object的每一項的連續乘積.
# 如: fprod([1,2,3,4,5])=1*2*3*4*5=120
mp.fprod([1,2,3,4,5])
# mpf('120.0')

# ! mpmath.fdot(A, B=None, conjugate=False)
# 接受兩個array-like object A和B,計算A,B的點積. sum(A[i]*B[i]) ,i=0,...,len(A)-1.
# if conjugate is True, B is conjugated before multiplication.  
# 如: fdot([1,2,3],[4,5,6])=1*4+2*5+3*6=32
mp.fdot([1,2,3],[4,5,6])
# mpf('32.0')

2.4.3 複數相關函式

fabs(x) :返回複數x的模或者實數x的絕對值.
arg(x):返回x的相位角(以弧度表示).-pi< arg(x) < pi .
sign(x) :返回x的符號,sign(x)=x/|x|.
re(x) :返回x的實部.
im(x) :返回x的虛部.
conj(x) :返回x的共軛複數\(\bar{x}\)
polar(x) :將複數x分解為極座標形式(r,θ)\(x=r\exp(i\theta)\)
rect(r,θ) :將極座標形式(r,θ)轉換為複數形式\(x=r(\cos\theta+i\sin\theta)\)

>>> from mpmath import *
>>> mp.dps = 15; mp.pretty = True
>>> chop(rect(2, pi))
-2.0
>>> rect(sqrt(2), -pi/4)
(1.0 - 1.0j)

2.4.4 處理整數和小數

floor(x) : 向下取整數
ceil(x) : 向上取整數
nint(x) : 四捨五入取整數
frac(x) : 返回x的小數部分,frac(x)=x-floor(x)

>>> from mpmath import *
>>> mp.pretty = False
>>> frac(1.25)
mpf('0.25')
>>> frac(3)
mpf('0.0')
>>> frac(-1.25)
mpf('0.75')

2.4.5 公差和近似比較

chop(x, tol=None) : 去除小的實部或者虛部,或者將接近於0的轉換為精確的0,x可以是數字或者iterable.The tolerance defaults to 100*eps.
almosteq(s, t, rel_eps=None, abs_eps=None) : 判斷s-t是否小於給定的誤差,rel_eps和abs_eps分別是相對誤差和絕對誤差.絕對誤差=|s-t|,相對誤差=|s-t|/max(|s|,|t|).

相關文章