Multiple Precision math
Пакет для работы с числами с плавающей точкой со сколь угодно высокой точностью. В нём реализованы алгоритмы вычисления элементарных функций, а также большого количества специальных функций.
from mpmath import *
%matplotlib inline
Точность контролируется глобальным объектом mp
.
print(mp)
prec
- число бит в мантиссе, dps
- число значащих десятичных цифр. Если изменить один из этих атрибутов, другой изменится соответственно.
mp.dps=50
print(mp)
mpf
создаёт число с плавающей (multiple precision float) точкой из строки или числа.
x=mpf('0.1')
print(x)
x
А вот так делать не надо. 0.1
сначала преобразуется в число с плавающей точкой со стандартной (т.е. двойной) точностью, а потом уже оно преобразуется в mpf
.
y=mpf(0.1)
print(y)
Чтобы не потерять точность, нужно делать mpf
из строки или из отношения целых чисел (вероятно, со знаменателем вида $10^n$).
y=mpf(1)/10
print(y)
Математические константы типа $\pi$ или $e$ реализованы в виде ленивых объектов. Они содержат сколько-то вычисленных бит плюс алгоритм, позволяющий получить больше бит, если потребуется.
pi
mp.prec=53
print(pi)
mp.prec=169
print(pi)
Когда объект pi
встречается в выражении, из него делается число с текущей точностью.
+pi
Реализованы арифметические операции и элементарные функции.
sin(pi/4)**2
plot([lambda x:besselj(0,x),
lambda x:besselj(1,x),
lambda x:besselj(2,x)],[0,10])
plot([lambda x:legendre(0,x),
lambda x:legendre(1,x),
lambda x:legendre(2,x),
lambda x:legendre(3,x)],[-1,1])
plot([lambda x:polylog(2,x),
lambda x:polylog(3,x),
lambda x:polylog(4,x)],[-4,1])
print(pi**2/zeta(2),pi**4/zeta(4))
splot(lambda x,y:abs(gamma(x+j*y)),[-4,4],[-4,4])
gamma(1.5)/sqrt(pi)
Корни многочлена
l=[1,0,0,0,1,1]
r=polyroots(l)
for x in r:
print(x)
for x in r:
print(polyval(l,x))
Решение уравнения
def f(x):
return exp(-x)-sin(x)
plot(f,[0,pi])
findroot(f,(0.5,0.7))
Решение системы уравнений
findroot([lambda x,y:x**2+y**2-1,lambda x,y:x*y-1/4],(1,0.25))
diff(f,0.5)
diff(f,0.5,2)
diff(lambda x,y:sin(x)*cos(y),(pi,pi),(1,2))
При вычислении этого интеграла все вычисления будут производиться с точностью, на 5 значащих цифр большей; затем она вернётся к прежней.
with extradps(5):
I=quad(lambda x:log(x)**2/(1+x),(0,1))
print(I)
Допустим, у нас есть причины подозревать, что этот интеграл равен $\zeta(3)$, умноженному на рациональное число (с не очень большими числителем и знаменателем). pslq([x1,x2,...])
находит целые числа $n_1$, $n_2$, ... такие, что $n_1\,x_1 + n_2\,x_2 + \cdots = 0$. Это - метод нахождения тождеств, называемый экспериментальной математикой. Для этого часто требуются вычисления с очень высокой точностью.
pslq([I,zeta(3)])
То есть наш интеграл равен $\frac{3}{2} \zeta(3)$. Это, конечно, не доказательство. Но если мы ещё увеличим точность вычисления интеграла, а результат pslq
не изменится, то мы можем быть практически уверены, что этот результат верен.
Двойной интеграл:
quad(lambda x,y:1/(1+x*y),[0,1],[0,1])
with extradps(5):
s=nsum(lambda n:(-1)**(n-1)/n**4,(1,inf))
print(s)
pslq([s,pi**4])
То есть эта сумма, вероятно, равна $\frac{7}{720} \pi^4$.
a=mpf('0.2')
def f(t,x):
global a
return [x[1],-x[0]-2*a*x[1]]
x=odefun(f,0,[1,0])
x(1)
plot([lambda t:x(t)[0],lambda t:x(t)[1]],[0,10])
Матрицы разреженные, реализованы как словари. Квадратная матрица
matrix(2)
Прямоугольная матрица
M=matrix(2,3)
M
M.rows,M.cols
M[0,1]=1
M
Операции с матрицами
M1=matrix([[0,1],[1,0]])
M2=matrix([[1,0],[0,-1]])
M1+M2
M1*M2
M2*M1
M1**(-1)
Решение системы линейных уравнений
A=matrix([[1,2],[3,4]])
b=matrix([1,-1])
b
x=lu_solve(A,b)
x
A*x-b
Собственные значения и собственные векторы
l,u=eig(A)
l
u
Диагональная матрица
L=diag(l)
L
A*u-u*L