SymPy 1.13 中文文件(十四)
原文:
docs.sympy.org/latest/index.html
向量積分的應用
原文:
docs.sympy.org/latest/modules/vector/vector_integration.html
要在區域上積分一個標量或向量場,我們必須首先定義一個區域。SymPy 提供了三種定義區域的方法:
-
使用帶有
ParametricRegion
的引數方程。 -
使用帶有
ImplicitRegion
的隱式方程。 -
使用幾何模組的物件。
vector_integrate()
函式用於在任何型別的區域上積分標量或向量場。它根據物件的性質自動確定積分的型別(線、面或體)。
我們定義一個座標系併為示例做必要的匯入。
>>> from sympy import sin, cos, exp, pi, symbols
>>> from sympy.vector import CoordSys3D, ParametricRegion, ImplicitRegion, vector_integrate
>>> from sympy.abc import r, x, y, z, theta, phi
>>> C = CoordSys3D('C')
周長、表面積和體積的計算
要計算圓的周長,我們需要定義它。讓我們使用其引數方程定義它。
>>> param_circle = ParametricRegion((4*cos(theta), 4*sin(theta)), (theta, 0, 2*pi))
我們也可以使用其隱式方程定義一個圓。
>>> implicit_circle = ImplicitRegion((x, y), x**2 + y**2 - 4)
圖形的周長等於它在單位標量場上的積分的絕對值。
>>> vector_integrate(1, param_circle)
8*pi
>>> vector_integrate(1, implicit_circle)
4*pi
假設使用者想要計算三角形的周長。確定三角形的參數列示可能很困難。相反,使用者可以使用幾何模組中 Polygon
類的物件。
>>> from sympy.geometry import Point, Polygon
>>> triangle = Polygon(Point(1, 2), (3, 5), (1,6))
>>> vector_integrate(1, triangle)
sqrt(5) + sqrt(13) + 4
要定義一個實心球,我們需要使用三個引數(r,theta 和 phi)。對於ParametricRegion
物件來說,限制的順序決定積分的符號。
>>> solidsphere = ParametricRegion((r*sin(phi)*cos(theta),r*sin(phi)*sin(theta), r*cos(phi)),
... (phi, 0, pi), (theta, 0, 2*pi), (r, 0, 3))
>>> vector_integrate(1, solidsphere)
36*pi
物體質量的計算
考慮一個三角形片段 𝑅,其頂點為 (0,0),(0, 5),(5,0),密度為 (\rho(x, y) = xy:kg/m²)。找到總質量。
>>> triangle = ParametricRegion((x, y), (x, 0, 5), (y, 0, 5 - x))
>>> vector_integrate(C.x*C.y, triangle)
625/24
找到以 z 軸為中心的圓柱體的質量,其高度為 h,半徑為 a,密度為 (\rho = x² + y²:kg/m²)。
>>> a, h = symbols('a h', positive=True)
>>> cylinder = ParametricRegion((r*cos(theta), r*sin(theta), z),
... (theta, 0, 2*pi), (z, 0, h), (r, 0, a))
>>> vector_integrate(C.x**2 + C.y**2, cylinder)
pi*a**4*h/2
通量的計算
1. 考慮空間中存在一個恆定向量場 (E(x, y, z) = a\mathbf{\hat{k}})。半徑為 r 的半球位於 x-y 平面上。該場透過球體的通量是多少?
>>> semisphere = ParametricRegion((r*sin(phi)*cos(theta), r*sin(phi)*sin(theta), r*cos(phi)),\
... (phi, 0, pi/2), (theta, 0, 2*pi))
>>> flux = vector_integrate(a*C.k, semisphere)
>>> flux
pi*a*r**2
2. 考慮空間中存在向量場 (E(x, y, z) = x² \mathbf{\hat{k}}) 在 x-y 平面上方,並且在 x-y 平面下方存在一個場 (E(x, y, z) = y² \mathbf{\hat{k}})。該向量場穿過邊長為 L 且中心在原點的立方體的通量是多少?
該場是沿著 z 軸平行的,因此只有箱子的頂部和底部會對通量有貢獻。
>>> L = symbols('L', positive=True)
>>> top_face = ParametricRegion((x, y, L/2), (x, -L/2, L/2), (y, -L/2, L/2))
>>> bottom_face = ParametricRegion((x, y, -L/2), (x, -L/2, L/2), (y, -L/2, L/2))
>>> flux = vector_integrate(C.x**2*C.k, top_face) + vector_integrate(C.y**2*C.k, bottom_face)
>>> flux
L**4/6
驗證斯托克斯定理
參見斯托克斯定理
示例 1
>>> from sympy.vector import curl
>>> curve = ParametricRegion((cos(theta), sin(theta)), (theta, 0, pi/2))
>>> surface = ParametricRegion((r*cos(theta), r*sin(theta)), (r, 0, 1), (theta, 0, pi/2))
>>> F = C.y*C.i + C.z*C.k + C.x*C.k
>>>
>>> vector_integrate(F, curve)
-pi/4
>>> vector_integrate(curl(F), surface)
-pi/4
示例 2
>>> circle = ParametricRegion((cos(theta), sin(theta), 1), (theta, 0, 2*pi))
>>> cone = ParametricRegion((r*cos(theta), r*sin(theta), r), (r, 0, 1), (theta, 0, 2*pi))
>>> cone = ParametricRegion((r*cos(theta), r*sin(theta), r), (r, 0, 1), (theta, 0, 2*pi))
>>> f = (-C.y**3/3 + sin(C.x))*C.i + (C.x**3/3 + cos(C.y))*C.j + C.x*C.y*C.z*C.k
>>> vector_integrate(f, circle)
pi/2
>>> vector_integrate(curl(f), cone)
pi/2
驗證散度定理
參見散度定理
示例 1
>>> from sympy.vector import divergence
>>> sphere = ParametricRegion((4*sin(phi)*cos(theta),4*sin(phi)*sin(theta), 4*cos(phi)),
... (phi, 0, pi), (theta, 0, 2*pi))
>>> solidsphere = ParametricRegion((r*sin(phi)*cos(theta),r*sin(phi)*sin(theta), r*cos(phi)),
... (r, 0, 4),(phi, 0, pi), (theta, 0, 2*pi))
>>> field = C.x**3*C.i + C.y**3*C.j + C.z**3*C.k
>>> vector_integrate(field, sphere)
12288*pi/5
>>> vector_integrate(divergence(field), solidsphere)
12288*pi/5
示例 2
>>> cube = ParametricRegion((x, y, z), (x, 0, 1), (y, 0, 1), (z, 0, 1))
>>> field = 2*C.x*C.y*C.i + 3*C.x*C.y*C.j + C.z*exp(C.x + C.y)*C.k
>>> vector_integrate(divergence(field), cube)
-E + 7/2 + E*(-1 + E)
向量 API
原文:
docs.sympy.org/latest/modules/vector/api/index.html
-
sympy.vector 中的關鍵類(文件字串)
-
定向器類(文件字串)
-
sympy.vector 中的關鍵函式(文件字串)
sympy.vector 中的基本類(文件字串)
原文連結:
docs.sympy.org/latest/modules/vector/api/classes.html
class sympy.vector.coordsysrect.CoordSys3D(name, transformation=None, parent=None, location=None, rotation_matrix=None, vector_names=None, variable_names=None)
代表三維空間中的座標系。
__init__(name, location=None, rotation_matrix=None, parent=None, vector_names=None, variable_names=None, latex_vects=None, pretty_vects=None, latex_scalars=None, pretty_scalars=None, transformation=None)
如果此係統在某個方向或位置相對於另一個定義,則方向/位置引數是必需的。
引數:
name : str
新 CoordSys3D 例項的名稱。
transformation : Lambda, Tuple, str
根據變換方程定義的轉換或從預定義的轉換中選擇的轉換。
location : Vector
新系統原點相對於父例項的位置向量。
rotation_matrix : SymPy ImmutableMatrix
新座標系的旋轉矩陣,相對於父座標系。換句話說,這是 new_system.rotation_matrix(parent) 的輸出。
parent : CoordSys3D
相對於其方向/位置(或兩者)正在定義的座標系。
vector_names, variable_names : iterable(optional)
每個都是包含 3 個字串的迭代器,分別用於新系統的基本向量和基本標量的自定義名稱。用於簡單的字串列印。
create_new(name, transformation, variable_names=None, vector_names=None)
返回一個透過變換與自身連線的 CoordSys3D。
引數:
name : str
新 CoordSys3D 例項的名稱。
transformation : Lambda, Tuple, str
根據變換方程定義的轉換或從預定義的轉換中選擇的轉換。
vector_names, variable_names : iterable(optional)
每個都是包含 3 個字串的迭代器,分別用於新系統的基本向量和基本標量的自定義名稱。用於簡單的字串列印。
示例
>>> from sympy.vector import CoordSys3D
>>> a = CoordSys3D('a')
>>> b = a.create_new('b', transformation='spherical')
>>> b.transformation_to_parent()
(b.r*sin(b.theta)*cos(b.phi), b.r*sin(b.phi)*sin(b.theta), b.r*cos(b.theta))
>>> b.transformation_from_parent()
(sqrt(a.x**2 + a.y**2 + a.z**2), acos(a.z/sqrt(a.x**2 + a.y**2 + a.z**2)), atan2(a.y, a.x))
locate_new(name, position, vector_names=None, variable_names=None)
返回一個 CoordSys3D,其原點位於給定位置相對於此座標系原點的位置。
引數:
name : str
新 CoordSys3D 例項的名稱。
position : Vector
相對於此係統原點的新系統原點的位置向量。
vector_names, variable_names : iterable(optional)
每個都是包含 3 個字串的迭代器,分別用於新系統的基本向量和基本標量的自定義名稱。用於簡單的字串列印。
示例
>>> from sympy.vector import CoordSys3D
>>> A = CoordSys3D('A')
>>> B = A.locate_new('B', 10 * A.i)
>>> B.origin.position_wrt(A.origin)
10*A.i
orient_new(name, orienters, location=None, vector_names=None, variable_names=None)
使用使用者指定的方式建立一個與此係統相關的新 CoordSys3D。
請參閱有關定向程式的定向器類文件以獲取更多資訊。
引數:
name : str
新 CoordSys3D 例項的名稱。
orienters : iterable/Orienter
一個 Orienter 或 Orienter 的迭代器,用於定向新座標系。如果提供了一個 Orienter,則應用它以獲得新系統。如果提供了一個可迭代物件,則按照它們出現的順序應用定向器。
location : Vector(optional)
新座標系原點相對於此係統原點的位置。如果未指定,則認為原點重合。
vector_names, variable_names : iterable(optional)
每個都是包含 3 個字串的迭代器,分別用於新系統的基本向量和基本標量的自定義名稱。用於簡單的字串列印。
示例
>>> from sympy.vector import CoordSys3D
>>> from sympy import symbols
>>> q0, q1, q2, q3 = symbols('q0 q1 q2 q3')
>>> N = CoordSys3D('N')
使用 AxisOrienter
>>> from sympy.vector import AxisOrienter
>>> axis_orienter = AxisOrienter(q1, N.i + 2 * N.j)
>>> A = N.orient_new('A', (axis_orienter, ))
使用 BodyOrienter
>>> from sympy.vector import BodyOrienter
>>> body_orienter = BodyOrienter(q1, q2, q3, '123')
>>> B = N.orient_new('B', (body_orienter, ))
使用 SpaceOrienter
>>> from sympy.vector import SpaceOrienter
>>> space_orienter = SpaceOrienter(q1, q2, q3, '312')
>>> C = N.orient_new('C', (space_orienter, ))
使用 QuaternionOrienter
>>> from sympy.vector import QuaternionOrienter
>>> q_orienter = QuaternionOrienter(q0, q1, q2, q3)
>>> D = N.orient_new('D', (q_orienter, ))
orient_new_axis(name, angle, axis, location=None, vector_names=None, variable_names=None)
軸旋轉是圍繞任意軸的旋轉,旋轉角度由 SymPy 表示式標量提供,軸由向量提供。
引數:
name : 字串
新座標系的名稱
angle : 表示式
新系統旋轉的角度
axis : 向量
執行旋轉的軸
location : 向量(可選)
新座標系的原點位置相對於該系統的原點。如果未指定,則認為原點重合。
vector_names, variable_names : 可迭代物件(可選)
每個具有 3 個字串的可迭代物件,分別為新系統的基向量和基標量的自定義名稱。用於簡單的字串列印。
示例
>>> from sympy.vector import CoordSys3D
>>> from sympy import symbols
>>> q1 = symbols('q1')
>>> N = CoordSys3D('N')
>>> B = N.orient_new_axis('B', q1, N.i + 2 * N.j)
orient_new_body(name, angle1, angle2, angle3, rotation_order, location=None, vector_names=None, variable_names=None)
Body orientation 透過連續三個簡單旋轉帶此座標系。
Body fixed rotations 包括尤拉角和 Tait-Bryan 角,請參見 zh.wikipedia.org/wiki/尤拉角
。
引數:
name : 字串
新座標系的名稱
angle1, angle2, angle3 : 表示式
連續三個角度旋轉座標系
rotation_order : 字串
定義旋轉軸順序的字串
location : 向量(可選)
新座標系的原點位置相對於該系統的原點。如果未指定,則認為原點重合。
vector_names, variable_names : 可迭代物件(可選)
每個具有 3 個字串的可迭代物件,分別為新系統的基向量和基標量的自定義名稱。用於簡單的字串列印。
示例
>>> from sympy.vector import CoordSys3D
>>> from sympy import symbols
>>> q1, q2, q3 = symbols('q1 q2 q3')
>>> N = CoordSys3D('N')
'Body' 固定旋轉由三個角度和三個固定於身體的旋轉軸描述。為了將座標系 D 相對於 N 定向,每個連續的旋轉總是圍繞固定在 D 上的正交單位向量進行的。例如,'123' 旋轉將指定關於 N.i、然後 D.j、然後 D.k 的旋轉。(最初,D.i 與 N.i 相同)因此,
>>> D = N.orient_new_body('D', q1, q2, q3, '123')
與之相同
>>> D = N.orient_new_axis('D', q1, N.i)
>>> D = D.orient_new_axis('D', q2, D.j)
>>> D = D.orient_new_axis('D', q3, D.k)
可接受的旋轉順序長度為 3,表達為 XYZ 或 123,並且不能連續兩次圍繞同一軸旋轉。
>>> B = N.orient_new_body('B', q1, q2, q3, '123')
>>> B = N.orient_new_body('B', q1, q2, 0, 'ZXZ')
>>> B = N.orient_new_body('B', 0, 0, 0, 'XYX')
orient_new_quaternion(name, q0, q1, q2, q3, location=None, vector_names=None, variable_names=None)
四元數方向用四元數使新的 CoordSys3D 定向,由 lambda,一個單位向量,以某個量 theta 進行有限旋轉定義。
此方向由四個引數描述:
q0 = cos(theta/2)
q1 = lambda_x sin(theta/2)
q2 = lambda_y sin(theta/2)
q3 = lambda_z sin(theta/2)
四元數不接受旋轉順序。
引數:
name : 字串
新座標系的名稱
q0, q1, q2, q3 : 表示式
用於旋轉座標系的四元數
location : 向量(可選)
新座標系的原點位置相對於該系統的原點。如果未指定,則認為原點重合。
vector_names, variable_names : 可迭代物件(可選)
每個具有新系統的基向量和基標量的自定義名稱的 3 個字串的可迭代。用於簡單的字串列印。
示例
>>> from sympy.vector import CoordSys3D
>>> from sympy import symbols
>>> q0, q1, q2, q3 = symbols('q0 q1 q2 q3')
>>> N = CoordSys3D('N')
>>> B = N.orient_new_quaternion('B', q0, q1, q2, q3)
orient_new_space(name, angle1, angle2, angle3, rotation_order, location=None, vector_names=None, variable_names=None)
空間旋轉類似於體旋轉,但是旋轉順序相反。
引數:
name:字串
新座標系的名稱
angle1, angle2, angle3:Expr
用於旋轉座標系的三個連續角度
rotation_order:字串
定義旋轉軸順序的字串
location:向量(可選)
新座標系原點的位置相對於此係統原點的位置。如果未指定,則假定原點重合。
vector_names, variable_names:可迭代(可選)
每個具有新系統的基向量和基標量的自定義名稱的 3 個字串的可迭代。用於簡單的字串列印。
示例
>>> from sympy.vector import CoordSys3D
>>> from sympy import symbols
>>> q1, q2, q3 = symbols('q1 q2 q3')
>>> N = CoordSys3D('N')
要將座標系 D 定向到 N,每個順序旋轉始終圍繞 N 的正交單位向量進行。例如,'123'旋轉將指定圍繞 N.i,然後 N.j,然後 N.k 的旋轉。因此,
>>> D = N.orient_new_space('D', q1, q2, q3, '312')
與...相同
>>> B = N.orient_new_axis('B', q1, N.i)
>>> C = B.orient_new_axis('C', q2, N.j)
>>> D = C.orient_new_axis('D', q3, N.k)
另請參閱
CoordSys3D.orient_new_body
透過尤拉角定向的方法
position_wrt(other)
返回此座標系的原點位置向量與另一個點/CoordSys3D 的原點的位置向量之間的位置向量。
引數:
other:點/CoordSys3D
如果 other 是一個點,則返回此係統原點相對於其的位置。如果其是 CoordSyRect 的例項,則返回相對於其原點的位置。
示例
>>> from sympy.vector import CoordSys3D
>>> N = CoordSys3D('N')
>>> N1 = N.locate_new('N1', 10 * N.i)
>>> N.position_wrt(N1)
(-10)*N.i
rotation_matrix(other)
返回此座標系與另一個系統之間的方向餘弦矩陣(DCM),也稱為‘旋轉矩陣’。
如果 v_a 是在系統‘A’中定義的向量(以矩陣格式),v_b 是在系統‘B’中定義的相同向量,則 v_a = A.rotation_matrix(B) * v_b。
返回一個 SymPy 矩陣。
引數:
other:CoordSys3D
生成 DCM 的系統。
示例
>>> from sympy.vector import CoordSys3D
>>> from sympy import symbols
>>> q1 = symbols('q1')
>>> N = CoordSys3D('N')
>>> A = N.orient_new_axis('A', q1, N.i)
>>> N.rotation_matrix(A)
Matrix([
[1, 0, 0],
[0, cos(q1), -sin(q1)],
[0, sin(q1), cos(q1)]])
scalar_map(other)
返回一個表達此框架的座標變數(基標量)與 otherframe 的變數相關的字典。
引數:
otherframe:CoordSys3D
對映變數到其他系統。
示例
>>> from sympy.vector import CoordSys3D
>>> from sympy import Symbol
>>> A = CoordSys3D('A')
>>> q = Symbol('q')
>>> B = A.orient_new_axis('B', q, A.k)
>>> A.scalar_map(B)
{A.x: B.x*cos(q) - B.y*sin(q), A.y: B.x*sin(q) + B.y*cos(q), A.z: B.z}
class sympy.vector.vector.Vector(*args)
所有向量類的超類。理想情況下,使用者不應該例項化此類或其任何子類。
property components
返回此向量的分量,以 Python 字典形式將 BaseVector 例項對映到相應的測量數。
示例
>>> from sympy.vector import CoordSys3D
>>> C = CoordSys3D('C')
>>> v = 3*C.i + 4*C.j + 5*C.k
>>> v.components
{C.i: 3, C.j: 4, C.k: 5}
cross(other)
返回此向量與另一個向量或二重例項的叉積。如果‘other’是向量,則叉積是一個向量。如果‘other’是二重,這將返回一個二重例項。
引數:
other:向量/二重
我們正在交叉的向量或二重的。
示例
>>> from sympy.vector import CoordSys3D
>>> C = CoordSys3D('C')
>>> C.i.cross(C.j)
C.k
>>> C.i ^ C.i
0
>>> v = 3*C.i + 4*C.j + 5*C.k
>>> v ^ C.i
5*C.j + (-4)*C.k
>>> d = C.i.outer(C.i)
>>> C.j.cross(d)
(-1)*(C.k|C.i)
dot(other)
返回此向量與另一個向量、二階張量或梯度運算元的點積。如果‘other’是一個向量,則返回點積標量(SymPy 表示式)。如果‘other’是一個二階張量,則返回點積作為一個向量。如果‘other’是 Del 的例項,則返回 Python 函式形式的方向導數運算元。如果將此函式應用於標量表示式,則返回標量場相對於此向量的方向導數。
引數:
other: 向量/二階張量/梯度運算元
我們正在與之點乘的向量或二階張量,或者是一個梯度運算元。
示例
>>> from sympy.vector import CoordSys3D, Del
>>> C = CoordSys3D('C')
>>> delop = Del()
>>> C.i.dot(C.j)
0
>>> C.i & C.i
1
>>> v = 3*C.i + 4*C.j + 5*C.k
>>> v.dot(C.k)
5
>>> (C.i & delop)(C.x*C.y*C.z)
C.y*C.z
>>> d = C.i.outer(C.i)
>>> C.i.dot(d)
C.i
magnitude()
返回此向量的大小。
normalize()
返回此向量的歸一化版本。
outer(other)
返回此向量與另一個向量的外積,以一個二階張量例項的形式。
引數:
other : 向量
與之進行外積計算的向量。
示例
>>> from sympy.vector import CoordSys3D
>>> N = CoordSys3D('N')
>>> N.i.outer(N.j)
(N.i|N.j)
projection(other, scalar=False)
返回‘self’上‘other’的向量或標量投影。
示例
>>> from sympy.vector.coordsysrect import CoordSys3D
>>> C = CoordSys3D('C')
>>> i, j, k = C.base_vectors()
>>> v1 = i + j + k
>>> v2 = 3*i + 4*j
>>> v1.projection(v2)
7/3*C.i + 7/3*C.j + 7/3*C.k
>>> v1.projection(v2, scalar=True)
7/3
separate()
這個向量在不同座標系中的成分,根據其定義。
返回一個字典,將每個 CoordSys3D 對映到相應的成分向量。
示例
>>> from sympy.vector import CoordSys3D
>>> R1 = CoordSys3D('R1')
>>> R2 = CoordSys3D('R2')
>>> v = R1.i + R2.i
>>> v.separate() == {R1: R1.i, R2: R2.i}
True
to_matrix(system)
返回此向量相對於指定座標系的矩陣形式。
引數:
system : 三維座標系
計算矩陣形式的系統
示例
>>> from sympy.vector import CoordSys3D
>>> C = CoordSys3D('C')
>>> from sympy.abc import a, b, c
>>> v = a*C.i + b*C.j + c*C.k
>>> v.to_matrix(C)
Matrix([
[a],
[b],
[c]])
class sympy.vector.dyadic.Dyadic(*args)
所有二階張量類的超類。
參考文獻
[R1074]
zh.wikipedia.org/wiki/二階張量
[R1075]
Kane, T., Levinson, D. 動力學理論與應用. 1985 McGraw-Hill
property components
返回此二階張量的分量,以 Python 字典形式對映 BaseDyadic 例項到相應的測量數。
cross(other)
返回此二階張量與一個向量的叉乘,作為一個向量例項。
引數:
other : 向量
我們正在與此二階張量進行叉乘的向量。
示例
>>> from sympy.vector import CoordSys3D
>>> N = CoordSys3D('N')
>>> d = N.i.outer(N.i)
>>> d.cross(N.j)
(N.i|N.k)
dot(other)
返回此二階張量與另一個二階張量或向量的點積(也稱為內積)。如果‘other’是一個二階張量,則返回一個二階張量。否則,返回一個向量(除非出現錯誤)。
引數:
other : 二階張量/向量
與之進行內積運算的其他二階張量或向量
示例
>>> from sympy.vector import CoordSys3D
>>> N = CoordSys3D('N')
>>> D1 = N.i.outer(N.j)
>>> D2 = N.j.outer(N.j)
>>> D1.dot(D2)
(N.i|N.j)
>>> D1.dot(N.j)
N.i
to_matrix(system, second_system=None)
返回與一個或兩個座標系相關的二階張量的矩陣形式。
引數:
system : 三維座標系
矩陣的行和列對應的座標系。如果提供第二個系統,則僅對應矩陣的行。
second_system : 三維座標系,可選,預設為 None
矩陣列對應的座標系。
示例
>>> from sympy.vector import CoordSys3D
>>> N = CoordSys3D('N')
>>> v = N.i + 2*N.j
>>> d = v.outer(N.i)
>>> d.to_matrix(N)
Matrix([
[1, 0, 0],
[2, 0, 0],
[0, 0, 0]])
>>> from sympy import Symbol
>>> q = Symbol('q')
>>> P = N.orient_new_axis('P', q, N.k)
>>> d.to_matrix(N, P)
Matrix([
[ cos(q), -sin(q), 0],
[2*cos(q), -2*sin(q), 0],
[ 0, 0, 0]])
class sympy.vector.deloperator.Del
表示向量微分運算元,通常在數學表示式中表示為‘nabla’符號。
cross(vect, doit=False)
表示此運算元與給定向量的叉乘 - 等同於向量場的旋度。
引數:
vect : 向量
要計算其旋度的向量。
doit : 布林值
如果為 True,則在呼叫每個分量的.doit()後返回結果。否則,返回的表示式包含 Derivative 例項。
示例
>>> from sympy.vector import CoordSys3D, Del
>>> C = CoordSys3D('C')
>>> delop = Del()
>>> v = C.x*C.y*C.z * (C.i + C.j + C.k)
>>> delop.cross(v, doit = True)
(-C.x*C.y + C.x*C.z)*C.i + (C.x*C.y - C.y*C.z)*C.j +
(-C.x*C.z + C.y*C.z)*C.k
>>> (delop ^ C.i).doit()
0
dot(vect, doit=False)
表示該運算子與給定向量的點積,等於向量場的散度。
引數:
vect : 向量
要計算其散度的向量。
doit : bool
如果為 True,則在呼叫每個分量的.doit()後返回結果。否則,返回的表示式包含 Derivative 例項。
示例
>>> from sympy.vector import CoordSys3D, Del
>>> delop = Del()
>>> C = CoordSys3D('C')
>>> delop.dot(C.x*C.i)
Derivative(C.x, C.x)
>>> v = C.x*C.y*C.z * (C.i + C.j + C.k)
>>> (delop & v).doit()
C.x*C.y + C.x*C.z + C.y*C.z
gradient(scalar_field, doit=False)
返回給定標量場的梯度,作為 Vector 例項。
引數:
scalar_field : SymPy 表示式
要計算其梯度的標量場。
doit : bool
如果為 True,則在呼叫每個分量的.doit()後返回結果。否則,返回的表示式包含 Derivative 例項。
示例
>>> from sympy.vector import CoordSys3D, Del
>>> C = CoordSys3D('C')
>>> delop = Del()
>>> delop.gradient(9)
0
>>> delop(C.x*C.y*C.z).doit()
C.y*C.z*C.i + C.x*C.z*C.j + C.x*C.y*C.k
class sympy.vector.parametricregion.ParametricRegion(definition, *bounds)
表示空間中的引數區域。
引數:
definition : 用於根據引數定義基礎標量的元組。
bounds : 用於定義引數及其相應下限和上限的引數或長度為 3 的元組。
示例
>>> from sympy import cos, sin, pi
>>> from sympy.abc import r, theta, t, a, b, x, y
>>> from sympy.vector import ParametricRegion
>>> ParametricRegion((t, t**2), (t, -1, 2))
ParametricRegion((t, t**2), (t, -1, 2))
>>> ParametricRegion((x, y), (x, 3, 4), (y, 5, 6))
ParametricRegion((x, y), (x, 3, 4), (y, 5, 6))
>>> ParametricRegion((r*cos(theta), r*sin(theta)), (r, -2, 2), (theta, 0, pi))
ParametricRegion((r*cos(theta), r*sin(theta)), (r, -2, 2), (theta, 0, pi))
>>> ParametricRegion((a*cos(t), b*sin(t)), t)
ParametricRegion((a*cos(t), b*sin(t)), t)
>>> circle = ParametricRegion((r*cos(theta), r*sin(theta)), r, (theta, 0, pi))
>>> circle.parameters
(r, theta)
>>> circle.definition
(r*cos(theta), r*sin(theta))
>>> circle.limits
{theta: (0, pi)}
引數化區域的維數確定區域是曲線、曲面還是體積區域。它不表示空間中的維數。
>>> circle.dimensions
1
class sympy.vector.implicitregion.ImplicitRegion(variables, equation)
表示空間中的隱式區域。
引數:
variables : 用於將隱式方程中的變數對映到基礎標量的元組。
equation : 表示區域隱式方程的表示式或等式。
示例
>>> from sympy import Eq
>>> from sympy.abc import x, y, z, t
>>> from sympy.vector import ImplicitRegion
>>> ImplicitRegion((x, y), x**2 + y**2 - 4)
ImplicitRegion((x, y), x**2 + y**2 - 4)
>>> ImplicitRegion((x, y), Eq(y*x, 1))
ImplicitRegion((x, y), x*y - 1)
>>> parabola = ImplicitRegion((x, y), y**2 - 4*x)
>>> parabola.degree
2
>>> parabola.equation
-4*x + y**2
>>> parabola.rational_parametrization(t)
(4/t**2, 4/t)
>>> r = ImplicitRegion((x, y, z), Eq(z, x**2 + y**2))
>>> r.variables
(x, y, z)
>>> r.singular_points()
EmptySet
>>> r.regular_point()
(-10, -10, 200)
multiplicity(point)
返回區域上奇點的多重性。
區域的奇點(x,y)如果所有 m-1 階偏導數在此處為零,則稱其為多重性 m。
示例
>>> from sympy.abc import x, y, z
>>> from sympy.vector import ImplicitRegion
>>> I = ImplicitRegion((x, y, z), x**2 + y**3 - z**4)
>>> I.singular_points()
{(0, 0, 0)}
>>> I.multiplicity((0, 0, 0))
2
rational_parametrization(parameters=('t', 's'), reg_point=None)
返回隱式區域的有理引數化。
示例
>>> from sympy import Eq
>>> from sympy.abc import x, y, z, s, t
>>> from sympy.vector import ImplicitRegion
>>> parabola = ImplicitRegion((x, y), y**2 - 4*x)
>>> parabola.rational_parametrization()
(4/t**2, 4/t)
>>> circle = ImplicitRegion((x, y), Eq(x**2 + y**2, 4))
>>> circle.rational_parametrization()
(4*t/(t**2 + 1), 4*t**2/(t**2 + 1) - 2)
>>> I = ImplicitRegion((x, y), x**3 + x**2 - y**2)
>>> I.rational_parametrization()
(t**2 - 1, t*(t**2 - 1))
>>> cubic_curve = ImplicitRegion((x, y), x**3 + x**2 - y**2)
>>> cubic_curve.rational_parametrization(parameters=(t))
(t**2 - 1, t*(t**2 - 1))
>>> sphere = ImplicitRegion((x, y, z), x**2 + y**2 + z**2 - 4)
>>> sphere.rational_parametrization(parameters=(t, s))
(-2 + 4/(s**2 + t**2 + 1), 4*s/(s**2 + t**2 + 1), 4*t/(s**2 + t**2 + 1))
對於某些圓錐曲線,regular_points()無法找到曲線上的點。在這種情況下,使用者需要確定區域上的一個點,並使用 reg_point 傳遞它以計算引數化表示。
>>> c = ImplicitRegion((x, y), (x - 1/2)**2 + (y)**2 - (1/4)**2)
>>> c.rational_parametrization(reg_point=(3/4, 0))
(0.75 - 0.5/(t**2 + 1), -0.5*t/(t**2 + 1))
參考文獻
- Christoph M. Hoffmann,“引數曲線和曲面之間的轉換方法”,普渡大學 e-Pubs,1990 年。可檢視:
docs.lib.purdue.edu/cgi/viewcontent.cgi?article=1827&context=cstech
regular_point()
返回隱式區域上的一個點。
示例
>>> from sympy.abc import x, y, z
>>> from sympy.vector import ImplicitRegion
>>> circle = ImplicitRegion((x, y), (x + 2)**2 + (y - 3)**2 - 16)
>>> circle.regular_point()
(-2, -1)
>>> parabola = ImplicitRegion((x, y), x**2 - 4*y)
>>> parabola.regular_point()
(0, 0)
>>> r = ImplicitRegion((x, y, z), (x + y + z)**4)
>>> r.regular_point()
(-10, -10, 20)
參考文獻
- Erik Hillgarter,“圓錐曲線上的有理點”,學位論文,RISC-Linz,約翰·開普勒林茨大學,1996 年。可檢視:
www3.risc.jku.at/publications/download/risc_1355/Rational%20Points%20on%20Conics.pdf
singular_points()
返回區域的奇點集合。
區域上的奇點是區域上所有偏導數均為零的點。
示例
>>> from sympy.abc import x, y
>>> from sympy.vector import ImplicitRegion
>>> I = ImplicitRegion((x, y), (y-1)**2 -x**3 + 2*x**2 -x)
>>> I.singular_points()
{(1, 1)}
class sympy.vector.integrals.ParametricIntegral(field, parametricregion)
表示標量或向量場在引數區域上的積分。
示例
>>> from sympy import cos, sin, pi
>>> from sympy.vector import CoordSys3D, ParametricRegion, ParametricIntegral
>>> from sympy.abc import r, t, theta, phi
>>> C = CoordSys3D('C')
>>> curve = ParametricRegion((3*t - 2, t + 1), (t, 1, 2))
>>> ParametricIntegral(C.x, curve)
5*sqrt(10)/2
>>> length = ParametricIntegral(1, curve)
>>> length
sqrt(10)
>>> semisphere = ParametricRegion((2*sin(phi)*cos(theta), 2*sin(phi)*sin(theta), 2*cos(phi)), (theta, 0, 2*pi), (phi, 0, pi/2))
>>> ParametricIntegral(C.z, semisphere)
8*pi
>>> ParametricIntegral(C.j + C.k, ParametricRegion((r*cos(theta), r*sin(theta)), r, theta))
0
定向器類(文件字串)
原文:
docs.sympy.org/latest/modules/vector/api/orienterclasses.html
class sympy.vector.orienters.Orienter(*args)
所有定向器類的超類。
rotation_matrix()
與此定向器例項對應的旋轉矩陣。
class sympy.vector.orienters.AxisOrienter(angle, axis)
表示軸定向器的類。
__init__(angle, axis)
軸旋轉是圍繞任意軸的旋轉,角度由 SymPy 表示式標量提供,軸由向量提供。
引數:
角度:Expr
用於旋轉順序的角度
軸:向量
需要執行旋轉的軸
示例
>>> from sympy.vector import CoordSys3D
>>> from sympy import symbols
>>> q1 = symbols('q1')
>>> N = CoordSys3D('N')
>>> from sympy.vector import AxisOrienter
>>> orienter = AxisOrienter(q1, N.i + 2 * N.j)
>>> B = N.orient_new('B', (orienter, ))
rotation_matrix(system)
與此定向器例項對應的旋轉矩陣。
引數:
系統:CoordSys3D
計算旋轉矩陣的座標系
class sympy.vector.orienters.BodyOrienter(angle1, angle2, angle3, rot_order)
表示體定向器的類。
__init__(angle1, angle2, angle3, rot_order)
體定向將此座標系透過三個連續的簡單旋轉。
'Body'固定旋轉包括尤拉角和泰特-布萊恩角,參見en.wikipedia.org/wiki/Euler_angles
。
引數:
角度 1,角度 2,角度 3:Expr
三個連續角度來旋轉座標系
旋轉順序:字串
定義旋轉軸順序的字串
示例
>>> from sympy.vector import CoordSys3D, BodyOrienter
>>> from sympy import symbols
>>> q1, q2, q3 = symbols('q1 q2 q3')
>>> N = CoordSys3D('N')
'Body'固定旋轉由三個角度和三個固定於 D 的體旋轉軸描述。為了將座標系 D 定向到 N,每次連續旋轉都是關於固定於 D 的正交單位向量。例如,'123'旋轉將指定關於 N.i、然後 D.j、然後 D.k 的旋轉。(最初,D.i 與 N.i 相同)因此,
>>> body_orienter = BodyOrienter(q1, q2, q3, '123')
>>> D = N.orient_new('D', (body_orienter, ))
同上
>>> from sympy.vector import AxisOrienter
>>> axis_orienter1 = AxisOrienter(q1, N.i)
>>> D = N.orient_new('D', (axis_orienter1, ))
>>> axis_orienter2 = AxisOrienter(q2, D.j)
>>> D = D.orient_new('D', (axis_orienter2, ))
>>> axis_orienter3 = AxisOrienter(q3, D.k)
>>> D = D.orient_new('D', (axis_orienter3, ))
可接受的旋轉順序長度為 3,表示為 XYZ 或 123,並且不能連續兩次圍繞同一軸旋轉。
>>> body_orienter1 = BodyOrienter(q1, q2, q3, '123')
>>> body_orienter2 = BodyOrienter(q1, q2, 0, 'ZXZ')
>>> body_orienter3 = BodyOrienter(0, 0, 0, 'XYX')
class sympy.vector.orienters.SpaceOrienter(angle1, angle2, angle3, rot_order)
表示空間定向器的類。
__init__(angle1, angle2, angle3, rot_order)
空間旋轉類似於體旋轉,但是旋轉的順序相反。
引數:
角度 1,角度 2,角度 3:Expr
三個連續角度來旋轉座標系
旋轉順序:字串
定義旋轉軸順序的字串
示例
>>> from sympy.vector import CoordSys3D, SpaceOrienter
>>> from sympy import symbols
>>> q1, q2, q3 = symbols('q1 q2 q3')
>>> N = CoordSys3D('N')
為了將座標系 D 定向到 N,每次連續旋轉都是關於 N 的正交單位向量。例如,'123'旋轉將指定關於 N.i、然後 N.j、然後 N.k 的旋轉。因此,
>>> space_orienter = SpaceOrienter(q1, q2, q3, '312')
>>> D = N.orient_new('D', (space_orienter, ))
同上
>>> from sympy.vector import AxisOrienter
>>> axis_orienter1 = AxisOrienter(q1, N.i)
>>> B = N.orient_new('B', (axis_orienter1, ))
>>> axis_orienter2 = AxisOrienter(q2, N.j)
>>> C = B.orient_new('C', (axis_orienter2, ))
>>> axis_orienter3 = AxisOrienter(q3, N.k)
>>> D = C.orient_new('C', (axis_orienter3, ))
另請參閱
BodyOrienter
相對於尤拉角定向系統的定向器。
class sympy.vector.orienters.QuaternionOrienter(q0, q1, q2, q3)
表示四元數定向器的類。
__init__(angle1, angle2, angle3, rot_order)
四元數定向使用四元數將新的 CoordSys3D 定向,定義為圍繞單位向量 lambda 的有限旋轉,旋轉量為 theta。
這個方向由四個引數描述:
q0 = cos(theta/2)
q1 = lambda_x sin(theta/2)
q2 = lambda_y sin(theta/2)
q3 = lambda_z sin(theta/2)
四元數不接受旋轉順序。
引數:
q0, q1, q2, q3:Expr
用於旋轉座標系的四元數
示例
>>> from sympy.vector import CoordSys3D
>>> from sympy import symbols
>>> q0, q1, q2, q3 = symbols('q0 q1 q2 q3')
>>> N = CoordSys3D('N')
>>> from sympy.vector import QuaternionOrienter
>>> q_orienter = QuaternionOrienter(q0, q1, q2, q3)
>>> B = N.orient_new('B', (q_orienter, ))
sympy.vector 中的基本功能(文件字串)
原文:
docs.sympy.org/latest/modules/vector/api/vectorfunctions.html
sympy.vector.matrix_to_vector(matrix, system)
將矩陣形式的向量轉換為 Vector 例項。
假設矩陣的元素表示‘system’的基向量上的向量分量的測量數。
引數:
矩陣:SymPy Matrix,尺寸:(3, 1)
要轉換為向量的矩陣
system:CoordSys3D
定義向量的座標系統
示例
>>> from sympy import ImmutableMatrix as Matrix
>>> m = Matrix([1, 2, 3])
>>> from sympy.vector import CoordSys3D, matrix_to_vector
>>> C = CoordSys3D('C')
>>> v = matrix_to_vector(m, C)
>>> v
C.i + 2*C.j + 3*C.k
>>> v.to_matrix(C) == m
True
sympy.vector.express(expr, system, system2=None, variables=False)
用於‘表達’功能的全域性函式。
在給定的座標系中重新表達向量、二重或標量(可用 sympyfiable)。
如果‘variables’為 True,則將向量/標量場或二重標量中其他座標系統的座標變數(基標量)也用給定系統的基標量代換。
引數:
表示式:向量/二重/標量(可用 sympyfiable)
要在 CoordSys3D ‘system’ 中重新表達的表示式
system: CoordSys3D
要表達的表示式的座標系統
system2: CoordSys3D
重新表達所需的其他座標系統(僅適用於 Dyadic Expr)
variables:布林值
指定是否要用引數系統中的表示式中存在的座標變數替換它們
示例
>>> from sympy.vector import CoordSys3D
>>> from sympy import Symbol, cos, sin
>>> N = CoordSys3D('N')
>>> q = Symbol('q')
>>> B = N.orient_new_axis('B', q, N.k)
>>> from sympy.vector import express
>>> express(B.i, N)
(cos(q))*N.i + (sin(q))*N.j
>>> express(N.x, B, variables=True)
B.x*cos(q) - B.y*sin(q)
>>> d = N.i.outer(N.i)
>>> express(d, B, N) == (cos(q))*(B.i|N.i) + (-sin(q))*(B.j|N.i)
True
sympy.vector.curl(vect, doit=True)
返回相對於給定座標系的基標量計算的向量場的旋度。
引數:
向量:向量
向量運算元
doit:bool
如果為 True,則在每個分量上呼叫 .doit() 後返回結果。否則,返回表示式包含 Derivative 例項
示例
>>> from sympy.vector import CoordSys3D, curl
>>> R = CoordSys3D('R')
>>> v1 = R.y*R.z*R.i + R.x*R.z*R.j + R.x*R.y*R.k
>>> curl(v1)
0
>>> v2 = R.x*R.y*R.z*R.i
>>> curl(v2)
R.x*R.y*R.j + (-R.x*R.z)*R.k
sympy.vector.divergence(vect, doit=True)
返回相對於給定座標系的基標量計算的向量場的散度。
引數:
向量:向量
向量運算元
doit:bool
如果為 True,則在每個分量上呼叫 .doit() 後返回結果。否則,返回表示式包含 Derivative 例項
示例
>>> from sympy.vector import CoordSys3D, divergence
>>> R = CoordSys3D('R')
>>> v1 = R.x*R.y*R.z * (R.i+R.j+R.k)
>>> divergence(v1)
R.x*R.y + R.x*R.z + R.y*R.z
>>> v2 = 2*R.y*R.z*R.j
>>> divergence(v2)
2*R.z
sympy.vector.gradient(scalar_field, doit=True)
返回相對於給定座標系的基標量計算的標量場的向量梯度。
引數:
標量場:SymPy Expr
要計算其梯度的標量場
doit:bool
如果為 True,則在每個分量上呼叫 .doit() 後返回結果。否則,返回表示式包含 Derivative 例項
示例
>>> from sympy.vector import CoordSys3D, gradient
>>> R = CoordSys3D('R')
>>> s1 = R.x*R.y*R.z
>>> gradient(s1)
R.y*R.z*R.i + R.x*R.z*R.j + R.x*R.y*R.k
>>> s2 = 5*R.x**2*R.z
>>> gradient(s2)
10*R.x*R.z*R.i + 5*R.x**2*R.k
sympy.vector.is_conservative(field)
檢查場是否保守。
引數:
場:向量
要檢查其保守屬性的場
示例
>>> from sympy.vector import CoordSys3D
>>> from sympy.vector import is_conservative
>>> R = CoordSys3D('R')
>>> is_conservative(R.y*R.z*R.i + R.x*R.z*R.j + R.x*R.y*R.k)
True
>>> is_conservative(R.z*R.j)
False
sympy.vector.is_solenoidal(field)
檢查場是否為旋量場。
引數:
場:向量
要檢查旋量性質的場
示例
>>> from sympy.vector import CoordSys3D
>>> from sympy.vector import is_solenoidal
>>> R = CoordSys3D('R')
>>> is_solenoidal(R.y*R.z*R.i + R.x*R.z*R.j + R.x*R.y*R.k)
True
>>> is_solenoidal(R.y * R.j)
False
sympy.vector.scalar_potential(field, coord_sys)
返回給定座標系中場的標量勢函式(不包括新增的積分常數)。
引數:
場:向量
要計算其標量勢函式的向量場
coord_sys:CoordSys3D
進行計算的座標系統
示例
>>> from sympy.vector import CoordSys3D
>>> from sympy.vector import scalar_potential, gradient
>>> R = CoordSys3D('R')
>>> scalar_potential(R.k, R) == R.z
True
>>> scalar_field = 2*R.x**2*R.y*R.z
>>> grad_field = gradient(scalar_field)
>>> scalar_potential(grad_field, R)
2*R.x**2*R.y*R.z
sympy.vector.scalar_potential_difference(field, coord_sys, point1, point2)
返回在給定座標系中,關於給定場的兩點之間的標量勢差。
如果提供了標量場,則考慮它在兩個點處的值。如果提供了保守向量場,則使用其在兩點處的標量勢函式的值。
返回(點 2 處的電勢)-(點 1 處的電勢)
兩個點的位置向量是相對於提供的座標系原點計算的。
引數:
field : 向量/表示式
要計算的場
coord_sys : CoordSys3D
在進行計算時使用的座標系
point1 : 點
在給定的座標系中的初始點
position2 : 點
給定座標系中的第二個點
示例
>>> from sympy.vector import CoordSys3D
>>> from sympy.vector import scalar_potential_difference
>>> R = CoordSys3D('R')
>>> P = R.origin.locate_new('P', R.x*R.i + R.y*R.j + R.z*R.k)
>>> vectfield = 4*R.x*R.y*R.i + 2*R.x**2*R.j
>>> scalar_potential_difference(vectfield, R, R.origin, P)
2*R.x**2*R.y
>>> Q = R.origin.locate_new('O', 3*R.i + R.j + 2*R.k)
>>> scalar_potential_difference(vectfield, R, P, Q)
-2*R.x**2*R.y + 18
sympy.vector.integrals.vector_integrate(field, *region)
計算在區域或一組引數上的向量/標量場的積分。
示例
>>> from sympy.vector import CoordSys3D, ParametricRegion, vector_integrate
>>> from sympy.abc import x, y, t
>>> C = CoordSys3D('C')
>>> region = ParametricRegion((t, t**2), (t, 1, 5))
>>> vector_integrate(C.x*C.i, region)
12
還可以計算幾何模組中某些物件上的積分。
>>> from sympy.geometry import Point, Circle, Triangle
>>> c = Circle(Point(0, 2), 5)
>>> vector_integrate(C.x**2 + C.y**2, c)
290*pi
>>> triangle = Triangle(Point(-2, 3), Point(2, 3), Point(0, 5))
>>> vector_integrate(3*C.x**2*C.y*C.i + C.j, triangle)
-8
可以計算一些簡單隱式區域上的積分。但在大多數情況下,計算它們需要太長時間。這是因為參數列示的表示式變得很大。
>>> from sympy.vector import ImplicitRegion
>>> c2 = ImplicitRegion((x, y), (x - 2)**2 + (y - 1)**2 - 9)
>>> vector_integrate(1, c2)
6*pi
與基礎標量相關的場的積分:
>>> vector_integrate(12*C.y**3, (C.y, 1, 3))
240
>>> vector_integrate(C.x**2*C.z, C.x)
C.x**3*C.z/3
>>> vector_integrate(C.x*C.i - C.y*C.k, C.x)
(Integral(C.x, C.x))*C.i + (Integral(-C.y, C.x))*C.k
>>> _.doit()
C.x**2/2*C.i + (-C.x*C.y)*C.k
數論
原文:
docs.sympy.org/latest/reference/public/numbertheory/index.html
目錄
- 數論
數論
原文連結:
docs.sympy.org/latest/modules/ntheory.html
Ntheory 類參考
class sympy.ntheory.generate.Sieve(sieve_interval=1000000)
質數列表,實現為動態增長的埃拉託斯特尼篩。當請求涉及尚未篩選的奇數時,篩網自動擴充套件至該數。實現細節限制了質數數量為 2³²-1
。
示例
>>> from sympy import sieve
>>> sieve._reset() # this line for doctest only
>>> 25 in sieve
False
>>> sieve._list
array('L', [2, 3, 5, 7, 11, 13, 17, 19, 23])
extend(n)
擴充套件篩以涵蓋所有小於等於 n 的質數。
示例
>>> from sympy import sieve
>>> sieve._reset() # this line for doctest only
>>> sieve.extend(30)
>>> sieve[10] == 29
True
extend_to_no(i)
擴充套件以包括第 i 個質數。
引數:
i:整數
示例
>>> from sympy import sieve
>>> sieve._reset() # this line for doctest only
>>> sieve.extend_to_no(9)
>>> sieve._list
array('L', [2, 3, 5, 7, 11, 13, 17, 19, 23])
注意事項
如果列表過短,會增加 50%,因此它很可能比請求的要長。
mobiusrange(a, b)
生成範圍 [a, b) 內的所有莫比烏斯函式數。
引數:
a:整數
範圍內的第一個數字
b:整數
超出範圍的第一個數字
示例
>>> from sympy import sieve
>>> print([i for i in sieve.mobiusrange(7, 18)])
[-1, 0, 0, 1, -1, 0, -1, 1, 1, 0, -1]
primerange(a, b=None)
生成範圍 [2, a) 或 [a, b) 內的所有質數。
示例
>>> from sympy import sieve, prime
小於 19 的所有質數:
>>> print([i for i in sieve.primerange(19)])
[2, 3, 5, 7, 11, 13, 17]
大於等於 7 且小於 19 的所有質數:
>>> print([i for i in sieve.primerange(7, 19)])
[7, 11, 13, 17]
透過第 10 個質數的所有質數
>>> list(sieve.primerange(prime(10) + 1))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
search(n)
返回界定 n 的質數的索引 i, j。
如果 n 是質數,則 i == j。
雖然 n 可以是一個表示式,但如果 ceiling 不能將其轉換為整數,則會引發一個 n 錯誤。
示例
>>> from sympy import sieve
>>> sieve.search(25)
(9, 10)
>>> sieve.search(23)
(9, 9)
totientrange(a, b)
生成範圍 [a, b) 內的所有尤拉函式數。
示例
>>> from sympy import sieve
>>> print([i for i in sieve.totientrange(7, 18)])
[6, 4, 6, 4, 10, 4, 12, 6, 8, 8, 16]
Ntheory 函式參考
sympy.ntheory.generate.prime(nth)
返回第 n 個質數,質數索引為 prime(1) = 2, prime(2) = 3,等等… 第 n 個質數大約是 (n\log(n))。
對於 x 的對數積分是小於等於 x 的質數數的一個相當不錯的近似值,即 li(x) ~ pi(x) 實際上,對於我們關心的數字( x<1e11 ),li(x) - pi(x) < 50000
此外,可以安全地假設對於此函式可以評估的數字,li(x) > pi(x)。
在這裡,我們使用二分查詢找到最小的整數 m,使得 li(m) > n。現在 pi(m-1) < li(m-1) <= n,
我們使用 primepi
函式找到 pi(m - 1)。
從 m 開始,我們必須找到 n - pi(m-1) 更多的質數。
對於此實現可以處理的輸入,我們最多需要測試約 10**5 個數的素性以獲得答案。
示例
>>> from sympy import prime
>>> prime(10)
29
>>> prime(1)
2
>>> prime(100000)
1299709
另請參閱
sympy.ntheory.primetest.isprime
測試 n 是否為質數
primerange
在給定範圍內生成所有質數
primepi
返回小於或等於 n 的質數的數量
參考資料
[R648]
en.wikipedia.org/wiki/Prime_number_theorem#Table_of_.CF.80.28x.29.2C_x_.2F_log_x.2C_and_li.28x.29
[R649]
en.wikipedia.org/wiki/Prime_number_theorem#Approximations_for_the_nth_prime_number
[R650]
en.wikipedia.org/wiki/Skewes%27_number
sympy.ntheory.generate.primepi(n)
表示質數計數函式 pi(n) = 小於或等於 n 的質數的數量。
自版本 1.13 開始不推薦使用:primepi
函式已棄用。請改用sympy.functions.combinatorial.numbers.primepi
。有關更多資訊,請參閱其文件。有關詳細資訊,請參閱從 ntheory 移動到 functions 的符號函式。
演算法描述:
在篩法中,我們移除所有質數 p 的倍數,除了 p 本身。
讓 phi(i,j)為從小於或等於 j 的質數中篩除後剩餘的 2 <= k <= i 的整數數量。顯然,pi(n) = phi(n, sqrt(n))
如果 j 不是一個質數,phi(i,j) = phi(i, j - 1)
如果 j 是一個質數,我們刪除所有最小質因數為 j 的數(除了 j 本身)。
讓(x= j \times a)為這樣一個數,其中(2 \le a \le i / j)。現在,在從質數(\le j - 1)中篩選後,a 必須保留(因為 x,因此 a 沒有質因數(\le j - 1))。顯然,有 phi(i / j, j - 1)個這樣的 a 在從質數(\le j - 1)中篩選後保留。
如果 a 是小於等於 j-1 的質數,(x= j \times a) 的最小質因數為 a,並且已經被移除(透過篩法從 a 中)。因此,我們不需要再次移除它。(注意:這樣的 x 有 pi(j-1)個)
因此,將被移除的 x 的數量為:phi(i / j, j - 1) - phi(j - 1, j - 1)(注意 pi(j - 1) = phi(j - 1, j - 1))
(\Rightarrow) phi(i,j) = phi(i, j - 1) - phi(i / j, j - 1) + phi(j - 1, j - 1)
因此,使用以下遞迴併實現 dp:
phi(a, b) = phi(a, b - 1),如果 b 不是質數 phi(a, b) = phi(a, b-1)-phi(a / b, b-1) + phi(b-1, b-1),如果 b 是質數
顯然 a 總是形式為 floor(n / k),最多可以取(2\sqrt{n})個值。維護兩個陣列 arr1,arr2,arr1[i] = phi(i, j),arr2[i] = phi(n // i, j)
最後的答案是 arr2[1]
示例
>>> from sympy import primepi, prime, prevprime, isprime
>>> primepi(25)
9
因此,小於或等於 25 的有 9 個質數。25 是質數嗎?
>>> isprime(25)
False
不是。因此,小於 25 的第一個質數必須是第 9 個質數:
>>> prevprime(25) == prime(9)
True
參見
sympy.ntheory.primetest.isprime
測試 n 是否為質數
primerange
在給定範圍內生成所有的質數
prime
返回第 n 個質數
sympy.ntheory.generate.nextprime(n, ith=1)
返回大於 n 的第 ith 個質數。
引數:
n : 整數
ith : 正整數
返回:
int : 返回大於 n 的第 ith 個質數
異常:
ValueError
如果
ith <= 0
。如果n
或ith
不是整數。
注意
潛在的質數位於 6*j +/- 1。這個性質在搜尋中被使用。
>>> from sympy import nextprime
>>> [(i, nextprime(i)) for i in range(10, 15)]
[(10, 11), (11, 13), (12, 13), (13, 17), (14, 17)]
>>> nextprime(2, ith=2) # the 2nd prime after 2
5
參見
prevprime
返回小於 n 的最大素數
primerange
生成給定範圍內的所有素數
sympy.ntheory.generate.prevprime(n)
返回小於 n 的最大素數。
註釋
潛在的素數位於 6*j +/- 1。這個性質在搜尋時使用。
>>> from sympy import prevprime
>>> [(i, prevprime(i)) for i in range(10, 15)]
[(10, 7), (11, 7), (12, 11), (13, 11), (14, 13)]
另請參閱
nextprime
返回大於 n 的第 i 個素數
primerange
生成給定範圍內的所有素數
sympy.ntheory.generate.primerange(a, b=None)
生成範圍為 [2, a) 或 [a, b) 的所有素數列表。
如果預設篩選器中存在範圍,則將從那裡返回值;否則將返回值但不會修改篩選器。
示例
>>> from sympy import primerange, prime
小於 19 的所有素數:
>>> list(primerange(19))
[2, 3, 5, 7, 11, 13, 17]
大於或等於 7 且小於 19 的所有素數:
>>> list(primerange(7, 19))
[7, 11, 13, 17]
所有小於第 10 個素數的素數
>>> list(primerange(prime(10) + 1))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
篩法方法 primerange 通常更快,但由於篩選器儲存值,記憶體佔用更多。可以使用名為 sieve 的預設篩選器例項:
>>> from sympy import sieve
>>> list(sieve.primerange(1, 30))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
註釋
一些關於素數出現頻率的著名猜想是 [1]:
-
孿生素數:儘管經常不是,以下將給出兩個素數
無限次數:
primerange(6n - 1, 6n + 2)
-
勒讓德定理:以下始終至少產生一個素數
primerange(n2, (n+1)2+1)
-
貝特朗定理(已證明):在範圍內總是有一個素數
primerange(n, 2*n)
-
布洛卡德定理:在給定範圍內至少有四個素數
primerange(prime(n)2, prime(n+1)2)
素數之間的平均間隔是 log(n) [2];素數之間的間隔可以任意大,因為合數序列可以任意大,例如序列 n! + 2, n! + 3 … n! + n 中的數字都是合數。
另請參閱
prime
返回第 n 個素數
nextprime
返回大於 n 的第 i 個素數
prevprime
返回小於 n 的最大素數
randprime
返回給定範圍內的隨機素數
primorial
基於條件返回素數的乘積
Sieve.primerange
返回從已計算的素數範圍或擴充套件篩選器以包含所請求範圍的範圍。
參考文獻
[R651]
en.wikipedia.org/wiki/Prime_number
[R652]
primes.utm.edu/notes/gaps.html
sympy.ntheory.generate.randprime(a, b)
返回在區間 a, b) 中的隨機素數。
貝特朗定理確保 randprime(a, 2*a) 對於 a > 1 總是成功。
請注意,由於實現困難,選擇的素數不是均勻隨機的。例如,在範圍 [112, 128) 中有兩個素數 113
和 127
,但 randprime(112, 128)
以 15/17 的機率返回 127
。
示例
>>> from sympy import randprime, isprime
>>> randprime(1, 30)
13
>>> isprime(randprime(1, 30))
True
另請參閱
[primerange
在給定範圍內生成所有素數
參考資料
[R653]
zh.wikipedia.org/wiki/貝特朗假設
sympy.ntheory.generate.primorial(n, nth=True)
返回前 n 個素數的乘積(預設)或小於等於 n 的素數(當 nth=False
時)。
示例
>>> from sympy.ntheory.generate import primorial, primerange
>>> from sympy import factorint, Mul, primefactors, sqrt
>>> primorial(4) # the first 4 primes are 2, 3, 5, 7
210
>>> primorial(4, nth=False) # primes <= 4 are 2 and 3
6
>>> primorial(1)
2
>>> primorial(1, nth=False)
1
>>> primorial(sqrt(101), nth=False)
210
人們可以認為素數是無限的,因為如果你取一組素數並將它們相乘(例如,素數階乘),然後加或減 1,結果不能被任何原始因子之一整除,因此這個素數的乘積必須被除以 1 或多個新的素數。
在這種情況下,數本身是一個新的素數:
>>> factorint(primorial(4) + 1)
{211: 1}
在這種情況下,兩個新的素數是因子:
>>> factorint(primorial(4) - 1)
{11: 1, 19: 1}
這裡,乘在一起的素數比這些素數更大或更小:
>>> p = list(primerange(10, 20))
>>> sorted(set(primefactors(Mul(*p) + 1)).difference(set(p)))
[2, 5, 31, 149]
另請參閱
primerange
在給定範圍內生成所有素數
sympy.ntheory.generate.cycle_length(f, x0, nmax=None, values=False)
對於給定的迭代序列,返回一個生成器,提供迭代週期的長度(lambda)和迴圈開始之前的項的長度(mu);如果 values
為 True,則將返回序列的項。序列以值 x0
開始。
注意:可能會返回多於第一個 lambda + mu 項,這是使用布倫特方法進行迴圈檢測的成本;然而,通常比使用弗洛伊德方法確定的正確結束點計算的項要少。
>>> from sympy.ntheory.generate import cycle_length
這將產生 i <– func(i) 的連續值:
>>> def gen(func, i):
... while 1:
... yield i
... i = func(i)
...
函式定義如下:
>>> func = lambda i: (i**2 + 1) % 51
並給定種子 4 和計算的 mu 和 lambda 項:
>>> next(cycle_length(func, 4))
(6, 3)
我們可以看到輸出的含義:
>>> iter = cycle_length(func, 4, values=True)
>>> list(iter)
[4, 17, 35, 2, 5, 26, 14, 44, 50, 2, 5, 26, 14]
第一個 3 之後有 6 個重複值。
如果懷疑一個序列的長度比你希望的長,可以使用 nmax
提前退出(mu 將返回為 None):
>>> next(cycle_length(func, 4, nmax = 4))
(4, None)
>>> list(cycle_length(func, 4, nmax = 4, values=True))
[4, 17, 35, 2]
程式碼修改自:
zh.wikipedia.org/wiki/迴圈檢測
。
sympy.ntheory.generate.composite(nth)
返回第 n 個複合數,其中複合數索引為 composite(1) = 4,composite(2) = 6,等等……
示例
>>> from sympy import composite
>>> composite(36)
52
>>> composite(1)
4
>>> composite(17737)
20000
另請參閱
sympy.ntheory.primetest.isprime
測試 n 是否為素數
primerange
在給定範圍內生成所有素數
primepi
返回小於或等於 n 的素數的數量
prime
返回第 n 個素數
compositepi
返回小於或等於 n
的正複合數的數量
sympy.ntheory.generate.compositepi(n)
返回小於或等於 n
的正複合數的數量。第一個正複合數是 4
,即 compositepi(4) = 1
。
示例
>>> from sympy import compositepi
>>> compositepi(25)
15
>>> compositepi(1000)
831
另見
sympy.ntheory.primetest.isprime
測試 n
是否為素數
primerange
在給定範圍內生成所有素數
prime
返回第 n
個質數
primepi
返回小於或等於 n
的素數的數量
composite
返回第 n
個複合數
sympy.ntheory.factor_.smoothness(n)
返回 n
的 B-平滑和 B-冪平滑值。
n
的平滑性是 n
的最大素因子;冪平滑性是最大除數升至其重數。
示例
>>> from sympy.ntheory.factor_ import smoothness
>>> smoothness(2**7*3**2)
(3, 128)
>>> smoothness(2**4*13)
(13, 16)
>>> smoothness(2)
(2, 2)
另見
factorint
, smoothness_p
sympy.ntheory.factor_.smoothness_p(n, m=-1, power=0, visual=None)
返回列表 [m, (p, (M, sm(p + m), psm(p + m)))…]
其中:
-
p**M
是n
的基數p
除數 -
sm(p + m)
是p + m
的平滑性(預設情況下m = -1
) -
psm(p + m)
是p + m
的冪平滑性
列表按平滑性(預設)或按冪平滑性(如果 power=1
)排序。
左側(m = -1
)或右側(m = 1
)的平滑性決定了從 p +/- 1
型別的因式方法獲得的結果。
>>> from sympy.ntheory.factor_ import smoothness_p, factorint
>>> smoothness_p(10431, m=1)
(1, [(3, (2, 2, 4)), (19, (1, 5, 5)), (61, (1, 31, 31))])
>>> smoothness_p(10431)
(-1, [(3, (2, 2, 2)), (19, (1, 3, 9)), (61, (1, 5, 5))])
>>> smoothness_p(10431, power=1)
(-1, [(3, (2, 2, 2)), (61, (1, 5, 5)), (19, (1, 3, 9))])
如果 visual=True
,則返回帶註釋的字串:
>>> print(smoothness_p(21477639576571, visual=1))
p**i=4410317**1 has p-1 B=1787, B-pow=1787
p**i=4869863**1 has p-1 B=2434931, B-pow=2434931
該字串也可以直接從因數分解字典生成,反之亦然:
>>> factorint(17*9)
{3: 2, 17: 1}
>>> smoothness_p(_)
'p**i=3**2 has p-1 B=2, B-pow=2\np**i=17**1 has p-1 B=2, B-pow=16'
>>> smoothness_p(_)
{3: 2, 17: 1}
輸出邏輯的表格如下:
視覺化 輸入 真 --- --- dict str str str tuple str n str mul str
另見
factorint
, smoothness
sympy.ntheory.factor_.multiplicity(p, n)
找到最大整數 m
,使得 p**m
可整除 n
。
示例
>>> from sympy import multiplicity, Rational
>>> [multiplicity(5, n) for n in [8, 5, 25, 125, 250]]
[0, 1, 2, 3, 3]
>>> multiplicity(3, Rational(1, 9))
-2
注意:在檢查大階乘中數字的重複性時,最有效的方法是將其作為未評估的階乘傳送或直接呼叫 multiplicity_in_factorial
:
>>> from sympy.ntheory import multiplicity_in_factorial
>>> from sympy import factorial
>>> p = factorial(25)
>>> n = 2**100
>>> nfac = factorial(n, evaluate=False)
>>> multiplicity(p, nfac)
52818775009509558395695966887
>>> _ == multiplicity_in_factorial(p, n)
True
另見
trailing
sympy.ntheory.factor_.perfect_power(n, candidates=None, big=True, factor=True)
返回 (b, e)
,使得若 n
是具有 e > 1
的唯一完全冪,則 n
== b**e
,否則返回 False
(例如 1
不是完全冪)。如果 n
不是有理數,則引發 ValueError
。
預設情況下,基數將遞迴分解並收集指數,因此尋找最大可能的 e
。如果 big=False
則選擇最小可能的 e
(因此是素數)。
如果factor=True
,則嘗試同時因式分解n
,因為找到一個因子表明n
的唯一可能根。這是預設值,因為在搜尋完美冪的過程中只會測試幾個小因子。
使用candidates
主要是為了內部使用;如果提供,則如果n
不能寫成其中一個候選數的冪,則返回 False,並且不會嘗試因式分解(超出測試因子 2)。
示例
>>> from sympy import perfect_power, Rational
>>> perfect_power(16)
(2, 4)
>>> perfect_power(16, big=False)
(4, 2)
負數只能有奇數完全冪:
>>> perfect_power(-4)
False
>>> perfect_power(-8)
(-2, 3)
有理數也被識別:
>>> perfect_power(Rational(1, 2)**3)
(1/2, 3)
>>> perfect_power(Rational(-3, 2)**3)
(-3/2, 3)
註釋
要知道一個整數是否是 2 的完全冪,使用
>>> is2pow = lambda n: bool(n and not n & (n - 1))
>>> [(i, is2pow(i)) for i in range(5)]
[(0, False), (1, True), (2, True), (3, False), (4, True)]
不需要提供candidates
。提供時,假定它們是整數。第一個大於計算的最大可能指數的候選數將為該程式的常規訊號。
>>> perfect_power(3**8, [9])
False
>>> perfect_power(3**8, [2, 4, 8])
(3, 8)
>>> perfect_power(3**8, [4, 8], big=False)
(9, 4)
參見
sympy.core.intfunc.integer_nthroot
,sympy.ntheory.primetest.is_square
sympy.ntheory.factor_.pollard_rho(n, s=2, a=1, retries=5, seed=1234, max_steps=None, F=None)
使用波拉德ρ方法嘗試提取n
的非平凡因子。返回的因子可能是複合數。如果找不到因子,則返回None
。
演算法使用生成器函式生成 x 的偽隨機值,並用 F(x)替換 x。如果未提供 F,則使用函式 x**2 + a
。提供給 F(x)的第一個值是s
。如果失敗(如果retries
> 0),將提供新的a
和s
;如果提供了 F,則將忽略a
。
這些函式生成的數字序列通常會引導到某個數字,然後迴圈回到該數字並開始重複序列,例如 1, 2, 3, 4, 5, 3, 4, 5 – 這種引導和迴圈看起來有點像希臘字母ρ,因此得名‘rho’。
對於給定的函式,可能會得到非常不同的主迴圈值,因此允許重試是個好主意:
>>> from sympy.ntheory.generate import cycle_length
>>> n = 16843009
>>> F = lambda x:(2048*pow(x, 2, n) + 32767) % n
>>> for s in range(5):
... print('loop length = %4i; leader length = %3i' % next(cycle_length(F, s)))
...
loop length = 2489; leader length = 43
loop length = 78; leader length = 121
loop length = 1482; leader length = 100
loop length = 1482; leader length = 286
loop length = 1482; leader length = 101
這是一個明確的例子,其中有一個三元素引導到一個序列的 3 個數字(11, 14, 4),然後重複:
>>> x=2
>>> for i in range(9):
... print(x)
... x=(x**2+12)%17
...
2
16
13
11
14
4
11
14
4
>>> next(cycle_length(lambda x: (x**2+12)%17, 2))
(3, 3)
>>> list(cycle_length(lambda x: (x**2+12)%17, 2, values=True))
[2, 16, 13, 11, 14, 4]
不是檢查所有生成的值與 n 的差異的替代品,僅檢查第 k 和 2*k 個數字,例如第一個和第二個,第二個和第四個,第三個和第六個,直到檢測到迴圈已遍歷。在 rho 找到因子或報告失敗之前,迴圈可能會有數千個步驟長。如果指定了max_steps
,則在指定的步數後取消迭代並失敗。
示例
>>> from sympy import pollard_rho
>>> n=16843009
>>> F=lambda x:(2048*pow(x,2,n) + 32767) % n
>>> pollard_rho(n, F=F)
257
使用預設設定和糟糕的a
值和無重試:
>>> pollard_rho(n, a=n-2, retries=0)
如果重試> 0,則當為 a 生成新值時,問題可能會得到糾正:
>>> pollard_rho(n, a=n-2, retries=1)
257
參考
[R654]
Richard Crandall & Carl Pomerance(2005 年),《素數:計算視角》,Springer,第二版,229-231
sympy.ntheory.factor_.pollard_pm1(n, B=10, a=2, retries=0, seed=1234)
使用波拉德 p-1 方法嘗試提取n
的非平凡因子。返回一個除數(可能是複合數)或None
。
a
的值是在測試 gcd(a**M - 1, n) 中使用的基數。預設值為 2. 如果 retries
> 0,則在第一次嘗試未找到因子後,將隨機生成一個新的 a
(使用 seed
),並重復該過程。
注意:M 的值是 lcm(1..B) = reduce(ilcm, range(2, B + 1))。
尋找具有比 B
小的冪平滑度的偶數旁邊的因子。選擇更大的 B 增加找到較大因子的可能性,但需要更長時間。無論是否找到 n 的因子取決於 a
和略小於因子 p 的偶數的冪平滑度(因此稱為 p - 1)。
儘管有關什麼構成一個好的 a
的討論,有些描述很難解釋。在下面引用的模組化數學網站中指出,如果 gcd(aM - 1, n) = N,則對於 N 的每個素數冪除數,aM % q**r 等於 1。但請考慮以下情況:
>>> from sympy.ntheory.factor_ import smoothness_p, pollard_pm1
>>> n=257*1009
>>> smoothness_p(n)
(-1, [(257, (1, 2, 256)), (1009, (1, 7, 16))])
因此,我們應該(並且可以)找到一個具有 B=16 的根:
>>> pollard_pm1(n, B=16, a=3)
1009
如果我們嘗試將 B 增加到 256,我們發現它不起作用:
>>> pollard_pm1(n, B=256)
>>>
但是,如果 a
的值改變,我們發現只有 257 的倍數有效,例如:
>>> pollard_pm1(n, B=256, a=257)
1009
檢查不同的 a
值表明所有未能成功的值都具有不等於 n
而等於其中一個因子的 gcd 值:
>>> from sympy import ilcm, igcd, factorint, Pow
>>> M = 1
>>> for i in range(2, 256):
... M = ilcm(M, i)
...
>>> set([igcd(pow(a, M, n) - 1, n) for a in range(2, 256) if
... igcd(pow(a, M, n) - 1, n) != n])
{1009}
但是,對於 n 的每個除數,aM % d 是否都等於 1?
>>> aM = pow(255, M, n)
>>> [(d, aM%Pow(*d.args)) for d in factorint(n, visual=True).args]
[(257**1, 1), (1009**1, 1)]
不,只有其中一個。因此,也許原則是,在給定 B 值的情況下,可以找到一個根,只要:
-
p - 1 值旁邊的冪平滑度不超過 B
-
對於每個 n 的除數,a**M % p != 1。
透過嘗試多個 a
可能會有一個能夠產生一個因子。
例子
使用預設平滑界限,這個數字無法破解:
>>> from sympy.ntheory import pollard_pm1
>>> pollard_pm1(21477639576571)
增加平滑界限有助於:
>>> pollard_pm1(21477639576571, B=2000)
4410317
檢視該數字的因子的平滑度時,我們發現:
>>> from sympy.ntheory.factor_ import smoothness_p, factorint
>>> print(smoothness_p(21477639576571, visual=1))
p**i=4410317**1 has p-1 B=1787, B-pow=1787
p**i=4869863**1 has p-1 B=2434931, B-pow=2434931
p - 1 的因子化的除數的 B 和 B-pow 是相同的,因為這些因子化有一個非常大的素因子:
>>> factorint(4410317 - 1)
{2: 2, 617: 1, 1787: 1}
>>> factorint(4869863-1)
{2: 1, 2434931: 1}
注意,直到 B 達到 B-pow 值為 1787,該數字才能被破解;
>>> pollard_pm1(21477639576571, B=1786)
>>> pollard_pm1(21477639576571, B=1787)
4410317
B 值與除數旁邊的數字的因子有關,而不是除數本身。最壞的情況是,旁邊的數字 p 有一個大的素數除數或者是一個完美的冪。如果這些條件適用,則冪平滑度將約為 p/2 或 p。更現實的情況是,旁邊將有一個大的素數因子需要一個大約 p/2 的 B 值。儘管可能已經在這個級別搜尋了素數,但 p/2 是 p - 1 的一個因子,我們不知道。下面的模組化數學引用表示,在 1015 到 1515 + 104 範圍內的數的 15% 是 106 平滑的,因此在該範圍內 B=106 的失敗率為 85%。從 108 到 108 + 103,百分比幾乎顛倒了…但在該範圍內,簡單的試除法非常快。
參考文獻
[R655]
Richard Crandall & Carl Pomerance (2005), “Prime Numbers: A Computational Perspective”, Springer, 第二版, 236-238
[R656]
web.archive.org/web/20150716201437/http://modular.math.washington.edu/edu/2007/spring/ent/ent-html/node81.html
[R657]
www.cs.toronto.edu/~yuvalf/Factorization.pdf
sympy.ntheory.factor_.factorint(n, limit=None, use_trial=True, use_rho=True, use_pm1=True, use_ecm=True, verbose=False, visual=None, multiple=False)
給定正整數n
,factorint(n)
返回一個字典,其中包含n
的素因子作為鍵和它們的重數作為值。例如:
>>> from sympy.ntheory import factorint
>>> factorint(2000) # 2000 = (2**4) * (5**3)
{2: 4, 5: 3}
>>> factorint(65537) # This number is prime
{65537: 1}
對於小於 2 的輸入,factorint
的行為如下:
factorint(1)
返回空因式分解{}
factorint(0)
返回{0:1}
factorint(-n)
將-1:1
新增到因子中,然後因式分解n
部分因式分解:
如果指定了limit
(>3),則在執行試除法達到(包括)限制(或進行相應數量的 rho/p-1 步驟)後停止搜尋。如果有一個大數,並且只想找到小因子(如果有的話),這是很有用的。注意,設定限制並不阻止較大的因子提前被發現;它僅僅意味著最大因子可能是複合的。由於檢查完全冪的成本相對較低,因此無論限制設定如何,都會執行此檢查。
例如,此數字有兩個小因子和一個難以輕易分解的巨大半素數因子:
>>> from sympy.ntheory import isprime
>>> a = 1407633717262338957430697921446883
>>> f = factorint(a, limit=10000)
>>> f == {991: 1, int(202916782076162456022877024859): 1, 7: 1}
True
>>> isprime(max(f))
False
此數有一個小因子和一個基數大於限制的剩餘完全冪:
>>> factorint(3*101**7, limit=5)
{3: 1, 101: 7}
因子列表:
如果設定了multiple
為True
,則返回包含素因子及其重數的列表。
>>> factorint(24, multiple=True)
[2, 2, 2, 3]
視覺因式分解:
如果visual
設定為True
,則會返回整數的視覺因式分解。例如:
>>> from sympy import pprint
>>> pprint(factorint(4200, visual=True))
3 1 2 1
2 *3 *5 *7
注意,這是透過在 Mul 和 Pow 中使用 evaluate=False 標誌實現的。如果您對 evaluate=False 的表示式進行其他操作,它可能會計算。因此,如果您希望執行因式分解後的操作,請僅在視覺化時使用 visual 選項,並且在 visual=False 時使用正常的字典返回。
您可以透過將它們傳送回factorint
輕鬆地在這兩種形式之間切換。
>>> from sympy import Mul
>>> regular = factorint(1764); regular
{2: 2, 3: 2, 7: 2}
>>> pprint(factorint(regular))
2 2 2
2 *3 *7
>>> visual = factorint(1764, visual=True); pprint(visual)
2 2 2
2 *3 *7
>>> print(factorint(visual))
{2: 2, 3: 2, 7: 2}
如果您希望傳送一個部分因式分解形式的數字,可以使用字典或未評估的表示式進行傳送:
>>> factorint(factorint({4: 2, 12: 3})) # twice to toggle to dict form
{2: 10, 3: 3}
>>> factorint(Mul(4, 12, evaluate=False))
{2: 4, 3: 1}
輸出邏輯表格如下:
Input True --- --- dict mul n mul mul mul
注意事項
演算法:
該函式在多個演算法之間切換。試除法快速找到小因子(約 1-5 位數字的順序),如果給定足夠時間,它會找到所有大因子。波拉德·羅和 p-1 演算法用於提前找到大因子;它們通常在幾秒鐘內找到大約 10 位數字的因子:
>>> factors = factorint(12345678910111213141516)
>>> for base, exp in sorted(factors.items()):
... print('%s %s' % (base, exp))
...
2 2
2507191691 1
1231026625769 1
以上任何方法均可選擇性地使用以下布林引數禁用:
use_trial
:切換使用試除法use_rho
:切換使用波拉德·羅方法use_pm1
:切換使用 Pollard 的 p-1 方法
factorint
還定期檢查剩餘部分是否為質數或完全冪,並在這些情況下停止。
對於未評估的階乘,它使用 Legendre 的公式(定理)。
如果 verbose
設定為 True
,則會列印詳細進度。
另請參見
smoothness
, smoothness_p
, divisors
sympy.ntheory.factor_.factorrat(rat, limit=None, use_trial=True, use_rho=True, use_pm1=True, verbose=False, visual=None, multiple=False)
給定有理數 r
,factorrat(r)
返回一個包含 r
的質因子為鍵和它們相應重數為值的字典。例如:
>>> from sympy import factorrat, S
>>> factorrat(S(8)/9) # 8/9 = (2**3) * (3**-2)
{2: 3, 3: -2}
>>> factorrat(S(-1)/987) # -1/789 = -1 * (3**-1) * (7**-1) * (47**-1)
{-1: 1, 3: -1, 7: -1, 47: -1}
請參閱 factorint
的文件字串,瞭解以下關鍵字的詳細說明和示例:
limit
:執行試除的整數限制use_trial
:切換使用試除法use_rho
:切換使用 Pollard 的 rho 方法use_pm1
:切換使用 Pollard 的 p-1 方法verbose
:切換詳細列印進度multiple
:切換返回因子列表或字典visual
:切換輸出的乘積形式
sympy.ntheory.factor_.primefactors(n, limit=None, verbose=False, **kwargs)
返回 n 的質因子的排序列表,忽略重複性和任何如果限制太低而殘留的複合因子的完全因子分解。與 factorint()
不同,primefactors()
不返回-1 或 0。
引數:
n:整數
**limit, verbose, kwargs:
要傳遞給
factorint
的額外關鍵字引數。由於kwargs
是 1.13 版本中的新內容,因此保留limit
和verbose
以確保相容性。
返回:
list(int):整數 n 的質數列表
示例
>>> from sympy.ntheory import primefactors, factorint, isprime
>>> primefactors(6)
[2, 3]
>>> primefactors(-5)
[5]
>>> sorted(factorint(123456).items())
[(2, 6), (3, 1), (643, 1)]
>>> primefactors(123456)
[2, 3, 643]
>>> sorted(factorint(10000000001, limit=200).items())
[(101, 1), (99009901, 1)]
>>> isprime(99009901)
False
>>> primefactors(10000000001, limit=300)
[101]
另請參見
factorint
, divisors
sympy.ntheory.factor_.divisors(n, generator=False, proper=False)
預設情況下,返回從 1 到 n 排序的 n 的所有除數。如果 generator
設定為 True
,則返回一個無序生成器。
如果有許多質因子(計算重複因子),則 n 的除數數量可能會很大。如果只需要因子的數量,請使用 divisor_count(n)
。
示例
>>> from sympy import divisors, divisor_count
>>> divisors(24)
[1, 2, 3, 4, 6, 8, 12, 24]
>>> divisor_count(24)
8
>>> list(divisors(120, generator=True))
[1, 2, 4, 8, 3, 6, 12, 24, 5, 10, 20, 40, 15, 30, 60, 120]
註釋
這是稍作修改的 Tim Peters 版本,參考自:stackoverflow.com/questions/1010381/python-factorization
另請參見
primefactors
, factorint
, divisor_count
sympy.ntheory.factor_.proper_divisors(n, generator=False)
預設情況下,返回除 n 以外的 n 的所有除數。如果 generator
設定為 True
,則返回一個無序生成器。
示例
>>> from sympy import proper_divisors, proper_divisor_count
>>> proper_divisors(24)
[1, 2, 3, 4, 6, 8, 12]
>>> proper_divisor_count(24)
7
>>> list(proper_divisors(120, generator=True))
[1, 2, 4, 8, 3, 6, 12, 24, 5, 10, 20, 40, 15, 30, 60]
另請參見
factorint
, divisors
, proper_divisor_count
sympy.ntheory.factor_.divisor_count(n, modulus=1, proper=False)
返回 n
的除數的數量。如果 modulus
不為 1,則僅計算可被 modulus
整除的除數。如果 proper
為 True
,則 n
的除數將不被計算。
示例
>>> from sympy import divisor_count
>>> divisor_count(6)
4
>>> divisor_count(6, 2)
2
>>> divisor_count(6, proper=True)
3
另見
factorint
, divisors
, totient
, proper_divisor_count
sympy.ntheory.factor_.proper_divisor_count(n, modulus=1)
返回 n
的真除數的數量。
示例
>>> from sympy import proper_divisor_count
>>> proper_divisor_count(6)
3
>>> proper_divisor_count(6, modulus=2)
1
另見
divisors
, proper_divisors
, divisor_count
sympy.ntheory.factor_.udivisors(n, generator=False)
預設情況下,返回排序後的 n 的所有單位除數。如果 generator
為 True
,則返回一個無序生成器。
如果存在許多質因數,則 n
的單位除數數量可能非常大。如果只需單位除數的數量,請使用 udivisor_count(n)
。
示例
>>> from sympy.ntheory.factor_ import udivisors, udivisor_count
>>> udivisors(15)
[1, 3, 5, 15]
>>> udivisor_count(15)
4
>>> sorted(udivisors(120, generator=True))
[1, 3, 5, 8, 15, 24, 40, 120]
另見
primefactors
, factorint
, divisors
, divisor_count
, udivisor_count
參考文獻
[R658]
en.wikipedia.org/wiki/Unitary_divisor
[R659]
mathworld.wolfram.com/UnitaryDivisor.html
sympy.ntheory.factor_.udivisor_count(n)
返回 n
的單位除數的數量。
引數:
n:整數
示例
>>> from sympy.ntheory.factor_ import udivisor_count
>>> udivisor_count(120)
8
另見
factorint
, divisors
, udivisors
, divisor_count
, totient
參考文獻
[R660]
mathworld.wolfram.com/UnitaryDivisorFunction.html
sympy.ntheory.factor_.antidivisors(n, generator=False)
預設情況下,返回排序後的 n 的所有反除數。
n 的反除數[R661]是不以最大可能邊界除 n 的數。如果 generator 為 True,則返回無序生成器。
示例
>>> from sympy.ntheory.factor_ import antidivisors
>>> antidivisors(24)
[7, 16]
>>> sorted(antidivisors(128, generator=True))
[3, 5, 15, 17, 51, 85]
另見
primefactors
, factorint
, divisors
, divisor_count
, antidivisor_count
參考文獻
[R661] (1,2)
定義見oeis.org/A066272/a066272a.html
sympy.ntheory.factor_.antidivisor_count(n)
返回 n
的反除數數目[R662]。
引數:
n:整數
示例
>>> from sympy.ntheory.factor_ import antidivisor_count
>>> antidivisor_count(13)
4
>>> antidivisor_count(27)
5
另見
factorint
, divisors
, antidivisors
, divisor_count
, totient
參考文獻
[R662] (1,2)
公式來自oeis.org/A066272
sympy.ntheory.factor_.totient(n)
計算尤拉 totient 函式 phi(n)
自 1.13 版本起不推薦使用:totient
函式已被棄用。請使用sympy.functions.combinatorial.numbers.totient
。更多資訊請參見其文件。詳細資訊請參見將 ntheory 中的符號函式重定位到 functions。
totient(n)
或 (\phi(n)) 是小於等於 n 的與 n 互質的正整數的數量。
引數:
n:整數
示例
>>> from sympy.functions.combinatorial.numbers import totient
>>> totient(1)
1
>>> totient(25)
20
>>> totient(45) == totient(5)*totient(9)
True
另見
divisor_count
參考文獻
[R663]
en.wikipedia.org/wiki/Euler%27s_totient_function
[R664]
mathworld.wolfram.com/TotientFunction.html
sympy.ntheory.factor_.reduced_totient(n)
計算 Carmichael 減少的尤拉 totient 函式 lambda(n)
自 1.13 版本起不推薦使用:reduced_totient
函式已被棄用。請使用sympy.functions.combinatorial.numbers.reduced_totient
。更多資訊請參見其文件。詳細資訊請參見將 ntheory 中的符號函式重定位到 functions。
reduced_totient(n)
或 (\lambda(n)) 是最小的 m > 0,使得對於所有與 n 互質的 k,都有 (k^m \equiv 1 \mod n)。
示例
>>> from sympy.functions.combinatorial.numbers import reduced_totient
>>> reduced_totient(1)
1
>>> reduced_totient(8)
2
>>> reduced_totient(30)
4
另見
totient
參考
[R665]
en.wikipedia.org/wiki/Carmichael_function
[R666]
mathworld.wolfram.com/CarmichaelFunction.html
sympy.ntheory.factor_.divisor_sigma(n, k=1)
計算正整數 n 的除數函式 (\sigma_k(n))
自版本 1.13 起不推薦使用:函式divisor_sigma
已不推薦使用。請使用sympy.functions.combinatorial.numbers.divisor_sigma
。有關詳細資訊,請參閱其文件。有關詳細資訊,請參見將符號函式從 ntheory 移至函式。
divisor_sigma(n, k)
等於 sum([x**k for x in divisors(n)])
如果 n 的素因數分解為:
[n = \prod_{i=1}^\omega p_i^{m_i},]
則
[\sigma_k(n) = \prod_{i=1}^\omega (1+p_ik+p_i+\cdots + p_i^{m_ik}).]
引數:
n:整數
k:整數,可選
和的除數的冪
對於 k = 0, 1:
divisor_sigma(n, 0)
等於divisor_count(n)
,divisor_sigma(n, 1)
等於sum(divisors(n))
預設情況下,k 為 1。
示例
>>> from sympy.functions.combinatorial.numbers import divisor_sigma
>>> divisor_sigma(18, 0)
6
>>> divisor_sigma(39, 1)
56
>>> divisor_sigma(12, 2)
210
>>> divisor_sigma(37)
38
另見
divisor_count
,totient
,divisors
,factorint
參考
[R667]
en.wikipedia.org/wiki/Divisor_function
sympy.ntheory.factor_.udivisor_sigma(n, k=1)
計算正整數 n 的單位除數函式 (\sigma_k^*(n))
自版本 1.13 起不推薦使用:函式udivisor_sigma
已不推薦使用。請使用sympy.functions.combinatorial.numbers.udivisor_sigma
。有關詳細資訊,請參閱其文件。有關詳細資訊,請參見將符號函式從 ntheory 移至函式。
udivisor_sigma(n, k)
等於 sum([x**k for x in udivisors(n)])
如果 n 的素因數分解為:
[n = \prod_{i=1}^\omega p_i^{m_i},]
則
[\sigma_k^*(n) = \prod_{i=1}^\omega (1+ p_i^{m_ik}).]
引數:
k:和的除數的冪
對於 k = 0, 1:
udivisor_sigma(n, 0)
等於udivisor_count(n)
,udivisor_sigma(n, 1)
等於sum(udivisors(n))
預設情況下,k 為 1。
示例
>>> from sympy.functions.combinatorial.numbers import udivisor_sigma
>>> udivisor_sigma(18, 0)
4
>>> udivisor_sigma(74, 1)
114
>>> udivisor_sigma(36, 3)
47450
>>> udivisor_sigma(111)
152
另見
divisor_count
, totient
, divisors
, udivisors
, udivisor_count
, divisor_sigma
, factorint
參考
[R668]
mathworld.wolfram.com/UnitaryDivisorFunction.html
sympy.ntheory.factor_.core(n, t=2)
計算正整數 n 的core_t(n)
= core(n, t)
core_2(n)
等於 n 的無平方數部分
如果 n 的質因數分解為:
[n = \prod_{i=1}^\omega p_i^{m_i},]
則
[core_t(n) = \prod_{i=1}^\omega p_i^{m_i \mod t}.]
引數:
n:整數
t:整數
core(n, t)
計算 n 的第 t 個無冪次方部分
core(n, 2)
是 n 的無平方數部分,core(n, 3)
是 n 的無立方數部分t 的預設值為 2。
例子
>>> from sympy.ntheory.factor_ import core
>>> core(24, 2)
6
>>> core(9424, 3)
1178
>>> core(379238)
379238
>>> core(15**11, 10)
15
參見
factorint
, sympy.solvers.diophantine.diophantine.square_factor
參考
[R669]
en.wikipedia.org/wiki/Square-free_integer#Squarefree_core
sympy.ntheory.factor_.digits(n, b=10, digits=None)
返回 n 在 b 進位制下的數字列表。列表中的第一個元素是 b(如果 n 為負,則為-b)。
引數:
n:整數
要返回其數字的數字。
b:整數
計算數字的基數。
digits:整數(或所有數字為 None)
要返回的數字位數(如有必要,用零填充)。
例子
>>> from sympy.ntheory.digits import digits
>>> digits(35)
[10, 3, 5]
如果數字為負,則負號將放置在基數上(即返回列表中的第一個元素):
>>> digits(-35)
[-10, 3, 5]
可以選擇除 10 以外(且大於 1)的基數b
:
>>> digits(27, b=2)
[2, 1, 1, 0, 1, 1]
如果需要確定特定位數的數字,請使用digits
關鍵字:
>>> digits(35, digits=4)
[10, 0, 0, 3, 5]
參見
sympy.core.intfunc.num_digits
, count_digits
sympy.ntheory.factor_.primenu(n)
計算正整數 n 的不同質因子的數量。
自版本 1.13 起已棄用:primenu
函式已棄用。請使用sympy.functions.combinatorial.numbers.primenu
。有關詳細資訊,請參見其文件。有關詳細資訊,請參閱從 ntheory 移動符號函式到函式。
如果 n 的素因數分解是:
[n = \prod_{i=1}^k p_i^{m_i},]
如果 primenu(n)
或者 (\nu(n)) 是:
[\nu(n) = k.]
例子
>>> from sympy.functions.combinatorial.numbers import primenu
>>> primenu(1)
0
>>> primenu(30)
3
參見
factorint
參考文獻
[R670]
mathworld.wolfram.com/PrimeFactor.html
sympy.ntheory.factor_.primeomega(n)
計算一個正整數 n 的素因數的個數(包括重數)。
自版本 1.13 起已棄用:primeomega
函式已棄用。使用 sympy.functions.combinatorial.numbers.primeomega
替代。更多資訊請參見其文件。詳情請見 將符號函式從 ntheory 移至 functions。
如果 n 的素因數分解是:
[n = \prod_{i=1}^k p_i^{m_i},]
如果 primeomega(n)
或者 (\Omega(n)) 是:
[\Omega(n) = \sum_{i=1}^k m_i.]
例子
>>> from sympy.functions.combinatorial.numbers import primeomega
>>> primeomega(1)
0
>>> primeomega(20)
3
參見
factorint
參考文獻
[R671]
mathworld.wolfram.com/PrimeFactor.html
sympy.ntheory.factor_.mersenne_prime_exponent(nth)
返回第 n 個 Mersenne prime 的指數 i
(形式為 (2^i - 1))。
例子
>>> from sympy.ntheory.factor_ import mersenne_prime_exponent
>>> mersenne_prime_exponent(1)
2
>>> mersenne_prime_exponent(20)
4423
sympy.ntheory.factor_.is_perfect(n)
返回 True 如果 n
是一個 perfect number,否則返回 False。
一個 perfect number 等於其正的真因數之和。
例子
>>> from sympy.functions.combinatorial.numbers import divisor_sigma
>>> from sympy.ntheory.factor_ import is_perfect, divisors
>>> is_perfect(20)
False
>>> is_perfect(6)
True
>>> 6 == divisor_sigma(6) - 6 == sum(divisors(6)[:-1])
True
參考文獻
[R672]
mathworld.wolfram.com/PerfectNumber.html
[R673]
en.wikipedia.org/wiki/Perfect_number
sympy.ntheory.factor_.abundance(n)
返回一個數的正因數之和與該數之差。
例子
>>> from sympy.ntheory import abundance, is_perfect, is_abundant
>>> abundance(6)
0
>>> is_perfect(6)
True
>>> abundance(10)
-2
>>> is_abundant(10)
False
sympy.ntheory.factor_.is_abundant(n)
返回 True 如果 n
是一個 abundant number,否則返回 False。
一個 abundant number 是小於其正因數之和的數。
例子
>>> from sympy.ntheory.factor_ import is_abundant
>>> is_abundant(20)
True
>>> is_abundant(15)
False
參考文獻
[R674]
mathworld.wolfram.com/AbundantNumber.html
sympy.ntheory.factor_.is_deficient(n)
返回 True 如果 n
是一個 deficient number,否則返回 False。
一個 deficient number 是大於其正因數之和的數。
例子
>>> from sympy.ntheory.factor_ import is_deficient
>>> is_deficient(20)
False
>>> is_deficient(15)
True
參考文獻
[R675]
mathworld.wolfram.com/DeficientNumber.html
sympy.ntheory.factor_.is_amicable(m, n)
返回 True 如果數字 (m) 和 (n) 是“amicable”,否則返回 False。
Amicable numbers 是兩個不同的相關數,其各自的真因數之和相等。
例子
>>> from sympy.functions.combinatorial.numbers import divisor_sigma
>>> from sympy.ntheory.factor_ import is_amicable
>>> is_amicable(220, 284)
True
>>> divisor_sigma(220) == divisor_sigma(284)
True
參考文獻
[R676]
en.wikipedia.org/wiki/Amicable_numbers
sympy.ntheory.factor_.is_carmichael(n)
返回 True 如果數字 (n) 是 Carmichael number,否則返回 False。
引數:
n : 整數
參考文獻
[R677]
en.wikipedia.org/wiki/Carmichael_number
[R678]
oeis.org/A002997
sympy.ntheory.factor_.find_carmichael_numbers_in_range(x, y)
返回在範圍內的 Carmichael 數的列表。
另請參閱
is_carmichael
sympy.ntheory.factor_.find_first_n_carmichaels(n)
返回前 n
個 Carmichael 數。
引數:
n:整數
另請參閱
is_carmichael
sympy.ntheory.modular.symmetric_residue(a, m)
返回模 m
內的剩餘部分,使其在模的一半範圍內。
>>> from sympy.ntheory.modular import symmetric_residue
>>> symmetric_residue(1, 6)
1
>>> symmetric_residue(4, 6)
-2
sympy.ntheory.modular.crt(m, v, symmetric=False, check=True)
中國剩餘定理。
在 m
中的模數被假設為兩兩互質。然後輸出是一個整數 f
,使得對於 v
和 m
中的每對,都有 f = v_i mod m_i
。如果 symmetric
為 False,則返回一個正整數,否則 |f| 小於或等於模數的 LCM,因此 f
可能為負數。
如果模數不互質,則在發現結果不正確時將返回正確結果。如果沒有解決方案,則結果將為 None
。
如果已知模數是互質的,則可以將關鍵字 check
設定為 False。
示例
例如,考慮一組剩餘 U = [49, 76, 65]
和一組模數 M = [99, 97, 95]
。那麼我們有:
>>> from sympy.ntheory.modular import crt
>>> crt([99, 97, 95], [49, 76, 65])
(639985, 912285)
這是正確的結果,因為:
>>> [639985 % m for m in [99, 97, 95]]
[49, 76, 65]
如果模數不互質,如果使用 check=False
,則可能會得到不正確的結果:
>>> crt([12, 6, 17], [3, 4, 2], check=False)
(954, 1224)
>>> [954 % m for m in [12, 6, 17]]
[6, 0, 2]
>>> crt([12, 6, 17], [3, 4, 2]) is None
True
>>> crt([3, 6], [2, 5])
(5, 6)
注意:相對於 crt
,gf_crt
的引數順序被顛倒了,solve_congruence
接受剩餘,模數對。
程式設計師注意:與檢查所有模數對不共享 GCD(O(n**2) 測試)或者分解所有模數然後看是否有共同因子的方法不同,這裡執行的操作是檢查結果是否給出了指定的剩餘部分 - 這是一個 O(n) 操作。
另請參閱
solve_congruence
sympy.polys.galoistools.gf_crt
低階 Chinese Remainder Theorem 執行在這個例程中使用。
sympy.ntheory.modular.crt1(m)
多個應用的 Chinese Remainder Theorem 的第一部分。
示例
>>> from sympy.ntheory.modular import crt, crt1, crt2
>>> m = [99, 97, 95]
>>> v = [49, 76, 65]
以下兩個程式碼具有相同的結果。
>>> crt(m, v)
(639985, 912285)
>>> mm, e, s = crt1(m)
>>> crt2(m, v, mm, e, s)
(639985, 912285)
但是,當我們希望固定 m
並計算多個 v
時,速度更快,即以下情況:
>>> mm, e, s = crt1(m)
>>> vs = [[52, 21, 37], [19, 46, 76]]
>>> for v in vs:
... print(crt2(m, v, mm, e, s))
(397042, 912285)
(803206, 912285)
另請參閱
sympy.polys.galoistools.gf_crt1
低階 Chinese Remainder Theorem 執行在這個例程中使用。
sympy.ntheory.modular.crt
, sympy.ntheory.modular.crt2
sympy.ntheory.modular.crt2(m, v, mm, e, s, symmetric=False)
多個應用的 Chinese Remainder Theorem 的第二部分。
參見 crt1
以獲取用法。
示例
>>> from sympy.ntheory.modular import crt1, crt2
>>> mm, e, s = crt1([18, 42, 6])
>>> crt2([18, 42, 6], [0, 0, 0], mm, e, s)
(0, 4536)
另請參閱
sympy.polys.galoistools.gf_crt2
低階 Chinese Remainder Theorem 執行在這個例程中使用。
sympy.ntheory.modular.crt
, sympy.ntheory.modular.crt1
sympy.ntheory.modular.solve_congruence(*remainder_modulus_pairs, **hint)
計算整數n
,當它被分別除以mi
時,餘數為ai
,其中ai
和mi
作為此函式的一對給定:((a1, m1), (a2, m2), ...)。如果沒有解決方案,則返回 None。否則返回n
及其模數。
mi
值不需要互質。如果已知模數不互質,則可以將提示check
設定為 False(預設為 True),並且將跳過透過 crt()(在模數互質時有效)尋找更快解決方案的檢查。
如果提示symmetric
為 True(預設為 False),則n
的值將在模數的 1/2 範圍內,可能為負。
示例
>>> from sympy.ntheory.modular import solve_congruence
數字是 2 模 3、3 模 5 和 2 模 7 的數字?
>>> solve_congruence((2, 3), (3, 5), (2, 7))
(23, 105)
>>> [23 % m for m in [3, 5, 7]]
[2, 3, 2]
如果您更喜歡將所有餘數放在一個列表中,將所有模數放在另一個列表中,則可以像這樣傳送引數:
>>> solve_congruence(*zip((2, 3, 2), (3, 5, 7)))
(23, 105)
模數不需要互質;在這種情況下可能存在或不存在解決方案:
>>> solve_congruence((2, 3), (4, 6)) is None
True
>>> solve_congruence((2, 3), (5, 6))
(5, 6)
對稱標誌將使結果在模數的 1/2 範圍內:
>>> solve_congruence((2, 3), (5, 6), symmetric=True)
(-1, 6)
另請參閱
crt
實現中國餘數定理的高階程式
sympy.ntheory.multinomial.binomial_coefficients(n)
返回包含對{(k1,k2) : C_kn}
的字典,其中C_kn
為二項式係數且n=k1+k2
。
示例
>>> from sympy.ntheory import binomial_coefficients
>>> binomial_coefficients(9)
{(0, 9): 1, (1, 8): 9, (2, 7): 36, (3, 6): 84,
(4, 5): 126, (5, 4): 126, (6, 3): 84, (7, 2): 36, (8, 1): 9, (9, 0): 1}
另請參閱
二項式係數列表
,多項式係數
sympy.ntheory.multinomial.binomial_coefficients_list(n)
返回帕斯卡三角形的行作為二項式係數的列表。
示例
>>> from sympy.ntheory import binomial_coefficients_list
>>> binomial_coefficients_list(9)
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
另請參閱
二項式係數
,多項式係數
sympy.ntheory.multinomial.multinomial_coefficients(m, n)
返回包含對{(k1,k2,..,km) : C_kn}
的字典,其中C_kn
為多項式係數,使得n=k1+k2+..+km
。
示例
>>> from sympy.ntheory import multinomial_coefficients
>>> multinomial_coefficients(2, 5) # indirect doctest
{(0, 5): 1, (1, 4): 5, (2, 3): 10, (3, 2): 10, (4, 1): 5, (5, 0): 1}
註釋
該演算法基於以下結果:
[\binom{n}{k_1, \ldots, k_m} = \frac{k_1 + 1}{n - k_1} \sum_{i=2}^m \binom{n}{k_1 + 1, \ldots, k_i - 1, \ldots}]
由 Yann Laigle-Chapuy 貢獻的程式碼,經作者許可複製。
另請參閱
二項式係數列表
,二項式係數
sympy.ntheory.multinomial.multinomial_coefficients_iterator(m, n, _tuple=<class 'tuple'>)
多項式係數迭代器
透過利用從multinomial_coefficients(n, n)
獲取的單項式元組t
去除零時的係數與後者的係數相同,因此,後者的係數預先計算以節省記憶體和時間。
>>> from sympy.ntheory.multinomial import multinomial_coefficients
>>> m53, m33 = multinomial_coefficients(5,3), multinomial_coefficients(3,3)
>>> m53[(0,0,0,1,2)] == m53[(0,0,1,0,2)] == m53[(1,0,2,0,0)] == m33[(0,1,2)]
True
示例
>>> from sympy.ntheory.multinomial import multinomial_coefficients_iterator
>>> it = multinomial_coefficients_iterator(20,3)
>>> next(it)
((3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), 1)
sympy.ntheory.partitions_.npartitions(n, verbose=False)
計算分割函式 P(n),即將 n 寫為正整數和的方式數。
自版本 1.13 起棄用:npartitions
函式已棄用。請使用 sympy.functions.combinatorial.numbers.partition
。有關更多資訊,請參閱其文件。詳細資訊請參見 將符號函式從 ntheory 移至 functions。
使用 Hardy-Ramanujan-Rademacher 公式計算 P(n) [R679]。
該實現的正確性已透過 (10^{10}) 的測試。
示例
>>> from sympy.functions.combinatorial.numbers import partition
>>> partition(25)
1958
參考文獻
[R679] (1,2)
mathworld.wolfram.com/PartitionFunctionP.html
sympy.ntheory.primetest.is_fermat_pseudoprime(n, a)
如果 n
是素數或是與 a
互質且滿足模算術同餘關係的奇合數,則返回 True:
[a^{n-1} \equiv 1 \pmod{n}]
(其中 mod 指的是模運算)。
引數:
n:整數
n
是正整數。
a:整數
a
是正整數。a
和n
應該互質。
返回:
bool:如果 n
是素數,則總是返回 True
。
返回稱為 Fermat 偽素數的合數。
示例
>>> from sympy.ntheory.primetest import is_fermat_pseudoprime
>>> from sympy.ntheory.factor_ import isprime
>>> for n in range(1, 1000):
... if is_fermat_pseudoprime(n, 2) and not isprime(n):
... print(n)
341
561
645
參考文獻
[R680]
en.wikipedia.org/wiki/Fermat_pseudoprime
sympy.ntheory.primetest.is_euler_pseudoprime(n, a)
如果 n
是素數或是與 a
互質且滿足模算術同餘關係的奇合數,則返回 True:
[a^{(n-1)/2} \equiv \pm 1 \pmod{n}]
(其中 mod 指的是模運算)。
引數:
n:整數
n
是正整數。
a:整數
a
是正整數。a
和n
應該互質。
返回:
bool:如果 n
是素數,則總是返回 True
。
返回稱為 Euler 偽素數的合數。
示例
>>> from sympy.ntheory.primetest import is_euler_pseudoprime
>>> from sympy.ntheory.factor_ import isprime
>>> for n in range(1, 1000):
... if is_euler_pseudoprime(n, 2) and not isprime(n):
... print(n)
341
561
參考文獻
[R681]
en.wikipedia.org/wiki/Euler_pseudoprime
sympy.ntheory.primetest.is_euler_jacobi_pseudoprime(n, a)
如果 n
是素數或是與 a
互質且滿足模算術同餘關係的奇合數,則返回 True:
[a^{(n-1)/2} \equiv \left(\frac{a}{n}\right) \pmod{n}]
(其中 mod 指的是模運算)。
引數:
n:整數
n
是正整數。
a:整數
a
是正整數。a
和n
應該互質。
返回:
bool:如果 n
是素數,則總是返回 True
。
返回稱為 Euler-Jacobi 偽素數的合數。
示例
>>> from sympy.ntheory.primetest import is_euler_jacobi_pseudoprime
>>> from sympy.ntheory.factor_ import isprime
>>> for n in range(1, 1000):
... if is_euler_jacobi_pseudoprime(n, 2) and not isprime(n):
... print(n)
561
參考文獻
[R682]
en.wikipedia.org/wiki/Euler%E2%80%93Jacobi_pseudoprime
sympy.ntheory.primetest.is_square(n, prep=True)
如果 n == a * a 則返回 True,否則返回 False。如果懷疑 n 不 是一個平方數,則這是確認其不是的快速方法。
示例
>>> from sympy.ntheory.primetest import is_square
>>> is_square(25)
True
>>> is_square(2)
False
另請參閱
sympy.core.intfunc.isqrt
參考文獻
[R683]
mersenneforum.org/showpost.php?p=110896
sympy.ntheory.primetest.mr(n, bases)
對 n 執行 Miller-Rabin 強偽素數測試,使用給定的基數/見證者列表。
示例
>>> from sympy.ntheory.primetest import mr
>>> mr(1373651, [2, 3])
False
>>> mr(479001599, [31, 73])
True
References
[R684]
Richard Crandall & Carl Pomerance (2005), “Prime Numbers: A Computational Perspective”, Springer, 2nd edition, 135-138
一個閾值列表及其所需的基數見這裡:zh.wikipedia.org/wiki/Miller%E2%80%93Rabin%E8%B4%A8%E6%80%A7%E6%80%A7%E6%A3%80%E6%B5%8B#確定性變體
sympy.ntheory.primetest.is_lucas_prp(n)
標準 Lucas 複合性測試,使用 Selfridge 引數。如果 n 明確是複合數,則返回 False;如果 n 是 Lucas 可能質數,則返回 True。
這通常與米勒-拉賓測試結合使用。
示例
>>> from sympy.ntheory.primetest import isprime, is_lucas_prp
>>> for i in range(10000):
... if is_lucas_prp(i) and not isprime(i):
... print(i)
323
377
1159
1829
3827
5459
5777
9071
9179
References
[R685]
Robert Baillie, Samuel S. Wagstaff, Lucas Pseudoprimes, Math. Comp. Vol 35, Number 152 (1980), pp. 1391-1417, doi.org/10.1090%2FS0025-5718-1980-0583518-6
mpqs.free.fr/LucasPseudoprimes.pdf
[R686]
OEIS A217120: Lucas 偽素數 oeis.org/A217120
[R687]
zh.wikipedia.org/wiki/%E8%8E%B1%E5%8D%A1%E6%96%AF%E8%99%9A%E7%B4%A0%E5%88%86%E6%9E%90
sympy.ntheory.primetest.is_strong_lucas_prp(n)
強 Lucas 複合性測試,使用 Selfridge 引數。如果 n 明確是複合數,則返回 False;如果 n 是強 Lucas 可能質數,則返回 True。
這通常與米勒-拉賓測試結合使用,特別是與 M-R 基數 2 結合建立強 BPSW 測試時。
示例
>>> from sympy.ntheory.primetest import isprime, is_strong_lucas_prp
>>> for i in range(20000):
... if is_strong_lucas_prp(i) and not isprime(i):
... print(i)
5459
5777
10877
16109
18971
References
[R688]
Robert Baillie, Samuel S. Wagstaff, Lucas Pseudoprimes, Math. Comp. Vol 35, Number 152 (1980), pp. 1391-1417, doi.org/10.1090%2FS0025-5718-1980-0583518-6
mpqs.free.fr/LucasPseudoprimes.pdf
[R689]
OEIS A217255: 強 Lucas 偽素數 oeis.org/A217255
[R690]
zh.wikipedia.org/wiki/%E8%8E%B1%E5%8D%A1%E6%96%AF%E8%99%9A%E7%B4%A0%E5%88%86%E6%9E%90
[R691]
zh.wikipedia.org/wiki/Baillie-PSW%E8%B4%A8%E6%95%B0%E6%B5%8B%E8%AF%95
sympy.ntheory.primetest.is_extra_strong_lucas_prp(n)
額外強 Lucas 複合性測試。如果 n 明確是複合數,則返回 False;如果 n 是“額外強” Lucas 可能質數,則返回 True。
使用 P = 3,Q = 1 選擇引數,然後遞增 P 直到 (D|n) == -1. 測試本身如 [R692] 中所定義,出自 Mo 和 Jones 的預印本。引數選擇和測試與 OEIS A217719、Perl 的 Math::Prime::Util 以及維基百科上的 Lucas 偽素數頁面相同。
它比強測試快 20-50%。
由於選擇了不同的引數,強 Lucas 偽素數和額外強 Lucas 偽素數之間沒有關係。特別地,一個不是另一個的子集。
示例
>>> from sympy.ntheory.primetest import isprime, is_extra_strong_lucas_prp
>>> for i in range(20000):
... if is_extra_strong_lucas_prp(i) and not isprime(i):
... print(i)
989
3239
5777
10877
參考文獻
[R692] (1,2)
Jon Grantham,Frobenius 偽素數,Math. Comp. Vol 70, Number 234 (2001),pp. 873-891,doi.org/10.1090%2FS0025-5718-00-01197-2
[R693]
OEIS A217719:額外強 Lucas 偽素數 oeis.org/A217719
[R694]
[zh.wikipedia.org/wiki/Lucas 偽素數
](https://zh.wikipedia.org/wiki/Lucas 偽素數)
sympy.ntheory.primetest.proth_test(n)
測試 Proth 數(n = k2^m + 1)是否為素數,其中 k 是正奇數且(2^m > k)。
引數:
n:整數
n
是 Proth 數
返回:
bool:如果為True
,則n
是 Proth 素數
丟擲異常:
數值錯誤
如果
n
不是 Proth 數。
示例
>>> from sympy.ntheory.primetest import proth_test
>>> proth_test(41)
True
>>> proth_test(57)
False
參考文獻
[R695]
[zh.wikipedia.org/wiki/Proth 素數
](https://zh.wikipedia.org/wiki/Proth 素數)
sympy.ntheory.primetest.is_mersenne_prime(n)
如果n
是梅森素數則返回 True,否則返回 False。
梅森素數是形如(2^i - 1)的素數。
示例
>>> from sympy.ntheory.factor_ import is_mersenne_prime
>>> is_mersenne_prime(6)
False
>>> is_mersenne_prime(127)
True
參考文獻
[R696]
mathworld.wolfram.com/MersennePrime.html
sympy.ntheory.primetest.isprime(n)
測試 n 是否為素數(True)或不是素數(False)。對於 n < 2⁶⁴,答案是確定的;較大的 n 值可能實際上是偽素數。
負數(例如 -2)不被認為是素數。
第一步是尋找顯著因子,如果找到則可以快速返回。接下來,如果篩選器足夠大,則在篩選器上使用二分搜尋。對於小數字,使用已知在其範圍內沒有反例的基數進行確定性 Miller-Rabin 測試。最後,如果數字大於 2⁶⁴,則執行強 BPSW 測試。雖然這是一個可能的素數測試,我們相信存在反例,但目前沒有已知的反例。
示例
>>> from sympy.ntheory import isprime
>>> isprime(13)
True
>>> isprime(15)
False
注意
此程式僅適用於整數輸入,不適用於可能代表數字的數值表示式。浮點數也會被拒絕,因為它們代表有限精度的數字。雖然允許 7.0 表示整數很誘人,但如果允許這樣做可能會“悄悄地”傳遞錯誤:
>>> from sympy import Float, S
>>> int(1e3) == 1e3 == 10**3
True
>>> int(1e23) == 1e23
True
>>> int(1e23) == 10**23
False
>>> near_int = 1 + S(1)/10**19
>>> near_int == int(near_int)
False
>>> n = Float(near_int, 10) # truncated by precision
>>> n % 1 == 0
True
>>> n = Float(near_int, 20)
>>> n % 1 == 0
False
參見
sympy.ntheory.generate.primerange
在給定範圍內生成所有素數
sympy.functions.combinatorial.numbers.primepi
返回小於或等於 n 的素數數量
sympy.ntheory.generate.prime
返回第 n 個素數
參考文獻
[R697]
zh.wikipedia.org/wiki/強偽素數
[R698]
Robert Baillie, Samuel S. Wagstaff, Lucas Pseudoprimes, Math. Comp. Vol 35, Number 152 (1980), pp. 1391-1417, doi.org/10.1090%2FS0025-5718-1980-0583518-6
mpqs.free.fr/LucasPseudoprimes.pdf
[R699]
en.wikipedia.org/wiki/Baillie-PSW_primality_test
sympy.ntheory.primetest.is_gaussian_prime(num)
測試 num 是否為高斯素數。
參考文獻
[R700]
oeis.org/wiki/Gaussian_primes
sympy.ntheory.residue_ntheory.n_order(a, n)
返回 a
模 n
的階數。
引數:
a:整數
n:整數,n > 1。a
和 n
應該是相對素的。
返回:
整數:a
模 n
的階數
引發:
數值錯誤
如果 (n \le 1) 或 (\gcd(a, n) \neq 1)。如果
a
或n
不是整數。
解釋
a
模 n
的階數是最小的整數 k
,使得 (a^k) 在 n
上留下餘數。
示例
>>> from sympy.ntheory import n_order
>>> n_order(3, 7)
6
>>> n_order(4, 7)
3
另請參閱
is_primitive_root
當 a
模 n
的階數等於 totient(n)
時,我們說 a
是 n
的原根。
sympy.ntheory.residue_ntheory.is_primitive_root(a, p)
如果 a
是 p
的原根,則返回 True。
引數:
a:整數
p:整數,p
> 1。a
和 p
應該是相對素的。
返回:
布林:如果為 True,則 a
是 p
的原根。
引發:
數值錯誤
如果 (p \le 1) 或 (\gcd(a, p) \neq 1)。如果
a
或p
不是整數。
解釋
如果 (\gcd(a, p) = 1) 並且 (\phi(p)) 是最小的正數,a
被稱為 p
的原根。
(a^{\phi(p)} \equiv 1 \pmod{p})。
其中 (\phi(p)) 是尤拉函式。
只有對於 (p = 2, 4, q^e, 2q^e)(q
是奇素數),p
的原根才存在。因此,如果不是這樣的 p
,則返回 False。要確定原根,我們需要知道 q-1
的素因子分解。這種確定的難度取決於這種複雜性。
示例
>>> from sympy.functions.combinatorial.numbers import totient
>>> from sympy.ntheory import is_primitive_root, n_order
>>> is_primitive_root(3, 10)
True
>>> is_primitive_root(9, 10)
False
>>> n_order(3, 10) == totient(10)
True
>>> n_order(9, 10) == totient(10)
False
另請參閱
primitive_root
sympy.ntheory.residue_ntheory.primitive_root(p, smallest=True)
返回 p
的一個原根或 None。
引數:
p:整數,p > 1
最小:如果為 True,則返回最小的原根,否則返回 None。
返回:
int | None:
如果存在原根,則返回
p
的原根。否則,返回 None。
引發:
數值錯誤
如果 (p \le 1) 或
p
不是整數。
解釋
有關原根定義,請參閱 is_primitive_root
的解釋。
對於p
的原始根僅適用於(p = 2, 4, q^e, 2qe)(`q`是奇質數)。現在,如果我們知道`q`的原始根,我們可以計算(qe)的原始根,如果我們知道(qe)的原始根,我們可以計算(2qe)的原始根。當不需要找到最小的原始根時,這個性質可以用來獲取快速的原始根。另一方面,當我們想要最小的原始根時,我們會天真地確定是否是原始根。
示例
>>> from sympy.ntheory.residue_ntheory import primitive_root
>>> primitive_root(19)
2
>>> primitive_root(21) is None
True
>>> primitive_root(50, smallest=False)
27
另請參閱
is_primitive_root
引用
[R701]
- Stein“初等數論”(2011 年),第 44 頁
[R702]
- Hackman“初等數論”(2009 年),第 C 章
sympy.ntheory.residue_ntheory.sqrt_mod(a, p, all_roots=False)
查詢x**2 = a mod p
的根。
引數:
a :整數
p :正整數
all_roots :如果為 True 則返回根列表或 None
注:
如果沒有根則返回 None;否則返回的根小於或等於p // 2
;一般來說不是最小的。僅當它是唯一的根時返回p // 2
。
僅在預期所有根都適合記憶體時使用all_roots
;否則使用sqrt_mod_iter
。
示例
>>> from sympy.ntheory import sqrt_mod
>>> sqrt_mod(11, 43)
21
>>> sqrt_mod(17, 32, True)
[7, 9, 23, 25]
sympy.ntheory.residue_ntheory.sqrt_mod_iter(a, p, domain=<class 'int'>)
迭代解決x**2 = a mod p
。
引數:
a :整數
p :正整數
domain :整數域,int
,ZZ
或 Integer
示例
>>> from sympy.ntheory.residue_ntheory import sqrt_mod_iter
>>> list(sqrt_mod_iter(11, 43))
[21, 22]
另請參閱
sqrt_mod
具有相同功能,但要求排序列表或僅有一個解。
sympy.ntheory.residue_ntheory.quadratic_residues(p) → list[int]
返回二次剩餘的列表。
示例
>>> from sympy.ntheory.residue_ntheory import quadratic_residues
>>> quadratic_residues(7)
[0, 1, 2, 4]
sympy.ntheory.residue_ntheory.nthroot_mod(a, n, p, all_roots=False)
找到x**n = a mod p
的解決方案。
引數:
a :整數
n :正整數
p :正整數
all_roots :如果為 False,則返回最小的根,否則返回根列表
返回:
list[int] | int | None:
解決
x**n = a mod p
。輸出型別表如下:
all_roots has roots Returns True Yes list[int] True No [] False Yes int False No None
引發:
ValueError
如果
a
,n
或p
不是整數。如果n
或p
不是正數。
示例
>>> from sympy.ntheory.residue_ntheory import nthroot_mod
>>> nthroot_mod(11, 4, 19)
8
>>> nthroot_mod(11, 4, 19, True)
[8, 11]
>>> nthroot_mod(68, 3, 109)
23
引用
[R703]
- Hackman“初等數論”(2009 年),第 76 頁
sympy.ntheory.residue_ntheory.is_nthpow_residue(a, n, m)
如果x**n == a (mod m)
有解則返回 True。
引用
[R704]
- Hackman“初等數論”(2009 年),第 76 頁
sympy.ntheory.residue_ntheory.is_quad_residue(a, p)
如果a
(mod p
)在p
的平方集中,則返回 True,即 a % p 在 set([i**2 % p for i in range(p)])中。
引數:
a :整數
p :正整數
返回:
bool :如果為 True,則x**2 == a (mod p)
有解。
引發:
ValueError
如果
a
,p
不是整數。如果p
不是正數。
示例
>>> from sympy.ntheory import is_quad_residue
>>> is_quad_residue(21, 100)
True
實際上,pow(39, 2, 100)
將是 21。
>>> is_quad_residue(21, 120)
False
即,對於任何整數x
,pow(x, 2, 120)
不是 21。
如果p
是奇質數,則使用迭代方法進行確定:
>>> from sympy.ntheory import is_quad_residue
>>> sorted(set([i**2 % 7 for i in range(7)]))
[0, 1, 2, 4]
>>> [j for j in range(7) if is_quad_residue(j, 7)]
[0, 1, 2, 4]
另請參閱
legendre_symbol
, jacobi_symbol
, sqrt_mod
sympy.ntheory.residue_ntheory.legendre_symbol(a, p)
返回勒讓德符號 ((a / p))。
自版本 1.13 起已棄用:legendre_symbol
函式已棄用。請使用 sympy.functions.combinatorial.numbers.legendre_symbol
替代。更多資訊請參閱其文件。參見 將符號函式從 ntheory 遷移到 functions 以獲取詳細資訊。
對於整數 a
和奇素數 p
,勒讓德符號定義為
[\begin{split}\genfrac(){}{}{a}{p} = \begin{cases} 0 & \text{如果 } p \text{ 整除 } a\ 1 & \text{如果 } a \text{ 是模 } p \text{ 的二次剩餘}\ -1 & \text{如果 } a \text{ 是模 } p \text{ 的二次非剩餘} \end{cases}\end{split}]
引數:
a : 整數
p : 奇素數
示例
>>> from sympy.functions.combinatorial.numbers import legendre_symbol
>>> [legendre_symbol(i, 7) for i in range(7)]
[0, 1, 1, -1, 1, -1, -1]
>>> sorted(set([i**2 % 7 for i in range(7)]))
[0, 1, 2, 4]
參見
is_quad_residue
, jacobi_symbol
sympy.ntheory.residue_ntheory.jacobi_symbol(m, n)
返回雅可比符號 ((m / n))。
自版本 1.13 起已棄用:jacobi_symbol
函式已棄用。請使用 sympy.functions.combinatorial.numbers.jacobi_symbol
替代。更多資訊請參閱其文件。參見 將符號函式從 ntheory 遷移到 functions 以獲取詳細資訊。
對於任意整數 m
和任意正奇整數 n
,雅可比符號定義為 n
的素因子對應的勒讓德符號的乘積:
[\genfrac(){}{}{m}{n} = \genfrac(){}{}{m}{p{1}} \genfrac(){}{}{m}{p{2}} ... \genfrac(){}{}{m}{p{k}} \text{ 其中 } n = p_1^{\alpha_1} p_2^{\alpha_2} ... p_k^{\alpha_k}]
像勒讓德符號一樣,如果雅可比符號 (\genfrac(){}{}{m}{n} = -1),則 m
是模 n
的二次非剩餘。
但與勒讓德符號不同的是,如果雅可比符號 (\genfrac(){}{}{m}{n} = 1),則 m
可能是模 n
的二次剩餘,也可能不是。
引數:
m : 整數
n : 奇正整數
示例
>>> from sympy.functions.combinatorial.numbers import jacobi_symbol, legendre_symbol
>>> from sympy import S
>>> jacobi_symbol(45, 77)
-1
>>> jacobi_symbol(60, 121)
1
jacobi_symbol
和 legendre_symbol
之間的關係可以如下所示:
>>> L = legendre_symbol
>>> S(45).factors()
{3: 2, 5: 1}
>>> jacobi_symbol(7, 45) == L(7, 3)**2 * L(7, 5)**1
True
參見
is_quad_residue
,legendre_symbol
sympy.ntheory.residue_ntheory.mobius(n)
Möbius 函式將自然數對映到{-1, 0, 1}
自版本 1.13 起不推薦使用mobius
函式。請使用sympy.functions.combinatorial.numbers.mobius
。有關詳細資訊,請參閱其文件。有關詳細資訊,請參閱從 ntheory 移動符號函式。
定義如下:
-
如果(n = 1),則為(1)。
-
如果(n)有一個平方素因子,則為(0)。
-
如果(n)是具有(k)個素因子的無平方正整數,則為((-1)^k)。
它是數論和組合數學中的重要乘性函式。在數學級數、代數數論以及物理學中(費米子運算元與 Möbius 函式模型有著非常具體的實現)有應用。
引數:
n : 正整數
示例
>>> from sympy.functions.combinatorial.numbers import mobius
>>> mobius(13*7)
1
>>> mobius(1)
1
>>> mobius(13*7*5)
-1
>>> mobius(13**2)
0
參考文獻
[R705]
en.wikipedia.org/wiki/M%C3%B6bius_function
[R706]
Thomas Koshy 的《Elementary Number Theory with Applications》
sympy.ntheory.residue_ntheory.discrete_log(n, a, b, order=None, prime_order=None)
計算a
以模n
為底的離散對數。
這是一個遞迴函式,用於將複合階迴圈群中的離散對數問題簡化為素數階迴圈群中的問題。
它根據問題使用不同的演算法(子群階大小,是否為素數階):
- 試乘法
- Baby-step giant-step 演算法
- 波拉德 Rho 演算法
- 指數演演算法
- Pohlig-Hellman
示例
>>> from sympy.ntheory import discrete_log
>>> discrete_log(41, 15, 7)
3
參考文獻
[R707]
mathworld.wolfram.com/DiscreteLogarithm.html
[R708]
“應用密碼學手冊”,Menezes, A. J., Van, O. P. C., & Vanstone, S. A. (1997).
sympy.ntheory.residue_ntheory.quadratic_congruence(a, b, c, n)
找到滿足(a x² + b x + c \equiv 0 \pmod{n})的解。
引數:
a : int
b : int
c : int
n : int
正整數。
返回:
list[int]:
解的排序列表。如果沒有解,則為
[]
。
示例
>>> from sympy.ntheory.residue_ntheory import quadratic_congruence
>>> quadratic_congruence(2, 5, 3, 7) # 2x² + 5x + 3 = 0 (mod 7)
[2, 6]
>>> quadratic_congruence(8, 6, 4, 15) # No solution
[]
參見
polynomial_congruence
解多項式同餘方程
sympy.ntheory.residue_ntheory.polynomial_congruence(expr, m)
解多項式同餘方程模 m。
引數:
expr : 整數係數多項式
m : 正整數
示例
>>> from sympy.ntheory import polynomial_congruence
>>> from sympy.abc import x
>>> expr = x**6 - 2*x**5 -35
>>> polynomial_congruence(expr, 6125)
[3257]
參見
sympy.polys.galoistools.gf_csolve
低階解決例程由該例程使用
sympy.ntheory.residue_ntheory.binomial_mod(n, m, k)
計算binomial(n, m) % k
。
引數:
n : 整數
m : 整數
k : 正整數
解釋
使用 Lucas 定理的一般化與 Granville 的 R709(由中國剩餘定理)提供的素數冪的餘數計算時間為 O(log²(n) + q⁴log(n)log(p) + q⁴p*log³(p))。
例子
>>> from sympy.ntheory.residue_ntheory import binomial_mod
>>> binomial_mod(10, 2, 6) # binomial(10, 2) = 45
3
>>> binomial_mod(17, 9, 10) # binomial(17, 9) = 24310
0
參考文獻
[R709] (1,2)
模素數冪的二項式係數,Andrew Granville,可用:web.archive.org/web/20170202003812/http://www.dms.umontreal.ca/~andrew/PDF/BinCoeff.pdf
sympy.ntheory.continued_fraction.continued_fraction(a) → list
返回有理數或二次無理數的連分數表示。
例子
>>> from sympy.ntheory.continued_fraction import continued_fraction
>>> from sympy import sqrt
>>> continued_fraction((1 + 2*sqrt(3))/5)
[0, 1, [8, 3, 34, 3]]
另見
continued_fraction_periodic
, continued_fraction_reduce
, continued_fraction_convergents
sympy.ntheory.continued_fraction.continued_fraction_convergents(cf)
返回一個連分數(CF)的收斂數迭代器。
引數應該是以下兩種形式之一:- 部分商的列表,最後一個元素可能是重複的部分商列表,例如由 continued_fraction 和 continued_fraction_periodic 返回的形式。- 返回連分數的連續部分商的可迭代物件,例如由 continued_fraction_iterator 返回的形式。
在計算收斂分數時,連分數不必嚴格處於規範形式(全為整數,除了第一個為正數)。分數和負數元素可能存在於展開中。
例子
>>> from sympy.core import pi
>>> from sympy import S
>>> from sympy.ntheory.continued_fraction import continued_fraction_convergents, continued_fraction_iterator
>>> list(continued_fraction_convergents([0, 2, 1, 2]))
[0, 1/2, 1/3, 3/8]
>>> list(continued_fraction_convergents([1, S('1/2'), -7, S('1/4')]))
[1, 3, 19/5, 7]
>>> it = continued_fraction_convergents(continued_fraction_iterator(pi))
>>> for n in range(7):
... print(next(it))
3
22/7
333/106
355/113
103993/33102
104348/33215
208341/66317
>>> it = continued_fraction_convergents([1, [1, 2]]) # sqrt(3)
>>> for n in range(7):
... print(next(it))
1
2
5/3
7/4
19/11
26/15
71/41
另見
continued_fraction_iterator
, continued_fraction
, continued_fraction_periodic
sympy.ntheory.continued_fraction.continued_fraction_iterator(x)
返回 x 的連分數展開作為迭代器。
例子
>>> from sympy import Rational, pi
>>> from sympy.ntheory.continued_fraction import continued_fraction_iterator
>>> list(continued_fraction_iterator(Rational(3, 8)))
[0, 2, 1, 2]
>>> list(continued_fraction_iterator(Rational(-3, 8)))
[-1, 1, 1, 1, 2]
>>> for i, v in enumerate(continued_fraction_iterator(pi)):
... if i > 7:
... break
... print(v)
3
7
15
1
292
1
1
1
參考文獻
[R710]
zh.wikipedia.org/wiki/連分數
sympy.ntheory.continued_fraction.continued_fraction_periodic(p, q, d=0, s=1) → list
找到二次無理數的週期連分數展開。
計算有理數或二次無理數的連分數展開,即 (\frac{p + s\sqrt{d}}{q}),其中 (p),(q \ne 0),(d \ge 0) 為整數。
作為整數列表返回連分數表示(規範形式),對於二次無理數,可選地以表示重複數字的整數列表結束。
引數:
p : int
數字的有理數部分
q:整數
數字的分母
d:整數,可選
數字的分母
s:整數,可選
無理部分的係數
示例
>>> from sympy.ntheory.continued_fraction import continued_fraction_periodic
>>> continued_fraction_periodic(3, 2, 7)
[2, [1, 4, 1, 1]]
黃金分割率具有最簡單的連分數展開:
>>> continued_fraction_periodic(1, 2, 5)
[[1]]
如果鑑別器為零或完全平方數,則該數字將是有理數:
>>> continued_fraction_periodic(4, 3, 0)
[1, 3]
>>> continued_fraction_periodic(4, 3, 49)
[3, 1, 2]
另見
continued_fraction_iterator
, continued_fraction_reduce
參考文獻
[R711]
zh.wikipedia.org/wiki/週期連分數
[R712]
K. Rosen. Elementary Number theory and its applications. Addison-Wesley, 3 Sub edition, pages 379-381, January 1992.
sympy.ntheory.continued_fraction.continued_fraction_reduce(cf)
將一個連分數化簡為有理數或二次無理數。
從其終止或週期連分數展開計算有理或二次無理數。連分數展開(cf)應被視為提供展開項的終止迭代器。對於終止連分數,這相當於list(continued_fraction_convergents(cf))[-1]
,只是效率稍高。如果展開部分重複,迭代器應返回重複項的列表作為最後一個元素。這是由 continued_fraction_periodic 返回的格式。
對於二次無理數,如果分數處於規範形式(除第一個外所有項均為正),則返回找到的最大解,通常是所需解。
示例
>>> from sympy.ntheory.continued_fraction import continued_fraction_reduce
>>> continued_fraction_reduce([1, 2, 3, 4, 5])
225/157
>>> continued_fraction_reduce([-2, 1, 9, 7, 1, 2])
-256/233
>>> continued_fraction_reduce([2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8]).n(10)
2.718281835
>>> continued_fraction_reduce([1, 4, 2, [3, 1]])
(sqrt(21) + 287)/238
>>> continued_fraction_reduce([[1]])
(1 + sqrt(5))/2
>>> from sympy.ntheory.continued_fraction import continued_fraction_periodic
>>> continued_fraction_reduce(continued_fraction_periodic(8, 5, 13))
(sqrt(13) + 8)/5
另見
continued_fraction_periodic
sympy.ntheory.digits.count_digits(n, b=10)
返回一個字典,其鍵是數字n
在給定基數b
中的數字,鍵表示數字出現在數字中的位置,值表示該數字出現的次數。
示例
>>> from sympy.ntheory import count_digits
>>> count_digits(1111339)
{1: 4, 3: 2, 9: 1}
返回的數字始終以十進位制表示,但數字本身可以以 Python 理解的任何格式輸入;如果數字的基數與 10 不同,也可以給出數字的基數:
>>> n = 0xFA; n
250
>>> count_digits(_)
{0: 1, 2: 1, 5: 1}
>>> count_digits(n, 16)
{10: 1, 15: 1}
預設情況下,字典將對任何未出現在數字中的數字返回 0。例如,77!
中出現 7 次的數字有哪些:
>>> from sympy import factorial
>>> c77 = count_digits(factorial(77))
>>> [i for i in range(10) if c77[i] == 7]
[1, 3, 7, 9]
另見
sympy.core.intfunc.num_digits
, digits
sympy.ntheory.digits.digits(n, b=10, digits=None)
返回n
在基數b
中的數字列表。列表中的第一個元素是b
(如果n
為負,則為-b
)。
引數:
n:整數
返回數字的位數。
b:整數
計算數字的基數。
digits:整數(或所有數字的 None)
要返回的數字位數(如有必要,用零填充)。
示例
>>> from sympy.ntheory.digits import digits
>>> digits(35)
[10, 3, 5]
如果數字為負,則負號將放在基數上(即返回列表中的第一個元素):
>>> digits(-35)
[-10, 3, 5]
可以選擇除了 10(大於 1 的)以外的基數 b
:
>>> digits(27, b=2)
[2, 1, 1, 0, 1, 1]
如果需要某個特定數量的數字,請使用 digits
關鍵字:
>>> digits(35, digits=4)
[10, 0, 0, 3, 5]
另請參閱
sympy.core.intfunc.num_digits
, count_digits
sympy.ntheory.digits.is_palindromic(n, b=10)
如果在給定的基數 b
中從左到右或從右到左讀取 n
時相同,則返回 True。
示例
>>> from sympy.ntheory import is_palindromic
>>> all(is_palindromic(i) for i in (-11, 1, 22, 121))
True
第二個引數允許您在其他基數中測試數字。例如,88 在十進位制中是迴文的,但在八進位制中不是:
>>> is_palindromic(88, 8)
False
另一方面,一個數字在八進位制中可能是迴文的,但在十進位制中不是:
>>> 0o121, is_palindromic(0o121)
(81, False)
或者在兩個基礎上是迴文的:
>>> oct(121), is_palindromic(121, 8) and is_palindromic(121)
('0o171', True)
sympy.ntheory.egyptian_fraction.egyptian_fraction(r, algorithm='Greedy')
返回所述有理數 (r) 的埃及分數展開的分母列表[R713]。
引數:
r:有理數或(p,q)
正有理數
p/q
。
algorithm:{“貪婪”,“Graham Jewett”,“Takenouchi”,“Golomb”},可選
指定要使用的演算法(預設為“貪婪”)。
示例
>>> from sympy import Rational
>>> from sympy.ntheory.egyptian_fraction import egyptian_fraction
>>> egyptian_fraction(Rational(3, 7))
[3, 11, 231]
>>> egyptian_fraction((3, 7), "Graham Jewett")
[7, 8, 9, 56, 57, 72, 3192]
>>> egyptian_fraction((3, 7), "Takenouchi")
[4, 7, 28]
>>> egyptian_fraction((3, 7), "Golomb")
[3, 15, 35]
>>> egyptian_fraction((11, 5), "Golomb")
[1, 2, 3, 4, 9, 234, 1118, 2580]
注意事項
目前支援以下演算法:
-
貪婪演算法
也稱為 Fibonacci-Sylvester 演算法[R714]。在每一步中,提取小於目標的最大單位分數,並用餘數替換目標。
它具有一些獨特的屬性:
-
給定最簡分數 (p/q),生成最大長度 (p) 的展開。即使分子變大,項數也很少超過一把。
-
使用最小記憶體。
-
術語可以爆炸(其標準示例為 5/121 和 31/311)。每一步中的分母最多是平方的(雙指數增長),通常表現出單指數增長。
-
-
Graham Jewett 演算法
根據 Graham 和 Jewett 的結果建議的演算法。請注意,這傾向於爆炸:結果展開的長度始終為
2**(x/gcd(x, y)) - 1
。參見[R715]。 -
Takenouchi 演算法
由 Takenouchi(1921)建議的演算法。與 Graham-Jewett 演算法僅在處理重複項時有所不同。參見[R715]。
-
Golomb 演算法
由 Golumb(1962)提出的方法,使用模算術和逆元。它與 Bleicher(1972)提出的使用連分數的方法產生相同的結果。參見[R716]。
如果給定的有理數大於或等於 1,則使用貪婪演算法對和諧序列 1/1 + 1/2 + 1/3 + …進行求和,直到新增一個以上的單位分數會比給定的數字大。這些分母的列表被新增到從剩餘部分使用的請求演算法的結果前面。例如,如果 r 是 8/3,使用貪婪演算法,我們得到[1, 2, 3, 4, 5, 6, 7, 14, 420],其中序列的開頭[1, 2, 3, 4, 5, 6, 7]是和諧序列的一部分,總和為 363/140,剩餘 31/420,貪婪演算法產生[14, 420]。埃及分數(Rational(8, 3),“Golomb”)的結果是[1, 2, 3, 4, 5, 6, 7, 14, 574, 2788, 6460, 11590, 33062, 113820],等等。
另見
sympy.core.numbers.Rational
參考文獻
[R713] (1,2)
en.wikipedia.org/wiki/Egyptian_fraction
[R714] (1,2)
en.wikipedia.org/wiki/Greedy_algorithm_for_Egyptian_fractions
[R715] (1,2,3)
www.ics.uci.edu/~eppstein/numth/egypt/conflict.html
[R716] (1,2)
web.archive.org/web/20180413004012/https://ami.ektf.hu/uploads/papers/finalpdf/AMI_42_from129to134.pdf
sympy.ntheory.bbp_pi.pi_hex_digits(n, prec=14)
返回一個包含prec
(預設為 14)個十六進位制π的第 n 位開始的數字的字串。數字的計數從 0 開始,小數點不計入,所以當 n = 0 時,返回的值以 3 開頭;n = 1 對應於小數點後的第一個數字(在十六進位制中為 2)。
引數:
n:非負整數
prec:非負整數,預設為 14
返回:
str:返回一個包含prec
個數字的字串
從π的第 n 位開始的十六進位制。如果
prec
= 0,則返回空字串。
提升:
ValueError
如果
n
< 0 或prec
< 0。或n
或prec
不是整數。
示例
>>> from sympy.ntheory.bbp_pi import pi_hex_digits
>>> pi_hex_digits(0)
'3243f6a8885a30'
>>> pi_hex_digits(0, 3)
'324'
這些與以下結果一致
>>> import math
>>> hex(int(math.pi * 2**((14-1)*4)))
'0x3243f6a8885a30'
>>> hex(int(math.pi * 2**((3-1)*4)))
'0x324'
參考文獻
[R717]
www.numberworld.org/digits/Pi/
ECM 函式
ecm
函式是一個次指數因數分解演算法,能夠在幾秒鐘內輕鬆地因式分解大約 35 位數的數字。ecm
的時間複雜度取決於該數的最小真因數。因此,即使數字很大,但其因子相對較小,ecm
也可以輕鬆地對其進行因式分解。例如,我們取帶有 15 位數因子的 N,如 15154262241479,15423094826093,799333555511111,809709509409109,888888877777777,914148152112161。現在 N 是一個 87 位數。ECM
需要大約 47 秒來因式分解它。
sympy.ntheory.ecm.ecm(n, B1=10000, B2=100000, max_curve=200, seed=1234)
使用 Lenstra 的橢圓曲線方法進行因式分解。
此函式重複呼叫 _ecm_one_factor
來計算 n 的因子。首先透過試除法去除所有小因子。然後使用 _ecm_one_factor
逐個計算一個因子。
引數:
n : 待分解的數
B1 : 第 1 階段界限。必須是偶數。
B2 : 第 2 階段界限。必須是偶數。
max_curve : 生成的最大麴線數
seed : 初始化偽隨機生成器
示例
>>> from sympy.ntheory import ecm
>>> ecm(25645121643901801)
{5394769, 4753701529}
>>> ecm(9804659461513846513)
{4641991, 2112166839943}
示例
>>> from sympy.ntheory import ecm
>>> ecm(7060005655815754299976961394452809, B1=100000, B2=1000000)
{6988699669998001, 1010203040506070809}
>>> ecm(122921448543883967430908091422761898618349713604256384403202282756086473494959648313841, B1=100000, B2=1000000)
{15154262241479,
15423094826093,
799333555511111,
809709509409109,
888888877777777,
914148152112161}
``` ## QS 函式
qs 函式是一種亞指數複雜度的因式分解演算法,適用於 100 位數以內的最快因式分解演算法。qs 的時間複雜度取決於數的大小,因此如果數包含大因子,則使用 qs。因此,在因式分解數時,首先使用 ecm 獲得約 15 位數的較小因子,然後使用 qs 獲取較大因子。
用於因式分解 \(2709077133180915240135586837960864768806330782747\) 的半素數,其具有兩個 25 位數的因子。qs 能在大約 248 秒內完成對其的因式分解。
```py
sympy.ntheory.qs.qs(N, prime_bound, M, ERROR_TERM=25, seed=1234)
使用自初始化二次篩法進行因式分解。在 SIQS 中,令 N 為待分解的數,且 N 不應為完全冪。如果我們找到兩個整數使得 X**2 = Y**2 modN
且 X != +-Y modN
,那麼 (gcd(X + Y, N)) 將顯示出 N 的一個正確因子。為了找到這些整數 X 和 Y,我們試圖找到形如 t**2 = u modN 的關係,其中 u 是小質數的乘積。如果我們有足夠多的這些關係,我們可以形成 (t1*t2...ti)**2 = u1*u2...ui modN
,使右邊是一個平方數,因此我們找到了一個關係 X**2 = Y**2 modN
。
這裡進行了幾項最佳化,如使用多項式篩選、快速切換多項式和使用部分關係。部分關係的使用可以使因式分解加速 2 倍。
引數:
N : 待分解的數
prime_bound : 質因數基中的質數上限
M : 篩選區間
ERROR_TERM : 檢查平滑性的誤差項
threshold : 因式分解的額外平滑關係
seed : 生成偽質數
示例
>>> from sympy.ntheory import qs
>>> qs(25645121643901801, 2000, 10000)
{5394769, 4753701529}
>>> qs(9804659461513846513, 2000, 10000)
{4641991, 2112166839943}
參考文獻
[R718]
pdfs.semanticscholar.org/5c52/8a975c1405bd35c65993abf5a4edb667c1db.pdf
[R719]
www.rieselprime.de/ziki/Self-initializing_quadratic_sieve
示例
>>> from sympy.ntheory import qs
>>> qs(5915587277*3267000013, 1000, 10000)
{3267000013, 5915587277}