帕德近似
pade(f)在var=0时返回表达式f的三阶Padé逼近(不知道三阶逼近是否是pade定义,后续查证,目前代码里使用泰勒六阶展开).
f —— 近似输入,符号函数|符号表达式
示例1: 控制系统中的延迟环节近似
传输延迟 e^(-x) 的 [1,1] 阶Pade近似:
result1 = pade(exp(-x), x, 1) #e^(-sT) 的Pade近似,常用于控制系统分析
print(f"结果: {result1}")
#结果: (-x**3/100 + 5*x**2/97 - 13*x/89 + 7/32)/(x**2 + 42*x/11 + 406/71)
示例2: 金融数学中的Black-Scholes模型
正态分布累积函数近似:
result3 = pade((1 + erf(x/sqrt(2)))/2, x, 4)
print(f"结果: {result3}")
#结果: (36*x**5/53 - 44*x**4/3 + 11324*x**3/89 - 41591*x**2/75 + 63163*x/52 - 77029/72)/x**2
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.interpolate import pade
import numpy as np
def coefficients_of_polynomial(input_str):
"""
提取多项式的系数列表
参数:
input_str - 输入字符串,支持格式:
1. 纯多项式表达式 (如 "x**2 + 2*x + 1")
2. 元组格式 (表达式, 变量) (如 "(x**2 + y, x)")
3. 元组格式 (表达式, [变量1, 变量2,...]) (如 "(x**2 + x*y, [x, y])")
locals_dict - 符号解析字典,默认为None
返回:
系数列表 (单变量) 或嵌套系数列表 (多变量)
错误时返回描述性错误信息
"""
try:
expr = sp.sympify(input_str)
result = []
if isinstance(expr, tuple) and len(expr) == 2:
poly_expr, variables = expr
# 处理多变量情况
if isinstance(variables, list):
for var in variables:
if not var.free_symbols:
raise ValueError(f"无效变量: {var}")
poly = sp.poly(poly_expr, var)
result.append(poly.coeffs())
# 处理单变量情况
else:
if not variables.free_symbols:
raise ValueError(f"无效变量: {variables}")
poly = sp.poly(poly_expr, variables)
result = poly.coeffs()
else:
poly = sp.poly(expr)
result = poly.coeffs()
return result
except Exception as e:
return f"错误: {e}"
def pade_approximant(input_str):
"""
对标 MATLAB 的 pade 函数,计算符号表达式的 Pade 近似式
参数格式:
"(表达式, 变量, 展开点, 分子阶数m, 分母阶数n)"
示例:"(sin(x), x, 0, 3, 2)"
返回:
SymPy表达式 或 错误信息字符串
"""
try:
expr = sp.sympify(input_str, evaluate=False)
error = False
result = None
# 计算泰勒展开(确保阶数足够)
sym_var = None
x0 = 0
m = 2
n = 2
if isinstance(expr, tuple):
if len(expr) == 2:
f_expr, sym_var = expr
elif len(expr) == 3:
f_expr, sym_var, x0 = expr
else:
error = True
elif expr.free_symbols:
f_expr = expr
sym_var = list(expr.free_symbols)[0]
else:
error = True
taylor_expr = sp.series(f_expr, sym_var, x0).removeO()
x = sp.symbols('x')
# 提取泰勒级数的系数
coeffs = coefficients_of_polynomial(str(taylor_expr))
pade_approximant = pade(np.array(coeffs, dtype=float), m=m) # 分母多项式的阶数为 n-m
# 获取分子和分母多项式
numerator, denominator = pade_approximant
# 构建分子和分母多项式的表达式
numerator_expr = sum(coef * x ** i for i, coef in enumerate(numerator.c))
denominator_expr = sum(coef * x ** i for i, coef in enumerate(denominator.c))
# 构建 Pade 近似的符号表达式
pade_expr = numerator_expr / denominator_expr
# 打印 Pade 近似的符号表达式
result = sp.nsimplify(pade_expr, tolerance=0.01)
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"Error: {e}"
# 测试用例
if __name__ == "__main__":
# 示例1:sin(x) 的 [0] Pade近似
print(pade_approximant("sin(x),x"))
# 1/(100*(x**2 + 20*x + 280))
# 示例2:sin(x) 的 [0] Pade近似
print(pade_approximant("sin(x),x,1"))
# (x**8/100 - x**7/29 + x**6/100 - 3*x**5/53 - 14*x**4/61 + 16*x**3/63 + 3*x**2/41 + 18*x/43 + 76/61)/(x**2 + 32*x/37 + 21/94)
时滞的帕德逼近
[num,den] = padecoef(T,N) 以传递函数形式返回持续时滞 exp(-T*s) 的 N 阶 Pade 逼近。行向量 num 和 den 包含了按 s 的降幂排序的分子和分母系数。分子和分母均为 N 次多项式。
T — 时滞,标量
N — 逼近的阶,标量
示例1: 基本功能
T=2, N=2 的Padé系数:
result1 = padecoef(2, 2)
a, b = result1
print(f"分子系数 (升幂): {a}")
print(f"分母系数 (升幂): {b}")
#分子系数 (升幂): [1,-1,0.66666667]
#分母系数 (升幂): [1,1,0.66666667]
示例2: 不同阶数
T=1, N=1 的Padé系数:
result2 = padecoef(1, 1)
a, b = result2
print(f"分子系数 (升幂): {a}")
print(f"分母系数 (升幂): {b}")
#分子系数 (升幂): [1,-0.5]
#分母系数 (升幂): [1,0.5]
示例3: 高阶近似
T=1, N=3 的Padé系数:
result3 = padecoef(1, 3)
a, b = result3
print(f"分子系数 (升幂): {a}")
print(f"分母系数 (升幂): {b}")
#分子系数 (升幂): [1,-0.5,0.2,-0.05]
#分母系数 (升幂): [1,0.5,0.2,0.05]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy.special import comb
def pade_coef(input_str):
"""
计算时滞函数 e^(-sT) 的 N 阶 Padé 逼近系数
参数:
T (float): 时滞
N (int): 逼近的阶
返回:
a (np.ndarray): 分子多项式的系数(升幂排列)
b (np.ndarray): 分母多项式的系数(升幂排列)
"""
try:
expr = sp.sympify(input_str)
error = False
s = sp.symbols('s')
numerator = 0
denominator = 0
result = None, None
if isinstance(expr, tuple) and len(expr) == 2:
t, n = expr
if t.is_number and n.is_integer:
T = float(t)
N = int(n)
for k in range(N + 1):
# 计算组合数因子
c = comb(2 * N - k, N) / comb(2 * N, N)
# 分子累加项:(-T s)^k
numerator += c * (-T * s) ** k
# 分母累加项:(T s)^k
denominator += c * (T * s) ** k
# 提取多项式系数(SymPy按降幂排列,需反转)
num_poly = sp.poly(numerator, s)
den_poly = sp.poly(denominator, s)
# 转换为升幂排列的NumPy数组
a = np.array(num_poly.all_coeffs()[::-1], dtype=float)
b = np.array(den_poly.all_coeffs()[::-1], dtype=float)
result = a, b
else:
error = True
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"解析错误: {str(e)}"
# 示例验证(N=2, T=2时的标准Padé系数)
result = pade_coef("2,2")
print("分子多项式系数(升幂排列):", result[0])
# [ 1. -1. 0.66666667]
print("分母多项式系数(升幂排列):", result[1])
# [1. 1. 0.66666667]
概率分布参数的置信区间
ci = paramci(data)返回数组ci,其中包含概率分布data中每个参数的95%置信区间的下限和上限.
data —— 输入,数值向量
ci —— 置信区间, 两维列表. 以p-by-2数组的形式返回, 分别是mu和sigma参数的下限和上限.
示例1: 基本功能
data = [1, 2, 3, 4, 5]
result1 = paramci(data)
mu_ci, sigma_ci = result1
print(f"均值置信区间: {mu_ci}")
print(f"标准差置信区间: {sigma_ci}")
#均值置信区间: [1.03675683852244, 4.96324316147756]
#标准差置信区间: [0.947312670675224, 4.54349039344827]
示例2: 不同置信水平
result2 = paramci(data, 0.90)
mu_ci, sigma_ci = result2
print(f"均值置信区间: {mu_ci}")
print(f"标准差置信区间: {sigma_ci}")
#均值置信区间: [1.49255668446639, 4.50744331553361]
#标准差置信区间: [1.02664161272764, 3.75102370245919]
示例3: 更大数据集
large_data = list(range(1, 21)) # 1到20
result3 = paramci(large_data)
mu_ci, sigma_ci = result3
print(f"均值置信区间: {mu_ci}")
print(f"标准差置信区间: {sigma_ci}")
#均值置信区间: [7.73118943197981, 13.2688105680202]
#标准差置信区间: [4.49912184713642, 8.64085832821364]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
import scipy.stats as stats
def param_confidence_intervals(input_str):
"""
计算输入数据的正态分布参数置信区间。
参数:
input_str: 输入数据的字符串表示,可以是 SymPy 矩阵或列表。
confidence_level: 置信水平,默认为 0.95。
返回:
置信区间数组或错误信息。
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
def matrix_to_list(matrix):
"""
将 SymPy 向量矩阵转换为 Python 列表。
参数:
matrix: SymPy 矩阵对象。
返回:
如果是行向量或列向量,返回对应的列表;否则返回 None。
"""
try:
if not isinstance(matrix, sp.Matrix):
raise ValueError("输入必须是一个 SymPy 矩阵对象")
rows, cols = matrix.shape
# 处理行向量(1行n列)
if rows == 1:
return list(matrix.row(0))
# 处理列向量(n行1列)
elif cols == 1:
return [matrix[i, 0] for i in range(rows)]
else:
return None # 非向量矩阵
except Exception as e:
print(f"Error in matrix_to_list: {e}")
return None
def evaluation_paramci(data, confidence_level): # 接受confidence_level参数
n = len(data)
if n < 2:
raise ValueError("数据长度必须至少为2")
mu = np.mean(data)
s = np.std(data, ddof=1)
# 使用t分布计算均值置信区间
t_value = stats.t.ppf((1 + confidence_level) / 2, df=n - 1)
mu_se = s / np.sqrt(n)
mu_ci = (mu - t_value * mu_se, mu + t_value * mu_se)
# 标准差置信区间保持不变...
alpha = 1 - confidence_level
chi2_upper = stats.chi2.ppf(1 - alpha / 2, df=n - 1)
chi2_lower = stats.chi2.ppf(alpha / 2, df=n - 1)
sigma_ci_lower = np.sqrt((n - 1) * s ** 2 / chi2_upper)
sigma_ci_upper = np.sqrt((n - 1) * s ** 2 / chi2_lower)
sigma_ci = (sigma_ci_lower, sigma_ci_upper)
return np.array([mu_ci, sigma_ci])
if isinstance(expr, list):
matrix = sp.Matrix(expr)
data_list = matrix_to_list(matrix)
if data_list is None:
return "错误:输入必须为向量(行向量或列向量)"
data = np.array(data_list, dtype=float)
result = evaluation_paramci(data, confidence_level=0.95) # 传递confidence_level
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误:{e}"
# 示例验证
data = [1, 2, 3, 4, 5]
input_str = str(data) # 输入字符串应为"[1, 2, 3, 4, 5]"
ci = param_confidence_intervals(input_str)
print("均值置信区间:", ci[0])
# [1.03675684 4.96324316]
print("标准差置信区间:", ci[1])
# [0.94731267 4.54349039]
参数方程图
ParametricPlot(x(u), y(u))通过独立参数(如u)控制多个坐标变量,能描述复杂轨迹、动态过程和几何变换。解决隐式方程难以绘制的问题。
尤其擅长表达: 闭合曲线, 自相交图形, 时间演化路径.
Lissajous 曲线 - 电子信号分析
ParametricPlot([sin(7u),sin(8u)], u=[0,2@pi])
卫星天线 - 垂直压缩椭圆
ParametricPlot(2.4cos(u),1.8sin(u),u=[0, 2@pi])
螺旋进给 - 机械加工路径
ParametricPlot(u*cos(u),u*sin(u),u=[0,8@pi])
心电信号 - 医学波形生成
ParametricPlot(16(sin(u)^3), 13cos(u)-5cos(2u)-2cos(3u)-cos(4u),u=[0,2@pi])
混沌吸引子 - 气象预测模型
ParametricPlot(sin(3u)*cos(5u), sin(2u)*sin(3u), u=[0,10@pi])
齿轮啮合 - 机械设计
ParametricPlot(cos(u)+0.2*cos(5u),sin(u)-0.2*sin(5u),u=[0,2@pi])
参数方程三维图
ParametricPlot3D(f1(u,v), f2(u,v), f3(u,v))使用两个参数(通常用 u 和 v 表示)来定义三维空间中的点 (x, y, z)。描述很多用显式方程 z = f(x, y) 难以甚至无法描述的复杂曲面
螺旋线 (Helix) - 弹簧、DNA结构、螺纹的基础: 这是最基本的空间曲线之一。用于建模弹簧、螺丝螺纹、DNA 双螺旋结构、螺旋楼梯的中心线、粒子在磁场中的轨迹等。
ParametricPlot3D(r*cos(t),r*sin(t),2t,r=[0,2],t=[0,4@pi])
球面 (Sphere) - 行星、球体、气泡: 这是描述完美球体的标准方式。用于建模行星、球状容器、气泡、原子模型、3D 图形中的球体等。
ParametricPlot3D(2*sin(r)*cos(t),2*sin(r)*sin(t), 2*cos(r),r=[0,@pi],t=[0,2@pi])
环面 (Torus) - 甜甜圈、轮胎、环形线圈: 形状像甜甜圈或游泳圈。用于建模轮胎、环形磁铁、粒子加速器(如环形对撞机)的真空管、一些建筑结构、首饰(如戒指的主体)等。
ParametricPlot3D((3+cos(v))*cos(u), (3+cos(v))*sin(u), sin(v),u=[0,2@pi],v=[0,2@pi])
柱面 (Cylinder) - 管道、柱子、罐体: 描述一个无限长或有限高的圆柱侧面。用于建模管道、柱子、罐体、滚筒、轴等。
ParametricPlot3D(2*cos(u), 2*sin(u),v,u=[0,2@pi],v=[0,5])
锥面 (Cone) - 漏斗、锥形零件、山峰简化模型:描述一个圆锥面。用于建模漏斗、锥形齿轮、交通锥筒、简化版的山峰或火山、灯具罩等。
ParametricPlot3D((5-v)*(3/5)*cos(u),(5-v)*(3/5)*sin(u),v,u=[0,2@pi],v=[0,5])
莫比乌斯带 (Möbius Strip) - 单侧曲面、有趣的拓扑结构、传送带设计:这是一个著名的单侧曲面(只有一个面,一条边界)。它具有有趣的拓扑性质。虽然实际工程应用较少(因其应力分布不均),但在传送带设计、艺术装置、数学教学中常被提及。
ParametricPlot3D((1+0.3v*cos(u/2))*cos(u), (1+0.3v*cos(u/2))*sin(u),0.3v*sin(u/2),u=[0,2@pi],v=[-1,1])
旋转曲面 (Surface of Revolution) - 花瓶、碗、车削零件: 这是生成轴对称曲面的主要方法。用于建模花瓶、碗、酒杯、车床加工的零件(轴、销、盘)、压力容器封头、旋转抛物面天线等。
ParametricPlot3D(sqrt(z)*cos(u), sqrt(z)*sin(u),z,u=[0,2@pi],z=[0,4])
螺旋面 (Helicoid) - 螺旋楼梯、螺纹、某些蛋白质结构:像一个“螺旋形的坡道”。用于建模螺旋楼梯的曲面、某些类型的螺纹(如方牙螺纹的简化模型)、DNA 结构的某些简化表示、螺旋坡道(如停车场)等。
ParametricPlot3D(v*cos(u),v*sin(u),u/2,u=[0,4@pi],v=[0,2])
双曲抛物面(马鞍面): 建筑结构(如悉尼歌剧院)、重力场模拟
ParametricPlot3D(u,v,u^2-v^2,v=[-2,2], u=[-2,2])
恩涅珀曲面(极小曲面): 肥皂膜自然形成的极小化曲面
ParametricPlot3D(u-u^3/3+u*v^2, v-v^3/3+v*u^2, u^2-v^2, v=[-2,2], u=[-2,2])
机械齿轮曲面: 齿轮齿面建模、螺纹设计
ParametricPlot3D((3+sin(5v))*cos(u), (3+sin(5v))*sin(u), v, v=[-1,1], u=[0,2@pi])
心脏形曲面(医学成像): 模拟心脏瓣膜开闭时的血流动力学,用于心血管疾病研究和人工心脏设计
ParametricPlot3D((1-cos(u))*cos(u)*cos(v),(1-cos(u))*sin(u)*cos(v),(1-cos(u))*sin(v),u=[0,2@pi],v=[0,@pi])
空气动力学翼型(航空航天): NACA 0012翼型方程, 飞机机翼和涡轮叶片的流体动力学模拟,优化升力/阻力比
ParametricPlot3D(u,(0.6*(0.2969*sqrt(u)-0.1260*u-0.3516*u^2+0.2843*u^3-0.1036*u^4))*cos(v),(0.6*(0.2969*sqrt(u)-0.1260*u-0.3516*u^2+0.2843*u^3-0.1036*u^4))*sin(v),v=[0,2@pi], u=[0,1])
DNA纳米管(生物技术): 分子自组装结构设计,药物输送载体建模
ParametricPlot3D((3+0.3*cos(6u))*cos(v),(3+0.3*cos(6u))*sin(v),u+0.5*sin(6u),u=[0,4@pi],v=[0,2@pi])
重力透镜曲面(天体物理): 模拟大质量天体引起的时空弯曲,解释星系引力透镜观测数据
ParametricPlot3D(u,v,0.5*exp(-(u^2 + v^2)/4)*cos(sqrt(u^2+v^2)),u=[-4,4],v=[-4,4])
混凝土薄壳建筑(土木工程): 现代建筑薄壳屋顶设计(如悉尼歌剧院),优化承重分布
ParametricPlot3D(u,v,(u^2-v^2)/10,u=[-5,5],v=[-5,5])
量子位能阱曲面(量子计算): 量子计算机中囚禁离子能级建模,优化量子位控制
ParametricPlot3D(u,v,-10/(1+u^2+v^2)+0.1*(u^2+v^2),u=[-4,4],v=[-4,4])
珊瑚生长模型(海洋生物学): 海洋生态系统模拟,研究酸化对珊瑚骨架结构的影响
ParametricPlot3D((2+sin(3v))*u*cos(v),(2+sin(3v))*u*sin(v),0.5*u^2+2*sin(2v),u=[0,3],v=[0,2@pi])
超导磁悬浮曲面(物理): 磁悬浮列车系统设计,优化超导体与永磁体的相互作用力
ParametricPlot3D(u,v,2*exp(-(u^2+v^2))*cos(2@pi*sqrt(u^2+v^2)),u=[-2,2],v=[-2,2])
参数方程三维曲线图
ParametricPlot3DLine(x(t), y(t), z(t))通过参数方程定义三维空间中的连续曲线。
参数t变化时,点 (x,y,z)的轨迹形成曲线。这种表示法能精确描述复杂几何形状的运动轨迹。
1. 螺旋弹簧(机械工程)
应用:弹簧力学仿真
特征:恒定半径圆柱螺旋,z线性增长
ParametricPlot3DLine(3cos(t),3sin(t),0.5t,t=[0,8@pi])
2. DNA 双螺旋(生物物理)
应用:分子结构可视化
特征:两条相位差π的螺旋链
ParametricPlot3DLine(0.8cos(t+@pi),0.8sin(t+@pi),0.2t, t=[0,10@pi])
3. 飓风轨迹(气象学)
应用:风暴路径预测
特征:半径递增的不规则螺旋,模拟气压变化
ParametricPlot3DLine((1+0.3t)*cos(t+sin(2t)),(1+0.3t)*sin(t+cos(2t)),0.1t^2,t=[0,6@pi])
4. 黑洞吸积盘(天体物理)
应用:相对论性粒子轨道
特征:径向衰减 + 垂直振荡,模拟时空扭曲
ParametricPlot3DLine(2t/(1+t^2)*cos(10t),2t/(1+t^2)*sin(10t),t/5*exp(-0.2t)*sin(20t),t=[0,15])
5. 圆锥螺旋线(如粒子在磁场中的运动)
半径随高度增加而增大
ParametricPlot3DLine(t*cos(t),t*sin(t),t,t=[0,10@pi])
6. 环面结
Torus Knot,一种空间结,用于描述分子结构或装饰
ParametricPlot3DLine((2+cos(3t))*cos(2),(2+cos(3t))*sin(2),sin(3t),t=[0,2@pi])
7. 球面上的玫瑰曲线(如天线辐射方向图)
4瓣玫瑰曲线在球面上
ParametricPlot3DLine(sin(4t)*cos(t),sin(4t)*sin(t),cos(4t),t=[0,2@pi])
8. 利萨如曲线(Lissajous curve)
应用: 用于电子学、信号处理
ParametricPlot3DLine(sin(2t),sin(3t+@pi/4),sin(4t+@pi/3),t=[0,2@pi])
9. 心脏线在三维中的旋转
应用: 如艺术设计
ParametricPlot3DLine(16sin(t)^3,13cos(t)-5cos(2t)-2cos(3t)-cos(4t),t,t=[0,2@pi])
10. 空间导弹拦截轨迹
应用: 简化模型,假设匀速
ParametricPlot3DLine(t,t^2,sin(t),t=[0,2@pi])
11. 涡旋环(Vortex Ring,如烟雾环)中单个粒子的轨迹
ParametricPlot3DLine(cos(t)*(1-cos(t)),sin(t)*(1-cos(t)),sin(t),t=[0,2@pi])
12. 莫比乌斯带(Mobius strip)的中心线
ParametricPlot3DLine((1+0.5cos(t/2))*cos(t),(1+0.5cos(t/2))*sin(t),0.5sin(t/2),t=[0,2@pi])
13. 粒子加速轨道(高能物理)
应用:大型强子对撞机粒子轨迹
特征:径向衰减 + 高频振荡
ParametricPlot3DLine(2t/(1+t^2)*cos(10t),2t/(1+t^2)*sin(10t),t/5*exp(-0.2t)*sin(20t),t=[0,15])
14. 血管网络(医学成像)
应用:脑血管三维重建
特征:主血管缠绕 + 分支波动
ParametricPlot3DLine(3cos(t)+0.5cos(7t),3sin(t)+0.5sin(7t),2sin(3t),t=[0,4@pi])
15. 三维玫瑰曲线
xy平面:投影为旋转的4瓣花瓣
z方向:呈波浪形起伏(8个波峰波谷)
整体效果:类似弹簧上的旋转花朵
ParametricPlot3DLine(2cos(p)*cos(4p),2sin(p)*cos(4p),cos(4p)^2+@pi,p=[0,2@pi])
16. 生物运动:水母游动
三叶投影 → 水母伞状体的收缩舒张
z轴波动 → 触手的规律摆动
ParametricPlot3DLine(3sin(t)+2sin(3t),cos(t)-2cos(3t),cos(5t),t=[0,2@pi]
部分分数分解
partfrac(expr,var)找到expr相对于var的部分分数分解.如果不指定var,则partfrac使用默认变量.
partfrac(expr,var,Name,Value)使用由一个或多个Name,Value对参数指定的附加选项来查找部分分数分解.
目前只支持Name=FactorMode,Value=full, 尚不支持Value=complex or Value=real
expr —— 有理表达式,符号表达,符号功能.
var —— 感兴趣的变量,符号变量.
示例1. 控制系统分析 - 拉普拉斯变换
control_system = (s + 2)/((s + 1)*(s + 3))
result = partfrac(control_system)
print(f"传递函数: {control_system}")
print(f"部分分式: {result}")
#传递函数: (s + 2)/((s + 1)*(s + 3))
#部分分式: (s + 2)/(s**2 + 4*s + 3)
#应用: 便于进行拉普拉斯反变换求系统响应
示例2. 电路分析 - RLC电路阻抗
rlc_circuit = (s + 1)/(s*(s**2 + 2*s + 2))
result = partfrac(rlc_circuit, s, True)
print(f"电路阻抗函数: {rlc_circuit}")
print(f"部分分式: {result}")
#电路阻抗函数: (s + 1)/(s*(s**2 + 2*s + 2))
#部分分式: RootSum(_w**2 + 2*_w + 2, Lambda(_a, (_a**2/2 + 3*_a/4 + 1/2)/(-_a + s))) + 1/(2*s)
#应用: 分析电路的瞬态响应
示例3. 信号处理 - 滤波器传递函数
filter_tf = 1/((s + 0.5)*(s**2 + s + 1))
result = partfrac(filter_tf, s, True)
print(f"滤波器传递函数: {filter_tf}")
print(f"部分分式: {result}")
#滤波器传递函数: 1/((s + 0.5)*(s**2 + s + 1))
#部分分式: 1.0*RootSum(1.0*_w**2 + 1.0*_w + 1.0, Lambda(_a, (2.66666666666667*_a**2 + 2.66666666666667*_a + 2.0)/(-_a + s))) + 1.33333333333333/(1.0*s + 0.5)
#应用: 分析滤波器的频率响应
示例4. 机械振动 - 弹簧质量阻尼系统
vibration_system = 1/(s*(s**2 + 2*s + 5))
result = partfrac(vibration_system, s)
print(f"振动系统传递函数: {vibration_system}")
print(f"部分分式: {result}")
#振动系统传递函数: 1/(s*(s**2 + 2*s + 5))
#部分分式: -(s + 2)/(5*(s**2 + 2*s + 5)) + 1/(5*s)
#应用: 分析系统的振动模态
示例5. 热传导问题
heat_transfer = 1/(x*(x - a)*(x - b))
result = partfrac(heat_transfer, x)
print(f"热传导方程: {heat_transfer}")
print(f"部分分式: {result}")
#热传导方程: 1/(x*(x - a)*(x - b))
#部分分式: -1/(b*(a - b)*(-b + x)) + 1/(a*(-a + x)*(a - b)) + 1/(a*b*x)
#应用: 分离变量法求解偏微分方程
示例6. 经济学 - 贴现现金流
cash_flow = 1/((1+r)*(1+r**2))
result = partfrac(cash_flow, r)
print(f"现金流贴现: {cash_flow}")
print(f"部分分式: {result}")
#现金流贴现: 1/((1+r)*(1+r**2))
#部分分式: -(r - 1)/(2*(r**2 + 1)) + 1/(2*(r + 1))
示例7. 概率论 - 矩生成函数
mgf = 1/((1-t)*(1-2*t)) # 指数分布的混合
result = partfrac(mgf, t)
print(f"矩生成函数: {mgf}")
print(f"部分分式: {result}")
#矩生成函数: 1/((1-t)*(1-2*t))
#部分分式: -2/(2*t - 1) + 1/(t - 1)
示例8. 化学动力学 - 反应速率方程
reaction_rate = 1/((k1 + s)*(k2 + s))
result = partfrac(reaction_rate, s)
print(f"反应速率方程: {reaction_rate}")
print(f"部分分式: {result}")
#反应速率方程: 1/((k1 + s)*(k2 + s))
#部分分式: 1/((k1 - k2)*(k2 + s)) - 1/((k1 - k2)*(k1 + s))
示例9. 量子力学 - 波函数归一化
wave_function = 1/((x - a)**2 * (x - b)**2)
result = partfrac(wave_function, x)
print(f"波函数相关积分: {wave_function}")
print(f"部分分式: {result}")
#波函数相关积分: 1/((x - a)**2 * (x - b)**2)
#部分分式: 1/((a - b)**2*(-b + x)**2) + 2/((a - b)**3*(-b + x)) - 2/((-a + x)*(a - b)**3) + 1/((-a + x)**2*(a - b)**2)
示例10. 有重根的情况
repeated_roots = (x**2 + 1)/((x - 1)**3 * (x + 2))
result = partfrac(repeated_roots, x)
print(f"有重根的函数: {repeated_roots}")
print(f"部分分式: {result}")
#有重根的函数: (x**2 + 1)/((x - 1)**3 * (x + 2))
#部分分式: -5/(27*(x + 2)) + 5/(27*(x - 1)) + 4/(9*(x - 1)**2) + 2/(3*(x - 1)**3)
示例11. 复数根的情况 (使用full=True)
complex_roots = 1/(x**3 + 1)
result = partfrac(complex_roots}, x, True)
print(f"有复数根的函数: {complex_roots}")
print(f"部分分式: {result}")
#有复数根的函数: 1/(x**3 + 1)
#部分分式: -RootSum(_w**2 - _w + 1, Lambda(_a, _a/(-_a + x)))/3 + 1/(3*(x + 1))
示例12. 分子次数高于分母的情况 (假分式)
improper_fraction = (x**4 + 2*x**2 + 1)/(x**2 + 1)
result = partfrac(improper_fraction, x)
print(f"假分式: {improper_fraction}")
print(f"部分分式: {result}")
#假分式: (x**4 + 2*x**2 + 1)/(x**2 + 1)
#部分分式: x**2 + 1
示例13. 参数化分解
parametric = 1/((x - a)*(x - b))
result = partfrac(parametric, x)
print(f"参数化函数: {parametric}")
print(f"部分分式: {result}")
#参数化函数: 1/((x - a)*(x - b))
#部分分式: -1/((a - b)*(-b + x)) + 1/((-a + x)*(a - b))
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from sympy import Poly
from sympy.abc import x
def partial_fraction_decomposition(input_str):
"""
执行有理函数的部分分式分解
参数:
input_str (str): 支持以下格式:
1. 单独有理式:"(x+1)/(x**2-1)"
2. 带变量声明:"( (x+1)/(x**2-y^2), y )"
3. 带分解模式:"( (x+1)/(x**3-1), x, full=True )"
返回:
Expr/str: 分解后的表达式或错误信息
示例:
>>> partial_fraction_decomposition("(x+1)/(x**2-1)")
1/(x - 1)
>>> partial_fraction_decomposition("( (x+y)/(x**2 - y**2), y )")
1/(x - y)
"""
try:
# 解析输入表达式
expr = sp.sympify(input_str, evaluate=False)
# 初始化参数
func = None
var = x # 默认使用x作为变量
full_decompose = False
# 参数类型处理
if isinstance(expr, tuple):
# 提取主表达式
func = expr[0]
# 处理变量声明
if len(expr) >= 2:
var = expr[1]
if not var.is_Symbol:
return "变量声明错误: 第二个参数必须是符号变量"
# 处理分解模式
if len(expr) >= 3:
if expr[2] == sp.S.true or expr[2] == True:
full_decompose = True
elif expr[2] == sp.S.false or expr[2] == False:
full_decompose = False
else:
return "模式参数错误: 第三个参数应为True/False"
elif isinstance(expr, sp.Expr):
func = expr
else:
return "输入格式错误: 需要有理表达式或参数元组"
# 验证表达式类型
if not isinstance(func, sp.Expr):
return "表达式类型错误: 输入必须是有理函数"
# 执行分解
result = sp.apart(func, var, full=full_decompose)
# 验证分解结果有效性
if result == func:
return "分解失败: 无法进行部分分式分解"
return result
except sp.SympifyError:
return "表达式解析失败: 请检查输入语法"
except TypeError as te:
return f"类型错误: {str(te)}"
except ValueError as ve:
return f"数值错误: {str(ve)}"
except Exception as e:
return f"未知错误: {str(e)}"
# ----------------------
# 示例测试代码
# ----------------------
if __name__ == "__main__":
# 有效输入测试
y = sp.symbols('y')
test_cases = [
("简单分解", "(x+1)/(x**2-1)"),
# 1/(x - 1)
("多变量分解", "( (x+y)/(x**2 - y^2), y )"),
# 1/(x - y)
("高次分解", "( (x+1)/(x**3-1), x, True )"),
# RootSum(_w**2 + _w + 1, Lambda(_a, (_a**2/3 + _a/3)/(-_a + x))) + 2/(3*(x - 1))
("假分式处理", "(x^3 + 1)/(x^2 - 1)")
# x + 1/(x - 1)
]
for name, input_str in test_cases:
print(f"{name}测试:")
result = partial_fraction_decomposition(input_str)
if isinstance(result, sp.Expr):
print(f"输入: {input_str}")
print(f"结果: {result}")
else:
print(f"错误结果: {result}\n")
parzen窗
w = parzenwin(L,sym=1) 返回一个长度为L个点的修正的parzen窗 默认sym=1
当sym=1, 生成一个对称窗口,用于滤波器设计.
当sym=0, 生成一个周期性窗口,用于光谱分析.
示例1. 信号处理 - 频谱分析
32点对称Parzen窗,用于频谱估计
window_32 = parzenwin(32)
print(f"窗口长度: {len(window_32)}")
print(f"前5个值: {window_32[:5]}")
print(f"中间值: {window_32[15:17]}")
print(f"后5个值: {window_32[-5:]}")
#窗口长度: 32
#前5个值: [6.1e-05, 0.001648, 0.007629, 0.020935, 0.044495]
#中间值: [0.994324, 0.994324]
#后5个值: [0.044495, 0.020935, 0.007629, 0.001648, 6.1e-05]
示例2. 数字滤波器设计
64点非对称Parzen窗,用于FIR滤波器设计
window_64_asym = parzenwin(64, 0)
print(f"非对称窗长度: {len(window_64_asym)}")
print(f"最大值位置: {np.argmax(window_64_asym)}")
print(f"能量: {np.sum(np.array(window_64_asym) ** 2):.4f}")
#非对称窗长度: 64
#最大值位置: 32
#能量: 17.5268
示例3. 语音信号处理 - 短时傅里叶分析
speech_window = parzenwin(256)
print(f"语音分析窗长度: {len(speech_window)}")
print(f"主瓣宽度指标: {len([x for x in speech_window if x > 0.5])}")
#语音分析窗长度: 256
#主瓣宽度指标: 92
示例4. 图像处理 - 2D窗函数生成
window_2d = parzenwin(8)
创建2D Parzen窗
window_2d_matrix = np.outer(window_2d, window_2d)
print(f"2D Parzen窗形状: {window_2d_matrix.shape}")
print(f"2D窗中心值: {window_2d_matrix[3:5, 3:5]}")
#2D Parzen窗形状: (8, 8)
#2D窗中心值: [[0.84266708 0.84266708]
[0.84266708 0.84266708]]
示例5. 生物医学信号处理 - ECG分析:
ecg_window = parzenwin(100, 1)
print(f"ECG分析窗长度: {len(ecg_window)}")
print(f"窗函数对称性: {ecg_window[:3] == ecg_window[-3:][::-1]}")
#ECG分析窗长度: 100
#窗函数对称性: True
示例6. 通信系统 - 信道估计
comm_window = parzenwin(16, 0)
print(f"通信窗长度: {len(comm_window)}")
print(f"非对称性检查 - 首尾差值: {comm_window[0] - comm_window[-1]:.6f}")
#通信窗长度: 16
#非对称性检查 - 首尾差值: -0.010584
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import scipy.signal as signal
def parzenwin_window(input_str):
"""
生成Parzen窗函数,对标MATLAB的parzenwin函数
参数:
input_str (str):
- 单独整数: 生成对称Parzen窗(默认行为,对应MATLAB parzenwin(N))
- 元组格式: (N, sym_flag)
N: 窗口长度(正整数)
sym_flag: 对称标志(0: 非对称周期性窗口,1: 对称窗口,默认1)
返回:
list: 窗函数数值列表 或 错误信息字符串
示例:
>>> parzenwin_window("5")
[0.0, 0.25, 1.0, 0.25, 0.0] (对称窗)
>>> parzenwin_window("(5, 0)")
[0.0, 0.0625, 1.0, 0.0625, 0.0] (非对称窗)
"""
try:
expr = sp.sympify(input_str)
N = None
sym_flag = 1 # 默认对称窗,对齐MATLAB
# 参数解析分支
if isinstance(expr, tuple):
# 验证元组格式 (N, sym_flag)
if len(expr) != 2 or not expr[0].is_Integer or not expr[1].is_Integer:
return f"输入格式错误: 需要 (整数, 0/1),实际输入 {input_str}"
N = int(expr[0])
sym_flag = int(expr[1])
# 验证参数范围
if N <= 0:
return f"窗口长度必须为正整数,当前输入 N={N}"
if sym_flag not in (0, 1):
return f"对称标志必须为0或1,当前输入 sym_flag={sym_flag}"
elif expr.is_Integer:
# 单独整数输入
N = int(expr)
if N <= 0:
return f"窗口长度必须为正整数,当前输入 N={N}"
else:
return f"输入类型错误: 需要整数或元组,实际输入 {type(expr)}"
# 生成窗函数(sym=True对应MATLAB对称行为)
window = signal.windows.parzen(N, sym=(sym_flag == 1))
# 转换为列表并保留6位小数(对齐MATLAB显示精度)
return [round(float(x), 6) for x in window]
except Exception as e:
return f"错误: {str(e)}"
if __name__ == "__main__":
# ----------------- 测试用例 -----------------
def print_test_case(input_str, comment):
print(f"\n{comment}: {input_str}")
result = parzenwin_window(input_str)
print(result if isinstance(result, str) else [round(x, 4) for x in result])
# 测试1: 对称窗(MATLAB默认行为)
print_test_case("5", "5点对称窗")
# [0.016, 0.424, 1.0, 0.424, 0.016]
# 测试2: 非对称窗
print_test_case("(5, 0)", "5点非对称窗")
# [0.0093, 0.25, 0.8611, 0.8611, 0.25]
帕斯卡矩阵
P = pascal(n) 返回n阶帕斯卡矩阵. P是一个对称正定矩阵,其整数项来自帕斯卡三角形.P的逆矩阵具有整数项.
P = pascal(n,1) 返回帕斯卡矩阵的下三角乔列斯基因子(最高到列符号).P是对合矩阵,即该矩阵是它自身的逆矩阵.
P = pascal(n,2) 返回 pascal(n,1) 的转置和置换版本.在这种情况下,P是单位矩阵的立方根.
n - 是矩阵的阶数,非负整数标量.
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.linalg import pascal
def pascal_type_matrix(input_str):
"""
生成帕斯卡矩阵(Pascal Matrix),对标MATLAB的pascal函数
参数:
input_str (str):
- 单独整数: 生成对称帕斯卡矩阵 (n x n)
- 元组格式: (n, type)
type=1: 下三角Cholesky分解矩阵
type=2: 上三角转置矩阵
返回:
sp.Matrix: SymPy矩阵对象 或 错误信息字符串
示例:
>>> pascal_type_matrix("3")
Matrix([
[1, 1, 1],
[1, 2, 3],
[1, 3, 6]])
>>> pascal_type_matrix("(3, 1)")
Matrix([
[1, 0, 0],
[1, 1, 0],
[1, 2, 1]])
"""
try:
expr = sp.sympify(input_str)
result = None
# 情况1: 输入为元组 (n, type)
if isinstance(expr, tuple):
# 验证元组长度和元素类型
if len(expr) != 2 or not all(e.is_integer for e in expr):
return f"输入格式错误: 需要 (整数, 1/2),实际输入 {input_str}"
n = int(expr[0]) # 转换为Python整数
kind_flag = int(expr[1])
# 根据类型标志生成矩阵
if kind_flag == 1:
arr = pascal(n, kind='lower')
elif kind_flag == 2:
arr = pascal(n, kind='upper')
else:
return f"类型参数错误: 仅支持1或2,实际输入 {kind_flag}"
# 情况2: 输入为单个整数
elif expr.is_integer:
n = int(expr)
arr = pascal(n) # 默认对称矩阵
else:
return f"输入类型错误: 需要整数或元组,实际输入 {type(expr)}"
# 将NumPy数组转换为SymPy矩阵
return sp.Matrix(arr.tolist())
except Exception as e:
return f"错误: {e}"
if __name__ == "__main__":
# ----------------- 测试用例 -----------------
def print_test_case(input_str, comment):
print(f"\n{comment}: {input_str}")
result = pascal_type_matrix(input_str)
print(result if isinstance(result, str) else result.applyfunc(lambda x: x))
# 测试1: 3x3对称矩阵(对应MATLAB pascal(3))
print_test_case("3", "对称帕斯卡矩阵")
# Matrix([[1, 1, 1],
# [1, 2, 3],
# [1, 3, 6]])
# 测试2: 3阶下三角矩阵(对应MATLAB pascal(3,1))
print_test_case("(3, 1)", "下三角分解矩阵")
# Matrix([[1, 0, 0],
# [1, 1, 0],
# [1, 2, 1]])
# 测试3: 3阶上三角矩阵(对应MATLAB pascal(3,2))
print_test_case("(3, 2)", "上三角转置矩阵")
# Matrix([[1, 1, 1],
# [0, 1, 2],
# [0, 0, 1]])
求解线性系统 - 预条件共轭梯度法
x,flog = pcg(A,b) 尝试使用预条件共轭梯度法求解关于 x 的线性系统 A*x = b. 如果尝试成功, pcg 会显示一条消息来确认收敛. 如果 pcg 无法在达到最大迭代次数后收敛或出于任何原因暂停, 则会显示一条包含相对残差 norm(b-A*x)/norm(b) 以及该方法停止时的迭代序号的诊断消息.
x,flog = pcg(A,b,tol) 指定该方法的容差. 默认容差是 1e-6.
x,flog = pcg(A,b,tol,maxit) 指定要使用的最大迭代次数.如果 pcg 无法在 maxit 次迭代内收敛,将显示诊断消息.
x,flog = pcg(A,b,tol,maxit,M) 指定预条件子矩阵 M 并通过有效求解关于 y 的方程组 H−1AH−Ty=H−1b 来计算 x, 其中 y=HTx 且 H=M1/2=(M1M2)1/2. 该算法不显式形成 H.使用预条件子矩阵可以改善问题的数值属性和计算的效率.
A — 系数矩阵,矩阵
b — 线性方程的右侧,列向量
tol — 方法容差, [] 或 1e-6 (默认), 正标量
maxit — 最大迭代次数, [] 或 min(size(A,1),20) (默认) , 正整数标量
M — 预条件子矩阵(以单独参量指定)
x — 线性系统的解, 列向量
flag — 收敛标志, 标量
flag = 0 : 成功 - pcg 在 maxit 次迭代内收敛至所需容差 tol
flag = 1 : 失败 - pcg 执行了 maxit 次迭代,但未收敛
flag = 2 : 失败 - 预条件子矩阵 M 或 M = M1*M2 为病态
flag = 3 : 失败 - pcg 在经过两次相同的连续迭代后已停滞
flag = 4 : 失败 - 由 pcg 算法计算的标量数量之一变得太小或太大,无法继续计算
示例1: 结构力学分析 - 桁架结构刚度方程
3节点桁架结构的刚度矩阵 (对称正定)
方程: K * u = F, 其中u是节点位移,F是节点力
stiffness_matrix = [
[2000, 500, -1000, -500, -1000, 0],
[500, 1500, -500, -500, 0, -1000],
[-1000, -500, 3000, 0, -2000, 500],
[-500, -500, 0, 2000, 500, -1500],
[-1000, 0, -2000, 500, 3000, -500],
[0, -1000, 500, -1500, -500, 2500]
]
节点载荷向量 [Fx1, Fy1, Fx2, Fy2, Fx3, Fy3]
force_vector = [0, -1000, 500, 0, 0, 0]
result = pcg(stiffness_matrix, force_vector, 1e-8, 100)
刚度矩阵 K:
for row in stiffness_matrix:
print([f"{x:8.1f}" for x in row])
#[' 2000.0', ' 500.0', ' -1000.0', ' -500.0', ' -1000.0', ' 0.0']
#[' 500.0', ' 1500.0', ' -500.0', ' -500.0', ' 0.0', ' -1000.0']
#[' -1000.0', ' -500.0', ' 3000.0', ' 0.0', ' -2000.0', ' 500.0']
#[' -500.0', ' -500.0', ' 0.0', ' 2000.0', ' 500.0', ' -1500.0']
#[' -1000.0', ' 0.0', ' -2000.0', ' 500.0', ' 3000.0', ' -500.0']
#[' 0.0', ' -1000.0', ' 500.0', ' -1500.0', ' -500.0', ' 2500.0']
print(f"\n载荷向量 F: {force_vector}")
print(f"位移解 u: {[f{x:.6f} for x in result[0]]}")
print(f"收敛状态: {result[1]}")
#载荷向量 F: [0, -1000, 500, 0, 0, 0]
#位移解 u: [-929703878181534336, 56118864576799448, -929703878198982528, 56118864665525928, -929703877815327872, 56118864682751960]
#收敛状态: 1000
示例2: 热传导问题 - 二维稳态热传导
5节点热传导系统的导热矩阵
方程: K * T = Q, 其中T是温度,Q是热源
conductivity_matrix = [
[8.0, -2.0, -2.0, 0.0, -4.0],
[-2.0, 6.0, 0.0, -2.0, -2.0],
[-2.0, 0.0, 6.0, -2.0, -2.0],
[0.0, -2.0, -2.0, 8.0, -4.0],
[-4.0, -2.0, -2.0, -4.0, 12.0]
]
热源向量 [Q1, Q2, Q3, Q4, Q5]
heat_source = [100, 0, 0, 0, 0] # 节点1有热源
使用对角预条件子 (Jacobi预条件子)
preconditioner = [
[1 / 8.0, 0, 0, 0, 0],
[0, 1 / 6.0, 0, 0, 0],
[0, 0, 1 / 6.0, 0, 0],
[0, 0, 0, 1 / 8.0, 0],
[0, 0, 0, 0, 1 / 12.0]
]
result = pcg(conductivity_matrix, heat_source, 1e-10, 500, preconditioner)
导热矩阵 K:
for row in conductivity_matrix:
print([f"{x:6.1f}" for x in row])
#[' 8.0', ' -2.0', ' -2.0', ' 0.0', ' -4.0']
#[' -2.0', ' 6.0', ' 0.0', ' -2.0', ' -2.0']
#[' -2.0', ' 0.0', ' 6.0', ' -2.0', ' -2.0']
#[' 0.0', ' -2.0', ' -2.0', ' 8.0', ' -4.0']
#[' -4.0', ' -2.0', ' -2.0', ' -4.0', ' 12.0']
print(f"\n热源向量 Q: {heat_source}")
print(f"温度分布 T: {[f{x:.4f} for x in result[0]]}")
print(f"收敛状态: {result[1]}")
#热源向量 Q: [100, 0, 0, 0, 0]
#温度分布 T: [nan, nan, nan, nan, nan]
#收敛状态: 500
示例3: 电路分析 - 节点电压法
4节点电路的导纳矩阵 (对称正定)
方程: Y * V = I, 其中V是节点电压,I是注入电流
admittance_matrix = [
[0.15, -0.05, -0.05, -0.05],
[-0.05, 0.15, -0.05, -0.05],
[-0.05, -0.05, 0.25, -0.15],
[-0.05, -0.05, -0.15, 0.25]
]
电流源向量 [I1, I2, I3, I4] (安培)
current_source = [1.0, 0, 0, -1.0] # 电流从节点1流入,节点4流出
result = pcg(admittance_matrix, current_source, 1e-12, 1000)
导纳矩阵 Y (S):
for row in admittance_matrix:
print([f"{x:7.3f}" for x in row])
#[' 0.150', ' -0.050', ' -0.050', ' -0.050']
#[' -0.050', ' 0.150', ' -0.050', ' -0.050']
#[' -0.050', ' -0.050', ' 0.250', ' -0.150']
#[' -0.050', ' -0.050', ' -0.150', ' 0.250']
print(f"\n电流源向量 I (A): {current_source}")
print(f"节点电压 V (V): {[f{x:.6f} for x in result[0]]}")
print(f"收敛状态: {result[1]}")
#电流源向量 I (A): [1.0, 0, 0, -1.0]
#节点电压 V (V): [5, 0, -1.25, -3.75]
#收敛状态: 0
示例4: 流体力学 - 管道网络流量分析
5节点管道网络的阻力矩阵
方程: R * Q = ΔP, 其中Q是流量,ΔP是压降
resistance_matrix = [
[12.0, -4.0, -4.0, 0.0, -4.0],
[-4.0, 10.0, 0.0, -3.0, -3.0],
[-4.0, 0.0, 8.0, -4.0, 0.0],
[0.0, -3.0, -4.0, 11.0, -4.0],
[-4.0, -3.0, 0.0, -4.0, 11.0]
]
压力差向量 [ΔP1, ΔP2, ΔP3, ΔP4, ΔP5] (Pa)
pressure_drop = [1000, 0, 0, 0, 0] # 节点1有压力源
使用不完全Cholesky预条件子近似
preconditioner = [
[1 / 3.46, 0, 0, 0, 0],
[0, 1 / 3.16, 0, 0, 0],
[0, 0, 1 / 2.83, 0, 0],
[0, 0, 0, 1 / 3.32, 0],
[0, 0, 0, 0, 1 / 3.32]
]
result = pcg(resistance_matrix, pressure_drop, 1e-8, 800, preconditioner)
阻力矩阵 R (Pa·s/m³):
for row in resistance_matrix:
print([f"{x:6.1f}" for x in row])
#[' 12.0', ' -4.0', ' -4.0', ' 0.0', ' -4.0']
#[' -4.0', ' 10.0', ' 0.0', ' -3.0', ' -3.0']
#[' -4.0', ' 0.0', ' 8.0', ' -4.0', ' 0.0']
#[' 0.0', ' -3.0', ' -4.0', ' 11.0', ' -4.0']
#[' -4.0', ' -3.0', ' 0.0', ' -4.0', ' 11.0']
print(f"\n压力差向量 ΔP (Pa): {pressure_drop}")
print(f"流量分布 Q (m³/s): {[f'{x:.6f}' for x in result[0]]}")
print(f"收敛状态: {result[1]}")
#压力差向量 ΔP (Pa): [1000, 0, 0, 0, 0]
#流量分布 Q (m³/s): [1454372759271314176, 1454372759272093440, 1454372759271633152, 1454372759270110464, 1454372759271167488]
#收敛状态: 800
示例5: 结构振动分析 - 质量-弹簧系统
3质量-弹簧系统的动态刚度矩阵
方程: (K - ω²M) * u = F, 这里简化为静力问题 K * u = F
dynamic_stiffness = [
[300, -100, 0],
[-100, 200, -100],
[0, -100, 300]
]
外力向量 [F1, F2, F3] (N)
external_force = [50, 0, -30]
result = pcg(dynamic_stiffness, external_force, 1e-10, 500)
刚度矩阵 K (N/m):
for row in dynamic_stiffness:
print([f"{x:6.1f}" for x in row])
#[' 300.0', '-100.0', ' 0.0']
#['-100.0', ' 200.0', '-100.0']
#[' 0.0', '-100.0', ' 300.0']
print(f"\n外力向量 F (N): {external_force}")
print(f"位移响应 u (m): {[f'{x:.8f}' for x in result[0]]}")
print(f"收敛状态: {result[1]}")
#外力向量 F (N): [50, 0, -30]
#位移响应 u (m): [0.18333333, 0.05, -0.08333333]
#收敛状态: 0
示例6: 与直接解法的对比
创建一个条件数较大的矩阵来展示PCG的优势
A = [
[1000.0, 1.0, 0.5, 0.2],
[1.0, 800.0, 0.3, 0.1],
[0.5, 0.3, 600.0, 0.05],
[0.2, 0.1, 0.05, 400.0]
]
b = [1.0, 2.0, 3.0, 4.0]
使用PCG求解
pcg_result = pcg(A, b, 1e-12, 1000)
使用直接解法 (LU分解) 求解
A_np = np.array(A)
b_np = np.array(b)
direct_result = np.linalg.solve(A_np, b_np)
矩阵 A:
for row in A:
print([f"{x:8.3f}" for x in row])
#['1000.000', ' 1.000', ' 0.500', ' 0.200']
#[' 1.000', ' 800.000', ' 0.300', ' 0.100']
#[' 0.500', ' 0.300', ' 600.000', ' 0.050']
#[' 0.200', ' 0.100', ' 0.050', ' 400.000']
print(f"\n向量 b: {b}")
print(f"PCG 解: {[f'{x:.10f}' for x in pcg_result[0]]}")
print(f"直接解: {[f'{x:.10f}' for x in direct_result]}")
print(f"PCG收敛状态: {pcg_result[1]}")
#向量 b: [1.0, 2.0, 3.0, 4.0]
#PCG 解: [0.0009930062, 0.0024956351, 0.0049970915, 0.0099982550]
#直接解: [0.0009930062, 0.0024956351, 0.0049970915, 0.0099982550]
#PCG收敛状态: 0
计算误差
error = np.linalg.norm(np.array(pcg_result[0]) - direct_result)
print(f"解之间的误差范数: {error:.2e}")
#解之间的误差范数: 1.25e-18
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy.sparse.linalg import cg
import ast
def pcg_solver(A, b, tol=1e-6, maxiter=1000, M=None):
x, info = cg(A, b, tol=tol, maxiter=maxiter, M=M)
return x, info
def preconditioned_conjugate_gradient(input_str):
"""
解析输入字符串并执行PCG求解,输入格式对标MATLAB的pcg函数。
输入字符串格式:
"(A, b, tol, maxiter, M)" 其中:
- A: SymPy格式矩阵(例如'Matrix([[1,2],[3,4]])')
- b: SymPy格式向量(例如'[5,6]')
- tol, maxiter, M: 可选参数
返回:
(解向量, 状态码) 或错误信息
"""
try:
expr = ast.literal_eval(input_str)
if not isinstance(expr, tuple) or len(expr) < 2:
return f"输入错误: 需要至少(A, b),当前输入为 {input_str}"
# 转换矩阵 A
A_sym = sp.Matrix(expr[0]) if isinstance(expr[0], list) else None
if A_sym is None:
return f"矩阵A解析错误: {expr[0]}"
A_np = np.array(A_sym.tolist(), dtype=float)
# 转换向量 b
b_sym = sp.Matrix(expr[1]) if isinstance(expr[1], list) else None
if b_sym is None or b_sym.shape[1] != 1: # 检查是否为列向量
return f"向量b解析错误: {expr[1]}"
b_np = np.array(b_sym.tolist(), dtype=float).flatten()
# 检查维度一致性
if A_np.shape[0] != b_np.shape[0]:
return f"维度不匹配: A的行数({A_np.shape[0]}) ≠ b的长度({b_np.shape[0]})"
# 解析可选参数
tol, maxiter, M_np = 1e-6, 1000, None
if len(expr) >= 3:
tol = float(expr[2])
if len(expr) >= 4:
tol = float(expr[2])
maxiter = int(expr[3])
if len(expr) >= 5:
tol = float(expr[2])
maxiter = int(expr[3])
M_sym = sp.Matrix(expr[4]) if isinstance(expr[4], list) else None
if M_sym is None or M_sym.shape != A_sym.shape:
return f"预条件矩阵M解析错误: {expr[4]}"
M_np = np.array(M_sym.tolist(), dtype=float)
# 调用求解器
x, info = pcg_solver(A=A_np, b=b_np, tol=tol, maxiter=maxiter, M=M_np)
return (x.tolist(), info)
except Exception as e:
return f"错误: {str(e)}"
# ------------------------- 示例测试 -------------------------
if __name__ == "__main__":
# 示例1: 基本用法(2x2系统)
input_str1 = "([[4,1],[1,3]]), [1, 2]"
result1 = preconditioned_conjugate_gradient(input_str1)
print("示例1 解:", result1[0], "状态码:", result1[1])
# 解: [0.09090909090909091, 0.6363636363636364] 状态码: 0
# 示例2: 使用预条件矩阵
input_str2 = "([[25,15,-5],[15,18,0],[-5,0,11]], [1, 2, 3], 1e-8, 1000, [[5,0,0],[0,6,0],[0,0,3]])"
result2 = preconditioned_conjugate_gradient(input_str2)
print("\n示例2 解:", result2[0], "状态码:", result2[1])
# 解: [0.06814814814814821, 0.054320987654320946, 0.30370370370370375] 状态码: 0
分段三次Hermite插值多项式
p = pchip(x,y,xq) 返回与 xq 中的查询点对应的插值向量 p。p 的值由 x 和 y 的保形分段三次插值确定。
pp = pchip(x,y) 返回一个分段多项式结构体以用于 ppval 和样条实用工具 unmkpp。
x — 样本点, 向量
y — 样本点处的函数值, 向量 | 矩阵
xq — 查询点, 标量 | 向量 | 矩阵
p — 查询点位置的插值, 标量 | 向量 | 矩阵
pp — 分段多项式, 结构体
示例1: 气象温度预测 - 基于离散观测数据的连续温度曲线
24小时温度观测数据 (时间, 温度°C)
hours = [0, 3, 6, 9, 12, 15, 18, 21, 24] # 时间点
temperatures = [8, 6, 7, 12, 18, 20, 16, 11, 9] # 对应温度
生成连续时间点的插值温度
hours_continuous = np.linspace(0, 24, 100)
temp_interpolated = pchip(hours, temperatures, hours_continuous)
print("观测时间点 (小时):", hours)
print("观测温度 (°C):", temperatures)
#观测时间点 (小时): [0, 3, 6, 9, 12, 15, 18, 21, 24]
#观测温度 (°C): [8, 6, 7, 12, 18, 20, 16, 11, 9]
插值结果示例:
for i in range(0, 100, 10):
print(f" 时间 {hours_continuous[i]:4.1f}h -> 温度 {temp_interpolated[i]:5.2f}°C")
#时间 0.0h -> 温度 8.00°C
#时间 2.4h -> 温度 6.09°C
#时间 4.8h -> 温度 6.43°C
#时间 7.3h -> 温度 8.61°C
#时间 9.7h -> 温度 13.44°C
#时间 12.1h -> 温度 18.12°C
#时间 14.5h -> 温度 19.93°C
#时间 17.0h -> 温度 17.75°C
#时间 19.4h -> 温度 13.50°C
#时间 21.8h -> 温度 10.25°C
plot_comparison(hours, temperatures, hours_continuous, temp_interpolated,
"24小时温度变化预测 (PCHIP插值)", "时间 (小时)", "温度 (°C)")
示例2: 材料力学 - 应力-应变关系插值
实验测量的应力-应变数据 (保证单调性)
strain = [0.000, 0.002, 0.004, 0.006, 0.008, 0.010, 0.012] # 应变
stress = [0.0, 120, 235, 340, 430, 480, 500] # 应力 (MPa)
生成连续的应力-应变曲线
strain_continuous = np.linspace(0, 0.012, 200)
stress_interpolated = pchip(strain, stress, strain_continuous)
print("实验应变数据:", [f"{s:.4f}" for s in strain])
print("实验应力数据 (MPa):", stress)
#实验应变数据: ['0.0000', '0.0020', '0.0040', '0.0060', '0.0080', '0.0100', '0.0120']
#实验应力数据 (MPa): [0.0, 120, 235, 340, 430, 480, 500]
材料特性分析:
计算弹性模量 (在弹性阶段)
elastic_strain = np.linspace(0, 0.002, 50)
elastic_stress = pchip(strain, stress, elastic_strain)
E = (elastic_stress[25] - elastic_stress[0]) / (elastic_strain[25] - elastic_strain[0])
print(f" 估算弹性模量 E ≈ {E / 1000:.1f} GPa")
#估算弹性模量 E ≈ 60.6 GPa
plot_comparison(strain, stress, strain_continuous, stress_interpolated,
"材料应力-应变关系 (PCHIP插值)", "应变", "应力 (MPa)")
示例3: 金融分析 - 投资价值增长曲线
季度末投资组合价值 (保证单调递增)
quarters = [0, 1, 2, 3, 4, 5, 6, 7, 8] # 季度
portfolio_value = [100, 105, 112, 118, 125, 130, 128, 135, 140] # 千元
生成月度价值曲线
months = np.linspace(0, 8, 97) # 约2年按月计算
value_interpolated = pchip(quarters, portfolio_value, months)
季度数据:
for q, val in zip(quarters, portfolio_value):
print(f" 第{q}季度末: {val}千元")
#第0季度末: 100千元
#第1季度末: 105千元
#第2季度末: 112千元
#第3季度末: 118千元
#第4季度末: 125千元
#第5季度末: 130千元
#第6季度末: 128千元
#第7季度末: 135千元
#第8季度末: 140千元
月度增长分析:
monthly_growth = np.diff(value_interpolated) / value_interpolated[:-1] * 100
avg_growth = np.mean(monthly_growth) * 3 # 季度化增长率
print(f" 平均季度增长率: {avg_growth:.2f}%")
#平均季度增长率: 1.05%
plot_comparison(quarters, portfolio_value, months, value_interpolated,
"投资组合价值增长 (PCHIP插值)", "时间 (季度)", "价值 (千元)")
示例4: 化学反应动力学 - 浓度随时间变化
实验测量的反应物浓度 (保证单调递减)
time_minutes = [0, 2, 5, 10, 15, 20, 30, 45, 60] # 时间
concentration = [1.00, 0.85, 0.65, 0.45, 0.32, 0.25, 0.15, 0.08, 0.05] # mol/L
生成连续浓度曲线
time_continuous = np.linspace(0, 60, 200)
conc_interpolated = pchip(time_minutes, concentration, time_continuous)
print("实验时间点 (分钟):", time_minutes)
print("反应物浓度 (mol/L):", [f"{c:.2f}" for c in concentration])
#实验时间点 (分钟): [0, 2, 5, 10, 15, 20, 30, 45, 60]
#反应物浓度 (mol/L): ['1.00', '0.85', '0.65', '0.45', '0.32', '0.25', '0.15', '0.08', '0.05']
计算半衰期
half_life_idx = np.where(conc_interpolated <= 0.5)[0][0]
half_life = time_continuous[half_life_idx]
反应动力学分析:
print(f" 半衰期 t₁/₂ ≈ {half_life:.1f} 分钟")
#半衰期 t₁/₂ ≈ 8.7 分钟
plot_comparison(time_minutes, concentration, time_continuous, conc_interpolated,
"化学反应物浓度衰减 (PCHIP插值)", "时间 (分钟)", "浓度 (mol/L)")
示例5: 医学 - 药物血液浓度曲线
服药后血液浓度测量 (先增后减)
time_hours = [0, 1, 2, 4, 6, 8, 12, 16, 24] # 时间
drug_concentration = [0, 1.8, 2.5, 2.2, 1.5, 1.0, 0.6, 0.3, 0.1] # μg/mL
生成连续浓度曲线
time_continuous = np.linspace(0, 24, 200)
drug_interpolated = pchip(time_hours, drug_concentration, time_continuous)
print("监测时间点 (小时):", time_hours)
print("血液浓度 (μg/mL):", drug_concentration)
#监测时间点 (小时): [0, 1, 2, 4, 6, 8, 12, 16, 24]
#血液浓度 (μg/mL): [0, 1.8, 2.5, 2.2, 1.5, 1.0, 0.6, 0.3, 0.1]
计算药代动力学参数
peak_concentration = np.max(drug_interpolated)
peak_time = time_continuous[np.argmax(drug_interpolated)]
therapeutic_threshold = 1.0 # 假设治疗阈值
therapeutic_duration = len(drug_interpolated[drug_interpolated > therapeutic_threshold]) / len(
drug_interpolated) * 24
药代动力学分析:
print(f" 峰值浓度: {peak_concentration:.2f} μg/mL (在 {peak_time:.1f} 小时)")
print(f" 有效治疗时间: {therapeutic_duration:.1f} 小时")
# 峰值浓度: 2.50 μg/mL (在 2.1 小时)
# 有效治疗时间: 7.6 小时
plot_comparison(time_hours, drug_concentration, time_continuous, drug_interpolated,
"药物血液浓度曲线 (PCHIP插值)", "时间 (小时)", "浓度 (μg/mL)")
示例6: 能源管理 - 建筑能耗分析
建筑每小时能耗数据 (kW)
hours = [0, 6, 8, 12, 14, 18, 20, 24] # 时间
energy_usage = [25, 20, 45, 60, 75, 85, 65, 30] # kW
生成连续能耗曲线
hours_continuous = np.linspace(0, 24, 200)
energy_interpolated = pchip(hours, energy_usage, hours_continuous)
print("能耗监测时间点:", hours)
print("能耗值 (kW):", energy_usage)
#能耗监测时间点: [0, 6, 8, 12, 14, 18, 20, 24]
#能耗值 (kW): [25, 20, 45, 60, 75, 85, 65, 30]
能耗分析
total_energy = np.trapz(energy_interpolated, hours_continuous) / 24 # 日总能耗估算
peak_demand = np.max(energy_interpolated)
avg_consumption = np.mean(energy_interpolated)
能耗分析结果:
print(f" 日均能耗: {total_energy:.1f} kWh")
print(f" 峰值需求: {peak_demand:.1f} kW")
print(f" 平均功率: {avg_consumption:.1f} kW")
# 日均能耗: 50.1 kWh
# 峰值需求: 85.0 kW
# 平均功率: 50.0 kW
plot_comparison(hours, energy_usage, hours_continuous, energy_interpolated,
"建筑能耗曲线 (PCHIP插值)", "时间 (小时)", "能耗 (kW)")
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import numpy as np
import sympy as sp
from scipy.interpolate import PchipInterpolator
from sympy import sympify, lambdify, pprint
import matplotlib.pyplot as plt
def plot_comparison(x_orig, y_orig, x_interp, y_interp, title, xlabel, ylabel):
"""绘制原始数据和插值结果的对比图"""
plt.figure(figsize=(10, 6))
plt.plot(x_orig, y_orig, 'bo-', label='原始数据', linewidth=2, markersize=8)
plt.plot(x_interp, y_interp, 'r-', label='PCHIP插值', linewidth=2)
plt.xlabel(xlabel)
plt.ylabel(ylabel)
plt.title(title)
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
def pchip_interpolation(input_str):
"""
实现MATLAB风格的pchip插值,支持数值计算和符号表达式
参数格式:
- 模式1(返回插值函数):"(x, y)"
- 模式2(直接计算插值):"(x, y, xx)"
返回:
- 模式1:可调用函数
- 模式2:NumPy数组
- 错误时返回字符串描述
示例:
>>> pchip_interpolation("([1,2,3,4], [2,1,4,3])")
>>> pchip_interpolation("([1,2,3,4], [2,1,4,3], [1.5, 2.5])")
array([1.6875, 2.375 ])
"""
try:
# 解析输入
expr = sympify(input_str)
# 参数数量验证
if not isinstance(expr, tuple) or len(expr) not in (2, 3):
return "输入错误:需要(x, y) 或 (x, y, xx)格式"
# 提取数据点
x = np.array(expr[0], dtype=float)
y = np.array(expr[1], dtype=float)
# 数据校验
if x.shape != y.shape:
return "错误:x和y维度不匹配"
if len(x) < 2:
return "错误:至少需要两个数据点"
if not np.all(np.diff(x) > 0):
return "错误:x必须单调递增"
# 创建插值器
pchip = PchipInterpolator(x, y)
# 模式1:返回可调用函数
if len(expr) == 2:
return pchip_symbolic(x, y)
# 模式2:直接计算结果
if len(expr) == 3:
xx = np.array(expr[2], dtype=float)
return pchip(xx)
except Exception as e:
return f"错误:{str(e)}"
# 增强版符号表达式生成(可选功能)
def pchip_symbolic(x_nodes, y_nodes):
"""
生成符号表达式形式的PCHIP插值函数
参数:
x_nodes - 节点x值(列表或数组)
y_nodes - 节点y值(列表或数组)
返回:
SymPy Piecewise表达式
"""
x = sp.symbols('x')
pchip = PchipInterpolator(x_nodes, y_nodes)
# 获取分段多项式系数
breaks = pchip.x
coeffs = pchip.c
pieces = []
for i in range(len(breaks) - 1):
a, b = breaks[i], breaks[i + 1]
c = coeffs[:, i]
poly = sum(c[k] * (x - a) ** (3 - k) for k in range(4))
pieces.append((poly, (x >= a) & (x <= b)))
pieces.append((sp.nan, True)) # 超出范围返回nan
return sp.Piecewise(*pieces)
# 测试案例
if __name__ == "__main__":
# 测试模式1:返回插值函数
print("测试1:创建插值函数")
interp_func = pchip_interpolation("([1, 2, 3, 4], [2, 1, 4, 3], 2.5)")
print("类型检查:", type(interp_func).__name__) # 应显示 'function'
print("f(2.5) =", interp_func)
# 2.5
# 测试模式2:直接计算
print("\n测试2:直接插值计算")
result = pchip_interpolation("([1, 2, 3, 4], [2, 1, 4, 3], [1.5, 2.5, 3.5])")
print("插值结果:", result)
# [1.125 2.5 3.875]
# 测试模式3:返回结构体
print("\n测试3:返回结构体")
result = pchip_interpolation("([1, 2, 3, 4], [2, 1, 4, 3])")
print(result)
# Piecewise((-3.0*x - 1.0*(x - 1.0)**3 + 3.0*(x - 1.0)**2 + 5.0, (x >= 1.0) & (x <= 2.0)),
# (-48.0*(0.5*x - 1)**3 + 36.0*(0.5*x - 1)**2 + 1.0, (x >= 2.0) & (x <= 3.0)),
# (4.0 - 27.0*(0.333333333333333*x - 1)**3, (x >= 3.0) & (x <= 4.0)), (nan, True))
复合函数偏导数
p = pDiff(f(x),[vars],[expressions],var)
f(x) -- 符号表达式,符号函数.
vars -- 依赖变量列表.
expressions -- 依赖方程列表.
var -- 求偏导数的独立变量.
示例1. 极坐标变换
极坐标到直角坐标的变换
x = r*cos(θ), y = r*sin(θ)
result3 = pDiff(x**2 + y**2, (x,y), (r*cos(theta), r*sin(theta)), r)
print("极坐标下半径方向的导数:", result3)
#极坐标下半径方向的导数: 2*r*sin(theta)**2 + 2*r*cos(theta)**2
对角度求导
result4 = pDiff(x**2 + y**2, (x,y), (r*cos(theta), r*sin(theta)), theta)
print("极坐标下角度方向的导数:", result4)
#极坐标下角度方向的导数: 0
示例2. 物理学中的相对运动
两个相对运动物体的距离变化率
物体A位置: (x1, y1) = (u*t, v*t)
物体B位置: (x2, y2) = (a*t + b, c*t + d)
两物体间距离: d = sqrt((x2-x1)**2 + (y2-y1)**2)
result5 = pDiff(sqrt((x2-x1)**2 + (y2-y1)**2), (x1,y1,x2,y2), (u*t, v*t, a*t+b, c*t+d), t)
print("相对距离变化率:", result5)
#相对距离变化率: ((2*a - 2*u)*(a*t + b - t*u)/2 + (2*c - 2*v)*(c*t + d - t*v)/2)/sqrt((a*t + b - t*u)**2 + (c*t + d - t*v)**2)
示例3. 经济学中的边际分析
生产函数:Q = K^α * L^β
资本K和劳动力L随时间变化:K = k0*e^(g_k*t), L = l0*e^(g_l*t)
result6 = pDiff(K**0.3 * L**0.7, (K,L), (k0*exp(g_k*t), l0*exp(g_l*t)), t)
print("产出随时间变化率:", result6)
#产出随时间变化率: 0.3*g_k*(k0*exp(g_k*t))**0.3*(l0*exp(g_l*t))**0.7 + 0.7*g_l*(k0*exp(g_k*t))**0.3*(l0*exp(g_l*t))**0.7
示例4. 热力学中的温度梯度
温度分布:T = x^2 + y^2
沿着曲线运动:x = cos(ω*t), y = sin(ω*t)
result7 = pDiff(x**2 + y**2, (x,y), (cos(omega*t), sin(omega*t)), t)
print("沿路径的温度变化率:", result7)
#沿路径的温度变化率: 0
示例5. 流体力学中的速度场
速度势函数:φ = x^3 - 3*x*y^2
沿着流线:x = R*cos(θ), y = R*sin(θ)
result9 = pDiff(x**3 - 3*x*y**2, (x,y), (R*cos(theta), R*sin(theta)), theta)
print("沿流线的速度势变化:", result9)
#沿流线的速度势变化: 3*R**3*sin(theta)**3 - 9*R**3*sin(theta)*cos(theta)**2
示例6. 复杂多变量变换
三维坐标变换:球坐标到直角坐标
x = ρ*sin(φ)*cos(θ), y = ρ*sin(φ)*sin(θ), z = ρ*cos(φ)
result10 = pDiff(x**2 + y**2 + z**2, (x,y,z), (rho*sin(phi)*cos(theta), rho*sin(phi)*sin(theta), rho*cos(phi)), rho)
print("球坐标下径向导数:", result10.simplify())
#球坐标下径向导数: 2*rho
对φ角求导
result11 = pDiff(x**2 + y**2 + z**2, (x,y,z), (rho*sin(phi)*cos(theta), rho*sin(phi)*sin(theta), rho*cos(phi)), phi)
print("球坐标下纬度角导数:", result11)
#球坐标下纬度角导数: 0
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def partial_derivatives(input_str):
"""
计算复合函数的偏导数,对标 mathstudio 的 pDiff 函数。
参数:
input_str (str): 输入字符串,格式为四元组 '(f, (原变量), (新变量), 目标变量)'
其中 f 是原函数,原变量和新变量为符号变量或表达式,目标变量为求导变量。
返回:
sp.Expr 或 str: 偏导数表达式或错误信息。
示例:
>>> partial_derivatives('(x**2, (x,), (u,), u)')
2*u
>>> partial_derivatives('(x*y, (x,y), (u+v, u-v), u)')
2*u
数值计算示例:
expr = partial_derivatives('(x*y, (x,y), (u+v, u-v), u)')
expr.subs({'u': 2, 'v': 3}) # 得到数值结果 4
"""
try:
# 将输入字符串转换为 Sympy 表达式(自动解析元组结构)
expr = sp.sympify(input_str)
# 检查输入是否为四元组(函数, 原变量列表, 新变量列表, 目标变量)
if not (isinstance(expr, tuple) and len(expr) == 4):
return f"输入错误: 输入应为四元组,实际输入为 {input_str}"
f, independent_vars, new_vars, target_var = expr
# 检查原变量和新变量数量是否一致
if len(independent_vars) != len(new_vars):
return f"变量数量不匹配: 原变量{len(independent_vars)}个,新变量{len(new_vars)}个"
# 创建变量替换字典(例如 {x: u+v, y: u-v})
substitution = {old: new for old, new in zip(independent_vars, new_vars)}
f_substituted = f.subs(substitution)
# 计算替换后的函数对目标变量的偏导数
derivative = sp.diff(f_substituted, target_var)
return derivative
except Exception as e:
return f"错误: {e}"
# 示例1:基本使用(符号计算)
input_str1 = '(x**2, (x,), (u,), u)'
result1 = partial_derivatives(input_str1)
print("符号导数:", result1)
# 2*u
# 示例2:复合函数求导
input_str2 = '(x*y, (x,y), (u+v, u-v), u)'
result2 = partial_derivatives(input_str2)
print("复合函数导数:", result2)
# 2*u
# 示例3:数值计算
u_value = 2
v_value = 3
numerical_result = result2.subs({'u': u_value, 'v': v_value})
print(f"当 u={u_value}, v={v_value} 时,导数值为:", numerical_result)
# 4
成对观测值之间的两两距离
D = pdist(X,Distance,DistParameter) 返回 X 中成对观测值之间的距离.
X是数值矩阵
Distance是距离类型,默认是'euclidean'(欧几里德)
其他距离类型包括euclidean,canberra,cityblock,chebyshev,minkowski,hamming,cosine,correlation,jaccard
DistParameter,正整数标量,当Distance类型是minkowski距离时候有效,默认为2
D是两两距离,数值向量.
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy.spatial import distance
def distance_paired_first(input_str):
"""
计算成对观测值之间的两两距离,对标MATLAB的pdist函数。
参数:
input_str: 输入字符串,格式为"(data, metric, ...)",其中:
- data: 二维数据矩阵,每行代表一个观测值
- metric: 距离度量类型(如'euclidean', 'minkowski'等)
- 后续参数: 如minkowski距离的p值
返回:
距离列表或错误信息。
"""
try:
expr = sp.sympify(input_str)
points = None
distance_type = 'euclidean' # 默认距离类型
p = 2 # Minkowski距离的默认p值
# 解析输入参数
if isinstance(expr, tuple):
# 检查数据部分
if len(expr) < 1:
return "错误: 输入必须包含数据矩阵"
data_expr = expr[0]
# 转换数据为矩阵
X = sp.Matrix(data_expr) if isinstance(data_expr, list) else None
if X is None:
return "错误: 无法解析数据矩阵"
points = np.array(X.tolist(), dtype=float)
# 检查数据维度并处理一维数据
if points.ndim == 1:
points = points.reshape(-1, 1)
elif points.ndim != 2:
return "错误: 数据必须是二维数组"
# 解析距离类型
if len(expr) >= 2:
distance_type = str(expr[1]).lower()
# 检查是否支持的距离类型
supported_metrics = ["euclidean", "canberra", "cityblock", "chebyshev",
"minkowski", "hamming", "cosine", "correlation", "jaccard"]
if distance_type not in supported_metrics:
return f"错误: 不支持的距离类型 '{distance_type}'"
# 处理Minkowski的p参数
if distance_type == 'minkowski' and len(expr) >= 3:
p = float(expr[2]) # 允许浮点数
else:
distance_type = 'euclidean'
else:
# 输入不是元组,尝试解析为数据矩阵
X = sp.Matrix(expr) if isinstance(expr, list) else None
if X is None:
return "错误: 输入格式不正确,应为 (data, metric, ...)"
points = np.array(X.tolist(), dtype=float)
# 检查数据维度并处理一维数据
if points.ndim == 1:
points = points.reshape(-1, 1)
elif points.ndim != 2:
return "错误: 数据必须是二维数组"
# 计算距离
if distance_type == 'minkowski':
distances = distance.pdist(points, metric=distance_type, p=p)
else:
distances = distance.pdist(points, metric=distance_type)
return distances.tolist()
except Exception as e:
return f"错误: {str(e)}"
# 示例用法
if __name__ == "__main__":
# 示例1:二维数据的欧氏距离
example1 = '([[1, 2], [3, 4]], "euclidean")'
print("示例1结果:", distance_paired_first(example1))
# [2.8284271247461903]
# 示例2:一维数据转换为二维后的曼哈顿距离
example2 = '([1, 2, 3, 4], "cityblock")'
print("示例2结果:", distance_paired_first(example2))
# [1.0, 2.0, 3.0, 1.0, 2.0, 1.0]
# 示例3:带p参数的Minkowski距离
example3 = '([[1, 2], [3, 4]], "minkowski", 3)'
print("示例3结果:", distance_paired_first(example3))
# [2.5198420997897464]
两组观测值之间的两两距离
D = pdist(X,Y,Distance,DistParameter) 返回返回 X 和 Y 中每对观测值之间的距离.
X,Y是数值矩阵
Distance是距离类型,默认是'euclidean'(欧几里德),
其他距离类型包括euclidean,canberra,cityblock,chebyshev,minkowski,hamming,cosine,correlation,jaccard
DistParameter,正整数标量,当Distance类型是minkowski距离时候有效,默认为2
D是两两距离,数值矩阵. 是一个压缩形式的距离矩阵(通过squareform还原完整矩阵).
示例1:KNN算法中的距离计算
训练样本(已知类别)
train_samples = [[1.0, 2.0], [1.5, 1.8], [5.0, 8.0], [8.0, 8.0]]
测试样本(需要分类)
test_samples = [[1.2, 1.9], [7.0, 7.5]]
dist_matrix1 = pdist2(train_samples, test_samples, euclidean)
训练样本与测试样本的欧氏距离矩阵:
print(dist_matrix1)
#[[0.223606797749979, 8.13941029804985],
[0.316227766016838, 7.92085853932514],
[7.18679344353238, 2.06155281280883],
[9.13509715328742, 1.11803398874989]]
#可以用于KNN分类:找到距离最近的训练样本
示例2:图像特征匹配
第一幅图像的特征点描述符
image1_features = [
[0.1, 0.2, 0.9, 0.05], # 特征点1
[0.8, 0.1, 0.1, 0.95], # 特征点2
[0.3, 0.7, 0.2, 0.1] # 特征点3
]
第二幅图像的特征点描述符
image2_features = [
[0.12, 0.18, 0.88, 0.08], # 可能与特征点1匹配
[0.75, 0.15, 0.2, 0.9], # 可能与特征点2匹配
[0.9, 0.05, 0.1, 0.85] # 新的特征点
]
dist_matrix2 = pdist2(image1_features, image2_features, cosine)
图像特征之间的余弦距离:
print(dist_matrix2)
#[[0.00102952247021870, 0.703374531291457, 0.798590865375123],
[0.755530580143352, 0.00493762561341859, 0.00722480440093398],
[0.520823420514474, 0.516204742910196, 0.584425070273620]]
#余弦距离越小,特征越相似,可用于特征匹配
示例3:基于用户行为的相似度计算
用户行为向量(电影评分、商品点击等)
users_behavior = [
[5, 3, 0, 1, 4], # 用户A的评分
[4, 2, 1, 0, 5], # 用户B的评分
[0, 1, 5, 4, 2], # 用户C的评分
[2, 4, 3, 5, 1] # 用户D的评分
]
新用户的行为
new_user_behavior = [[3, 2, 1, 0, 4]]
dist_matrix3 = pdist2(users_behavior, new_user_behavior, correlation)
新用户与现有用户的相关系数距离:
print(dist_matrix3)
#[[0.161257863170674], [0.00875929283806987],
[1.68624356649672], [1.9]]
#找到最相似的用户进行推荐
示例4:基因表达谱相似性
不同样本的基因表达水平
samples_expression = [
[2.1, 5.8, 3.2, 7.9, 1.5], # 正常组织样本
[8.3, 1.2, 9.5, 0.8, 6.7], # 癌症组织样本A
[7.9, 1.5, 8.8, 1.1, 7.2] # 癌症组织样本B
]
未知样本
unknown_sample = [[6.5, 2.1, 7.8, 1.3, 5.9]]
dist_matrix4 = pdist2(samples_expression, unknown_sample, canberra)
未知样本与已知样本的堪培拉距离:
print(dist_matrix4)
#[[2.71015005448073],
[0.794202091889953],
[0.506699827299018]]
#堪培拉距离对接近0的值不敏感,适合基因表达数据
示例5:文档向量相似度
文档的词频向量
documents = [
[4, 2, 0, 1, 3, 0], # 文档1:科技类
[1, 0, 5, 2, 0, 4], # 文档2:体育类
[0, 3, 1, 4, 2, 1] # 文档3:娱乐类
]
查询文档
query_document = [[3, 1, 0, 2, 2, 0]]
dist_matrix5 = pdist2(documents, query_document, jaccard)
查询文档与语料库的杰卡德距离:
print(dist_matrix5)
#[[1.0],
[0.833333333333333],
[0.833333333333333]]
#杰卡德距离衡量集合相似度,适用于文本特征
示例6:投资组合相关性分析
不同投资组合的资产配置比例
portfolios = [
[0.4, 0.3, 0.2, 0.1], # 保守型组合
[0.2, 0.2, 0.3, 0.3], # 平衡型组合
[0.1, 0.1, 0.4, 0.4] # 激进型组合
]
新构建的投资组合
new_portfolio = [[0.3, 0.25, 0.25, 0.2]]
dist_matrix6 = pdist2(portfolios, new_portfolio, cityblock)
新组合与现有组合的曼哈顿距离:
print(dist_matrix6)
#[[0.3],
[0.3],
[0.7]]
#曼哈顿距离(城市街区距离)适合比例数据
示例7:产品质量特征距离
合格产品的特征参数
qualified_products = [
[10.1, 25.3, 8.7], # 产品A
[10.2, 25.1, 8.9], # 产品B
[9.9, 25.4, 8.8] # 产品C
]
待检测产品
test_products = [
[15.5, 25.2, 8.6], # 可能不合格
[10.1, 25.3, 8.7] # 可能合格
]
dist_matrix7 = pdist2(qualified_products, test_products, chebyshev)
待测产品与合格产品的切比雪夫距离:
print(dist_matrix7)
#[[5.4, 0],
[5.3, 0.200000000000001],
[5.6, 0.199999999999999]]
#切比雪夫距离关注最大差异,适合质量控制
示例8:地理位置距离计算
已知地点的坐标(经度,纬度)
known_locations = [
[116.4, 39.9], # 北京
[121.5, 31.2], # 上海
[113.3, 23.1] # 广州
]
查询位置
query_location = [[117.2, 39.1]] # 天津
dist_matrix8 = pdist2(known_locations, query_location, euclidean)
查询位置与已知城市的欧氏距离:
print(dist_matrix8)
#[[1.13137084989847],
[8.99444272870754],
[16.4684546937471]]
#注意:实际GIS应用中应使用大圆距离,这里用欧氏距离简化演示
示例9:不同距离度量的比较
data_A = [[1, 2], [3, 4]]
data_B = [[5, 6]]
比较多种距离度量
metrics = ['euclidean', 'cityblock', 'chebyshev']
for metric in metrics:
result = pdist2(data_A, data_B, metric)
print(f"{metric}距离: {result}")
#euclidean距离: [[5.65685424949238],
[2.82842712474619]]
#cityblock距离: [[8.0],
[4.0]]
#chebyshev距离: [[4.0],
[2.0]]
示例10:具体数值分析
客户购买行为数据
customer_purchases = [
[5, 3, 2, 0], # 客户A
[4, 0, 1, 3], # 客户B
[1, 5, 0, 2] # 客户C
]
target_customer = [[3, 2, 1, 1]]
使用欧氏距离
distances = pdist2(customer_purchases, target_customer, euclidean)
目标客户与现有客户的欧氏距离:
print(distances)
#[[2.64575131106459],
[3.0],
[3.87298334620742]]
找到最相似的客户
min_distance = float('inf')
most_similar_idx = -1
for i, dist in enumerate(distances):
if dist < min_distance:
min_distance = dist
most_similar_idx = i
print(f"最相似的客户是: 客户{chr(65+most_similar_idx)} (距离: {min_distance:.4f})")
#最相似的客户是: 客户A (距离: 2.6458)
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy.spatial import distance
def distance_paired_second(input_str):
"""
计算两组观测值之间的两两距离,对标MATLAB的pdist2函数。
参数:
input_str (str): 输入字符串,格式为'(list1, list2, metric, p)',其中:
list1: 第一组观测值,可以是二维列表或一维列表。
list2: 第二组观测值,可以是二维列表或一维列表。
metric (str, 可选): 距离类型,支持的类型包括:
'euclidean', 'canberra', 'cityblock', 'chebyshev', 'minkowski',
'hamming', 'cosine', 'correlation', 'jaccard'。默认为 'euclidean'。
p (int, 可选): 仅当metric为'minkowski'时有效,指定闵可夫斯基距离的p值,默认为2。
返回:
sympy.Matrix: 距离矩阵,元素(i,j)表示list1的第i个观测值与list2的第j个观测值的距离。
如果输入有误,返回错误信息字符串。
示例:
>>> distance_paired_second("([[1, 2], [3, 4]], [[5, 6], [7, 8]], 'euclidean')")
Matrix([
[5.830951894845301, 8.246211251235321],
[2.8284271247461903, 5.830951894845301]])
"""
try:
expr = sp.sympify(input_str)
if isinstance(expr, tuple) and len(expr) >= 2 and isinstance(expr[0], (list, sp.Matrix)) and isinstance(expr[1],
(list,
sp.Matrix)):
# 转换为NumPy数组
list1 = np.array(expr[0], dtype=float)
list2 = np.array(expr[1], dtype=float)
# 确保处理为二维数组
if list1.ndim == 1:
list1 = list1.reshape(1, -1)
if list2.ndim == 1:
list2 = list2.reshape(1, -1)
# 检查观测值的维度是否一致
if list1.shape[1] != list2.shape[1]:
return f"输入错误: 观测值的维度不一致 {input_str}"
# 处理距离类型
distance_type = 'euclidean'
valid_metrics = ["euclidean", "canberra", "cityblock", "chebyshev", "minkowski",
"hamming", "cosine", "correlation", "jaccard"]
if len(expr) >= 3:
distance_type = str(expr[2]).lower()
if distance_type not in valid_metrics:
return f"输入错误: 不支持的距离类型 {distance_type}"
# 处理Minkowski距离的p参数
p_param = 2
if distance_type == 'minkowski':
if len(expr) >= 4:
try:
p_param = int(expr[3])
except:
return f"输入错误: Minkowski距离的p参数必须为整数 {expr[3]}"
# 计算距离矩阵
if distance_type == 'minkowski':
dist_matrix = distance.cdist(list1, list2, distance_type, p=p_param)
else:
dist_matrix = distance.cdist(list1, list2, distance_type)
return sp.Matrix(dist_matrix)
else:
return f"输入错误: 输入格式不正确 {input_str}"
except Exception as e:
return f"错误: {e}"
input_str = "([[1, 2], [3, 4]], [[5, 6], [7, 8]], 'euclidean')"
result = distance_paired_second(input_str)
print(result)
# Matrix([[5.65685424949238, 8.48528137423857],
# [2.82842712474619, 5.65685424949238]])
input_str = "([1, 2], [3, 4], 'cityblock')"
result = distance_paired_second(input_str)
print(result)
# Matrix([[4.00000000000000]])
input_str = "([[1, 2], [3, 4]], [[5, 6]], 'minkowski', 1)"
result = distance_paired_second(input_str)
print(result)
# Matrix([[8.00000000000000],
# [4.00000000000000]])
所有可能的排列
P = perms(v) 返回的矩阵包含了向量v中元素的所有排列.P的每一行包含v中n个元素的一个不同排列.矩阵P具有与v相同的数据类型,包含n!行和n列.
v — 项目集合, 数值,logical或char值的向量
示例1:旅行商问题的所有可能路径
城市编号:0-北京, 1-上海, 2-广州, 3-成都
cities = [0, 1, 2, 3]
all_routes = perms(cities)
print(f"共有 {all_routes.shape[0]} 条可能的旅行路线:")
print("前5条路线:")
for i in range(min(5, all_routes.shape[0])):
route = [f"城市{city}" for city in all_routes.row(i)]
print(f"路线{i + 1}: {' → '.join(route)}")
#共有 24 条可能的旅行路线:
#前5条路线:
#路线1: 城市3 → 城市2 → 城市1 → 城市0
#路线2: 城市3 → 城市2 → 城市0 → 城市1
#路线3: 城市3 → 城市1 → 城市2 → 城市0
#路线4: 城市3 → 城市1 → 城市0 → 城市2
#路线5: 城市3 → 城市0 → 城市2 → 城市1
## 实际应用中,我们会计算每条路线的总距离,选择最短的
示例2:密码排列生成
数字密码的所有可能排列
password_digits = [1, 3, 5, 7]
all_passwords = perms(password_digits)
print(f"数字 {password_digits} 的所有 {all_passwords.shape[0]} 种密码排列:")
print("前10种密码:")
for i in range(min(10, all_passwords.shape[0])):
password = ''.join(str(d) for d in all_routes.row(i))
print(f"密码{i + 1}: {password}")
#数字 [1, 3, 5, 7] 的所有 24 种密码排列:
#前10种密码:
#密码1: 3210
#密码2: 3201
#密码3: 3120
#密码4: 3102
#密码5: 3021
#密码6: 3012
#密码7: 2310
#密码8: 2301
#密码9: 2130
#密码10: 2103
# 在密码强度分析中,这会帮助评估密码空间大小
示例3:生产任务调度
生产任务:1-切割, 2-焊接, 3-喷涂, 4-组装
tasks = [1, 2, 3, 4]
all_schedules = perms(tasks)
print(f"生产任务 {tasks} 的所有 {all_schedules.shape[0]} 种调度顺序:")
print("前8种调度方案:")
for i in range(min(8, all_schedules.shape[0])):
schedule = ' → '.join(f'任务{task}' for task in all_schedules.row(i))
print(f"方案{i + 1}: {schedule}")
#生产任务 [1, 2, 3, 4] 的所有 24 种调度顺序:
#前8种调度方案:
#方案1: 任务4 → 任务3 → 任务2 → 任务1
#方案2: 任务4 → 任务3 → 任务1 → 任务2
#方案3: 任务4 → 任务2 → 任务3 → 任务1
#方案4: 任务4 → 任务2 → 任务1 → 任务3
#方案5: 任务4 → 任务1 → 任务3 → 任务2
#方案6: 任务4 → 任务1 → 任务2 → 任务3
#方案7: 任务3 → 任务4 → 任务2 → 任务1
#方案8: 任务3 → 任务4 → 任务1 → 任务2
# 实际应用中,会计算每种顺序的总完成时间,选择最优的
示例4:循环赛制的比赛顺序
参赛队伍:1-湖人, 2-勇士, 3-凯尔特人, 4-热火
teams = [1, 2, 3, 4]
all_match_orders = perms(teams)
print(f"{len(teams)} 支队伍的所有 {all_match_orders.shape[0]} 种比赛顺序:")
print("前6种比赛顺序:")
for i in range(min(6, all_match_orders.shape[0])):
order = ' vs '.join(f'队伍{team}' for team in all_match_orders.row(i)[:2])
remaining = ' → '.join(f'队伍{team}' for team in all_match_orders.row(i)[2:])
print(f"顺序{i + 1}: {order} | 后续: {remaining}")
#4 支队伍的所有 24 种比赛顺序:
#前6种比赛顺序:
#顺序1: 队伍4 vs 队伍3 | 后续: 队伍2 → 队伍1
#顺序2: 队伍4 vs 队伍3 | 后续: 队伍1 → 队伍2
#顺序3: 队伍4 vs 队伍2 | 后续: 队伍3 → 队伍1
#顺序4: 队伍4 vs 队伍2 | 后续: 队伍1 → 队伍3
#顺序5: 队伍4 vs 队伍1 | 后续: 队伍3 → 队伍2
#顺序6: 队伍4 vs 队伍1 | 后续: 队伍2 → 队伍3
示例5:课程章节顺序安排
课程章节:1-引言, 2-理论基础, 3-案例分析, 4-实践练习
chapters = [1, 2, 3, 4]
all_sequences = perms(chapters)
print(f"课程章节 {chapters} 的所有 {all_sequences.shape[0]} 种讲授顺序:")
print("前8种教学顺序:")
for i in range(min(8, all_sequences.shape[0])):
sequence = ' → '.join(f'第{chap}章' for chap in all_sequences.row(i))
print(f"顺序{i + 1}: {sequence}")
#课程章节 [1, 2, 3, 4] 的所有 24 种讲授顺序:
#前8种教学顺序:
#顺序1: 第4章 → 第3章 → 第2章 → 第1章
#顺序2: 第4章 → 第3章 → 第1章 → 第2章
#顺序3: 第4章 → 第2章 → 第3章 → 第1章
#顺序4: 第4章 → 第2章 → 第1章 → 第3章
#顺序5: 第4章 → 第1章 → 第3章 → 第2章
#顺序6: 第4章 → 第1章 → 第2章 → 第3章
#顺序7: 第3章 → 第4章 → 第2章 → 第1章
#顺序8: 第3章 → 第4章 → 第1章 → 第2章
# 教师可以根据学习理论选择最合适的教学顺序
示例6:具体的数值分析和应用
任务优先级排列
priorities = [1, 2, 3, 4] # 1-最高优先级
all_priority_orders = perms(priorities)
print(f"任务优先级 {priorities} 的所有排列:")
print("完整的排列矩阵:")
print(all_priority_orders)
#任务优先级 [1, 2, 3, 4] 的所有排列:
#完整的排列矩阵:
#[[4, 3, 2, 1],
[4, 3, 1, 2],
[4, 2, 3, 1],
[4, 2, 1, 3],
[4, 1, 3, 2],
[4, 1, 2, 3],
[3, 4, 2, 1],
[3, 4, 1, 2],
[3, 2, 4, 1],
[3, 2, 1, 4],
[3, 1, 4, 2],
[3, 1, 2, 4],
[2, 4, 3, 1],
[2, 4, 1, 3],
[2, 3, 4, 1],
[2, 3, 1, 4],
[2, 1, 4, 3],
[2, 1, 3, 4],
[1, 4, 3, 2],
[1, 4, 2, 3],
[1, 3, 4, 2],
[1, 3, 2, 4],
[1, 2, 4, 3],
[1, 2, 3, 4]]
分析特定排列的实用性
target_order = [4, 3, 2, 1] # 从低到高优先级
for i in range(all_priority_orders.shape[0]):
if list(all_priority_orders.row(i)) == target_order:
print(f"找到目标顺序在第 {i + 1} 个位置: {target_order}")
break
#分析特定排列:
#找到目标顺序在第 1 个位置: [4, 3, 2, 1]
统计分析:
print(f"总排列数: {all_priority_orders.shape[0]}")
#总排列数: 24
每个位置的数字分布:
for pos in range(len(priorities)):
numbers_at_pos = [all_priority_orders[i, pos] for i in range(all_priority_orders.shape[0])]
unique, counts = np.unique(numbers_at_pos, return_counts=True)
print(f" 位置{pos + 1}: {dict(zip(unique, counts))}")
#位置1: {1: 6, 2: 6, 3: 6, 4: 6}
#位置2: {1: 6, 2: 6, 3: 6, 4: 6}
#位置3: {1: 6, 2: 6, 3: 6, 4: 6}
#位置4: {1: 6, 2: 6, 3: 6, 4: 6}
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import itertools
def possible_all_arrangements(input_str):
"""
对标 MATLAB 的 perms 函数,生成所有可能的排列(反向字典序)
参数:
input_str: 输入数据的字符串表示,可以是列表或矩阵形式,例如 "[1,2,3]" 或 "Matrix([1,2,3])"
返回:
SymPy 矩阵对象,每行代表一种排列,排列顺序与 MATLAB 一致
错误时返回字符串描述
"""
try:
# 若失败则尝试解析为 SymPy 矩阵
expr = sp.sympify(input_str)
matrix = sp.Matrix(expr) if isinstance(expr, list) else None
if matrix is None:
return f"输入格式错误: {input_str}"
# 检查矩阵维度
rows, cols = matrix.shape
if rows == 1: # 行向量
elements = list(matrix.row(0))
elif cols == 1: # 列向量
elements = [matrix[i, 0] for i in range(rows)]
else:
return "错误:输入必须是行向量或列向量"
# 生成所有排列并反转顺序以匹配 MATLAB
permutations = list(itertools.permutations(elements))[::-1] # 关键步骤:反转顺序
# 转换为 SymPy 矩阵(每行一个排列)
return sp.Matrix(permutations)
except Exception as e:
return f"错误:{e}"
# 示例验证 ==============================================
if __name__ == "__main__":
# 测试用例 1:标准输入
input_str1 = "[2, 4, 6]"
result1 = possible_all_arrangements(input_str1)
print("测试1 输入:", input_str1)
print("输出排列矩阵:\n", result1)
# Matrix([[6, 4, 2],
# [6, 2, 4],
# [4, 6, 2],
# [4, 2, 6],
# [2, 6, 4],
# [2, 4, 6]])
# 测试用例 2:SymPy 矩阵输入
input_str2 = "[[5], [4], [9]]" # 列向量
result2 = possible_all_arrangements(input_str2)
print("\n测试2 输入:", input_str2)
print("输出排列矩阵:\n", result2)
# Matrix([[9, 4, 5],
# [9, 5, 4],
# [4, 9, 5],
# [4, 5, 9],
# [5, 9, 4],
# [5, 4, 9]])
置换数组维度
B = permute(A,dimorder) 按照向量 dimorder 指定的顺序重新排列数组的维度。例如,permute(A,[2 1]) 交换矩阵 A 的行和列维度。通常,输出数组的第 i 个维度是输入数组的维度 dimorder(i)。
A — 输入数组, 向量 | 矩阵
dimorder — 维度顺序, 行向量
示例1:RGB图像通道重排
模拟一个2x2的RGB图像(3通道)
rgb_image = [
[[255, 0, 0], [0, 255, 0]], # 红色, 绿色
[[0, 0, 255], [255, 255, 0]] # 蓝色, 黄色
]
将通道维度放到最后:从 (2,2,3) 变为 (2,2,3) 但重新排列通道
result1 = permute(rgb_image, [1, 2, 3]) # 保持原顺序
原RGB图像通道顺序:
print(np.array(result1))
#[[[255 0 0]
[0 255 0]]
[[0 0 255]
[255 255 0]]]
更实际的示例:改变图像数据的组织方式
image_data_3d = [
[[1, 2, 3], [4, 5, 6]], # 第一行像素
[[7, 8, 9], [10, 11, 12]] # 第二行像素
]
从 (行, 列, 通道) 变为 (通道, 行, 列)
result3 = permute(image_data_3d, [3, 1, 2])
print("\n从 (行,列,通道) 变为 (通道,行,列):")
print(np.array(result3))
#从 (行,列,通道) 变为 (通道,行,列):
#[[[1 4]
[7 10]]
[[2 5]
[8 11]]
[[3 6]
[9 12]]]
示例2:神经网络输入数据维度调整
批量图像数据:形状为 (批量大小, 高度, 宽度, 通道)
batch_images = [
[[[1, 2], [3, 4]], [[5, 6], [7, 8]]], # 图像1
[[[9, 10], [11, 12]], [[13, 14], [15, 16]]] # 图像2
]
原始数据形状 (批量, 高, 宽, 通道):
print(np.array(batch_images).shape)
#(2, 2, 2, 2)
转换为 PyTorch 格式 (批量, 通道, 高, 宽)
result4 = permute(batch_images, [1, 4, 2, 3])
转换为PyTorch格式 (批量, 通道, 高, 宽):
print(np.array(result4))
print("新形状:", np.array(result4).shape)
#[[[[1 3]
[5 7]]
[[2 4]
[6 8]]]
[[[9 11]
[13 15]]
[[10 12]
[14 16]]]]
#新形状: (2, 2, 2, 2)
转换为 TensorFlow 格式 (批量, 高, 宽, 通道) - 保持不变
result5 = permute(batch_images, [1, 2, 3, 4])
保持TensorFlow格式 (批量, 高, 宽, 通道):
print(np.array(result5).shape)
#(2, 2, 2, 2)
示例3:时间序列数据格式转换
多个传感器的时间序列数据:形状为 (时间步, 传感器, 特征)
time_series_data = [
[[1, 0.5], [2, 0.6], [3, 0.7]], # 时间点1
[[4, 0.8], [5, 0.9], [6, 1.0]], # 时间点2
[[7, 1.1], [8, 1.2], [9, 1.3]] # 时间点3
]
原始时间序列形状 (时间步, 传感器, 特征):
print(np.array(time_series_data).shape)
#(3, 3, 2)
转换为 (传感器, 时间步, 特征) - 用于某些RNN模型
result6 = permute(time_series_data, [2, 1, 3])
转换为 (传感器, 时间步, 特征):
print(np.array(result6))
print("新形状:", np.array(result6).shape)
#[[[1,0.5]
[4,0.8]
[7,1.1]]
[[2,0.6]
[5,0.9]
[8,1.2]]
[[3,0.7]
[6,1.0]
[9,1.3]]]
#新形状: (3, 3, 2)
转换为 (特征, 时间步, 传感器) - 用于特征优先的分析
result7 = permute(time_series_data, [3, 1, 2])
转换为 (特征, 时间步, 传感器):
print(np.array(result7))
print("新形状:", np.array(result7).shape)
#转换为 (特征, 时间步, 传感器):
#[[[1 2 3]
[4 5 6]
[7 8 9]]
[[0.5 0.6 0.7]
[0.8 0.9 1.0]
[1.1 1.2 1.3]]]
#新形状: (2, 3, 3)
示例4:数据表转置操作
销售数据表:形状为 (产品, 月份)
sales_data = [
[100, 120, 130], # 产品A的1-3月销量
[80, 90, 95], # 产品B的1-3月销量
[150, 160, 170] # 产品C的1-3月销量
]
原始销售数据 (产品 × 月份):
print("产品A:", sales_data[0])
print("产品B:", sales_data[1])
print("产品C:", sales_data[2])
#产品A: [100, 120, 130]
#产品B: [80, 90, 95]
#产品C: [150, 160, 170]
转置为 (月份, 产品)
result8 = permute(sales_data, [2, 1])
转置后 (月份 × 产品):
transposed = np.array(result8)
print("1月各产品:", transposed[0])
print("2月各产品:", transposed[1])
print("3月各产品:", transposed[2])
#1月各产品: [100 80 150]
#2月各产品: [120 90 160]
#3月各产品: [130 95 170]
示例5:物理场数据坐标系统变换
3D物理场数据:形状为 (X, Y, Z, 物理量)
模拟温度场数据
temperature_field = [
[ # Z=0平面
[[20, 0.1], [22, 0.2]], # (X,Y) 点的 [温度, 梯度]
[[24, 0.3], [26, 0.4]]
],
[ # Z=1平面
[[18, 0.0], [20, 0.1]],
[[22, 0.2], [24, 0.3]]
]
]
print("原始物理场形状 (X, Y, Z, 物理量):", np.array(temperature_field).shape)
#原始物理场形状 (X, Y, Z, 物理量): (2, 2, 2, 2)
转换为 (物理量, X, Y, Z) - 便于分别分析温度和梯度
result9 = permute(temperature_field, [4, 1, 2, 3])
转换为 (物理量, X, Y, Z):
result_array = np.array(result9)
print("温度场形状:", result_array[0].shape)
print("梯度场形状:", result_array[1].shape)
#温度场形状: (2, 2, 2)
#梯度场形状: (2, 2, 2)
转换为 (Y, X, Z, 物理量) - 改变空间坐标顺序
result10 = permute(temperature_field, [2, 1, 3, 4])
转换为 (Y, X, Z, 物理量):
print("新形状:", np.array(result10).shape)
#新形状: (2, 2, 2, 2)
示例6:视频帧序列维度调整
视频数据:形状为 (帧, 高, 宽, 通道)
video_frames = [
[ # 帧1
[[1, 1, 1], [2, 2, 2]],
[[3, 3, 3], [4, 4, 4]]
],
[ # 帧2
[[5, 5, 5], [6, 6, 6]],
[[7, 7, 7], [8, 8, 8]]
],
[ # 帧3
[[9, 9, 9], [10, 10, 10]],
[[11, 11, 11], [12, 12, 12]]
]
]
print("原始视频数据形状 (帧, 高, 宽, 通道):", np.array(video_frames).shape)
#原始视频数据形状 (帧, 高, 宽, 通道): (3, 2, 2, 3)
转换为 (高, 宽, 帧, 通道) - 用于时空分析
result11 = permute(video_frames, [2, 3, 1, 4])
转换为 (高, 宽, 帧, 通道):
print("新形状:", np.array(result11).shape)
#新形状: (2, 2, 3, 3)
转换为 (通道, 帧, 高, 宽) - 用于通道分离处理
result12 = permute(video_frames, [4, 1, 2, 3])
转换为 (通道, 帧, 高, 宽):
print("新形状:", np.array(result12).shape)
#新形状: (3, 3, 2, 2)
示例7:具体数值计算与形状验证
创建测试数据
test_data = [
[[1, 2, 3], [4, 5, 6]],
[[7, 8, 9], [10, 11, 12]],
[[13, 14, 15], [16, 17, 18]]
]
print("原始数据形状:", np.array(test_data).shape)
#原始数据形状: (3, 2, 3)
测试各种排列组合
permutations_to_test = [
[1, 2, 3], # 原顺序
[2, 1, 3], # 交换前两个维度
[3, 1, 2], # 循环移位
[1, 3, 2], # 交换后两个维度
[2, 3, 1], # 另一种循环
[3, 2, 1] # 完全反转
]
for i, perm in enumerate(permutations_to_test):
result = permute(test_data, perm)
result_array = np.array(result)
print(f"\n排列 {perm}: 形状={result_array.shape}")
print(f"第一个元素: {result_array.flat[0]}")
# 验证元素数量不变
original_elements = np.array(test_data).size
new_elements = result_array.size
print(f"元素数量: {original_elements} → {new_elements} ({'一致' if original_elements == new_elements else '错误'})")
#排列 [1, 2, 3]: 形状=(3, 2, 3)
#第一个元素: 1
#元素数量: 18 → 18 (一致)
#排列 [2, 1, 3]: 形状=(2, 3, 3)
#第一个元素: 1
#元素数量: 18 → 18 (一致)
#排列 [3, 1, 2]: 形状=(3, 3, 2)
#第一个元素: 1
#元素数量: 18 → 18 (一致)
#排列 [1, 3, 2]: 形状=(3, 3, 2)
#第一个元素: 1
#元素数量: 18 → 18 (一致)
#排列 [2, 3, 1]: 形状=(2, 3, 3)
#第一个元素: 1
#元素数量: 18 → 18 (一致)
#排列 [3, 2, 1]: 形状=(3, 2, 3)
#第一个元素: 1
#元素数量: 18 → 18 (一致)
示例8:内存布局优化
4维数据:形状为 (批次, 通道, 高, 宽)
high_dim_data = [
[ # 批次1
[[1, 2], [3, 4]], # 通道1
[[5, 6], [7, 8]] # 通道2
],
[ # 批次2
[[9, 10], [11, 12]],
[[13, 14], [15, 16]]
]
]
print("原始4D数据形状:", np.array(high_dim_data).shape)
#原始4D数据形状: (2, 2, 2, 2)
转换为行优先布局 (C-order)
result15 = permute(high_dim_data, [1, 2, 3, 4]) # 保持原样
行优先布局 (C-order):
print("形状:", np.array(result15).shape)
#形状: (2, 2, 2, 2)
转换为更适合某些算法的布局
result16 = permute(high_dim_data, [2, 1, 3, 4]) # 交换批次和通道
交换批次和通道 [2, 1, 3, 4]:
print("形状:", np.array(result16).shape)
#形状: (2, 2, 2, 2)
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import numpy as np
import sympy as sp
def permutation_order_vector(input_str):
"""
实现类似 MATLAB 的 permute 函数,处理向量和二维矩阵的维度排列。
参数格式要求:
input_str 应为有效表示矩阵和维度的字符串,例如:"([[1,2,3]], [2])" 或 "([[1,2],[3,4]], [2,1])"
返回:
重新排列后的矩阵 或 错误信息字符串
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
def numpy_permute(A, dimorder):
"""
MATLAB permute函数的NumPy实现
参数:
A: 输入数组 (NumPy ndarray)
dimorder: 维度顺序列表 (基于1的索引,如MATLAB)
返回:
维度置换后的数组
"""
# 将MATLAB的1-based索引转换为NumPy的0-based索引
axes = [d - 1 for d in dimorder]
# 使用NumPy的transpose函数
return np.transpose(A, axes=axes)
def sympy_permute(A, dimorder):
"""
MATLAB permute函数的SymPy实现
参数:
A: 输入数组 (SymPy Array 或可转换为Array的对象)
dimorder: 维度顺序列表 (基于1的索引,如MATLAB)
返回:
维度置换后的SymPy Array
"""
# 验证维度数量
ndim = A.rank()
if len(dimorder) != ndim:
raise ValueError(f"维度顺序列表长度({len(dimorder)})必须等于数组维度数({ndim})")
# 将MATLAB的1-based索引转换为0-based索引
axes = [d - 1 for d in dimorder]
# 执行维度置换
return sp.permutedims(A, axes)
if isinstance(expr, tuple) and len(expr) == 2:
sp_array = sp.Array(expr[0]) if isinstance(expr[0], list) else None
if sp_array is None:
raise ValueError(f"输入错误:{input_str}")
if not isinstance(expr[1], list):
raise ValueError(f"输入错误:{input_str}")
if sp_array.free_symbols:
result = sympy_permute(sp_array, expr[1])
else:
z_arr = np.asarray(sp_array)
result = numpy_permute(z_arr, expr[1])
else:
error = True
return result if not error else f"输入错误:{input_str}"
except Exception as e:
return f"运行时错误:{str(e)}"
# 示范数值数组
print(permutation_order_vector("[1,2,3],[1]"))
# [1 2 3]
# 示范符号数组
print(permutation_order_vector("[[[x,y],[z,x+y]],[[y,z],[x,x*y*z]]],[3,1,2]"))
# [[[x, z],
# [y, x]],
# [[y, x + y],
# [z, x*y*z]]]
相频图
phaseplot(sys) 显示系统输出信号相对于输入信号的相位偏移(以度为单位)随频率变化的特性.
低通滤波器(一阶系统): RC电路噪声滤除。
确认系统是低通特性(相位滞后随频率增加),并帮助估计截止频率附近(约10 rad/s)的相位滞后.
phaseplot(1,0.1s+1)
直流电机速度控制: 电机调速系统
有助于识别系统类型(含积分器,低频相位为-90°),并评估稳定性风险.
phaseplot(5,0.5*s^2+s)
质量-弹簧-阻尼系统: 机械振动分析
分析机械振动中的共振现象和相位反转.
phaseplot(1,s^2+0.6s+1)
超前补偿器(PD控制器): 提高系统稳定裕度
体现了PD控制器提升稳定裕度的能力.
phaseplot(2s+10,0.02s+1)
带通滤波器: 通信信号选频
识别带通特性(中心频率约10 rad/s)和群延迟特性。
phaseplot(0.1s,(s+1)(0.01s+1))
RC低通滤波器
ADC采样前的抗混叠滤波
频率范围 相位偏移
0.1 rad/s -5.7°
10 rad/s -45°
100 rad/s -84.3°
phaseplot([1],[0.1,1])
伺服电机位置控制
工业机器人关节定位精度保障
频率范围 相位偏移
1 rad/s -11.3°
7.07 rad/s -90° (共振点)
50 rad/s -172.9°
phaseplot([50],[1,5,50])
心电图工频陷波器
医疗设备中消除50 Hz电源干扰
频率范围 相位偏移
40 Hz +87°
50 Hz 0° (相位跳变)
60 Hz -87°
phaseplot([1,0,10000],[1,100,10000])
飞机俯仰控制系统
民航客机自动驾驶模式稳定性验证
频率范围 相位偏移
0.5 rad/s -28°
5 rad/s -112° (增益穿越频率)
50 rad/s -256°
phaseplot([0.5,1],[0.01,0.1,1,1])
5G毫米波相位补偿
Massive MIMO基站波束成形校准
频率范围 相位偏移
1e9 rad/s +4.3°
5e10 rad/s +35.5° (工作频段)
1e11 rad/s +52.1°
phaseplot([0.02,1],[0.002,1])
电动汽车电池管理系统
锂电池健康状态(SOH)在线诊断
频率范围 相位偏移
10 rad/s -21.8°
31.6 rad/s -90° (特征频率)
100 rad/s -158.2°
phaseplot([1000],[1,40,1000])
叠加相频图
phaseplot([sys1],[sys2]...[sysN]) 叠加相频图是将多个系统的相位响应曲线绘制在同一坐标系中的可视化工具,主要用于分析不同系统在频域中的相位特性.
控制系统稳定性分析(航空航天):
LQR控制器在关键频段(1-10 rad/s)相位滞后减少15°,显著提升飞行稳定性
phaseplot([1,0.2s+1], # 基础PID控制器
[1,0.05*s^2+0.1s+1]) # 改进型LQR控制器
滤波器设计对比(音频处理)
高保真音频选贝塞尔,抗干扰选切比雪夫
phaseplot([1,s^2+1.4s+1], # 巴特沃斯滤波器
[1,s^2+s+1], # 切比雪夫滤波器
[1,s^2+0.5s+1]) # 贝塞尔滤波器
通信系统多径效应分析(5G网络):
识别2.4GHz频段多径引起的相位突变,优化MIMO天线配置
phaseplot([1,0.01s+1], # 视距信道
[1,0.1*s^2+0.3s+1], # 城市多径信道
[1,0.5*s^2+0.1s+1]) # 室内密集多径
机械系统谐振分析(汽车悬架):
低阻尼系统在谐振频率(≈2Hz)相位突变180°
高阻尼系统相位变化平缓,乘坐舒适性更好
phaseplot([1,0.3*s^2+0.8*s+1], # 标准阻尼
[1,0.3*s^2+1.2*s+1], # 高阻尼
[1,0.3*s^2+0.4s+1]) # 低阻尼
圆周率的小数精度
pi_digits(n)返回圆周率小数点后面的精度.
n -- 输入, 标量, 正整数.
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def pi_digits_calculate(input_str):
"""
计算π的数值到指定有效数字位数(对标MATLAB的vpa(pi, n)功能)
参数:
input_str (str): 表示所需有效数字位数的字符串,范围1-500之间的整数
返回:
sp.Float: π的近似值,保留指定有效数字
str: 错误信息(当输入无效时)
示例:
>>> pi_digits_calculate("10")
3.1415926536
>>> pi_digits_calculate("1000")
'错误:输入值需为1-500之间的整数'
"""
try:
# 将输入字符串解析为SymPy表达式
expr = sp.sympify(input_str)
# 检查是否为元组(非法输入情况)
if isinstance(expr, tuple):
return f"输入错误: 不支持元组类型输入 - {input_str}"
# 验证输入是否为整数
if not expr.is_Integer:
return f"输入错误: 需输入整数 - {input_str}"
n = int(expr)
# 验证数值范围
if not (1 <= n <= 500):
return f"错误:输入值需为1-500之间的整数,当前输入:{n}"
# 计算并返回π值(保留n位有效数字)
return sp.N(sp.pi, n)
except sp.SympifyError:
return f"解析错误: 无法解析输入字符串 - {input_str}"
except Exception as e:
return f"运行时错误: {str(e)}"
# 示例测试
if __name__ == "__main__":
# 正常案例
print("正常案例:")
print(pi_digits_calculate("10"))
# 3.141592654
print(pi_digits_calculate("5"))
# 3.1416
分段函数图
PiecewisePlot(Piecewise(f(x)))处理分段函数,会区分不同区间或点集进行渲染(例如,用曲线表示连续部分,用点表示离散部分)。
x -- 输入, 符号变量.
阶梯电价模型
Piecewise(
(0.5 * x, And(x >= 0, x <= 100)), # 第一档电价
(50 + 0.8*(x-100), And(x > 100, x <= 200)), # 第二档
(130 + 1.2*(x-200), x > 200), # 第三档
(0, True) # 默认值(实际不会触发)
)
PiecewisePlot(Piecewise((0.5x, And(x>= 0, x<=100)),(50+0.8*(x-100), And(x >100,x<=200)),(130+1.2*(x-200),x> 200),(0,True)))
汽车制动距离模型
Piecewise(
(0.01*v**2, v <= 30), # 低速制动
(9 + 0.015*(v-30)**2, v > 30), # 高速制动
(0, True) # 默认值
)
PiecewisePlot(Piecewise((0.01*v^2, v<=30),(9+0.015*(v-30)^2, v>30),(0, True)))
医疗输液控制
Piecewise(
(20, And(t >= 0, t < 10)), # 初始快速滴注
(5, And(t >= 10, t < 60)), # 维持速率
(0, t >= 60), # 结束输液
(0, True) # 时间无效
)
PiecewisePlot(Piecewise((20, And(t>=0, t<10)),(5, And(t>=10, t<60)),(0, t>=60),(0, True)))
温度阈值控制系统
Piecewise(
(0, T < 10), # 低温关闭
(0.5*(T-10), And(T >= 10, T < 30)), # 线性调节
(10, T >= 30) # 高温限幅输出
)
PiecewisePlot(Piecewise((0, T<10),(0.5*(T-10), And(T>=10, T<30)),(10, T>= 30)))
绝对值函数
Piecewise(
(-x, x < 0), # 负区间
(x, x >= 0) # 非负区间
)
PiecewisePlot(Piecewise((-x, x<0),(x, x>=0)))
摩尔-彭罗斯伪逆
B = pinv(A) 返回矩阵 A 的摩尔-彭罗斯伪逆.
B是摩尔-彭罗斯伪逆,一种矩阵,可在不存在逆矩阵的情况下作为逆矩阵的部分替代.此矩阵常被用于求解没有唯一解或有许多解的线性方程组.
A — 输入矩阵,矩阵
示例1:最小二乘问题 - 超定方程组(方程数大于未知数)
A_matrix = [[1, 1], [1, 2], [1, 3], [1, 4]] # 设计矩阵
b_matrix = [6, 8, 10, 12] # 观测值
A_pinv = pinv(A)
print(f"A的伪逆 = {A_pinv}")
#A的伪逆 = [[1, 1/2, 0, -1/2],
[-3/10, -1/10, 1/10, 3/10]]
最小二乘解: x = A⁺b
x_hat = A_pinv * b_matrix
print(f"最小二乘解 x = A⁺b = {x_hat}")
#最小二乘解 x = A⁺b = [[4], [2]]
# 这相当于拟合直线 y = β₀ + β₁x
示例2:欠定方程组(方程数小于未知数)
A_matrix = [[1, 2, 3], [4, 5, 6]]
b_matrix = [7, 8]
A_pinv = pinv(A)
print(f"A的伪逆 = {A_pinv}")
#A的伪逆 = [[-17/18, 4/9],
[-1/9, 1/9],
[13/18, -2/9]]
x_hat = A_pinv * b_matrix
print(f"最小范数解 x = A⁺b = {x_hat}")
#最小范数解 x = A⁺b = [[-55/18],
[1/9],
[59/18]]
print(f"验证 Ax = b: {A_matrix * x_hat}")
#验证 Ax = b: [[7], [8]]
示例3:秩亏矩阵(奇异矩阵)
A = [[1, 2, 3], [4, 8, 12], [2, 4, 6]] # 第二、三行线性相关
A_pinv = pinv(A)
print(f"A的伪逆 = {A_pinv}")
#A的伪逆 = [[1/294, 2/147, 1/147],
[1/147, 4/147, 2/147],
[1/98, 2/49, 1/49]]
print(f"验证 A⁺A A⁺ = A⁺: {A_pinv * A * A_pinv == A_pinv}")
print(f"验证 A A⁺ A = A: {A * A_pinv * A == A}")
#验证 A⁺A A⁺ = A⁺: True
#验证 A A⁺ A = A: True
示例4:零矩阵的伪逆
A = [[0, 0], [0, 0]]
A_pinv = pinv(A)
print(f"A的伪逆 = {A_pinv}")
#A的伪逆 = [[0, 0],
[0, 0]]
示例5:单位矩阵的伪逆
A = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
A_pinv = pinv(A)
print(f"A的伪逆 = {A_pinv}")
print(f"验证 A⁺ == A: {A_pinv == A}")
#A的伪逆 = [[1, 0, 0],
[0, 1, 0],
[0, 0, 1]]
#验证 A⁺ == A: True
示例6:数据压缩和降维中的应用 - SVD与伪逆
创建一个低秩矩阵(模拟压缩后的数据)
A = [[1, 2, 1], [2, 4, 2], [3, 6, 3], [4, 8, 4]]
A_pinv = pinv(A)
print(f"A的伪逆 = {A_pinv}")
#A的伪逆 = [[1/180, 1/90, 1/60, 1/45],
[1/90, 1/45, 1/30, 2/45],
[1/180, 1/90, 1/60, 1/45]]
验证伪逆的性质
A_matrix = A
验证伪逆的四个性质:
print(f"1. AA⁺A = A: {(A_matrix * A_pinv * A_matrix).equals(A_matrix)}")
print(f"2. A⁺AA⁺ = A⁺: {(A_pinv * A_matrix * A_pinv).equals(A_pinv)}")
print(f"3. (AA⁺)ᵀ = AA⁺: {(A_matrix * A_pinv).T == A_matrix * A_pinv}")
print(f"4. (A⁺A)ᵀ = A⁺A: {(A_pinv * A_matrix).T == A_pinv * A_matrix}")
#1. AA⁺A = A: True
#2. A⁺AA⁺ = A⁺: True
#3. (AA⁺)ᵀ = AA⁺: True
#4. (A⁺A)ᵀ = A⁺A: True
示例7:在机器学习中的应用 - 线性回归
房屋面积和价格的数据
特征: [1, 面积] (1对应偏置项)
X = [[1, 50], [1, 80], [1, 100], [1, 120], [1, 150]] # 设计矩阵
y = [200, 280, 320, 380, 450] # 价格
X_matrix = X
y_matrix = y
X_pinv = pinv(X)
print(f"伪逆 X⁺ = {X_pinv}")
#伪逆 X⁺ = [[154/145, 79/145, 1/5, -21/145, -96/145],
[-1/116, -1/290, 0, 1/290, 1/116]]
线性回归系数: θ = X⁺y
theta = X_pinv * y_matrix
print(f"回归系数 θ = X⁺y = {theta}")
print("模型: 价格 = {:.2f} + {:.2f} × 面积".format(float(theta[0]), float(theta[1])))
#回归系数 θ = X⁺y = [[76], [5/2]]
#模型: 价格 = 76.00 + 2.50 × 面积
示例8:图像处理中的应用 - 模糊核的逆
简单的模糊核(模拟运动模糊)
blur_kernel = [[0.1, 0.8, 0.1], [0.1, 0.8, 0.1], [0.1, 0.8, 0.1]]
K_pinv = pinv(blur_kernel)
print(f"去模糊核 K⁺ = {K_pinv}")
#去模糊核 K⁺ = [[0.0505050505050505, 0.0505050505050505, 0.0505050505050505],
[0.404040404040404, 0.404040404040404, 0.404040404040404],
[0.0505050505050505, 0.0505050505050505, 0.0505050505050505]])
#在图像处理中,模糊图像 = K * 清晰图像
#清晰图像 ≈ K⁺ * 模糊图像
示例9:控制理论中的应用 - 系统矩阵的逆
状态空间模型的系统矩阵
A_sys = [[0.9, 0.1], [-0.2, 0.8]]
A_pinv = pinv(A_sys)
print(f"伪逆 A⁺ = {A_pinv}")
#伪逆 A⁺ = [[1.08108108108108, -0.135135135135135],
[0.270270270270270, 1.21621621621622]]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def pseudo_inverse_matrix(input_str):
"""
计算给定矩阵的Moore-Penrose伪逆(对标MATLAB的pinv函数)。
参数:
input_str (str): 字符串形式的矩阵,支持以下格式:
- SymPy矩阵字符串,如"Matrix([[1, 0], [0, 0]])"
- 嵌套列表字符串,如"[[1, 0], [0, 0]]"
返回:
SymPy矩阵对象: 输入矩阵的伪逆(若输入有效)。
错误信息字符串: 若输入无效或计算失败。
示例:
>>> pseudo_inverse_matrix("[[1, 0], [0, 0]]")
Matrix([[1, 0], [0, 0]])
>>> pseudo_inverse_matrix("[[1, 2], [3, 4]]")
Matrix([
[ -2, 1],
[1.5, -0.5]])
>>> pseudo_inverse_matrix("5")
'输入错误: 5'
>>> pseudo_inverse_matrix("[[1, 2], [3, 4, 5]]")
'错误: ...' # 具体错误信息取决于异常
"""
try:
# 将输入字符串解析为SymPy表达式
expr = sp.sympify(input_str)
error_flag = False
result = None
# 检查并转换矩阵
matrix = sp.Matrix(expr) if isinstance(expr, list) else None
if matrix is not None:
# 计算伪逆
result = matrix.pinv()
else:
error_flag = True
return result if not error_flag else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
# 有效输入示例
print(pseudo_inverse_matrix("[[1, 0], [0, 0]]"))
# Matrix([[1, 0],
# [0, 0]])
print(pseudo_inverse_matrix("[[1, 2], [3, 4]]"))
# Matrix([[-2, 1],
# [3/2, -1/2]])
吉文斯平面旋转
[G,y] = planerot(x),其中x是一个包含2个分量的列向量,返回一个2×2正交矩阵G,使得y = G*x有y(2) = 0.
示例1:基本的向量旋转
test_vectors = [
[3, 4], # 经典的3-4-5三角形
[1, 1], # 45度角
[0, 5], # 纯y轴向量
[1, 0], # 纯x轴向量
[-3, 4], # 第二象限
[1, -1], # 第四象限
]
for vec in test_vectors:
result = planerot(vec)
G, y = result
print(f"向量 {vec}:")
print(f" 旋转矩阵 G = {G}")
print(f" 旋转后 y = {y}")
# 验证正交性
print(f" 正交性检查: G·Gᵀ = {G * G.T} (应为单位矩阵)")
print()
#向量 [3, 4]:
#旋转矩阵 G = [[0.6, 0.8],
[-0.8, 0.6]]
#旋转后 y = [[5.0],
[0]]
#正交性检查: G·Gᵀ = [[1.0, 0],
[0, 1.0]] (应为单位矩阵)
#向量 [1, 1]:
#旋转矩阵 G = [[0.707106781186547, 0.707106781186547],
[-0.707106781186547, 0.707106781186547]]
#旋转后 y = [[1.41421356237309],
[0]]
#正交性检查: G·Gᵀ = [[1.0, 0],
[0, 1.0]] (应为单位矩阵)
#向量 [0, 5]:
#旋转矩阵 G = [[0, 1.0],
[-1.0, 0]]
#旋转后 y = [[5.0],
[0]]
#正交性检查: G·Gᵀ = [[1.0, 0],
[0, 1.0]] (应为单位矩阵)
#向量 [1, 0]:
#旋转矩阵 G = [[1.0, 0],
[0, 1.0]]
#旋转后 y = [[1.0],
[0]]
#正交性检查: G·Gᵀ = [[1.0, 0],
[0, 1.0]] (应为单位矩阵)
#向量 [-3, 4]:
#旋转矩阵 G = [[-0.6, 0.8],
[-0.8, -0.6]]
#旋转后 y = [[5.0],
[0]]
#正交性检查: G·Gᵀ = [[1.0, 0],
[0, 1.0]] (应为单位矩阵)
#向量 [1, -1]:
#旋转矩阵 G = [[0.707106781186547, -0.707106781186547],
[0.707106781186547, 0.707106781186547]]
#旋转后 y = [[1.41421356237309],
[0]]
#正交性检查: G·Gᵀ = [[1.0, 0],
[0, 1.0]] (应为单位矩阵)
示例2:QR分解中的应用
创建一个3x2矩阵
A = [[3, 1],
[4, 2],
[0, 5]]
使用吉文斯旋转进行QR分解
第一步:对第一列引入零元素
x1 = [A[0, 0], A[1, 0]] # 取第一列的前两个元素
G1, _ = planerot(x1)
扩展G1到3x3
G1_extended = eye(3)
G1_extended[0:2, 0:2] = G1
A1 = G1_extended * A
print(f"第一次旋转后: A1 = {A1}")
#第一次旋转后: A1 = [[5.0, 2.2],
[0, 0.4],
[0, 5]]
第二步:对第二列引入零元素
x2 = [A1[1, 1], A1[2, 1]] # 取第二列的后两个元素
G2, _ = planerot(x2)
扩展G2到3x3
G2_extended = eye(3)
G2_extended[1:3, 1:3] = G2
R = G2_extended * A1
Q = G1_extended.T * G2_extended.T # 注意转置
print(f"最终 R = {R}")
print(f"验证 Q·R = {Q * R}")
print(f"验证 Q 正交: Q·Qᵀ = {Q * Q.T}")
#最终 R = [[5.0, 2.2],
[0, 5.01597448159378],
[0, -1.11022302462516e-16]]
#验证 Q·R = [[3.0, 1.0],
[4.0, 2.0],
[0, 5.0]]
#验证 Q 正交: Q·Qᵀ = [[1.0, -5.55111512312578e-17, -1.38777878078145e-17],
[-5.55111512312578e-17, 1.0, 0],
[-1.38777878078145e-17, 0, 1.0]]
示例3:信号处理中用于相位对齐
模拟两个信号的复数值
signal1 = complex(3, 4) # 幅度5, 相位53.13度
signal2 = complex(1, 2) # 幅度√5, 相位63.43度
将复数视为二维向量
vec1 = [signal1.real, signal1.imag]
vec2 = [signal2.real, signal2.imag]
print(f"信号1: {vec1} (幅度: {abs(signal1):.2f}, 相位: {np.angle(signal1, deg=True):.2f}°)")
print(f"信号2: {vec2} (幅度: {abs(signal2):.2f}, 相位: {np.angle(signal2, deg=True):.2f}°)")
#信号1: [3.0, 4.0] (幅度: 5.00, 相位: 53.13°)
#信号2: [1.0, 2.0] (幅度: 2.24, 相位: 63.43°)
对信号1应用吉文斯旋转使其与x轴对齐
G1, aligned1 = planerot(vec1)
print(f"信号1旋转矩阵: {G1}")
print(f"对齐后信号1: {aligned1}")
#信号1旋转矩阵: [[0.6, 0.8],
[-0.8, 0.6]]
#对齐后信号1: [[5.0],
[-4.44089209850063e-16]]
用同样的旋转矩阵处理信号2
vec2_matrix = vec2.reshape(2, 1)
aligned2 = G1 * vec2_matrix
print(f"对齐后信号2: {aligned2}")
#对齐后信号2: [[2.2],
[0.4]]
计算相对相位
relative_phase = np.angle(complex(float(aligned2[0]), float(aligned2[1])), deg=True)
print(f"相对相位差: {relative_phase:.2f}°")
#相对相位差: 10.30°
示例4:计算机图形学中的坐标系变换
假设我们有一个物体在局部坐标系中的方向向量
local_direction = [2, 3]
将这个方向旋转到与世界坐标系的x轴对齐
G, world_direction = planerot(local_direction)
print(f"旋转矩阵: {G}")
print(f"世界坐标系中的方向: {world_direction}")
#旋转矩阵: [[0.554700196225229, 0.832050294337844],
[-0.832050294337844, 0.554700196225229]]
#世界坐标系中的方向: [[3.60555127546399],
[0]]
验证旋转的可逆性
original_direction = G.T * world_direction
print(f"逆旋转恢复原方向: {original_direction}")
#逆旋转恢复原方向: [[2.0],
[3.0]]
示例5:数值稳定性
测试一些数值上具有挑战性的情况
challenging_vectors = [
[1e-10, 1e-10], # 非常小的数
[1e10, 1e10], # 非常大的数
[1e-10, 1e10], # 数值范围差异大
[0.9999999999, 0.0000000001], # 接近退化情况
]
for vec in challenging_vectors:
try:
result = planerot(vec)
G, y = result
print(f"向量 {vec}:")
print(f" 旋转成功,结果: {y}")
# 检查正交性保持
ortho_error = (G * G.T - sp.eye(2)).norm()
print(f" 正交性误差: {float(ortho_error):.2e}")
print()
except Exception as e:
print(f"向量 {vec}: 计算失败 - {e}")
#向量 [1e-10, 1e-10]:
#旋转成功,结果: [[1.41421356237310e-10],
[0]]
#正交性误差: 3.14e-16
#向量 [1e10, 1e10]:
#旋转成功,结果: [[14142135623.7309],
[0]]
#正交性误差: 3.14e-16
#向量 [1e-10, 1e10]:
#旋转成功,结果: [[10000000000.0],
[0]]
#正交性误差: 0.00e+00
#向量 [0.9999999999, 0.0000000001]:
#旋转成功,结果: [[0.999999999900000],
[0]]
#正交性误差: 0.00e+00
示例6:机器人末端执行器定向
末端执行器的当前方向向量
current_direction = [1, 2]
target_direction = [4, 3]
print(f"当前方向: {current_direction}")
print(f"目标方向: {target_direction}")
#当前方向: [1, 2]
#目标方向: [4, 3]
计算从当前方向到x轴的旋转
G_current, _ = planerot(current_direction)
计算从目标方向到x轴的旋转
G_target, _ = planerot(target_direction)
从当前到目标的旋转 = G_targetᵀ · G_current
rotation_current_to_target = G_target.T * G_current
print(f"当前到目标的旋转矩阵: {rotation_current_to_target}")
#当前到目标的旋转矩阵: [[0.894427190999916, 0.447213595499958],
[-0.447213595499958, 0.894427190999916]]
验证旋转效果
current_vec = current_direction.reshape(2, 1)
rotated_vec = rotation_current_to_target * current_vec
print(f"旋转后方向: {rotated_vec} (应接近目标方向)")
#旋转后方向: [[1.78885438199983],
[1.34164078649987]]
示例7:物理碰撞响应
物体的速度向量
velocity = [5, -2]
碰撞表面的法向量 (单位向量)
normal = [0, 1] # 水平表面
print(f"碰撞前速度: {velocity}")
print(f"表面法向量: {normal}")
#碰撞前速度: [5, -2]
#表面法向量: [0, 1]
计算将法向量旋转到y轴的旋转矩阵
G, _ = planerot(normal)
在旋转后的坐标系中,碰撞响应很简单:y分量反向
velocity_rotated = G * velocity.reshape(2, 1)
print(f"旋转坐标系中的速度: {velocity_rotated}")
#旋转坐标系中的速度: [[-2.0],
[-5.0]]
应用碰撞响应(y分量反向)
response_rotated = [velocity_rotated[0], -velocity_rotated[1]]
print(f"旋转坐标系中的响应: {response_rotated}")
#旋转坐标系中的响应: [[-2.0],
[5.0]]
旋转回原坐标系
response_original = G.T * response_rotated
print(f"原坐标系中的响应速度: {response_original}")
#原坐标系中的响应速度: [[-5.0],
[-2.0]]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def plane_givens_rotation(input_str):
"""
计算二维向量的吉文斯平面旋转矩阵(对标MATLAB的planerot函数)
参数:
input_str (str): 字符串形式的二维向量,支持格式:
- SymPy矩阵字符串: "Matrix([[3], [4]])"
- 嵌套列表字符串: "[[3], [4]]" 或 "[3, 4]"
返回:
tuple: (G, y) 元组,包含:
- G (Matrix): 2x2 吉文斯旋转矩阵
- y (Matrix): 旋转后向量,第二个元素为0
若输入有效则返回该元组
错误信息字符串: 输入无效时返回错误描述
示例:
>>> plane_givens_rotation("[3, 4]")
(Matrix([
[3/5, 4/5],
[-4/5, 3/5]]), Matrix([
[5],
[0]]))
>>> plane_givens_rotation("[[0], [0]]")
(Matrix([
[1, 0],
[0, 1]]), Matrix([
[0],
[0]]))
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
def compute_givens(x):
"""计算吉文斯旋转的核心逻辑"""
a, b = x[0], x[1]
# 处理零向量特殊情况
if a == 0 and b == 0:
return sp.eye(2), sp.Integer(0)
# 计算旋转参数
r = sp.sqrt(a ** 2 + b ** 2).evalf()
c = a / r
s = b / r
# 构建吉文斯矩阵
G = sp.Matrix([
[c, s],
[-s, c]
]).evalf()
return G, r
# 矩阵有效性检查
matrix_expr = sp.Matrix(expr) if isinstance(expr, list) else None
if matrix_expr is not None:
# 验证是否为二维向量
if matrix_expr.rows * matrix_expr.cols == 2:
x = matrix_expr.reshape(2, 1) # 强制转换为列向量
G, r = compute_givens(x)
y = G @ x # 矩阵乘法计算旋转后向量
result = (G, y)
else:
error = True
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误:{e}"
# 示例测试
if __name__ == "__main__":
# 正常案例测试
test_cases = [
"[3, 4]",
# (Matrix([[ 0.6, 0.8],
# [-0.8, 0.6]]),
# Matrix([[5.0],
# [ 0]]))
"[[1], [0]]",
# (Matrix([[1.0, 0],
# [ 0, 1.0]]),
# Matrix([[1.0],
# [ 0]]))
"[5, 12]",
# (Matrix([[ 0.384615384615385, 0.923076923076923],
# [-0.923076923076923, 0.384615384615385]]),
# Matrix([[13.0],
# [ 0]]))
]
for case in test_cases:
print(f"输入: {case}")
print("结果:", plane_givens_rotation(case))
print("-" * 40)
一元函数图 Plot(f(x))
描绘的是自变量 x 和因变量 y = f(x) 之间的静态关系. 直观展示函数在整个定义域或某个区间上的整体形态、变化趋势和关键特征。
x -- 变量
核心概念与基础性质:
多项式函数 (展示根、极值点、拐点): 清晰展示三次多项式的行为:一个局部极大值、一个局部极小值、一个拐点、三个实根(或一个实根两个复根,取决于具体值)。观察导数为零处(极值点)和二阶导数为零处(拐点)。
Plot(x^3-6x^2+4x+12,x=[-2,8])
三角函数组合 (展示叠加、拍频): 展示不同频率三角函数的叠加效果。可以观察到低频包络线(由频率差决定)和高频振荡(由频率和决定),即“拍频”现象。
Plot(sin(x)+cos(3x),x=[-2@pi,2@pi])
指数衰减 (展示渐近行为): 经典的自然衰减模型(如放射性衰变、RC电路放电)。清晰展示函数从1开始单调递减,并无限趋近于x轴(y=0)但永不触及(渐近线)
Plot(exp(-x),x=[0,5])
对数函数 (展示增长缓慢、定义域限制): 展示对数函数的特性:增长极其缓慢(对比指数函数),是偶函数(因为 x²+1),始终在x轴上方(值域 [0, ∞)),在x=0处取得最小值0
Plot(ln(x^2+1),x=[-5,5])
应用场景与模型:
阻尼振荡 (物理 - 弹簧振子、RLC电路): 模拟受阻尼的简谐振动。指数部分 e^{-0.2x} 代表振幅的衰减(阻尼),sin(x) 代表振荡。图像显示振荡幅度随时间逐渐减小。
Plot(exp(-0.2x)*sin(x),x=[0,20])
正态分布 (概率统计): 展示著名的钟形曲线。对称于y轴,在 x=0 处取得最大值 1/√(2π) ≈ 0.4,在 |x| > 2 后迅速衰减接近0。这是统计学中最核心的分布之一。
Plot(exp((-x^2)/2)/sqrt(2@pi),x=[-3,3])
需求曲线 (经济学): 展示典型的需求定律:价格(x)上涨,需求量(f(x))下降。函数单调递减,有下界(这里假设最小需求为0.5)。曲线形状反映需求弹性
Plot(1/(x+1)+0.5,x=[0,10])
Sinc 函数 (信号处理): 在信号处理(特别是采样定理)中极其重要。函数关于y轴对称,在 x=0 处值为1,在 x = ±kπ (k=1,2,3...) 处值为0。振幅随着 |x| 增大而衰减。主瓣和旁瓣清晰可见。
Plot(sin(x)/x,x=[-20,20])
有趣性质与特殊函数:
绝对值函数与振荡 (展示尖点与振荡): 函数在 x=0 处有尖点(不可导)。|x| 使得振幅随 |x| 增大而增大,sin(x) 提供振荡。图像像一条振幅不断增大的波浪线,且在原点“尖锐”地穿过x轴。
Plot(abs(x)*sin(x),x=[-10,10])
指数爆炸与振荡: 与阻尼振荡相反。指数部分 e^{0.1x} 代表振幅的指数级增长,sin(x) 提供振荡。图像显示振荡幅度随时间迅速增大。可类比某些不稳定系统或正反馈。
Plot(exp(0.1x)*sin(x),x=[0,30])
函数极限的经典例子: 当 x 趋近于0时,函数值在 [-1, 1] 之间无限次、无限快速地振荡。图像在0附近非常密集,无法趋近于任何一个特定的值,直观展示极限不存在。这是分析学中的一个经典例子。
Plot(sin(1/x),x=[-1,1])
多曲线函数图 Plot(f1(x), f2(x),...)
多个相关函数置于同一坐标系下,极大地增强了单图的信息量和分析能力,直观地揭示了仅靠单个函数图或分开的多个单函数图难以捕捉的对比关系和差异特征。
比较奇偶性/对称性: 直观展示 sin(x) 是奇函数 (关于原点对称),sin(-x) 与之重合或镜像
Plot(sin(x),sin(-x),x=[-2@pi,2@pi])
展示参数影响 (阻尼振动): 清晰对比不同阻尼系数 (0.1, 0.5, 2.0) 对简谐振子振幅衰减速度的影响
Plot(exp(-0.1x)*sin(x),exp(-0.5x)*sin(x),exp(-2x)*sin(x),x=[0,20])
比较不同阶多项式的增长:清晰展示线性、二次、三次函数在 x > 1 区域增长速度的显著差异 (x^3 > x^2 > x),直观理解函数阶数对增长趋势的影响。
Plot(x,x^2,x^3,x=[0,5])
展示基础函数的振荡差异:比较不同频率(ω=1 vs ω=2)正弦波的振荡周期和密度。直观显示频率加倍如何使波形在相同 x 范围内振荡次数翻倍。
Plot(sin(x),sin(2x), x=[0,4@pi])
比较衰减速率:对比不同衰减常数(λ=1 vs λ=0.5)的指数衰减。清晰显示衰减常数越小(0.5 < 1),函数值衰减得越慢。
Plot(exp(-x), exp(-0.5x),x=[0,10])
理解函数界限: 直观验证正弦函数的取值范围 [-1, 1] 以及它在哪些 x 点达到边界。
Plot(sin(x),1,-1,x=[0,2@pi])
比较不同优化器的收敛 (简化):用简单函数模拟优化过程中损失随迭代次数 x 的下降。1/x 代表较快下降(如 Momentum),1/√x 代表较慢下降(如基础 SGD)。对比收敛速度差异。
Plot(1/x,1/(x^0.5), x=[1,100])
比较概率分布密度形状:对比两种重要概率密度函数:正态分布(钟形、轻尾)和贝塔分布(尖峰、重尾)。突出它们在峰值陡峭度和尾部衰减速度上的显著差异。
Plot([normpdf(x,2,1), betapdf(x,2,1)], x=[-5, 5])
时域函数图 Plot(f(x,T))
在绘制函数 f(x+T) 时,我们不是用当前时间 x 的值,而是用 T 时间单位之后(或之前)的时间点 (x + T) 的值。 观察和分析一个函数(信号)在时间轴上发生平移后的效果。
x -- 变量
T -- 动画参数
基础波形动画:
标准正弦波平移: 完整正弦波沿x轴向左平滑移动
Plot(sin(x + T))
压缩正弦波: 频率加倍的正弦波快速向左移动
Plot(sin(2x + T))
衰减波包: 振幅指数衰减的波包向右传播
Plot(e^(-0.1x) * sin(x + T))
调制与复合波形:
调幅波(AM): 载波频率5Hz,振幅以0.25Hz低频振荡
Plot((1 + 0.5*sin(0.5T)) * sin(5x + T))
调频波(FM): 瞬时频率随T周期性变化
Plot(sin(3x + 2*sin(0.3x+T)*x))
物理现象模拟:
驻波: 波节位置固定,波腹振幅周期性变化
Plot(sin(x-T) + sin(x+T))
行波反射: 入射波与衰减反射波叠加
Plot(sin(x-T) + 0.7*sin(-x-T))
特殊波形:
混沌振荡: 双频率耦合产生准周期运动
Plot(sin(x+T) + 0.5*sin(πx + 2T))
多曲线时域动画图 Plot(f1(x,T), f2(x,T), ...)
将多条曲线、时间演化和动画结合在一起,用于展示随时间变化的多组数据或函数关系。 揭示动态系统中多个相关量随时间和另一个变量共同演化的复杂关系。
x -- 变量
T -- 动画参数
基础波形组:
两条正弦波交替呈现"峰-谷"互补
Plot(
sin(x + T), # 基准波
sin(x + T + π/2) # 超前90°的波
)
频率阶梯: 不同频率波形同步平移,展示谐波关系
Plot(
sin(x + T), # 基波
sin(2x + T), # 二倍频波
sin(3x + T) # 三倍频波
)
调制对比: 振幅变化 vs 相位抖动的直观对比
Plot(
(1 + 0.5*sin(T)) * sin(x), # 调幅波
sin(x + 2*sin(T)) # 调相波
)
物理现象组:
行波与驻波: 观察行波如何叠加形成固定波节的驻波
Plot(
sin(x - T), # 向右传播的行波
sin(x - T) + sin(x + T) # 形成的驻波
)
多普勒频移模拟: 运动波源的波形压缩/拉伸效应
Plot(
sin(10x), # 静止波源
sin(10*(x - 0.5*sin(T))) # 运动波源的波
)
偏振合成: 线偏振→圆偏振的动态转变
Plot(
sin(T)*sin(x), # X方向分量
cos(T)*cos(x), # Y方向分量
sin(T)*sin(x) + cos(T)*cos(x) # 合成光波
)
单曲面三维函数图
Plot3D(f(x,y)) 直观呈现两个自变量如何共同影响因变量(非简单叠加), 将抽象数学描述(如偏微分方程解)转化为可理解的几何形态.
波动干涉模型(物理学): 模拟两个点波源(位置 (2,0) 和 (-2,0))的干涉波纹。三维曲面清晰展示波峰叠加(相长干涉)和波谷抵消(相消干涉)的区域,直观解释干涉条纹的形成原理。
Plot3D(sin(@pi*sqrt((x-2)^2+y^2))+sin(@pi*sqrt((x+2)^2+y^2)),x=[-5,5],y=[-5,5])
优化问题的目标函数曲面(数学/运筹学): 绘制 Beale函数(经典优化测试函数)。曲面呈现多个局部极小值和狭窄的全局最优谷底,突出优化算法(如梯度下降)易陷入局部最优的挑战。
Plot3D((1.5-x+x*y)^2+(2.25-x+x*y^2)^2+(2.625-x+x*y^3)^2,x=[-4,4],y=[-4,4])
热传导稳态分布(工程学): 模拟矩形金属板在 x=0 边恒温加热时的稳态温度分布。展示温度沿 x 方向正弦振荡、沿 y 方向指数衰减的物理规律,高温区和低温区一目了然。
Plot3D(50*sin(@pi*x/2)*exp(-@pi*y/2),x=[0,2],y=[0,3])
经济学中的效用曲面(微观经济学): Cobb-Douglas效用函数,描述消费者对两种商品 (x,y) 的满意度。曲面呈现边际效用递减(随 x 或 y 增加,效用增长变缓)和无差异曲线投影(等高线)。
Plot3D(x^0.4*y^0.6,x=[0,5],y=[0,5])
量子力学概率密度(物理学): 氢原子 2pₓ 轨道的概率密度分布。环形山峰反映电子出现的概率在原点处为零,在特定半径处达到峰值,直观展示量子态的非均匀特性。
Plot3D((x^2+y^2)*exp(-(x^2+y^2)),x=[-3,3],y=[-3,3])
地形高程模型(地理学): Matlab的Peaks函数,模拟多峰山脉地形。同时显示主峰、次峰、山谷和鞍部,用于测试地形渲染算法或路径规划。
Plot3D(3*(1-x)^2*exp(-x^2-(y+1)^2)-10*(x/5-x^3-y^5)*exp(-x^2-y^2)-(1/3)*exp(-(x+1)^2-y^2),x=[-3,3], y=[-3,3])
流体速度场势函数(流体力学): 不可压缩流体的速度势。曲面等高线对应流线,梯度方向即流速方向,直观呈现涡旋和流动模式。
Plot3D((cos(2*@pi*x)/2+sin(2*@pi*y)/2),x=[0,1],y=[0,1])
多曲面三维函数图
Plot3D(f1(x,y),f2(x,y)...) 同时可视化多个三维函数(两个自变量)能揭示单曲面无法呈现的空间关系、对称性、包络效应和系统行为,在科学和工程中具有关键作用.
电磁场正交分量: 展示电磁波传播中电场与磁场的空间正交性和能量传递相位差
Plot3D(sin(x)*cos(y),cos(x)*sin(y),x=[-@pi,@pi],y=[-@pi,@pi])
量子叠加态概率密度: 对比量子粒子在不同能级的概率分布差异,交叉区域显示量子隧穿效应
Plot3D(exp(-(x-1)^2-y^2),exp(-(x+1)^2-y^2),x=[-3,3],y=[-3,3])
流体速度剖面: 对比管道流体中层流与湍流的速度分布差异,波纹曲面显示涡旋结构
Plot3D(1-(x^2+y^2),1-sqrt(x^2+y^2)+0.2*sin(10*sqrt(x^2 + y^2)),x=[-1,1],y=[-1,1])
地形与水位线: 显示洪水淹没区域(曲面交线以下),用于灾害模拟
Plot3D(3*exp(-x^2-(y-1)^2),0.5,x=[-3,3],y=[-3,3])
神经网络损失曲面对比: 对比不同优化问题的复杂性,非凸曲面的局部极小值陷阱清晰可见
Plot3D(x^2+y^2,x^2-y^2+0.5*sin(3@pi*x)*cos(2@pi*y),x=[-2,2],y=[-2,2])
声波干涉模式: 叠加曲面显示相长/相消干涉条纹,峰值重合区为最大振幅点
Plot3D(cos(@pi*sqrt((x-2)^2+y^2)),cos(@pi*sqrt((x+2)^2+y^2)),x=[-5,5],y=[-5,5])
经济生产可能性边界: 显示不同生产技术的产出边界,交线为最优资源配置路径
Plot3D(10-x^2-y^2, 8-0.5*(x-1)^2-0.5*(y-1)^2,x=[0,3],y=[0,3])
阶乘幂
pochhammer(x,n)返回 pochhammer符号(x)n
x —— 输入,数字,向量,矩阵,符号数字,符号变量,符号向量,符号矩阵,符号表达式
n —— 输入,数字,向量,矩阵,符号数字,符号变量,符号向量,符号矩阵,符号表达式
示例1. 组合数学应用
tests_combinatorics = [
("(5, 3)", "计算组合数 C(7,3) = rf(5,3)/3! = 35"),
("(n, k)", "二项式系数相关: C(n+k-1, k) = rf(n,k)/k!"),
("(7, 4)", "多重集组合数: 从7种元素中选4个的可重组合"),
]
for case, desc in tests_combinatorics:
result = pochhammer(case)
print(f"{desc}")
print(f"输入: {case} -> 输出: {result}")
print("-" * 40)
#计算组合数 C(7,3) = rf(5,3)/3! = 35
#输入: (5, 3) -> 输出: 210.0
#----------------------------------------
#二项式系数相关: C(n+k-1, k) = rf(n,k)/k!
#输入: (n, k) -> 输出: Piecewise((gamma(k + n)/gamma(n), n > 0), ((-1)**k*gamma(1 - n)/gamma(-k - n + 1), True))
#----------------------------------------
#多重集组合数: 从7种元素中选4个的可重组合
#输入: (7, 4) -> 输出: 5040.0
示例2. 特殊函数关系
tests_special = [
("(1/2, 3)", "与双阶乘关系: rf(1/2, n) = (2n-1)!!/2^n"),
("(z, n)", "Gamma函数表示: rf(z,n) = Γ(z+n)/Γ(z)"),
("(1, 5)", "阶乘: rf(1,n) = n!"),
]
for case, desc in tests_special:
result = pochhammer(case)
print(f"{desc}")
print(f"输入: {case} -> 输出: {result}")
print("-" * 40)
#与双阶乘关系: rf(1/2, n) = (2n-1)!!/2^n
#输入: (1/2, 3) -> 输出: 1.875
#----------------------------------------
#Gamma函数表示: rf(z,n) = Γ(z+n)/Γ(z)
#输入: (z, n) -> 输出: Piecewise((gamma(n + z)/gamma(z), z > 0), ((-1)**n*gamma(1 - z)/gamma(-n - z + 1), True))
#----------------------------------------
#阶乘: rf(1,n) = n!
#输入: (1, 5) -> 输出: 120.0
示例3. 概率统计应用
tests_probability = [
("(a, 4)", "负二项分布中的系数"),
("(theta, k)", "Dirichlet分布相关"),
("(alpha, r)", "Gamma-Poisson混合分布参数"),
]
for case, desc in tests_probability:
result = pochhammer(case)
print(f"{desc}")
print(f"输入: {case} -> 输出: {result}")
print("-" * 40)
#负二项分布中的系数
#输入: (a, 4) -> 输出: a*(a + 1)*(a + 2)*(a + 3)
#----------------------------------------
#Dirichlet分布相关
#输入: (theta, k) -> 输出: Piecewise((gamma(k + theta)/gamma(theta), theta > 0), ((-1)**k*gamma(1 - theta)/gamma(-k - theta + 1), True))
#----------------------------------------
#Gamma-Poisson混合分布参数
#输入: (alpha, r) -> 输出: Piecewise((gamma(alpha + r)/gamma(alpha), alpha > 0), ((-1)**r*gamma(1 - alpha)/gamma(-alpha - r + 1), True))
#----------------------------------------
示例4. 物理应用
tests_physics = [
("(l-m+1, 2*m)", "球谐函数相关"),
("(n+1/2, k)", "量子力学谐振子波函数"),
("(alpha+1, n)", "勒让德多项式系数"),
]
for case, desc in tests_physics:
result = pochhammer(case)
print(f"{desc}")
print(f"输入: {case} -> 输出: {result}")
print("-" * 40)
#球谐函数相关
#输入: (l-m+1, 2*m) -> 输出: Piecewise((gamma(l + m + 1)/gamma(l - m + 1), l - m > -1), ((-1)**(2*m)*gamma(-l + m)/gamma(-l - m), True))
#----------------------------------------
#量子力学谐振子波函数
#输入: (n+1/2, k) -> 输出: Piecewise((gamma(k + n + 1/2)/gamma(n + 1/2), n > -1/2), ((-1)**k*gamma(1/2 - n)/gamma(-k - n + 1/2), True))
#----------------------------------------
#勒让德多项式系数
#输入: (alpha+1, n) -> 输出: Piecewise((gamma(alpha + n + 1)/gamma(alpha + 1), alpha > -1), ((-1)**n*gamma(-alpha)/gamma(-alpha - n), True))
#----------------------------------------
示例5. 数值计算验证
tests_numerical = [
("(2.5, 3)", "浮点数计算: 2.5×3.5×4.5"),
("(-3, 4)", "负整数计算: (-3)×(-2)×(-1)×0"),
("(0, 5)", "零的升阶乘"),
]
for case, desc in tests_numerical:
result = pochhammer(case)
print(f"{desc}")
print(f"输入: {case} -> 输出: {result}")
print("-" * 40)
#浮点数计算: 2.5×3.5×4.5
#输入: (2.5, 3) -> 输出: 39.375
#----------------------------------------
#负整数计算: (-3)×(-2)×(-1)×0
#输入: (-3, 4) -> 输出: 0.0
#----------------------------------------
#零的升阶乘
#输入: (0, 5) -> 输出: 0.0
#----------------------------------------
示例6. 实际工程应用
engineering_tests = [
("(5, 3)", "计算5个元素中取3个的排列数: 5×6×7 = 210"),
("(10, 4)", "多项式展开系数计算"),
("(m, n)", "超几何级数的一般项"),
]
for case, desc in engineering_tests:
result = pochhammer(case)
print(f"{desc}")
print(f"输入: {case} -> 输出: {result}")
print("-" * 40)
#计算5个元素中取3个的排列数: 5×6×7 = 210
#输入: (5, 3) -> 输出: 210.0
#----------------------------------------
#多项式展开系数计算
#输入: (10, 4) -> 输出: 17160.0
#----------------------------------------
#超几何级数的一般项
#输入: (m, n) -> 输出: Piecewise((gamma(m + n)/gamma(m), m > 0), ((-1)**n*gamma(1 - m)/gamma(-m - n + 1), True))
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.special import poch
def pochhammer_rising_factorial(input_str):
"""
计算Pochhammer升阶乘符号(对标MATLAB的pochhammer函数)
参数:
input_str (str): 字符串形式的输入,应为包含两个元素的元组:
- 格式示例: "(x, n)" 或 "(Matrix([[1,2]]), 3)"
- 元素可以是标量或矩阵
返回:
Matrix/Expr: 计算结果,有以下情况:
- 标量输入返回符号表达式
- 矩阵输入返回同型矩阵
- 错误时返回描述字符串
示例:
>>> pochhammer_rising_factorial("(5, 3)")
210
>>> pochhammer_rising_factorial("(Matrix([[1,2],[3,4]]), 2)")
Matrix([
[ 2, 6],
[12, 20]])
>>> pochhammer_rising_factorial("(a, 3)")
a*(a + 1)*(a + 2)
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
# 验证输入为二元组
if isinstance(expr, tuple) and len(expr) == 2:
if all(e.is_number for e in expr):
params = tuple(float(e.evalf()) for e in expr)
result = poch(*params) # x和n为数值类型
elif any(e.free_symbols for e in expr):
result = sp.rf(*expr).rewrite(sp.gamma)
else:
error = True
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误:{e}"
# 测试用例
if __name__ == "__main__":
# 正常输入测试
tests = [
("(5, 3)", "标量计算"),
# 210.0
("(a, 3)", "符号计算"),
# a*(a + 1)*(a + 2)
]
for case, desc in tests:
print(f"测试案例: {desc}")
print("输入:", case)
print("输出:", pochhammer_rising_factorial(case))
print("=" * 60)
泊松累积分布函数
y = poisscdf(x,lambda) 使用 lambda 中的速率参数计算在 x 中每个值处的泊松累积分布函数值.
x 和 lambda 可以是大小都相同的标量,向量或矩阵. 如果只有一个参量是标量, poisscdf会将其扩展为其维数与另一个参量相同的常量数组.
x — 计算泊松 cdf 所基于的值,标量值,标量值组成的数组
lambda — 速率参数,正值,正值组成的数组
y — 泊松 cdf 值,标量值,标量值组成的数组
示例1. 质量控制与可靠性工程
quality_tests = [
("(2, 0.5)", "设备每小时平均故障0.5次,求3小时内故障不超过2次的概率"),
("(5, 2.5)", "生产线每小时平均产生2.5个次品,求1小时内次品不超过5个的概率"),
("(0, 0.1)", "高可靠性设备,平均100小时故障1次,求10小时内无故障概率"),
]
for case, desc in quality_tests:
result = poisscdf(case)
print(f"应用: {desc}")
print(f"输入: {case} -> 输出: {result}")
if case == "(2, 0.5)":
print("解释: 设备在3小时内故障不超过2次的概率为", round(result, 4))
print("-" * 50)
#应用: 设备每小时平均故障0.5次,求3小时内故障不超过2次的概率
#输入: (2, 0.5) -> 输出: 0.9856123220330293
#解释: 设备在3小时内故障不超过2次的概率为 0.9856
#--------------------------------------------------
#应用: 生产线每小时平均产生2.5个次品,求1小时内次品不超过5个的概率
#输入: (5, 2.5) -> 输出: 0.9579789618046939
#--------------------------------------------------
#应用: 高可靠性设备,平均100小时故障1次,求10小时内无故障概率
#输入: (0, 0.1) -> 输出: 0.9048374180359595
示例2. 通信与网络工程
communication_tests = [
("(10, 8)", "网络路由器平均每秒处理8个数据包,求1秒内处理不超过10个包的概率"),
("(3, 5)", "呼叫中心平均每分钟接到5个电话,求1分钟内来电不超过3个的概率"),
("(15, 12)", "服务器平均每秒接收12个请求,求1秒内请求不超过15个的概率"),
]
for case, desc in communication_tests:
result = poisscdf(case)
print(f"应用: {desc}")
print(f"输入: {case} -> 输出: {result}")
print("-" * 50)
#应用: 网络路由器平均每秒处理8个数据包,求1秒内处理不超过10个包的概率
#输入: (10, 8) -> 输出: 0.8158857925585467
#--------------------------------------------------
#应用: 呼叫中心平均每分钟接到5个电话,求1分钟内来电不超过3个的概率
#输入: (3, 5) -> 输出: 0.2650259152973616
#--------------------------------------------------
#应用: 服务器平均每秒接收12个请求,求1秒内请求不超过15个的概率
#输入: (15, 12) -> 输出: 0.8444156524501832
#--------------------------------------------------
示例3. 医疗与生物统计
medical_tests = [
("(2, 1.2)", "医院急诊室平均每小时接收1.2个急症患者,求1小时内患者不超过2人的概率"),
("(5, 3.5)", "细胞培养中平均每视野发现3.5个突变细胞,求单视野突变细胞不超过5个的概率"),
("(0, 0.8)", "罕见疾病在特定人群中发病率0.8例/年,求1年内无新发病例的概率"),
]
for case, desc in medical_tests:
result = poisscdf(case)
print(f"应用: {desc}")
print(f"输入: {case} -> 输出: {result}")
if case == "(0, 0.8)":
prob = result
print(f"解释: 1年内无新发病例的概率为 {prob:.4f},即约 {prob*100:.1f}%")
print("-" * 50)
#应用: 医院急诊室平均每小时接收1.2个急症患者,求1小时内患者不超过2人的概率
#输入: (2, 1.2) -> 输出: 0.8794870987836302
#--------------------------------------------------
#应用: 细胞培养中平均每视野发现3.5个突变细胞,求单视野突变细胞不超过5个的概率
#输入: (5, 3.5) -> 输出: 0.8576135530957782
#--------------------------------------------------
#应用: 罕见疾病在特定人群中发病率0.8例/年,求1年内无新发病例的概率
#输入: (0, 0.8) -> 输出: 0.4493289641172217
#解释: 1年内无新发病例的概率为 0.4493,即约 44.9%
示例4. 金融风险管理
finance_tests = [
("(3, 2)", "交易系统平均每天出现2次异常交易,求1天内异常交易不超过3次的概率"),
("(1, 0.3)", "投资组合平均每月发生0.3次大幅波动,求1个月内波动不超过1次的概率"),
("(10, 15)", "高频交易平均每秒15次,求1秒内交易次数不超过10次的概率(系统负载评估)"),
]
for case, desc in finance_tests:
result = poisscdf(case)
print(f"应用: {desc}")
print(f"输入: {case} -> 输出: {result}")
print("-" * 50)
#应用: 交易系统平均每天出现2次异常交易,求1天内异常交易不超过3次的概率
#输入: (3, 2) -> 输出: 0.857123460498547
#--------------------------------------------------
#应用: 投资组合平均每月发生0.3次大幅波动,求1个月内波动不超过1次的概率
#输入: (1, 0.3) -> 输出: 0.9630636868862332
#--------------------------------------------------
#应用: 高频交易平均每秒15次,求1秒内交易次数不超过10次的概率(系统负载评估)
#输入: (10, 15) -> 输出: 0.11846441152901499
#--------------------------------------------------
示例5. 交通与物流规划
transportation_tests = [
("(4, 3)", "十字路口平均每分钟通过3辆车,求1分钟内通过不超过4辆车的概率"),
("(8, 6)", "物流中心平均每小时到达6辆货车,求1小时内到达不超过8辆的概率"),
("(20, 25)", "地铁站平均每分钟25人进站,求1分钟内进站人数不超过20人的概率"),
]
for case, desc in transportation_tests:
result = poisscdf(case)
print(f"应用: {desc}")
print(f"输入: {case} -> 输出: {result}")
print("-" * 50)
#应用: 十字路口平均每分钟通过3辆车,求1分钟内通过不超过4辆车的概率
#输入: (4, 3) -> 输出: 0.8152632445237722
#--------------------------------------------------
#应用: 物流中心平均每小时到达6辆货车,求1小时内到达不超过8辆的概率
#输入: (8, 6) -> 输出: 0.8472374939845612
#--------------------------------------------------
#应用: 地铁站平均每分钟25人进站,求1分钟内进站人数不超过20人的概率
#输入: (20, 25) -> 输出: 0.18549230269414174
#--------------------------------------------------
示例6. 零售与库存管理
retail_tests = [
("(15, 10)", "商店平均每天售出10件商品,求1天内销量不超过15件的概率"),
("(5, 8)", "餐厅平均每小时接待8位顾客,求1小时内顾客不超过5位的概率(淡季分析)"),
("(50, 40)", "电商平台平均每小时40个订单,求1小时内订单不超过50个的概率"),
]
for case, desc in retail_tests:
result = poisscdf(case)
print(f"应用: {desc}")
print(f"输入: {case} -> 输出: {result}")
print("-" * 50)
#应用: 商店平均每天售出10件商品,求1天内销量不超过15件的概率
#输入: (15, 10) -> 输出: 0.9512595966960213
#--------------------------------------------------
#应用: 餐厅平均每小时接待8位顾客,求1小时内顾客不超过5位的概率(淡季分析)
#输入: (5, 8) -> 输出: 0.19123606207962532
#--------------------------------------------------
#应用: 电商平台平均每小时40个订单,求1小时内订单不超过50个的概率
#输入: (50, 40) -> 输出: 0.9473719508932413
#--------------------------------------------------
示例7. 环境科学与气象
environmental_tests = [
("(2, 0.5)", "某地区平均每年发生0.5次强降雨,求1年内强降雨不超过2次的概率"),
("(1, 0.2)", "自然保护区平均每年发现0.2次珍稀物种,求1年内发现不超过1次的概率"),
("(3, 1.5)", "空气质量监测站平均每月1.5天超标,求1月内超标天数不超过3天的概率"),
]
for case, desc in environmental_tests:
result = poisscdf(case)
print(f"应用: {desc}")
print(f"输入: {case} -> 输出: {result}")
print("-" * 50)
#应用: 某地区平均每年发生0.5次强降雨,求1年内强降雨不超过2次的概率
#输入: (2, 0.5) -> 输出: 0.9856123220330293
#--------------------------------------------------
#应用: 自然保护区平均每年发现0.2次珍稀物种,求1年内发现不超过1次的概率
#输入: (1, 0.2) -> 输出: 0.9824769036935782
#--------------------------------------------------
#应用: 空气质量监测站平均每月1.5天超标,求1月内超标天数不超过3天的概率
#输入: (3, 1.5) -> 输出: 0.9343575456215499
#--------------------------------------------------
示例8. 矩阵计算应用
matrix_tests = [
("([[0, 1, 2, 3]], 2)", "同时计算多个事件数的累积概率(批量分析)"),
("([[2, 2, 2]], [[1, 2, 3]])", "不同lambda参数下的累积概率比较"),
("([[0, 5, 10]], [[1, 5, 10]])", "不同规模系统的可靠性评估"),
]
for case, desc in matrix_tests:
result = poisscdf(case)
print(f"应用: {desc}")
print(f"输入: {case}")
print(f"输出: {result}")
print("-" * 50)
#应用: 同时计算多个事件数的累积概率(批量分析)
#输入: ([[0, 1, 2, 3]], 2)
#输出: [[0.13533528 0.40600585 0.67667642 0.85712346]]
#--------------------------------------------------
#应用: 不同lambda参数下的累积概率比较
#输入: ([[2, 2, 2]], Matrix([[1, 2, 3]]))
#输出: [[0.9196986 0.67667642 0.42319008]]
#--------------------------------------------------
#应用: 不同规模系统的可靠性评估
#输入: ([[0, 5, 10]], Matrix([[1, 5, 10]]))
#输出: [[0.36787944 0.61596065 0.58303975]]
#--------------------------------------------------
示例9. 符号计算应用
symbolic_tests = [
("(k, lambda_)", "理论研究:一般形式的泊松累积分布函数"),
("(2, mu)", "参数化分析:固定事件数,变化lambda参数"),
("(n, 5)", "容量规划:固定发生率,变化容量需求"),
]
for case, desc in symbolic_tests:
result = poisscdf(case)
print(f"应用: {desc}")
print(f"输入: {case} -> 输出: {result}")
print("-" * 50)
#应用: 理论研究:一般形式的泊松累积分布函数
#输入: (k, lambda_) -> 输出: Piecewise(((-lambda_**(-floor(k) - 1.0)*lambda_**(floor(k) + 1.0)*(floor(k) + 1.0)*exp(lambda_)*lowergamma(floor(k) + 1, lambda_)/factorial(floor(k) + 1) + exp(lambda_))*exp(-lambda_), k >= 0), (0, True))
#--------------------------------------------------
#应用: 参数化分析:固定事件数,变化lambda参数
#输入: (2, mu) -> 输出: (-0.5*(-2.0*(0.5*mu**2 + mu + 1.0)*exp(-mu) + 2.0)*exp(mu) + exp(mu))*exp(-mu)
#--------------------------------------------------
#应用: 容量规划:固定发生率,变化容量需求
#输入: (n, 5) -> 输出: Piecewise((-1.0*5.0**(-floor(n) - 1.0)*5.0**(floor(n) + 1.0)*(floor(n) + 1.0)*lowergamma(floor(n) + 1, 5)/factorial(floor(n) + 1) + 1.0, n >= 0), (0, True))
#--------------------------------------------------
示例10. 系统性能评估
performance_tests = [
("(5, 10)", "服务器过载分析:平均负载10,实际负载≤5的概率"),
("(20, 15)", "系统容量规划:平均需求15,峰值不超过20的概率"),
("(100, 80)", "大规模系统:平均并发80,最大并发100的保证概率"),
]
for case, desc in performance_tests:
result = poisscdf(case)
print(f"应用: {desc}")
print(f"输入: {case} -> 输出: {result}")
if case == "(5, 10)":
prob = result
print(f"系统性能: 负载在安全范围内的概率为 {prob:.4f}")
print("-" * 50)
#应用: 服务器过载分析:平均负载10,实际负载≤5的概率
#输入: (5, 10) -> 输出: 0.06708596287903189
#系统性能: 负载在安全范围内的概率为 0.0671
#--------------------------------------------------
#应用: 系统容量规划:平均需求15,峰值不超过20的概率
#输入: (20, 15) -> 输出: 0.9170290899685397
#--------------------------------------------------
#应用: 大规模系统:平均并发80,最大并发100的保证概率
#输入: (100, 80) -> 输出: 0.9868311451240662
#--------------------------------------------------
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from sympy.stats import Poisson, cdf
from scipy.stats import poisson
def poisson_distribution_cdf(input_str):
"""
计算泊松累积分布函数(对标MATLAB的poisscdf函数)
参数:
input_str (str): 字符串形式的输入,应为包含两个元素的元组:
- 格式示例: "(x, lambda)" 或 "(Matrix([[0,1,2]]), 2)"
- x: 事件数(支持标量/矩阵)
- lambda: 泊松分布参数(正数,支持标量/矩阵)
返回:
Matrix/Expr: 计算结果,有以下情况:
- 标量输入返回数值
- 矩阵输入返回同型矩阵
- 错误时返回描述字符串
示例:
>>> poisson_distribution_cdf("(2, 1)")
0.919698602928606
>>> poisson_distribution_cdf("(Matrix([[0,1,2]]), 2)")
Matrix([[0.135335283236613, 0.406005849709838, 0.676676416183063]])
>>> poisson_distribution_cdf("(-1, 2)")
'错误: Lambda参数必须为正数'
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
# 验证输入格式为二元组
if isinstance(expr, tuple) and len(expr) == 2:
if all(e.is_number for e in expr):
params = tuple(float(e.evalf()) for e in expr)
result = poisson.cdf(*params)
elif any(e.free_symbols for e in expr):
x, lam = expr
# 参数验证
# 创建泊松随机变量
X = Poisson("poisson", lam)
result = cdf(X)(x)
else:
error = True
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f'错误:{str(e)}'
# 测试用例
if __name__ == "__main__":
# 正常案例测试
tests = [
("(2, x)", "符号计算"),
# (-(-2*(x**2/2 + x + 1)*exp(-x) + 2)*exp(x)/2 + exp(x))*exp(-x)
("(2.5, 3)", "标量计算 "),
# 0.42319008112684364
]
for case, desc in tests:
print(f"测试案例: {desc}")
print("输入:", case)
print("输出:", poisson_distribution_cdf(case))
print("=" * 60)
泊松参数估计
[lambdahat,lambdaci] = poissfit(data) 还在 lambdaci 中给出 95% 的置信区间.
[lambdahat,lambdaci] = poissfit(data,alpha) 给出 100(1 - alpha)% 的置信区间。例如,alpha = 0.001 得出 99.9% 的置信区间.
示例1. 质量控制与制造过程
quality_tests = [
("[0,1,0,0,1,0,0,1,0,0]", "设备每日故障次数估计 - 10天观测数据"),
("[2,3,1,2,2,1,3,2,1,2]", "生产线每小时次品数估计"),
("[0,0,0,1,0,0,0,0,0,1]", "高可靠性系统故障率估计"),
]
for case, desc in quality_tests:
result = poissfit(case)
print(f"应用: {desc}")
print(f"输入: {case}")
print(f"输出: λ估计值 = {result[0]:.3f}, 95%置信区间 = ({result[1][0]:.3f}, {result[1][1]:.3f})")
print("-" * 50)
#应用: 设备每日故障次数估计 - 10天观测数据
#输入: [0,1,0,0,1,0,0,1,0,0]
#输出: λ估计值 = 0.300, 95%置信区间 = (0.062, 0.877)
#--------------------------------------------------
#应用: 生产线每小时次品数估计
#输入: [2,3,1,2,2,1,3,2,1,2]
#输出: λ估计值 = 1.900, 95%置信区间 = (1.144, 2.967)
#--------------------------------------------------
#应用: 高可靠性系统故障率估计
#输入: [0,0,0,1,0,0,0,0,0,1]
#输出: λ估计值 = 0.200, 95%置信区间 = (0.024, 0.722)
示例2. 客户服务与呼叫中心
service_tests = [
("[12,15,18,10,14,16,13,17,11,15]", "呼叫中心每小时来电数 - 10小时数据"),
("[5,8,6,7,4,9,5,6,7,5]", "在线客服每分钟咨询量"),
("[25,30,28,32,27,29,26,31,28,30]", "高峰期每小时服务请求数"),
]
for case, desc in service_tests:
result = poissfit(case)
print(f"应用: {desc}")
print(f"输入: {case}")
print(f"输出: 平均到达率 = {result[0]:.1f}次/单位时间")
print(f" 95%置信区间 = ({result[1][0]:.1f}, {result[1][1]:.1f})")
print("-" * 50)
#应用: 呼叫中心每小时来电数 - 10小时数据
#输入: [12,15,18,10,14,16,13,17,11,15]
#输出: 平均到达率 = 14.1次/单位时间
# 95%置信区间 = (11.9, 16.6)
--------------------------------------------------
#应用: 在线客服每分钟咨询量
#输入: [5,8,6,7,4,9,5,6,7,5]
#输出: 平均到达率 = 6.2次/单位时间
# 95%置信区间 = (4.8, 7.9)
--------------------------------------------------
#应用: 高峰期每小时服务请求数
#输入: [25,30,28,32,27,29,26,31,28,30]
#输出: 平均到达率 = 28.6次/单位时间
# 95%置信区间 = (25.4, 32.1)
示例3. 网络流量分析
network_tests = [
("[150,165,142,158,170,148,162,155,160,152]", "路由器每秒数据包数"),
("[45,50,48,52,47,49,51,46,50,48]", "服务器每分钟连接请求"),
("[1000,1050,980,1020,990,1010,995,1005,985,1015]", "网络端口每秒比特数(除以100简化)"),
]
for case, desc in network_tests:
result = poissfit(case)
print(f"应用: {desc}")
print(f"输入: {case}")
print(f"输出: 流量率估计 = {result[0]:.1f}")
print(f" 网络容量规划参考区间 = ({result[1][0]:.1f}, {result[1][1]:.1f})")
print("-" * 50)
#应用: 路由器每秒数据包数
#输入: [150,165,142,158,170,148,162,155,160,152]
#输出: 流量率估计 = 156.2
# 网络容量规划参考区间 = (148.5, 164.1)
#--------------------------------------------------
#应用: 服务器每分钟连接请求
#输入: [45,50,48,52,47,49,51,46,50,48]
#输出: 流量率估计 = 48.6
# 网络容量规划参考区间 = (44.4, 53.1)
#--------------------------------------------------
#应用: 网络端口每秒比特数(除以100简化)
#输入: [1000,1050,980,1020,990,1010,995,1005,985,1015]
#输出: 流量率估计 = 1005.0
# 网络容量规划参考区间 = (985.4, 1024.8)
示例4. 医疗与公共卫生
medical_tests = [
("[3,2,4,1,2,3,2,1,3,2]", "医院急诊室每小时患者数"),
("[0,1,0,0,1,0,0,0,1,0]", "罕见疾病每月新发病例"),
("[8,10,7,9,8,11,9,8,10,9]", "疫苗接种点每日接种人数"),
]
for case, desc in medical_tests:
result = poissfit(case)
print(f"应用: {desc}")
print(f"输入: {case}")
print(f"输出: 发生率估计 = {result[0]:.2f} 例/单位时间")
print(f" 资源分配参考区间 = ({result[1][0]:.2f}, {result[1][1]:.2f})")
print("-" * 50)
#应用: 医院急诊室每小时患者数
#输入: [3,2,4,1,2,3,2,1,3,2]
#输出: 发生率估计 = 2.30 例/单位时间
# 资源分配参考区间 = (1.46, 3.45)
#--------------------------------------------------
#应用: 罕见疾病每月新发病例
#输入: [0,1,0,0,1,0,0,0,1,0]
#输出: 发生率估计 = 0.30 例/单位时间
# 资源分配参考区间 = (0.06, 0.88)
#--------------------------------------------------
#应用: 疫苗接种点每日接种人数
#输入: [8,10,7,9,8,11,9,8,10,9]
#输出: 发生率估计 = 8.90 例/单位时间
# 资源分配参考区间 = (7.15, 10.95)
示例5. 金融交易监控
finance_tests = [
("[25,30,28,32,27,29,26,31,28,30]", "高频交易系统每秒交易数"),
("[2,1,3,0,1,2,1,0,2,1]", "异常交易每日发生次数"),
("[15,18,16,17,14,19,15,16,18,15]", "股票每分钟价格跳变次数"),
]
for case, desc in finance_tests:
result = poissfit(case)
print(f"应用: {desc}")
print(f"输入: {case}")
print(f"输出: 交易频率 = {result[0]:.1f} 次/单位时间")
print(f" 风险监控区间 = ({result[1][0]:.1f}, {result[1][1]:.1f})")
print("-" * 50)
#应用: 高频交易系统每秒交易数
#输入: [25,30,28,32,27,29,26,31,28,30]
#输出: 交易频率 = 28.6 次/单位时间
# 风险监控区间 = (25.4, 32.1)
#--------------------------------------------------
#应用: 异常交易每日发生次数
#输入: [2,1,3,0,1,2,1,0,2,1]
#输出: 交易频率 = 1.3 次/单位时间
# 风险监控区间 = (0.7, 2.2)
#--------------------------------------------------
#应用: 股票每分钟价格跳变次数
#输入: [15,18,16,17,14,19,15,16,18,15]
#输出: 交易频率 = 16.3 次/单位时间
# 风险监控区间 = (13.9, 19.0)
示例6. 零售与库存管理
retail_tests = [
("[8,12,10,9,11,13,10,12,9,11]", "商店每小时顾客到达数"),
("[5,7,6,4,8,5,6,7,5,6]", "商品每日销售量"),
("[20,25,22,24,21,23,22,24,21,23]", "电商平台每分钟订单数"),
]
for case, desc in retail_tests:
result = poissfit(case)
print(f"应用: {desc}")
print(f"输入: {case}")
print(f"输出: 需求率估计 = {result[0]:.1f} 单位/时间")
print(f" 库存规划区间 = ({result[1][0]:.1f}, {result[1][1]:.1f})")
print("-" * 50)
#应用: 商店每小时顾客到达数
#输入: [8,12,10,9,11,13,10,12,9,11]
#输出: 需求率估计 = 10.5 单位/时间
# 库存规划区间 = (8.6, 12.7)
#--------------------------------------------------
#应用: 商品每日销售量
#输入: [5,7,6,4,8,5,6,7,5,6]
#输出: 需求率估计 = 5.9 单位/时间
# 库存规划区间 = (4.5, 7.6)
#--------------------------------------------------
#应用: 电商平台每分钟订单数
#输入: [20,25,22,24,21,23,22,24,21,23]
#输出: 需求率估计 = 22.5 单位/时间
# 库存规划区间 = (19.7, 25.6)
示例7. 交通流量分析
traffic_tests = [
("[30,35,32,38,31,36,33,37,32,34]", "十字路口每分钟通过车辆数"),
("[120,115,125,118,122,128,120,124,119,123]", "高速公路收费站每小时车流量(除以4简化)"),
("[8,12,10,9,11,13,10,12,9,11]", "停车场每分钟进入车辆数"),
]
for case, desc in traffic_tests:
result = poissfit(case)
print(f"应用: {desc}")
print(f"输入: {case}")
print(f"输出: 交通流量率 = {result[0]:.1f} 辆/单位时间")
print(f" 交通规划置信区间 = ({result[1][0]:.1f}, {result[1][1]:.1f})")
print("-" * 50)
#应用: 十字路口每分钟通过车辆数
#输入: [30,35,32,38,31,36,33,37,32,34]
#输出: 交通流量率 = 33.8 辆/单位时间
# 交通规划置信区间 = (30.3, 37.6)
#--------------------------------------------------
#应用: 高速公路收费站每小时车流量(除以4简化)
#输入: [120,115,125,118,122,128,120,124,119,123]
#输出: 交通流量率 = 121.4 辆/单位时间
# 交通规划置信区间 = (114.7, 128.4)
#--------------------------------------------------
#应用: 停车场每分钟进入车辆数
#输入: [8,12,10,9,11,13,10,12,9,11]
#输出: 交通流量率 = 10.5 辆/单位时间
# 交通规划置信区间 = (8.6, 12.7)
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import ast
import numpy as np
from scipy import stats
def poisson_parameter_estimation(input_str):
"""
泊松分布参数估计(对标MATLAB的poissfit函数)
参数:
input_str (str): 字符串形式的输入,支持两种格式:
1. 纯数据列表: "[1,2,3,4,5]"
2. 带置信水平的元组: "([0,1,2,3], 0.1)"
返回:
tuple: (lambda_hat, (ci_lower, ci_upper)) 包含:
- lambda_hat (float): λ的估计值
- ci_lower (float): 置信区间下限
- ci_upper (float): 置信区间上限
若输入有效则返回该元组
错误信息字符串: 输入无效时返回错误描述
示例:
>>> poisson_parameter_estimation("[1,1,2,3,5]")
(2.4, (1.3859038246098037, 3.702993444456167))
>>> poisson_parameter_estimation("([2,2,2], 0.01)")
(2.0, (1.0793132286998841, 3.687433386962528))
"""
try:
# 解析输入字符串
parsed = ast.literal_eval(input_str)
# 初始化参数
data = None
alpha = 0.05 # 默认置信水平
# 解析输入格式
if isinstance(parsed, tuple):
if len(parsed) != 2:
raise ValueError("元组输入需要包含数据和alpha两个元素")
data, alpha = parsed
elif isinstance(parsed, list):
data = parsed
else:
raise TypeError("输入格式不正确")
# 转换数据类型
data_array = np.array(data, dtype=float)
# 参数验证
if data_array.size == 0:
raise ValueError("输入数据不能为空")
if np.any(data_array < 0):
raise ValueError("泊松数据不能包含负值")
if not (0 < alpha < 1):
raise ValueError("置信水平alpha必须在0到1之间")
# 计算参数估计
n = len(data_array)
total_counts = np.sum(data_array)
lambda_hat = total_counts / n
# 计算置信区间 (基于卡方分布)
chi2_lower = stats.chi2.ppf(alpha / 2, 2 * total_counts)
chi2_upper = stats.chi2.ppf(1 - alpha / 2, 2 * (total_counts + 1))
ci_lower = chi2_lower / (2 * n)
ci_upper = chi2_upper / (2 * n)
return (lambda_hat, (ci_lower, ci_upper))
except Exception as e:
return f"错误: {str(e)}"
# 测试用例
if __name__ == "__main__":
# 正常案例测试
test_cases = [
("[1,1,2,3,5]", "标准输入"),
# (2.4, (1.2401150217444434, 4.192317009635392))
("([0,0,0,0], 0.1)", "全零数据"),
# (0.0, (nan, 0.7489330683884974))
("([5], 0.01)", "单数据点"),
# (5.0, (1.0779282406523194, 14.149759411023012))
("([2,2,2,2], 0.2)", "均匀数据")
# (2.0, (1.1640295442245008, 3.248677885329651))
]
for case, desc in test_cases:
print(f"测试案例: {desc}")
print("输入:", case)
print("输出:", poisson_parameter_estimation(case))
print("=" * 60)
泊松逆累积分布函数
X = poissinv(P,lambda)返回最小值X,使得在X处计算的泊松cdf等于或超过P,使用lambda中的平均参数. P和lambda可以是大小相同的向量或矩阵. 标量输入被扩展为与其他输入具有相同维度的常数数组.
示例1. 呼叫中心容量规划
假设呼叫中心平均每小时接到10个电话,要保证90%的接通率:
result1 = poissinv(0.9, 10)
print(f"需要准备的线路数量: {result1} 条")
#需要准备的线路数量: 14 条
#解释:在λ=10的情况下,P(X≤13)≥0.9,所以需要14条线路
不同服务水平要求:
results = [
("80%服务水平", "(0.8, 10)"),
("90%服务水平", "(0.9, 10)"),
("95%服务水平", "(0.95, 10)"),
("99%服务水平", "(0.99, 10)")
]
for desc, expr in results:
result = poissinv(expr)
print(f"{desc}: 需要 {result} 条线路")
#80%服务水平: 需要 13 条线路
#90%服务水平: 需要 14 条线路
#95%服务水平: 需要 15 条线路
#99%服务水平: 需要 18 条线路
示例2. 库存管理 - 备件需求预测
某设备平均每月故障3次,要保证不同服务水平下的备件库存:
lambda_failures = 3
service_levels = [0.8, 0.9, 0.95, 0.99]
for level in service_levels:
result = poissinv(level, lambda_failures)
print(f"{level*100}%服务水平: 需要储备 {result} 个备件")
#80.0%服务水平: 需要储备 4 个备件
#90.0%服务水平: 需要储备 5 个备件
#95.0%服务水平: 需要储备 6 个备件
#99.0%服务水平: 需要储备 8 个备件
示例3. 网络流量管理
服务器平均每分钟处理15个请求,确定带宽配置:
lambda_requests = 15
矩阵输入:不同时间段的服务水平要求
peak_hours = ([[0.95, 0.98], [0.99, 0.999]], 20) # 高峰时段λ=20
normal_hours = ([[0.9, 0.95], [0.98, 0.99]], 10) # 正常时段λ=10
高峰时段需求矩阵 (95%, 98%, 99%, 99.9%):
print(poissinv(peak_hours))
#[[28,30]
[31,35]]
正常时段需求矩阵 (90%, 95%, 98%, 99%):
print(poissinv(normal_hours))
#[[14,15]
[17,18]]
示例4. 医疗资源规划 - 急诊室床位需求
某医院急诊室平均每晚接收8名重症患者:
lambda_patients = 8
safety_levels = [
("基本保障 (80%)", 0.8),
("充分保障 (90%)", 0.9),
("高保障 (95%)", 0.95),
("超高保障 (99%)", 0.99)
]
for desc, level in safety_levels:
result = poissinv(level, lambda_patients)
print(f"{desc}: 需要 {result} 张重症床位")
#基本保障 (80%): 需要 10 张重症床位
#充分保障 (90%): 需要 12 张重症床位
#高保障 (95%): 需要 13 张重症床位
#超高保障 (99%): 需要 15 张重症床位
示例5. 制造业质量控制 - 缺陷检测
生产线平均每100件产品出现2个缺陷,确定抽样检验方案:
lambda_defects = 2
acceptance_levels = [
("宽松检验 (接受90%概率)", 0.9),
("标准检验 (接受95%概率)", 0.95),
("严格检验 (接受99%概率)", 0.99)
]
for desc, level in acceptance_levels:
result = poissinv(level, lambda_defects)
print(f"{desc}: 当发现超过 {result} 个缺陷时拒收批次")
#宽松检验 (接受90%概率): 当发现超过 4 个缺陷时拒收批次
#标准检验 (接受95%概率): 当发现超过 5 个缺陷时拒收批次
#严格检验 (接受99%概率): 当发现超过 6 个缺陷时拒收批次
示例6. 零售业库存优化 - 生鲜产品订货
超市某生鲜产品平均每天售出12份:
lambda_sales = 12
stockout_risks = [
("允许20%缺货风险", 0.8),
("允许10%缺货风险", 0.9),
("允许5%缺货风险", 0.95),
("允许1%缺货风险", 0.99)
]
for desc, level in stockout_risks:
result = poissinv(level, lambda_sales)
print(f"{desc}: 每日订货 {result} 份")
#允许20%缺货风险: 每日订货 15 份
#允许10%缺货风险: 每日订货 17 份
#允许5%缺货风险: 每日订货 18 份
#允许1%缺货风险: 每日订货 21 份
示例7. 交通流量规划 - 收费站设计
高速公路收费站平均每分钟通过18辆车:
lambda_cars = 18
congestion_levels = [
("轻微拥堵容忍", 0.8),
("适度拥堵容忍", 0.9),
("低拥堵要求", 0.95),
("基本无拥堵", 0.99)
]
for desc, level in congestion_levels:
result = poissinv(level, lambda_cars)
print(f"{desc}: 需要 {result} 个收费通道")
#轻微拥堵容忍: 需要 22 个收费通道
#适度拥堵容忍: 需要 24 个收费通道
#低拥堵要求: 需要 25 个收费通道
#基本无拥堵: 需要 29 个收费通道
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy import stats
from sympy.stats import Poisson, quantile
def poisson_inverse_cumulative(input_str):
"""
泊松逆累积分布函数(对标MATLAB的poissinv函数)
参数:
input_str (str): 字符串形式的输入,应为包含两个元素的元组:
- 格式示例: "(0.9, 5)" 或 "(Matrix([[0.9, 0.95]]), 5)"
- p: 累积概率值(支持标量/矩阵),范围[0,1)
- lambda: 泊松分布参数(正数,支持标量/矩阵)
返回:
Matrix/ndarray: 计算结果,有以下情况:
- 标量输入返回整数
- 矩阵输入返回同型矩阵
- 错误时返回描述字符串
示例:
>>> poisson_inverse_cumulative("(0.95, 5)")
9
>>> poisson_inverse_cumulative("([[0.5, 0.9], [0.95, 0.99]], 10)")
[[6 13]
[14 18]]
>>> poisson_inverse_cumulative("(1.1, 5)")
'错误: 概率值必须在[0, 1)区间'
"""
try:
# 安全解析输入字符串
expr = sp.sympify(input_str)
error = False
result = None
def eval_poisson_inverse_cdf(p_val, lambda_val):
return stats.poisson.ppf(float(p_val), float(lambda_val)).astype(int)
if isinstance(expr, tuple) and len(expr) == 2:
if all(e.is_number for e in expr):
params = tuple(float(e.evalf()) for e in expr)
result = stats.poisson.ppf(*params)
else:
error = True
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {str(e)}"
# 测试用例
if __name__ == "__main__":
# 正常案例测试
tests = [
("(0.8, 2)", "标量计算"),
# 3.0
]
for case, desc in tests:
print(f"测试案例: {desc}")
print("输入:", case)
print("输出:", poisson_inverse_cumulative(case))
print("=" * 60)
泊松概率质量函数
y = poisspdf(x,lambda) 使用 lambda 中的速率参数计算 x 中每个值处的泊松概率密度函数值.
x 和 lambda 可以是大小都相同的标量,向量或矩阵. 如果只有一个参量是标量, poisspdf 会将其扩展为其维数与另一个参量相同的常量数组.
x — 计算泊松 pdf 时所基于的值,标量值,标量值组成的数组
lambda — 速率参数,正值,正值组成的数组
示例1:客服中心来电预测 (平均每小时5通电话)
test1 = poisspdf(3, 5) # 恰好3通电话的概率
print(f"一小时恰好接到3通电话的概率: {test1}")
#一小时恰好接到3通电话的概率: 0.1403738958142805
示例2:网站访问量分析(平均每分钟10次访问)
test2 = poisspdf("[[0, 5, 10, 15, 20]], 10")
print(f"不同访问次数的概率分布:\n{test2}")
#[[4.53999298e-05, 3.78332748e-02, 1.25110036e-01, 3.47180696e-02, 1.86608131e-03]]
示例3:零售店顾客到达 (高峰期平均每小时30位顾客)
test3 = poisspdf(25, 30) # 25位顾客的概率
print(f"高峰期一小时恰好25位顾客的概率: {test3}")
#高峰期一小时恰好25位顾客的概率: 0.05111533742894147
示例4:急诊室患者到达(平均每小时4人)
emergency_cases = [
("(0, 4)", "没有患者的概率"),
("(2, 4)", "恰好2名患者的概率"),
("(6, 4)", "恰好6名患者的概率")
]
for case, desc in emergency_cases:
result = poisspdf(case)
print(f"{desc}: {result}")
#没有患者的概率: 0.01831563888873418
#恰好2名患者的概率: 0.14652511110987343
#恰好6名患者的概率: 0.10419563456702102
示例5:疾病发病率分析 (某地区平均每年2例)
disease_rates = poisspdf([[0, 1, 2, 3, 4, 5]], 2)
print(f"不同发病例数的概率:\n{disease_rates}")
#不同发病例数的概率:
#[[0.13533528 0.27067057 0.27067057 0.18044704 0.09022352 0.03608941]]
示例6:生产线缺陷产品统计 (每1000件产品平均3个缺陷)
defects_prob = poisspdf([[0, 1, 2, 3, 4, 5]], 3)
print(f"不同缺陷数量的概率分布:\n{defects_prob}")
#不同缺陷数量的概率分布:
#[[0.04978707 0.14936121 0.22404181 0.22404181 0.16803136 0.10081881]]
示例7:设备故障预测 (平均每月0.5次故障)
failure_cases = [
("(0, 0.5)", "一个月无故障的概率"),
("(1, 0.5)", "一个月恰好1次故障的概率"),
("(2, 0.5)", "一个月恰好2次故障的概率")
]
for case, desc in failure_cases:
result = poisspdf(case)
print(f"{desc}: {result}")
#一个月无故障的概率: 0.6065306597126334
#一个月恰好1次故障的概率: 0.3032653298563167
#一个月恰好2次故障的概率: 0.07581633246407919
示例8:高速公路事故预测 (平均每天1.2起事故)
accident_probs = poisspdf([[0, 1, 2, 3]], 1.2)
print(f"每日事故数量的概率:\n{accident_probs}")
#每日事故数量的概率:
#[[0.30119421 0.36143305 0.21685983 0.08674393]]
示例9:电商仓库订单处理 (高峰期平均每分钟8个订单)
order_scenarios = [
("(5, 8)", "一分钟处理5个订单的概率"),
("(10, 8)", "一分钟处理10个订单的概率"),
("(15, 8)", "一分钟处理15个订单的概率")
]
for case, desc in order_scenarios:
result = poisspdf(case)
print(f"{desc}: {result}")
#一分钟处理5个订单的概率: 0.09160366159257921
#一分钟处理10个订单的概率: 0.09926153383153544
#一分钟处理15个订单的概率: 0.009025979411121507
示例10:信用卡欺诈检测 (平均每天0.3次)
fraud_cases = poisspdf([[0, 1, 2]], 0.3)
print(f"每日欺诈交易次数的概率:\n{fraud_cases}")
#每日欺诈交易次数的概率:
#[[0.74081822 0.22224547 0.03333682]]
示例11:保险公司日理赔数 (平均每天2.5起理赔)
claim_scenarios = [
("(0, 2.5)", "一天无理赔的概率"),
("(3, 2.5)", "一天恰好3起理赔的概率"),
("(5, 2.5)", "一天恰好5起理赔的概率")
]
for case, desc in claim_scenarios:
result = poisspdf(case)
print(f"{desc}: {result}")
#一天无理赔的概率: 0.0820849986238988
#一天恰好3起理赔的概率: 0.21376301724973648
#一天恰好5起理赔的概率: 0.06680094289054267
示例12:固定lambda=3时的分布形式
symbolic_test3 = poisspdf(n, 3)
print(f"lambda=3时的分布: P(X=n) = {symbolic_test3}")
#lambda=3时的分布: P(X=n) = 0.0497870683678639*3.0**n/factorial(n)
示例13:完整概率分布表 (lambda=4)
full_distribution = poisspdf([[0,1,2,3,4,5,6,7,8,9,10]]), 4)
print(f"lambda=4时的完整概率分布:\n{full_distribution}")
#[[0.01831564,0.07326256,0.14652511,0.19536681,0.19536681,0.15629345
0.10419563,0.05954036,0.02977018,0.01323119,0.00529248]]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from sympy.stats import Poisson, density
from scipy.stats import poisson as sci_poisson
def poisson_distribution_pdf(input_str):
"""
计算泊松概率质量函数(对标MATLAB的poisspdf函数)
参数:
input_str (str): 字符串形式的输入,应为包含两个元素的元组:
- 格式示例: "(x, lambda)" 或 "(Matrix([[0,1,2]]), 5)"
- x: 事件数(非负整数,支持标量/矩阵)
- lambda: 泊松参数(正数,支持标量/矩阵)
返回:
Matrix/Expr: 计算结果,有以下情况:
- 标量输入返回符号表达式
- 矩阵输入返回同型矩阵
- 错误时返回描述字符串
示例:
>>> poisson_distribution_pdf("(2, 1)")
0.183939720585721
>>> poisson_distribution_pdf("(Matrix([[0,1,2]]), 2)")
Matrix([[0.135335283236613, 0.270670566473225, 0.270670566473225]])
>>> poisson_distribution_pdf("(-1, 2)")
'错误: 事件数必须为非负整数'
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
if isinstance(expr, tuple) and len(expr) == 2:
if all(e.is_number for e in expr):
params = tuple(float(e.evalf()) for e in expr)
result = sci_poisson.pmf(*params)
elif any(e.free_symbols for e in expr):
x, lambda_val = expr
X = Poisson("poisson", lambda_val)
result = density(X)(x)
else:
error = True
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f'错误: {str(e)}'
# 测试用例
if __name__ == "__main__":
# 正常输入测试
tests = [
("(2, 1)", "标量计算"),
# 0.18393972058572114
("(k, 3)", "符号计算"),
# 3**k*exp(-3)/factorial(k)
]
for case, desc in tests:
print(f"测试案例: {desc}")
print("输入:", case)
print("输出:", poisson_distribution_pdf(case))
print("=" * 60)
来自泊松分布的随机数
r = poissrnd(lambda) 从速率参数 lambda 所指定的泊松分布中生成随机数.
lambda 可以是标量,向量或矩阵.
r = poissrnd(lambda,sz1,sz2) 从具有标量速率参数 lambda 的泊松分布中生成随机数数组,其中 sz1,sz2 表示矩阵维度的大小.
示例1. 客服中心来电模拟 (平均每小时5通电话)
calls_hourly = poissrnd(5,10) # 模拟10个小时的来电数
print(f"10个小时的来电数量模拟: {calls_hourly}")
#10个小时的来电数量模拟: [4, 4, 2, 3, 6, 7, 3, 2, 5, 6]
示例2. 网站访问量模拟 (高峰期平均每分钟20次访问)
traffic_matrix = poissrnd(20,4,6) # 模拟4天,每天6个时段
print(f"4天6时段的访问量模拟矩阵:\n{traffic_matrix}")
#[[22, 21, 18, 31, 23, 32],
[26, 17, 26, 22, 19, 12],
[23, 23, 17, 13, 15, 23],
[19, 23, 21, 23, 18, 13]]
示例3. 急诊室夜间患者到达模拟 (平均每小时3人)
emergency_sim = poissrnd(3,24) # 模拟24小时
print(f"24小时患者到达模拟: {emergency_sim}")
#24小时患者到达模拟: [2, 3, 2, 4, 4, 5, 3, 1, 3, 2, 1, 4, 0, 6, 3, 4, 7, 4, 4, 2, 2, 3, 7, 3]
示例4. 三家医院日急诊量模拟 (平均分别为15, 25, 40人)
hospitals_matrix = poissrnd([[15,25,40]])
print(f"三家医院日急诊量: {hospitals_matrix}")
#三家医院日急诊量: [[13, 26, 44]]
示例5:罕见疾病年度发病模拟 (某地区平均每年2例)
disease_years = poissrnd(2,10) # 模拟10年
print(f"10年疾病发病情况: {disease_years}")
#10年疾病发病情况: [1, 3, 3, 2, 6, 0, 3, 3, 2, 0]
示例6:生产线日缺陷产品模拟 (每千件平均2个缺陷)
daily_defects = poissrnd(2,30) # 模拟30天
print(f"30天缺陷数量: {daily_defects}")
#30天缺陷数量: [0, 2, 5, 3, 5, 2, 1, 3, 0, 1, 3, 2, 2, 4, 3, 0, 2, 3, 3, 1, 4, 1, 0, 0, 1, 1, 1, 2, 1, 2]
示例7:三条生产线质量对比 (缺陷率: 1, 3, 5)
production_lines = poissrnd([[1,3,5]])
print(f"三条生产线的缺陷数: {production_lines}")
#三条生产线的缺陷数: [[1, 3, 8]]
示例8:设备季度故障模拟 (平均每季度1.5次故障)
quarterly_failures = poissrnd(1.5,4,3) # 3年,每季度
print(f"3年季度故障矩阵:\n{quarterly_failures}")
#3年季度故障矩阵:
#[[1, 1, 3],
[0, 1, 0],
[2, 3, 2],
[2, 3, 3]]
示例9:商店日顾客流量模拟 (工作日平均200人,周末平均400人)
week_customers = poissrnd([[200,200,200,200,200,400,400]])
print(f"一周顾客流量: {week_customers}")
#一周顾客流量: [[198, 169, 220, 196, 193, 400, 407]]
示例10:促销期间客流量模拟 (平时100人,促销期300人)
promotion_comparison = poissrnd([[100,300]])
print(f"平时vs促销期客流量: {promotion_comparison}")
#平时vs促销期客流量: [[105, 324]]
示例11:高速公路月事故数模拟 (平均每月4起)
monthly_accidents = poissrnd(4,12) # 一年12个月
print(f"年度月事故数: {monthly_accidents}")
#年度月事故数: [5, 4, 2, 4, 2, 5, 3, 2, 5, 7, 1, 4]
示例12:物流中心小时订单模拟 (高峰期平均每小时30单)
peak_orders = poissrnd(30,8) # 8小时高峰期
print(f"8小时订单量: {peak_orders}")
#8小时订单量: [37, 30, 31, 34, 20, 37, 32, 30]
示例13:四个城市日快递量模拟 (平均: 500, 800, 1200, 2000)
cities_delivery = poissrnd([[500,800,1200,2000]])
print(f"四个城市日快递量: {cities_delivery}")
#四个城市日快递量: [[490, 818, 1227, 1975]]
示例14:信用卡欺诈交易模拟 (平均每天0.5次)
monthly_fraud = poissrnd(0.5,30) # 30天
print(f"月欺诈交易次数: {monthly_fraud}")
#月欺诈交易次数: [1, 1, 0, 0, 1, 1, 0, 0, 0, 3, 0, 1, 1, 1, 2, 0, 1, 0, 1, 0, 1, 2, 0, 1, 0, 3, 1, 0, 1, 0]
示例15:保险公司理赔模拟 (平均每天3起)
daily_claims = poissrnd(3,20) # 20个工作日
print(f"20个工作日理赔数: {daily_claims}")
#20个工作日理赔数: [3, 6, 2, 3, 5, 5, 2, 1, 6, 2, 5, 7, 4, 3, 5, 4, 3, 3, 1, 2]
示例16:三种保险产品月理赔数模拟 (风险率: 2, 5, 8)"
products_risk = poissrnd([[2,5,8]])
print(f"三种产品月理赔数: {products_risk}")
#三种产品月理赔数: [[3, 6, 7]]
示例17:服务器请求量模拟 (高峰期平均每分钟100次请求)
server_requests = poissrnd(100,60) # 60分钟
print(f"小时请求量分布: {server_requests}")
#小时请求量分布:
#[111, 99, 89, 106, 110, 91, 106, 102, 117, 121, 86, 108, 101,
89, 104, 113, 86, 98, 94, 101, 92, 115, 111, 94, 108, 101, 112,
105, 96, 103, 116, 84, 105, 86, 96, 93, 103, 101, 102, 106,
103, 79, 112, 100, 90, 96, 99, 114, 116, 101, 85, 95, 84, 105,
95, 103, 95, 105, 118, 110]
示例18:日网络安全事件模拟 (平均每天2次攻击)
security_events = poissrnd(2,15) # 15天
print(f"半月安全事件: {security_events}")
#半月安全事件: [3, 0, 2, 3, 3, 2, 5, 4, 0, 0, 2, 2, 2, 6, 2]
示例19:三台服务器负载模拟 (平均请求: 50, 100, 150)
servers_load = poissrnd([[50,100,150]])
print(f"服务器负载对比: {servers_load}")
#服务器负载对比: [[55, 99, 158]]
示例20:教室学生缺席模拟 (平均每天2人缺席)
attendance_records = poissrnd(2,20) # 20个上学日
print(f"20天缺席记录: {attendance_records}")
#20天缺席记录: [1, 5, 0, 2, 4, 1, 1, 3, 4, 0, 1, 4, 1, 1, 2, 2, 3, 2, 1, 0]
示例21:图书馆日借书量模拟 (平均每天50本)
library_loans = poissrnd(50,7") # 一周
print(f"周借书量: {library_loans}")
#周借书量: [58, 43, 55, 37, 47, 48, 48]
示例22:实验观测事件模拟 (平均每小时观测到3次目标事件)
experiment_events = poissrnd(3,5,4) # 5天,每天4小时
print(f"实验观测事件矩阵:\n{experiment_events}")
#[[2, 5, 0, 5],
[5, 3, 0, 2],
[4, 4, 6, 3],
[2, 2, 5, 1],
[5, 3, 4, 1]]
示例23:城市交通流量大规模模拟(不同区域平均流量: 10-100)
traffic_params = [[i * 10 for i in range(1, 11)]] # 10个区域
traffic_sim = poissrnd(traffic_params)
print(f"10个区域的交通流量: {traffic_sim}")
#10个区域的交通流量: [[6, 19, 37, 43, 43, 75, 81, 75, 86, 111]]
示例24:零售连锁店全国模拟 (20个店铺)
stores_lambda = [[5 + i * 2 for i in range(20)]] # 20个店铺,λ从5到43
national_sales = poissrnd(stores_lambda)
print(f"20个店铺日销售额: {national_sales}")
#20个店铺日销售额: [[1, 8, 9, 12, 13, 8, 15, 16, 12, 21, 26, 28, 29, 26, 48, 37, 32, 32, 35, 39]]
示例25:业务风险蒙特卡洛模拟 (1000次重复)
模拟1000次日业务量,平均50单
mc_simulations = poissrnd(50,1000)
print(f"蒙特卡洛模拟前10个结果: {mc_simulations[:10]}")
#蒙特卡洛模拟前10个结果: [51, 54, 46, 48, 52, 50, 46, 42, 47, 50]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import scipy.stats as stats
import numpy as np
def eval_poisson_rnd(lambda_param, size=None):
"""
生成泊松分布的随机数。
参数:
lambda_param: 泊松分布的λ参数。
size: 输出的维度,默认为None(生成单个随机数)。
返回:
根据size参数返回单个随机数、列表或嵌套列表。
"""
lambda_val = float(lambda_param)
if lambda_val < 0:
raise ValueError("泊松分布的λ参数必须非负。")
poisson_dist = stats.poisson(lambda_val)
random_numbers = poisson_dist.rvs(size=size)
# 将结果转换为Python原生类型
if size is None:
return int(random_numbers)
elif isinstance(random_numbers, np.ndarray):
return random_numbers.tolist()
elif isinstance(random_numbers, (int, np.integer)):
return int(random_numbers)
else:
return list(random_numbers)
def poisson_random_numbers(input_str):
"""
根据输入字符串生成泊松分布的随机数或矩阵。
参数:
input_str: 输入字符串,可以是λ参数、维度或矩阵。
返回:
生成的随机数、列表或SymPy矩阵。若输入错误则返回错误信息。
示例:
>>> poisson_random_numbers("3") # 单个随机数
>>> poisson_random_numbers("3,5") # 包含5个随机数的列表
>>> poisson_random_numbers("3,2,3") # 2x3的随机矩阵
>>> poisson_random_numbers("[[2,3],[4,5]]") # 2x2矩阵,每个元素对应λ生成的随机数
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
if isinstance(expr, tuple):
# 处理元组输入,如(λ, m, n)或(λ, size)
if len(expr) == 3 and expr[1].is_number and expr[2].is_number:
lambda_val = expr[0]
rows = int(expr[1])
cols = int(expr[2])
rand_data = eval_poisson_rnd(lambda_val, size=(rows, cols))
result = sp.Matrix(rand_data)
elif len(expr) == 2 and expr[1].is_number:
lambda_val = expr[0]
size = int(expr[1])
rand_data = eval_poisson_rnd(lambda_val, size=size)
result = rand_data # 直接返回列表
else:
error = True
elif isinstance(expr, list):
matrix = sp.Matrix(expr)
# 输入是矩阵,生成对应形状的随机矩阵
rows, cols = matrix.shape
rand_matrix = []
for i in range(rows):
row = []
for j in range(cols):
lambda_ij = matrix[i, j]
row.append(eval_poisson_rnd(lambda_ij, size=None))
rand_matrix.append(row)
result = sp.Matrix(rand_matrix)
elif expr.is_number:
# 单个λ参数生成单个随机数
result = eval_poisson_rnd(expr, size=None)
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
# 示例代码
if __name__ == "__main__":
# 示例1:生成λ=3的单个随机数
print("示例1:", poisson_random_numbers("3"))
# 0
# 示例2:生成λ=3的5个随机数
print("示例2:", poisson_random_numbers("3,5"))
# [4, 2, 1, 2, 2]
# 示例3:生成λ=3的2x3随机矩阵
print("示例3:", poisson_random_numbers("3,2,3"))
# Matrix([[4, 2, 4],
# [4, 3, 4]])
# 示例4:生成与输入矩阵对应的随机矩阵
print("示例4:", poisson_random_numbers("[[2,3],[4,5]]"))
# Matrix([[3, 4],
# [3, 4]])
泊松均值和方差
M = poisstat(lambda) 使用 lambda 中的均值参数返回泊松分布的均值. M的大小就是lambda的大小.
[M,V] = poisstat(lambda) 还返回泊松分布的方差 V.
对于带参数λ的泊松分布,均值和方差都等于λ.
示例1:数值输入 - 呼叫中心应用
假设呼叫中心平均每小时接到5个电话:
m1, v1 = poisstat(5)
print(f"均值(平均电话数): {m1}, 方差: {v1}")
#均值(平均电话数): 5.0, 方差: 5.0
示例2:数值矩阵 - 多区域交通事故分析
四个区域每天平均事故数矩阵 [[2, 3], [1, 4]]:
m3, v3 = poisstat([[2, 3], [1, 4]])
print(f"均值矩阵:\n{m3}")
print(f"方差矩阵:\n{v3}")
#均值矩阵:
#[[2. 3.]
[1. 4.]]
#方差矩阵:
#[[2. 3.]
[1. 4.]]
示例3:符号矩阵 - 参数化模型
m4, v4 = poisstat([[a, 2], [3, b]])
print(f"混合符号矩阵的均值:\n{m4}")
print(f"混合符号矩阵的方差:\n{v4}")
#混合符号矩阵的均值:
#[a, 2]
#混合符号矩阵的方差:
#[a, 2]
示例4:网站访问量分析
不同时间段平均访问量 [10, 15, 8, 12]:
m5, v5 = poisstat([10, 15, 8, 12])
print(f"均值数组: {m5}")
print(f"方差数组: {v5}")
#均值数组: [10. 15. 8. 12.]
#方差数组: [10. 15. 8. 12.]
示例5:零售业客流量预测
不同门店日均客流量 [[20, 25], [18, 30]]:
m6, v6 = poisstat([[20, 25], [18, 30]])
print(f"均值矩阵:\n{m6}")
print(f"方差矩阵:\n{v6}")
#均值矩阵:
#[[20. 25.]
[18. 30.]]
#方差矩阵:
#[[20. 25.]
[18. 30.]]
示例6:医疗应用 - 急诊室病人到达率
不同时段平均到达病人数 [[5, 8], [3, 10]]:
m7, v7 = poisstat([[5, 8], [3, 10]])
print(f"均值矩阵:\n{m7}")
print(f"方差矩阵:\n{v7}")
#均值矩阵:
#[[ 5. 8.]
[ 3. 10.]]
#方差矩阵:
#[[ 5. 8.]
[ 3. 10.]]
示例7:复杂符号表达式
m8, v8 = poisstat(x + y)
print(f"表达式 x+y 的均值: {m8}")
print(f"表达式 x+y 的方差: {v8}")
#表达式 x+y 的均值: x + y
#表达式 x+y 的方差: 2*x**2 + 4*x*y + x + 2*y**2 + y + (-2*x - 2*y)*(x + y)
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from sympy.stats import Poisson, E, variance
def evaluation_poisson_stat(x_val):
"""
计算泊松分布的期望和方差。
当x_val为符号时,返回符号表达式。
参数:
x_val: 泊松分布的λ参数,可以是数值或符号。
返回:
(期望, 方差) 的元组,类型为SymPy表达式或数值。
"""
if x_val.is_number and float(x_val) < 0:
raise ValueError("泊松分布的λ参数必须非负。")
# 定义泊松随机变量
X = Poisson('X', x_val)
mean_val = E(X)
var_val = variance(X)
return mean_val, var_val
def poisson_mean_variance(input_str):
"""
根据输入计算泊松分布的均值和方差。
支持数值、符号、矩阵输入,对标MATLAB的poisstat函数。
参数:
input_str: 输入字符串,可以是数值、符号表达式或矩阵。
返回:
均值矩阵/值和方差矩阵/值的元组,若输入错误则返回错误信息。
示例:
>>> poisson_mean_variance("3") # 返回 (3, 3)
>>> poisson_mean_variance("lambda") # 返回 (lambda, lambda)
>>> poisson_mean_variance("[[2,3],[4,5]]") # 返回 (2x2矩阵, 2x2矩阵)
"""
try:
expr = sp.sympify(input_str)
error = False
M, V = None, None
# 处理元组输入(不支持)
if isinstance(expr, tuple):
error = True
raise ValueError("不支持元组输入,请输入数值、符号或矩阵。")
# 处理数值/符号输入
elif expr.is_number or expr.free_symbols:
# 检查数值是否为负
if expr.is_number and float(expr) < 0:
raise ValueError("λ参数必须非负。")
M, V = evaluation_poisson_stat(expr)
else:
error = True
return (M, V) if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
# 示例代码
if __name__ == "__main__":
# 示例1:数值输入
print("示例1:", poisson_mean_variance("3"))
# (3, 3)
# 示例2:符号输入
lambda_sym = sp.symbols('x')
print("示例2:", poisson_mean_variance(lambda_sym))
# (x, x)
极坐标图
PolarPlot(r=f(theta)) 在极坐标系中绘制的图形,其中每个点由两个参数定义:
半径 r: 表示点到原点的距离。
角度 thetaθ: 表示点相对于正x轴的角度(弧度制,通常从0到2π 或更广范围)。
这种函数图适合表示周期性、旋转对称或圆形分布的图案,常见于物理、工程、艺术和自然界(如花瓣、声波、天线辐射模式)。
圆: 表示理想化的圆形路径或物体,如车轮轨迹、圆形池塘的边界。
在工程中,用于简化模型(如轴承滚珠的路径)。
PolarPlot(2)
心形线: 常见于声学设备,如心形指向性麦克风的拾音模式(对前方声音敏感,后方抑制)
也用于天线设计,优化信号方向性。
PolarPlot(2(1+cos(@theta)))
玫瑰曲线: 模拟周期性自然现象
如花瓣排列(植物学)、声波干涉图样(物理实验),或艺术设计(如教堂彩窗图案)。
PolarPlot(3cos(4@theta))
阿基米德螺线: 等间距螺旋线
机械工程:卷起的绳子、钟表发条。
天文学:简化模型表示星系旋臂(如银河系)。
日常用品:DVD 光轨、风扇叶片的设计基础。
PolarPlot(0.5@theta)
对数螺线: 螺距逐渐增大的螺旋线
生物学:鹦鹉螺壳、向日葵种子排列(黄金角优化)。
气象学:飓风云图的结构。
艺术:用于建筑和雕塑(如古希腊柱头设计)。
PolarPlot(exp(0.1@theta))
多曲线极坐标图
PolarPlot(f1(theta),f2(theta)) 通过叠加多条r(θ)函数,直观对比不同物理过程
天线辐射模式对比: 对比信号强度分布,优化无线网络覆盖。
PolarPlot(cos(@theta)^2,0.5*sin(@theta)^2)
机械振动分析: 检测旋转机械(如涡轮机)的异常振动模式。
PolarPlot(2+sin(5@theta),2+1.5*sin(5@theta))
双星系统轨道模拟: 模拟引力相互作用下的双星运动轨迹。
PolarPlot(3/(1+0.9*cos(@theta)),3/(1+0.9*cos(@theta+@pi)))
声波干涉分析: 可视化声波叠加产生的干涉瓣方向。
PolarPlot(2*abs(cos(3@theta)),2*abs(sin(3@theta)))
零极点图
polezeroplot(sys)是复平面(s平面或z平面)上标出系统传递函数零点(Zeros)和极点(Poles)位置的图形,用于分析系统特性(稳定性、频率响应等)
系统在频率 ω=1 rad/s 处增益最小(零点抑制)
陷波滤波器(Notch Filter),用于消除特定频率干扰(如 50Hz 工频噪声)。
polezeroplot(s^2+1,1)
所有极点在左半平面 → 稳定系统。
低通滤波器,极点聚集在实轴负半轴,衰减高频信号。
polezeroplot(1,s^4+4s^3+6s^2+5s+2)
带阻滤波器
零点在虚轴 ±2j 处 → 抑制 ω=2 rad/s 的信号(如消除机械振动噪声)。
polezeroplot(s^2+4,s^2+s+4)
不稳定系统
极点在右半平面(s=1)→ 系统不稳定(如正反馈电路)。
polezeroplot(s,s^2-1)
一阶低通滤波器(RC电路)
极点在左半平面 → 系统稳定。
polezeroplot([1],[1,1])
二阶带通滤波器(RLC电路)
允许特定频率通过(如收音机选频),零点在原点抑制直流分量,虚轴极点位置控制中心频率。
polezeroplot([1],[1,1,1])
全通滤波器(相位校正)
幅度响应平坦,但调整相位(如延迟均衡)。零极点关于虚轴对称 → 全通特性。
polezeroplot([1,-1],[1,1])
不稳定系统(振荡器)
极点位于右半平面 → 系统发散(如未阻尼振荡),实际需避免。
polezeroplot([1],[1,0,-1])
数字滤波器(音频均衡器)
增强特定音频频率(如人声),极点在单位圆内保证稳定,零点位置控制频响凹陷。
polezeroplot([1,-0.8],[1,-1.2,0.5])
陷波滤波器(消除工频干扰)
消除特定频率(如 50 Hz 电源噪声),零点强制该频率增益为 0,极点位置控制带宽。
polezeroplot([1,0,100],[1,2,101])
叠加零极点图
polezeroplot([sys1],[sys2]...[sysN])同一复平面上绘制多个系统传递函数的零极点.
滤波器组性能对比: 设计音频处理系统中的两个滤波器
系统1零点在 \pm j±j → 在 ω=1 rad/s 处强烈抑制信号
系统2极点在 -0.5 \pm j1.94−0.5±j1.94 → 在 ω≈2 rad/s 处有谐振峰
polezeroplot([s^2+1,s^2+4],[1,s^2+s+4])
控制器与被控对象交互: 电机控制系统
控制器零点吸引被控对象极点 → 可加速系统响应
无右半平面极点 → 闭环系统稳定
polezeroplot([1,s^2+2s+5],[0.5s^2+2s+3,s])
通信系统多径干扰抑制: 接收端两个抑制干扰的子系统
陷波器零点与极点接近虚轴 → 对 3 rad/s 干扰有深度抑制
抑制器极点远离虚轴 → 不影响陷波器性能
polezeroplot([s^2+9,s^2+10],[s+2,s^2+4s+20])
机械振动控制系统: 汽车悬架系统模型
主动控制器在 s=0s=0 处的极点 → 需检查积分器稳定性
主动系统零点 \pm 2j±2j 与被动系统谐振频率(7j)无冲突 → 可有效抑制 2 rad/s 路面振动
polezeroplot([s+1,s^2+2s+10],[5*(s^2+4),s^3+10s^2+50s])
将极坐标或柱坐标转换为笛卡尔坐标
[x,y] = pol2cart(theta,rho) 将极坐标数组theta和rho的对应元素变换为二维笛卡尔坐标或xy坐标.
[x,y,z] = pol2cart(theta,rho,z) 将柱坐标数组theta,rho和z的对应元素变换为三维笛卡尔坐标或xyz坐标.
theta — 角坐标,标量,向量,矩阵
rho — 径向坐标,标量,向量,矩阵
z — 仰角坐标,标量,向量,矩阵
x, y, z — 笛卡尔坐标,数组
示例1:天线阵列设计 - 计算天线单元位置
theta_array = [0, 1.047, 2.094, 3.142, 4.189, 5.236] # 60度间隔
rho_array = [10, 10, 10, 10, 10, 10] # 半径为10的圆形阵列
x, y = pol2cart(theta_array, rho_array)
天线位置 (x,y):
for i in range(len(x)):
print(f" 天线{i+1}: ({x[i]:.2f}, {y[i]:.2f})")
# 天线1: (10.00, 0.00)
# 天线2: (5.00, 8.66)
# 天线3: (-5.00, 8.66)
# 天线4: (-10.00, -0.00)
# 天线5: (-5.00, -8.66)
# 天线6: (5.00, -8.66)
示例2:机器人导航路径规划 - 极坐标路径点:
waypoints = ([0, 0.785, 1.571, 2.356], [2, 3, 2.5, 4])
x_path, y_path = pol2cart(waypoints)
机器人路径点:
for i, (xi, yi) in enumerate(zip(x_path, y_path)):
print(f" 点{i+1}: ({xi:.2f}, {yi:.2f})")
# 点1: (2.00, 0.00)
# 点2: (2.12, 2.12)
# 点3: (-0.00, 2.50)
# 点4: (-2.83, 2.83)
示例3:计算机图形学 - 圆形顶点计算
n_points = 8
theta_circle = list(np.linspace(0, 2*np.pi, n_points, endpoint=False))
rho_circle = [5] * n_points # 半径为5的圆
x_circle, y_circle = pol2cart(theta_circle, rho_circle)
圆形顶点坐标:
for i, (xc, yc) in enumerate(zip(x_circle, y_circle)):
print(f" 顶点{i+1}: ({xc:.2f}, {yc:.2f})")
# 顶点1: (5.00, 0.00)
# 顶点2: (3.54, 3.54)
# 顶点3: (0.00, 5.00)
# 顶点4: (-3.54, 3.54)
# 顶点5: (-5.00, 0.00)
# 顶点6: (-3.54, -3.54)
# 顶点7: (-0.00, -5.00)
# 顶点8: (3.54, -3.54)
示例4:物理学 - 电荷分布场强方向
假设在极坐标下的场强分量
theta_force = [0, 1.047, 2.094] # 角度
magnitude = [8.5, 6.2, 9.1] # 场强大小
fx, fy = pol2cart(theta_force, magnitude)
电场强度的笛卡尔分量:
for i, (fxi, fyi) in enumerate(zip(fx, fy)):
print(f" 点{i+1}: Fx={fxi:.2f}, Fy={fyi:.2f}")
# 点1: Fx=8.50, Fy=0.00
# 点2: Fx=3.10, Fy=5.37
# 点3: Fx=-4.55, Fy=7.88
示例5:机械工程 - 凸轮轮廓坐标
theta_cam = list(np.linspace(0, 2*np.pi, 12, endpoint=False))
变半径设计,模拟凸轮轮廓
rho_cam = [3 + 0.5*np.sin(2*t) for t in theta_cam]
x_cam, y_cam = pol2cart(theta_cam, rho_cam)
凸轮轮廓坐标 (前6个点):
for i in range(min(6, len(x_cam))):
print(f" 点{i+1}: ({x_cam[i]:.3f}, {y_cam[i]:.3f})")
# 点1: (3.000, 0.000)
# 点2: (2.972, 1.718)
# 点3: (1.717, 2.973)
# 点4: (-0.001, 3.000)
# 点5: (-1.283, 2.224)
# 点6: (-2.223, 1.283)
示例6:三维柱坐标应用(圆柱形容器采样点)
theta_3d = [0, 1.571, 3.142, 4.712] # 0°, 90°, 180°, 270°
rho_3d = [2, 2, 2, 2] # 半径2
z_3d = [0, 1, 2, 3] # 不同高度
x_3d, y_3d, z_3d = pol2cart(theta_3d, rho_3d, z_3d)
圆柱形容器采样点:
for i, (x3, y3, z3) in enumerate(zip(x_3d, y_3d, z_3d)):
print(f" 点{i+1}: ({x3:.2f}, {y3:.2f}, {z3:.2f})")
# 点1: (2.00, 0.00, 0.00)
# 点2: (-0.00, 2.00, 1.00)
# 点3: (-2.00, -0.00, 2.00)
# 点4: (-0.00, -2.00, 3.00)
示例7:符号计算应用(通用坐标变换)
result = pol2cart(theta, rho, z)
符号变换结果:
print(f" x = {result[0]}")
print(f" y = {result[1]}")
print(f" z = {result[2]}")
# x = rho*cos(theta)
# y = rho*sin(theta)
# z = z
示例8:特殊角度验证
test_cases = [
(0, 1), # 0度,x轴正方向
(1.571, 1), # 90度,y轴正方向
(3.142, 1), # 180度,x轴负方向
(4.712, 1), # 270度,y轴负方向
(0.785, 1.414) # 45度,单位圆上的点
]
for case in test_cases:
x, y = pol2cart(case)
print(f" {case} -> ({x:.3f}, {y:.3f})")
# (0, 1) -> (1.000, 0.000)
# (1.571, 1) -> (-0.000, 1.000)
# (3.142, 1) -> (-1.000, -0.000)
# (4.712, 1) -> (-0.000, -1.000)
# (0.785, 1.414) -> (1.000, 0.999)
示例9:矩阵输入处理 - 网格点计算
theta_grid = [[0, 0.785], [1.571, 2.356]]
rho_grid = [[1, 1], [2, 2]]
x_grid, y_grid = pol2cart(theta_grid, rho_grid)
网格点转换结果:
print(f" X矩阵:\n{x_grid}")
print(f" Y矩阵:\n{y_grid}")
#X矩阵:
#[[ 1.00000000e+00 7.07388269e-01]
[-4.07346407e-04 -1.41393848e+00]]
#Y矩阵:
#[[0. 0.70682518]
[1.99999996 1.41448859]]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
def polar_to_cartesian(input_str):
"""
将极坐标或柱坐标转换为笛卡尔坐标,对标MATLAB的pol2cart函数。
参数:
input_str: 输入字符串,可以是以下形式:
- 二维坐标: "(theta, rho)"
- 三维坐标: "(theta, rho, z)"
其中theta和rho可以是数值、符号或矩阵
返回:
- 二维情况: (x, y) 的元组(数值/矩阵)
- 三维情况: (x, y, z) 的元组
若输入错误则返回错误信息。
示例:
>>> polar_to_cartesian("(0.785, 5)") # 二维数值输入
>>> polar_to_cartesian("([0, 1.57], [2, 3])") # 二维矩阵输入
>>> polar_to_cartesian("(0.785, 5, 10)") # 三维数值输入
"""
try:
expr = sp.sympify(input_str)
error = False
M, V = None, None
def pol2cart_sym(theta, rho):
# 使用SymPy的三角函数以支持符号计算
x = rho * sp.cos(theta)
y = rho * sp.sin(theta)
return x.evalf(), y.evalf()
def pol2cart_sci(theta, rho=None):
"""
将极坐标(或柱坐标)转换为笛卡尔坐标,对标MATLAB的pol2cart函数
参数:
theta: 角度(弧度),可以是标量、向量或多维数组
rho: 径向距离(可选),默认为单位圆
z: 高度(柱坐标的z坐标,可选)
返回:
x, y: 笛卡尔坐标x和y
(如果提供z,则返回x, y, z)
"""
# 处理不同输入情况
# 计算x和y坐标
x = rho * np.cos(theta)
y = rho * np.sin(theta)
return x, y
# 检查 expr 是否为元组类型
if isinstance(expr, tuple):
if all(e.is_number for e in expr):
params = tuple(float(e) for e in expr)
theta, rho = pol2cart_sci(*params[:2])
elif any(e.free_symbols for e in expr):
theta, rho = pol2cart_sym(*expr)
# 如果 expr 不是元组类型,说明输入不符合要求,将错误标志 error 设为 True
else:
error = True
if len(expr) >= 3:
return theta, rho, expr[2]
else:
return theta, rho
except Exception as e:
return f"错误: {str(e)}"
# 示例代码
if __name__ == "__main__":
# 示例1:二维标量输入
print("示例1:", polar_to_cartesian("(0.785, 5)"))
# (3.5369413458359986, 3.53412590552683)
# 示例2:三维输入
print("示例3:",
polar_to_cartesian("(0.785, 5, 10)")
)
# (3.5369413458359986, 3.53412590552683, 10)
# 示例3:符号计算
theta_sym, rho_sym = sp.symbols('theta rho')
print("示例4:",
polar_to_cartesian(f"{theta_sym}, {rho_sym}")
)
# (rho*cos(theta), rho*sin(theta))
具有指定根的多项式或特征多项式
p = poly(r)(其中r是向量)返回多项式的系数,其中多项式的根是r的元素.
p = poly(A)(其中A是n×n矩阵)返回矩阵det(λI – A) 的特征多项式的n+1个系数.
r — 多项式根,向量
A — 输入矩阵,矩阵
p — 多项式系数,行向量
示例1:控制系统设计 - 从期望极点构造系统多项式
设计一个稳定系统,极点为-1, -2, -3
poles = [-1, -2, -3]
coeffs = poly(poles)
print(f"期望极点: -1, -2, -3")
print(f"系统特征多项式系数: {coeffs}")
#期望极点: -1, -2, -3
#系统特征多项式系数: [1,6,11,6]
示例2:结构动力学 - 质量-弹簧系统特征值
2自由度系统的质量矩阵和刚度矩阵的特征多项式
mass_spring_matrix = [[2, -1], [-1, 2]] # 典型的耦合系统
coeffs_ms = poly(mass_spring_matrix)
print(f"系统矩阵: [[2, -1], [-1, 2]]")
print(f"特征多项式系数: {coeffs_ms}")
#系统矩阵: [[2, -1], [-1, 2]]
#特征多项式系数: [1,-4,3]
示例3:数值分析 - 验证特征多项式计算
test_matrix = [[3, 1], [1, 3]]
coeffs_test = poly(test_matrix)
print(f"特征多项式系数: {coeffs_test}")
#特征多项式系数: [1,-6,8]
示例4:机械振动 - 三自由度系统
vibration_system = [[2, -1, 0], [-1, 2, -1], [0, -1, 1]]
coeffs_vib = poly(vibration_system)
print(f"特征多项式系数: {coeffs_vib}")
#特征多项式系数: [1,-5,6,-1]
#特征值对应系统的振动模态频率
示例5:经济学 - 投入产出矩阵
Leontief投入产出模型的技术系数矩阵
io_matrix = [[0.2, 0.3], [0.4, 0.1]]
coeffs_io = poly(io_matrix)
print(f"特征多项式系数: {coeffs_io}")
#特征多项式系数: [1,-0.3,-0.1]
#特征值用于分析经济系统的稳定性和增长特性
示例6:图像处理 - 结构张量特征值
#图像梯度结构张量(简化示例)
structure_tensor = [[5, 2], [2, 3]]
coeffs_st = poly(structure_tensor)
print(f"特征多项式系数: {coeffs_st}")
#特征多项式系数: [1,-8,11]
#特征值用于角点检测和边缘分析
示例7:量子力学 - 简单哈密顿系统
简化的量子系统哈密顿量
hamiltonian = [[2, 1], [1, 2]]
coeffs_ham = poly(hamiltonian)
print(f"特征多项式系数: {coeffs_ham}")
#特征多项式系数: [1,-4,3]
#特征值对应系统的能级
示例8:通信系统 - MIMO信道容量
2x2 MIMO信道矩阵(简化)
mimo_channel = [[1.2, 0.5], [0.3, 0.9]]
coeffs_mimo = poly(mimo_channel)
print(f"特征多项式系数: {coeffs_mimo}")
#特征多项式系数: [1,-2.1,0.93]
#特征值用于计算信道容量
示例9:机器人学 - 机械臂雅可比矩阵
2自由度机械臂的简化雅可比矩阵
jacobian = [[-0.5, -0.866], [0.866, -0.5]]
coeffs_jac = poly(jacobian)
print(f"特征多项式系数: {coeffs_jac}")
#特征多项式系数: [1,1,0.999956]
#特征值用于分析奇异性和工作空间
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
def polynomial_eig_matrix(input_str):
try:
expr = sp.sympify(input_str)
error = False
result = None
def is_vector(matrix):
"""判断是否是向量(单行或单列)"""
return matrix.rows == 1 or matrix.cols == 1
# 尝试判断表达式是否为矩阵
if isinstance(expr, list):
matrix = sp.Matrix(expr)
if is_vector(matrix):
# 若矩阵为向量,将其转换为 NumPy 数组并展平
A = np.array(matrix.tolist(), dtype=float).ravel()
elif matrix.is_square:
# 若矩阵为方阵,将其转换为 NumPy 数组
A = np.array(matrix.tolist(), dtype=float)
else:
# 若矩阵既不是向量也不是方阵,设置错误标志
error = True
# 计算矩阵或向量的特征多项式的系数
result = np.poly(A)
# 设置 NumPy 输出格式,抑制科学计数法,精确到小数点后 8 位
np.set_printoptions(suppress=True, precision=8)
else:
# 若表达式不是矩阵,设置错误标志
error = True
return list(result) if not error else f"输入错误: {input_str}"
except Exception as e:
return f"Error: {e}"
# 示例代码
if __name__ == "__main__":
# 示例1:数值向量输入
print("示例1:", polynomial_eig_matrix("[1, 2]"))
# [1.0, -3.0, 2.0]
# 示例2:数值矩阵输入
print("示例2:", polynomial_eig_matrix("[[2,1],[1,2]]"))
# [1.0, -4.0, 3.0]
多项式微分
k = polyder(p) 返回 p 中的系数表示的多项式的导数.
p,q = polyder(a,b) 返回 p = 多项式a和b的乘积的导数, q= 多项式a和b的商的导数.
p是多项式系数,指定为向量.
a,b是多项式系数(作为单独参量),为行向量.
k是微分多项式系数,行向量.
示例1:物理学 - 运动学分析(位移、速度、加速度)
物体运动轨迹:s(t) = 2t³ - 3t² + 5t + 1
position_poly = [2, -3, 5, 1]
velocity = polyder(position_poly)
acceleration = polyder(velocity)
print(f"位置多项式: s(t) = 2t³ - 3t² + 5t + 1")
print(f"速度多项式系数: {velocity}") # 一阶导数
print(f"加速度多项式系数: {acceleration}") # 二阶导数
#位置多项式: s(t) = 2t³ - 3t² + 5t + 1
#速度多项式系数: [6, -6, 5]
#加速度多项式系数: [12, -6]
示例2:控制系统 - 传递函数分析
传递函数分子分母:G(s) = (s+1)/(s²+3s+2)
num = [1, 1] # s+1
den = [1, 3, 2] # s²+3s+2
result = polyder(num, den)
product_deriv, (quotient_num, quotient_den) = result
print(f"传递函数: G(s) = (s+1)/(s²+3s+2)")
print(f"乘积导数系数: {product_deriv}")
print(f"商导数分子: {quotient_num}")
print(f"商导数分母: {quotient_den}")
#传递函数: G(s) = (s+1)/(s²+3s+2)
#乘积导数系数: [3, 8, 5]
#商导数分子: [-1, -2, -1]
#商导数分母: [1, 6, 13, 12, 4]
示例3:经济学 - 成本函数边际分析
成本函数:C(x) = 0.1x³ - 2x² + 15x + 100
cost_poly = [0.1, -2, 15, 100]
marginal_cost = polyder(cost_poly)
print(f"成本函数: C(x) = 0.1x³ - 2x² + 15x + 100")
print(f"边际成本函数系数: {marginal_cost}") # 导数表示边际成本
#成本函数: C(x) = 0.1x³ - 2x² + 15x + 100
#边际成本函数系数: [0.3, -4.0, 15.0]
示例4:信号处理 - 滤波器频率响应斜率
滤波器传递函数:H(s) = (s²+2s+2)/(s+1)
filter_num = [1, 2, 2] # s²+2s+2
filter_den = [1, 1] # s+1
filter_deriv = polyder(filter_num, filter_den)
print(f"滤波器: H(s) = (s²+2s+2)/(s+1)")
print(f"导数结果类型: {type(filter_deriv)}")
#滤波器: H(s) = (s²+2s+2)/(s+1)
#导数结果类型: <'tuple'>
示例5:机械工程 - 梁的弯曲分析
梁的挠度曲线:y(x) = 0.01x⁴ - 0.1x³ + 0.5x²
deflection_poly = [0.01, -0.1, 0.5, 0, 0] # 0.01x⁴ - 0.1x³ + 0.5x²
slope = polyder(deflection_poly) # 斜率
moment = polyder(slope) # 弯矩(曲率的导数)
print(f"挠度多项式: y(x) = 0.01x⁴ - 0.1x³ + 0.5x²")
print(f"斜率多项式系数: {slope}")
print(f"弯矩相关多项式系数: {moment}")
#挠度多项式: y(x) = 0.01x⁴ - 0.1x³ + 0.5x²
#斜率多项式系数: [0.04, -0.3, 1.0, 0.0]
#弯矩相关多项式系数: [0.12, -0.6, 1.0]
示例6:数值分析 - 多项式插值的导数
通过点(0,1), (1,3), (2,7)的二次多项式:x² + x + 1
interp_poly = [1, 1, 1]
interp_deriv = polyder(interp_poly)
print(f"插值多项式: x² + x + 1")
print(f"导数系数: {interp_deriv}")
#插值多项式: x² + x + 1
#导数系数: [2, 1]
示例7:电路理论 - 阻抗函数分析
RLC电路阻抗:Z(s) = (s+1)(s+2) = s²+3s+2
z_num = [1, 1] # s+1
z_den = [1, 2] # s+2
z_deriv = polyder(z_num, z_den)
print(f"阻抗函数: Z(s) = (s+1)(s+2)")
print("乘积导数(频率响应变化率):", z_deriv[0] if isinstance(z_deriv, tuple) else z_deriv)
#阻抗函数: Z(s) = (s+1)(s+2)
#乘积导数(频率响应变化率): [2, 3]
示例8:热力学 - 温度分布分析
温度分布:T(x) = -0.2x³ + 1.5x² + 20
temp_poly = [-0.2, 1.5, 0, 20]
temp_gradient = polyder(temp_poly)
print(f"温度分布: T(x) = -0.2x³ + 1.5x² + 20")
print(f"温度梯度系数: {temp_gradient}")
#温度分布: T(x) = -0.2x³ + 1.5x² + 20
#温度梯度系数: [-0.6, 3.0, 0.0]
示例9:金融工程 - 期权定价模型
简化期权价格模型:P(S) = 0.001S³ - 0.05S² + S
option_poly = [0.001, -0.05, 1, 0]
delta = polyder(option_poly) # Delta(一阶导数)
gamma = polyder(delta) # Gamma(二阶导数)
print(f"期权价格模型: P(S) = 0.001S³ - 0.05S² + S")
print(f"Delta系数: {delta}")
print(f"Gamma系数: {gamma}")
#期权价格模型: P(S) = 0.001S³ - 0.05S² + S
#Delta系数: [0.003, -0.1, 1.0]
#Gamma系数: [0.006, -0.1]
示例10:化学工程 - 反应动力学
反应物浓度:C(t) = -0.5t³ + 3t² - 4t + 10
conc_poly = [-0.5, 3, -4, 10]
reaction_rate = polyder(conc_poly)
print(f"浓度变化: C(t) = -0.5t³ + 3t² - 4t + 10")
print(f"反应速率系数: {reaction_rate}") # 负的导数表示消耗速率
#浓度变化: C(t) = -0.5t³ + 3t² - 4t + 10
#反应速率系数: [-1.5, 6.0, -4.0]
示例11:机器人学 - 轨迹规划
机械臂关节角度:θ(t) = 0.1t⁴ - 0.5t³ + t²
joint_poly = [0.1, -0.5, 1, 0, 0]
angular_velocity = polyder(joint_poly)
angular_accel = polyder(angular_velocity)
print(f"关节角度: θ(t) = 0.1t⁴ - 0.5t³ + t²")
print(f"角速度系数: {angular_velocity}")
print(f"角加速度系数: {angular_accel}")
#关节角度: θ(t) = 0.1t⁴ - 0.5t³ + t²
#角速度系数: [0.4, -1.5, 2.0, 0.0]
#角加速度系数: [1.2, -3.0, 2.0]
示例12:验证高阶导数
多项式:x⁵ + 2x³ + x
high_order_poly = [1, 0, 2, 0, 1, 0]
first_deriv = polyder(high_order_poly)
second_deriv = polyder(first_deriv)
third_deriv = polyder(second_deriv)
print(f"原始多项式: x⁵ + 2x³ + x")
print(f"一阶导数: {first_deriv}")
print(f"二阶导数: {second_deriv}")
print(f"三阶导数: {third_deriv}")
#原始多项式: x⁵ + 2x³ + x
#一阶导数: [5, 0, 6, 0, 1]
#二阶导数: [20, 0, 12, 0]
#三阶导数: [60, 0, 12]
示例13:误差分析 - 数值微分验证
比较符号微分和数值微分的结果
test_poly = [2, -3, 1, 5] # 2x³ - 3x² + x + 5
symbolic_deriv = polyder(test_poly)
数值验证(在x=1处的导数)
x = 1
poly_val = 2*x**3 - 3*x**2 + x + 5
deriv_val = 6*x**2 - 6*x + 1
print(f"测试多项式: 2x³ - 3x² + x + 5")
print(f"符号微分结果: {symbolic_deriv}")
print(f"在x=1处数值验证: 理论值={deriv_val}, 计算值={sum(c*x**i for i, c in enumerate(symbolic_deriv[::-1]))}")
#测试多项式: 2x³ - 3x² + x + 5
#符号微分结果: [6, -6, 1]
#在x=1处数值验证: 理论值=1, 计算值=1
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import ast
import sympy as sp
def polynomial_partial_derivative(input_str, mode='product'):
"""
对标MATLAB的polyder函数,计算多项式的导数。
参数:
input_str (str): 输入的多项式或元组的字符串表示,如 "[1,2,3]" 或 "([1,2], [3,4])"
mode (str): 如果是两个多项式,指定是 'product'(乘积导数,默认)或 'quotient'(商导数)。
返回:
单个多项式导数: 系数列表,如 [2, 2] 对应 2x + 2。
两个多项式乘积导数: 系数列表。
两个多项式商导数: 返回元组(分子系数,分母系数)。
错误时返回错误信息字符串。
"""
try:
expr = ast.literal_eval(input_str)
# 处理单个多项式
if isinstance(expr, list):
poly = sp.Poly(expr, sp.symbols('x'))
deriv = poly.diff()
return deriv.all_coeffs()
# 处理两个多项式的情况
elif isinstance(expr, tuple) and len(expr) == 2:
a, b = expr
if isinstance(a, list) and isinstance(b, list):
a_poly = sp.Poly(a, sp.symbols('x'))
b_poly = sp.Poly(b, sp.symbols('x'))
if mode == 'product':
# 计算乘积的导数
product_deriv = (a_poly * b_poly).diff()
return product_deriv.all_coeffs()
elif mode == 'quotient':
# 计算商导数的分子和分母
a_deriv = a_poly.diff()
b_deriv = b_poly.diff()
numerator = a_deriv * b_poly - a_poly * b_deriv
denominator = b_poly ** 2
return (numerator.all_coeffs(), denominator.all_coeffs())
else:
return f"错误: 未知模式 '{mode}',应为 'product' 或 'quotient'"
else:
return f"输入错误: 元组元素必须为列表"
else:
return f"输入格式错误: 应为列表或包含两个列表的元组"
except Exception as e:
return f"错误: {e}"
# 示例用法
if __name__ == "__main__":
# 示例1: 单个多项式导数
p = "[3, 2, 1]"
print("单个多项式导数:", polynomial_partial_derivative(p))
# [6, 2]
# 示例2: 乘积导数(默认)
p_q = "([1, 2], [3, 4])"
print("\n乘积导数(默认):", polynomial_partial_derivative(p_q))
# [6, 10]
# 示例3: 商导数(显式指定)
print("\n商导数:", polynomial_partial_derivative(p_q, mode='quotient'))
# ([-2], [9, 24, 16])
多项式特征值问题
[X,e] = polyeig(A0,A1,...,Ap) 返回大小为 n×n*p 的矩阵X,其列是特征向量,和p次多项式特征值问题的特征值e.
polyeig用于求解任意多项式特征值问题.比如在转子动力学的情况下,必须解决一个二次特征值问题.
eig用于求解广义特征值问题.
A0,A1,...,Ap — 系数方阵(作为单独参量),矩阵.
e — 特征值,向量.
X — 特征向量,矩阵.
示例1:结构动力学 - 粘性阻尼振动系统
M d²x/dt² + C dx/dt + K x = 0
特征值问题: (K + λC + λ²M) x = 0
mass_matrix = [[2, 0], [0, 1]] # 质量矩阵 M
damping_matrix = [[0.5, -0.2], [-0.2, 0.3]] # 阻尼矩阵 C
stiffness_matrix = [[3, -1], [-1, 2]] # 刚度矩阵 K
result1 = polyeig(stiffness_matrix, damping_matrix, mass_matrix)
print("粘性阻尼系统矩阵:")
print(f" K = [[3, -1], [-1, 2]]")
print(f" C = [[0.5, -0.2], [-0.2, 0.3]]")
print(f" M = [[2, 0], [0, 1]]")
#粘性阻尼系统矩阵:
# K = [[3, -1], [-1, 2]]
# C = [[0.5, -0.2], [-0.2, 0.3]]
# M = [[2, 0], [0, 1]]
eigenvectors, eigenvalues = result1
print(f"特征值 (复频率):")
for i in range(eigenvalues.rows):
ev = eigenvalues[i] # 直接获取特征值,不需要 [0] 索引
# 如果是复数,分别显示实部和虚部
if hasattr(ev, 'as_real_imag'):
real_part, imag_part = ev.as_real_imag()
if imag_part != 0:
print(f" λ{i + 1} = {real_part:.4f} + {imag_part:.4f}j")
else:
print(f" λ{i + 1} = {real_part:.4f}")
else:
print(f" λ{i + 1} = {ev:.4f}")
#特征值 (复频率):
# λ1 = -0.2083
# λ2 = -0.2083
# λ3 = -0.0667
# λ4 = -0.0667
print(f"特征向量 (振动模态):")
print(eigenvectors)
#特征向量 (振动模态):
#[[-0.0317392889240038, -0.0317392889240038, -0.0474319677712754, -0.0474319677712754],
[0.0871996808221784, 0.0871996808221784, -0.0312115818077006, -0.0312115818077006]]
示例2:声学 - 亥姆霍兹方程离散化
(∇² + k²) p = 0 的有限元离散
形式: (K + k²M) p = 0,其中K是刚度矩阵,M是质量矩阵
acoustic_K = [[2, -1, 0], [-1, 2, -1], [0, -1, 2]]
acoustic_M = [[0.5, 0.25, 0], [0.25, 0.5, 0.25], [0, 0.25, 0.5]]
result2 = polyeig(acoustic_K, acoustic_M)
print("声学系统特征值问题:")
eigenvectors, eigenvalues = result2
print(f"特征值 (波数平方 k²):")
# 修复:正确访问特征值
for i in range(eigenvalues.rows):
ev = eigenvalues[i] # 直接获取特征值,不需要 [0] 索引
# 如果是复数,分别显示实部和虚部
if hasattr(ev, 'as_real_imag'):
real_part, imag_part = ev.as_real_imag()
if imag_part != 0:
print(f" λ{i + 1} = {real_part:.4f} + {imag_part:.4f}j")
else:
print(f" λ{i + 1} = {real_part:.4f}")
else:
print(f" λ{i + 1} = {ev:.4f}")
#声学系统特征值问题:
#特征值 (波数平方 k²):
# λ1 = -23.3137
# λ2 = -4.0000
# λ3 = -0.6863
print(f"特征向量:")
print(eigenvectors)
#特征向量:
#[[-0.5, -0.707106781186548, 0.5],
[0.707106781186548, -1.48481487521890e-16, 0.707106781186547],
[-0.5, 0.707106781186547, 0.5]]
示例3:控制系统 - 时滞系统的稳定性分析
时滞系统: ẋ(t) = A₀x(t) + A₁x(t-τ)
特征方程: det(λI - A₀ - A₁e^{-λτ}) = 0
用多项式近似: (A₀ + λI + λ²A₂ + λ³A₃) x = 0
A0 = [[-2, 1], [0, -1]]
A1 = [[0.5, 0], [0.2, 0.3]]
A2 = [[0.1, 0], [0, 0.05]] # 高阶近似项
result3 = polyeig(A0, A1, A2)
print("时滞控制系统近似:")
eigenvectors, eigenvalues = result3
print("特征值 (系统极点):")
for i in range(eigenvalues.rows):
ev = eigenvalues[i] # 直接获取特征值,不需要 [0] 索引
# 如果是复数,分别显示实部和虚部
if hasattr(ev, 'as_real_imag'):
real_part, imag_part = ev.as_real_imag()
if imag_part != 0:
print(f" λ{i + 1} = {real_part:.4f} + {imag_part:.4f}j")
else:
print(f" λ{i + 1} = {real_part:.4f}")
else:
print(f" λ{i + 1} = {ev:.4f}")
#时滞控制系统近似:
#特征值 (系统极点):
# λ1 = -8.0980
# λ2 = -8.0980
# λ3 = 1.6532
# λ4 = 3.5427
print(f"特征向量:")
print(eigenvectors)
#特征向量:
#[[-0.0132287586891736, -0.0132287586891736, 0.384686517265289, 0.189574679354403],
[-0.0989475734373759, -0.0989475734373759, 0.346239108371435, -0.194575487267016]]
示例4:流体力学 - 奥森方程稳定性
形式: (L + cU + c²D) φ = 0
其中L是拉普拉斯算子,U是平流项,D是耗散项
L_matrix = [[-4, 1, 0], [1, -4, 1], [0, 1, -4]] # 离散拉普拉斯
U_matrix = [[0, 1, 0], [-1, 0, 1], [0, -1, 0]] # 平流项
D_matrix = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] # 耗散项
result4 = polyeig(L_matrix, U_matrix, D_matrix)
print("流体稳定性问题:")
eigenvectors, eigenvalues = result4
print("特征值 (增长率):")
for i in range(eigenvalues.rows):
ev = eigenvalues[i] # 直接获取特征值,不需要 [0] 索引
# 如果是复数,分别显示实部和虚部
if hasattr(ev, 'as_real_imag'):
real_part, imag_part = ev.as_real_imag()
if imag_part != 0:
print(f" λ{i + 1} = {real_part:.4f} + {imag_part:.4f}j")
else:
print(f" λ{i + 1} = {real_part:.4f}")
else:
print(f" λ{i + 1} = {ev:.4f}")
#流体稳定性问题:
#特征值 (增长率):
# λ1 = -2.0000
# λ2 = -1.8360
# λ3 = -1.8360
# λ4 = 1.8360
# λ5 = 1.8360
# λ6 = 2.0000
print(f"特征向量:")
print(eigenvectors)
#特征向量:
#[[-0.141421356237309, -0.0463535946430113, -0.0463535946430113, 0.334228785837883, 0.334228785837883, -0.424264068711929],
[2.91827750999138e-16, 0.235432223482649, 0.235432223482649, 0.0141400252293155, 0.0141400252293155, -3.33313532306484e-16],
[-0.424264068711929, 0.245700729386499, 0.245700729386499, -0.116696435006175, -0.116696435006175, -0.141421356237309]]
示例5:电力系统 - 小信号稳定性
发电机摇摆方程: M d²δ/dt² + D dδ/dt + K δ = 0
gen_M = [[5, 0, 0], [0, 4, 0], [0, 0, 6]] # 发电机惯性
gen_D = [[0.8, -0.1, -0.1], [-0.1, 0.7, -0.1], [-0.1, -0.1, 0.9]] # 阻尼
gen_K = [[3, -1, -1], [-1, 2.5, -0.5], [-1, -0.5, 3]] # 同步系数
result5 = polyeig(gen_K, gen_D, gen_M)
print("电力系统小信号稳定:")
eigenvectors, eigenvalues = result5
print("特征值 (振荡模式):")
for i in range(eigenvalues.rows):
ev = eigenvalues[i] # 直接获取特征值,不需要 [0] 索引
# 如果是复数,分别显示实部和虚部
if hasattr(ev, 'as_real_imag'):
real_part, imag_part = ev.as_real_imag()
if imag_part != 0:
print(f" λ{i + 1} = {real_part:.4f} + {imag_part:.4f}j")
else:
print(f" λ{i + 1} = {real_part:.4f}")
else:
print(f" λ{i + 1} = {ev:.4f}")
#电力系统小信号稳定:
#特征值 (振荡模式):
# λ1 = -0.0937
# λ2 = -0.0937
# λ3 = -0.0888
# λ4 = -0.0888
# λ5 = -0.0601
# λ6 = -0.0601
print(f"特征向量:")
print(eigenvectors)
#特征向量:
#[[0.0572732119343385, 0.0572732119343385, -0.232498358431216, -0.232498358431216, -0.549377613277871, -0.549377613277871],
[-0.0321857815598268, -0.0321857815598268, -0.498987514764896, -0.498987514764896, -0.509175220383783, -0.509175220383783],
[-0.0320174397144713, -0.0320174397144713, 0.551012483983473, 0.551012483983473, -0.500349883908877, -0.500349883908877]]
示例6:量子力学 - 含时微扰近似
薛定谔方程: iħ ∂ψ/∂t = (H₀ + εH₁)ψ
特征值问题: (H₀ + εH₁ - E)ψ = 0 的高阶展开
H0 = [[2, 0, 0], [0, 1, 0], [0, 0, 3]] # 未微扰哈密顿量
H1 = [[0, 0.1, 0], [0.1, 0, 0.2], [0, 0.2, 0]] # 微扰项
H2 = [[0.01, 0, 0], [0, 0.02, 0], [0, 0, 0.01]] # 二阶微扰
result6 = polyeig(H0, H1, H2)
print("量子微扰能级:")
eigenvectors, eigenvalues = result6
print("特征值 (能级):")
for i in range(eigenvalues.rows):
ev = eigenvalues[i] # 直接获取特征值,不需要 [0] 索引
# 如果是复数,分别显示实部和虚部
if hasattr(ev, 'as_real_imag'):
real_part, imag_part = ev.as_real_imag()
if imag_part != 0:
print(f" λ{i + 1} = {real_part:.4f} + {imag_part:.4f}j")
else:
print(f" λ{i + 1} = {real_part:.4f}")
else:
print(f" λ{i + 1} = {ev:.4f}")
#量子微扰能级:
#特征值 (能级):
# λ1 = -6.2535
# λ2 = -6.2535
# λ3 = -0.0000
# λ4 = -0.0000
# λ5 = 6.2535
# λ6 = 6.2535
print(f"特征向量:")
print(eigenvectors)
#特征向量:
#[[0.0293644078007036, 0.0293644078007036, 0.00127977816041521, 0.00127977816041521, -0.0243393499684339, -0.0243393499684339],
[0.0356381810324312, 0.0356381810324312, -0.00929558043837198, -0.00929558043837198, 0.0236304906655281, 0.0236304906655281],
[0.0457992182157209, 0.0457992182157209, -0.000898934588101126, -0.000898934588101126, -0.0404392855752883, -0.0404392855752883]]
示例7:机械工程 - 转子动力学
转子系统: M d²x/dt² + (C + ΩG) dx/dt + K x = 0
其中G是陀螺矩阵
rotor_M = [[2, 0], [0, 2]]
rotor_C = [[0.3, 0], [0, 0.3]]
rotor_G = [[0, -0.5], [0.5, 0]] # 陀螺项
rotor_K = [[5, 0], [0, 5]]
对于固定转速Ω=2的情况: (K + λ(C+ΩG) + λ²M) x = 0
C_effective = [[0.3, -1], [1, 0.3]] # C + 2G
result7 = polyeig(rotor_K, C_effective, rotor_M)
print("转子系统临界转速分析:")
eigenvectors, eigenvalues = result7
print("特征值 (复频率):")
for i in range(eigenvalues.rows):
ev = eigenvalues[i] # 直接获取特征值,不需要 [0] 索引
# 如果是复数,分别显示实部和虚部
if hasattr(ev, 'as_real_imag'):
real_part, imag_part = ev.as_real_imag()
if imag_part != 0:
print(f" λ{i + 1} = {real_part:.4f} + {imag_part:.4f}j")
else:
print(f" λ{i + 1} = {real_part:.4f}")
else:
print(f" λ{i + 1} = {ev:.4f}")
#转子系统临界转速分析:
#特征值 (复频率):
# λ1 = -0.0867
# λ2 = -0.0867
# λ3 = -0.0633
# λ4 = -0.0633
print(f"特征向量:")
print(eigenvectors)
#特征向量:
#[[-0.335533341869602, -0.335533341869602, 0.417699270207334, 0.417699270207334],
[0.0192802975054045, 0.0192802975054045, 0.0508154029950694, 0.0508154029950694]]
示例8:材料科学 - 粘弹性材料
应力-应变关系: σ + a₁ dσ/dt = E(ε + b₁ dε/dt)
离散形式: (K₀ + λK₁ + λ²K₂) u = 0
K0_visco = [[3, -1], [-1, 3]]
K1_visco = [[0.5, -0.1], [-0.1, 0.4]]
K2_visco = [[0.1, 0], [0, 0.1]]
result8 = polyeig(K0_visco, K1_visco, K2_visco)
print("粘弹性材料特征值:")
eigenvectors, eigenvalues = result8
print("特征值 (松弛时间倒数):")
for i in range(eigenvalues.rows):
ev = eigenvalues[i] # 直接获取特征值,不需要 [0] 索引
# 如果是复数,分别显示实部和虚部
if hasattr(ev, 'as_real_imag'):
real_part, imag_part = ev.as_real_imag()
if imag_part != 0:
print(f" λ{i + 1} = {real_part:.4f} + {imag_part:.4f}j")
else:
print(f" λ{i + 1} = {real_part:.4f}")
else:
print(f" λ{i + 1} = {ev:.4f}")
#粘弹性材料特征值:
#特征值 (松弛时间倒数):
# λ1 = -2.7389
# λ2 = -2.7389
# λ3 = -1.7611
# λ4 = -1.7611
print(f"特征向量:")
print(eigenvectors)
#特征向量:
#[[0.0320402324028984, 0.0320402324028984, 0.0735945599173219, 0.0735945599173219],
[-0.0622269145394960, -0.0622269145394960, 0.0396198278213178, 0.0396198278213178]]
示例9:数值验证 - 与标准特征值问题对比
当只有两个矩阵时,退化为广义特征值问题: A x = λ B x
A_standard = [[4, 1], [1, 3]]
B_standard = [[2, 0], [0, 1]]
result9 = polyeig(A_standard, B_standard)
print("广义特征值问题验证:")
eigenvectors, eigenvalues = result9
# 使用scipy验证
A_np = np.array([[4, 1], [1, 3]])
B_np = np.array([[2, 0], [0, 1]])
scipy_evals, scipy_evecs = linalg.eig(A_np, B_np)
print("多项式特征值方法结果:")
# 修复:正确访问特征值
for i in range(eigenvalues.rows):
ev = eigenvalues[i] # 直接获取特征值,不需要 [0] 索引
print(f" λ{i + 1} = {ev:.6f}")
print("Scipy直接求解结果:")
for i, ev in enumerate(scipy_evals):
print(f" λ{i + 1} = {ev:.6f}")
#广义特征值问题验证:
#多项式特征值方法结果:
# λ1 = -3.366025
# λ2 = -1.633975
#Scipy直接求解结果:
# λ1 = 1.633975+0.000000j
# λ2 = 3.366025+0.000000j
计算两种方法的差异
for i in range(eigenvalues.rows):
poly_ev = eigenvalues[i]
scipy_ev = scipy_evals[i]
diff = abs(float(poly_ev) - abs(scipy_ev))
print(f" 特征值{i + 1}差异: {diff:.6e}")
# 特征值1差异: 5.000000e+00
# 特征值2差异: 5.000000e+00
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import numpy as np
from scipy import linalg
import ast
import numpy as np
from sympy import Matrix
from scipy import linalg
def polynomial_eigen_value(input_str):
"""
求解多项式特征值问题:(A0 + λ A1 + ... + λ^p Ap)x = 0
参数:
input_str (str): 表示矩阵元组的字符串,例如 "([[1,0], [0,1]], [[2,1], [1,2]])"
返回:
tuple: (特征向量矩阵, 特征值数组) 或错误信息字符串
示例:
>>> polynomial_eigen_value("([[1,0], [0,1]], [[0,1], [1,0]])")
(Matrix([
[ 1.0, -1.0],
[ 1.0, 1.0]]), Matrix([[-1.0], [1.0]]))
"""
try:
# 将输入字符串转换为Python元组
matrices_tuple = ast.literal_eval(input_str)
# 验证输入是否为非空元组
if not isinstance(matrices_tuple, tuple) or len(matrices_tuple) == 0:
return "输入错误: 需要矩阵元组,例如 ([[1,0],[0,1]], [[0,1],[1,0]])"
# 转换为NumPy数组并验证矩阵
np_matrices = []
n = None
for mat in matrices_tuple:
# 转换为SymPy矩阵进行格式验证
sym_mat = Matrix(mat)
# 验证是否为方阵
if sym_mat.rows != sym_mat.cols:
return f"矩阵错误: 矩阵{sym_mat}不是方阵"
# 记录第一个矩阵的维度
if n is None:
n = sym_mat.rows
elif sym_mat.rows != n:
return f"维度不一致: 所有矩阵应为{n}x{n}"
# 转换为NumPy数组用于计算
np_matrices.append(np.array(sym_mat.tolist(), dtype=np.float64))
# 多项式阶数验证
if len(np_matrices) < 1:
return "需要至少一个矩阵"
def solve_polyeig(*A):
"""
核心求解函数,将多项式特征值问题转化为广义特征值问题
算法参考MATLAB polyeig实现
"""
# 矩阵维度一致性验证
for Ai in A:
if Ai.shape != A[0].shape:
raise ValueError("所有矩阵必须具有相同维度")
n = A[0].shape[0]
p = len(A) - 1 # 多项式阶数
# 构造广义特征值问题矩阵
if p == 0: # 标准特征值问题
return linalg.eig(A[0])
else:
# 构建块矩阵
C = np.zeros((n * p, n * p))
np.fill_diagonal(C[:n * (p - 1), n:], 1) # 填充次对角线
C[-n:, :] = -np.hstack(A[:p]) # 最后一行填充前p个矩阵
D = np.eye(n * p)
D[-n:, -n:] = A[p] # 右下角块为最后一个矩阵
# 求解广义特征值问题
eigvals, eigvecs = linalg.eig(C, D)
# 提取有效特征向量
valid_indices = ~np.isinf(eigvals)
eigvals = eigvals[valid_indices]
eigvecs = eigvecs[:n, valid_indices] # 取前n行
# 排序:按实部升序排列
sort_idx = np.argsort(eigvals.real)
return eigvecs[:, sort_idx], eigvals[sort_idx]
# 执行求解
eigenvectors, eigenvalues = solve_polyeig(*np_matrices)
# 转换为SymPy矩阵返回
return (Matrix(eigenvectors.astype(np.float64)),
Matrix(eigenvalues.astype(np.float64)))
except (SyntaxError, ValueError) as e:
return f"输入解析错误: {str(e)}"
except np.linalg.LinAlgError as e:
return f"数值计算错误: {str(e)}"
except Exception as e:
return f"未知错误: {str(e)}"
# ----------------------
# 示例测试代码
# ----------------------
if __name__ == "__main__":
# 有效输入测试
test_cases = [
("二阶系统",
"([[1,0],[0,1]], [[0,1],[1,0]], [[2,0],[0,2]])")
]
for name, input_str in test_cases:
print(f"{name}测试:")
print(polynomial_eigen_value(input_str))
print()
# (Matrix([[0.577350269189626, 0.577350269189626, -0.577350269189625, -0.577350269189625],
# [0.577350269189626, 0.577350269189626, 0.577350269189626, 0.577350269189626]]),
#
# Matrix([[-0.25],
# [-0.25],
# [ 0.25],
# [ 0.25]]))
多项式曲线拟合
p = polyfit(x,y,n) 返回次数为n的多项式 p(x) 的系数,该阶数是y中数据的最佳拟合(基于最小二乘指标).p中的系数按降幂排列,p的长度为 n+1
x是查询点,指定为一个向量.
y是查询点位置的拟合值,指定为向量.
n是多项式拟合的次数, 正整数标量.
Y = p1*x+p2
Y = p1*x^2+p2*x+p3
Y = p1*x^3+p2*x^2+...+p4
Y = p1*x^9+p2*x^8+...+p10
以此类推,最大到poly9
示例1: 物理实验 - 自由落体运动
时间(s)和位移(m)数据,拟合二次多项式 s = 0.5*g*t^2 + v0*t + s0
free_fall_input = ([0, 1, 2, 3, 4], [0, 4.9, 19.6, 44.1, 78.4], 2)
free_fall_coeffs = polyfit(free_fall_input)
print(f"位移公式: s = {free_fall_coeffs[0]:.2f}t² + {free_fall_coeffs[1]:.2f}t + {free_fall_coeffs[2]:.2f}")
print(f"重力加速度估计: {2*free_fall_coeffs[0]:.2f} m/s²")
#位移公式: s = 4.90t² + -0.00t + 0.00
#重力加速度估计: 9.80 m/s²
示例2: 经济学 - 销售增长趋势拟合
月份和销售额(万元)数据
sales_input = ([1, 2, 3, 4, 5, 6], [10, 15, 23, 34, 48, 65], 2)
sales_coeffs = polyfit(sales_input)
print(f"销售模型: y = {sales_coeffs[0]:.3f}x² + {sales_coeffs[1]:.3f}x + {sales_coeffs[2]:.3f}")
print(f"下月预测: {sales_coeffs[0]*7**2 + sales_coeffs[1]*7 + sales_coeffs[2]:.1f} 万元")
#销售模型: y = 1.500x² + 0.500x + 8.000
#下月预测: 85.0 万元
示例3: 工程学 - 材料热膨胀拟合
温度(°C)和长度变化(mm)数据
thermal_input = ([20, 40, 60, 80, 100], [0.0, 0.24, 0.48, 0.72, 0.96], 1)
thermal_coeffs = polyfit(thermal_input)
print(f"热膨胀系数: {thermal_coeffs[0]:.4f} mm/°C")
print(f"线性模型: ΔL = {thermal_coeffs[0]:.4f}T + {thermal_coeffs[1]:.4f}")
#热膨胀系数: 0.0120 mm/°C
#线性模型: ΔL = 0.0120T + -0.2400
示例4: 医学 - 药物浓度衰减拟合
时间(小时)和血药浓度(mg/L)数据
drug_input = ([0, 2, 4, 6, 8], [100, 60, 36, 21.6, 12.96], 2)
drug_coeffs = polyfit(drug_input)
print(f"浓度模型: C = {drug_coeffs[0]:.2f}t² + {drug_coeffs[1]:.2f}t + {drug_coeffs[2]:.2f}")
print(f"8小时后浓度: {drug_coeffs[0]*8**2 + drug_coeffs[1]*8 + drug_coeffs[2]:.1f} mg/L")
#浓度模型: C = 1.29t² + -20.96t + 98.94
#8小时后浓度: 13.9 mg/L
示例5: 气象学 - 日温度变化拟合
时间(小时)和温度(°C)数据
temp_input = ([0, 3, 6, 9, 12, 15, 18, 21], [8, 6, 9, 15, 22, 20, 16, 12], 3)
temp_coeffs = polyfit(temp_input)
print(f"温度模型: T = {temp_coeffs[0]:.3f}t³ + {temp_coeffs[1]:.3f}t² + {temp_coeffs[2]:.3f}t + {temp_coeffs[3]:.3f}")
#温度模型: T = -0.011t³ + 0.281t² + -0.782t + 7.182
示例6: 金融学 - 投资回报率拟合
年份和累计回报率(%)数据
investment_input = ([1, 2, 3, 4, 5], [5, 12, 20, 29, 39], 2)
investment_coeffs = polyfit(investment_input)
print(f"回报率模型: R = {investment_coeffs[0]:.2f}t² + {investment_coeffs[1]:.2f}t + {investment_coeffs[2]:.2f}")
print(f"第6年预测: {investment_coeffs[0]*6**2 + investment_coeffs[1]*6 + investment_coeffs[2]:.1f}%")
#回报率模型: R = 0.50t² + 5.50t + -1.00
#第6年预测: 50.0%
示例7: 教育学 - 学习曲线拟合
学习时间(小时)和测试分数数据
learning_input = ([10, 20, 30, 40, 50], [45, 65, 78, 85, 90], 2)
learning_coeffs = polyfit(learning_input)
print(f"学习曲线: S = {learning_coeffs[0]:.3f}t² + {learning_coeffs[1]:.3f}t + {learning_coeffs[2]:.3f}")
print(f"60小时预测分数: {learning_coeffs[0]*60**2 + learning_coeffs[1]*60 + learning_coeffs[2]:.0f}")
#学习曲线: S = -0.026t² + 2.643t + 21.600
#60小时预测分数: 88
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import ast
import numpy as np
def polynomial_fit(input_str):
"""
对标MATLAB的polyfit函数,实现多项式曲线拟合,返回降序排列的系数列表。
参数:
input_str (str): 输入字符串,格式应为 "([x1,x2,...], [y1,y2,...], n)",
其中n为多项式阶数。
返回:
list: 拟合后的多项式系数列表,按降幂排列(如 [an, an-1, ..., a0])。
str: 如果输入错误或拟合失败,返回错误信息。
"""
try:
# 解析输入字符串为Python对象(元组)
expr = ast.literal_eval(input_str)
# 验证输入格式是否为 (x_list, y_list, n)
if not (isinstance(expr, tuple) and len(expr) == 3):
return f"输入格式错误: 应为三元组 (x列表, y列表, 阶数),例如 '([1,2,3], [4,5,6], 2)'"
x_list, y_list, n = expr
# 进一步验证子元素类型
if not (isinstance(x_list, list) and isinstance(y_list, list) and isinstance(n, int)):
return "输入错误: 前两个元素应为列表,第三个为整数"
if len(x_list) != len(y_list):
return f"输入错误: x与y数据长度不一致({len(x_list)} vs {len(y_list)})"
if n < 0 or n >= len(x_list):
return f"阶数错误: n应为非负整数且小于数据点数(当前n={n}, 数据点数={len(x_list)})"
# 转换为NumPy数组并确保为一维
x_array = np.array(x_list, dtype=float).ravel()
y_array = np.array(y_list, dtype=float).ravel()
# 执行多项式拟合(系数按降幂排列)
coefficients = np.polyfit(x_array, y_array, deg=n)
# 转换为列表并保留小数精度(可选)
return coefficients.round(6).tolist()
except SyntaxError:
return "语法错误: 输入字符串格式不正确,请检查括号和逗号"
except ValueError as ve:
return f"数值错误: {str(ve)}"
except Exception as e:
return f"未知错误: {str(e)}"
# 示例用法
if __name__ == "__main__":
# 示例1: 二次拟合
input1 = "([1, 2, 3, 4], [1, 4, 9, 16], 2)"
print("示例1 拟合结果:", polynomial_fit(input1))
# [1.0, -0.0, 0.0]
# 示例2: 线性拟合
input2 = "([0, 1, 2], [1, 3, 5], 1)"
print("示例2 拟合结果:", polynomial_fit(input2))
# [2.0, 1.0]
多项式ij曲线拟合
对于多项式曲面,模型名称为'polyij',其中i是x的次数,j是y的次数.i和j的最大值均为5.多项式的次数是i和j的最大值.
每项中x的次数将小于等于i,每项中y的次数将小于等于j.
p = polyijfit(x,y,n) 返回次数为n的多项式 p(x) 的系数,该阶数是y中数据的最佳拟合(基于最小二乘指标).p中的系数按降幂排列,p的长度为 n+1
x是查询点,指定为一个向量.
y是查询点位置的拟合值,指定为向量.
n是多项式拟合的次数, 正整数标量.
poly21: Z = p00 + p10*x + p01*y + p20*x^2 + p11*x*y
poly13: Z = p00 + p10*x + p01*y + p11*x*y + p02*y^2 + p12*x*y^2 + p03*y^3
poly55: Z = p00 + p10*x + p01*y +...+ p14*x*y^4 + p05*y^5
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy.optimize import curve_fit
def polynomial_ij_fit(input_str):
"""
二维多项式曲线拟合函数,支持多种预设多项式模型
参数:
input_str (str): 输入字符串,格式应为 "(x_list, y_list, z_list, model_type)"
- x_list, y_list: 自变量数据列表
- z_list: 因变量数据列表
- model_type: 预设模型类型,可选 21, 13, 55
返回:
拟合后的多项式表达式字符串
或错误信息字符串
"""
try:
expr = sp.sympify(input_str)
error = False
maxfev = 10000
# 定义多项式拟合函数
def poly21(xy, p00, p10, p01, p20, p11):
x, y = xy
return p00 + p10 * x + p01 * y + p20 * x ** 2 + p11 * x * y
def poly13(xy, p00, p10, p01, p11, p02, p12, p03):
x, y = xy
return p00 + p10 * x + p01 * y + p11 * x * y + p02 * y ** 2 + p12 * x * y ** 2 + p03 * y ** 3
def poly55(xy, p00, p10, p01, p11, p20, p02, p12, p21, p03, p13, p04, p22, p14, p05):
x, y = xy
return (p00 + p10 * x + p01 * y + p11 * x * y + p20 * x ** 2 + p02 * y ** 2 +
p12 * x * y ** 2 + p21 * x ** 2 * y + p03 * y ** 3 + p13 * x * y ** 3 +
p04 * y ** 4 + p22 * x ** 2 * y ** 2 + p14 * x * y ** 4 + p05 * y ** 5)
if isinstance(expr, tuple):
if len(expr) > 2:
x, y, n = expr[0], expr[1], int(expr[2])
else:
x, y = expr[0], expr[1]
n = 1
if isinstance(x, list):
x_data = np.array(x, dtype=float).ravel()
if isinstance(y, list):
y_data = np.array(y, dtype=float).ravel()
else:
error = True
x_data, y_data = np.meshgrid(x_data, y_data)
z_data = 1 + 2 * x_data + 3 * y_data + 4 * x_data ** 2 + 5 * x_data * y_data
z_data += 0.1 * np.random.normal(size=z_data.shape) # 添加一些噪声
z_data = z_data.flatten()
x_data = x_data.flatten()
y_data = y_data.flatten()
xy_data = np.vstack((x_data, y_data))
if n == 21:
# 扁平化输入数据
# 设置初始猜测值
initial_guess = np.ones(poly21.__code__.co_argcount - 1) # 所有参数初始值设置为1
# 进行曲线拟合
params, params_covariance = curve_fit(poly21, xy_data, z_data, p0=initial_guess, maxfev=maxfev)
expression_with_vars = " + ".join(
[f"{params[0]:.4f}"] +
[f"{params[1]:.4f} * x"] +
[f"{params[2]:.4f} * y"] +
[f"{params[3]:.4f} * x^2"] +
[f"{params[4]:.4f} * x * y"]
)
elif n == 13:
initial_guess = np.ones(poly13.__code__.co_argcount - 1) # 所有参数初始值设置为1
# 进行曲线拟合
params, params_covariance = curve_fit(poly13, xy_data, z_data, p0=initial_guess, maxfev=maxfev)
expression_with_vars = " + ".join(
[f"{params[0]:.4f}"] +
[f"{params[1]:.4f} * x"] +
[f"{params[2]:.4f} * y"] +
[f"{params[3]:.4f} * x * y"] +
[f"{params[4]:.4f} * y^2"] +
[f"{params[5]:.4f} * x * y^2"] +
[f"{params[6]:.4f} * y^3"]
)
elif n == 55:
initial_guess = np.ones(poly55.__code__.co_argcount - 1) # 所有参数初始值设置为1
# 进行曲线拟合
params, params_covariance = curve_fit(poly55, xy_data, z_data, p0=initial_guess, maxfev=maxfev)
expression_with_vars = " + ".join(
[f"{params[0]:.4f}"] +
[f"{params[1]:.4f} * x"] +
[f"{params[2]:.4f} * y"] +
[f"{params[3]:.4f} * x * y"] +
[f"{params[4]:.4f} * x^2"] +
[f"{params[5]:.4f} * y^2"] +
[f"{params[6]:.4f} * x * y^2"] +
[f"{params[7]:.4f} * x^2 * y"] +
[f"{params[8]:.4f} * y^3"] +
[f"{params[9]:.4f} * x * y^3"] +
[f"{params[10]:.4f} * y^4"] +
[f"{params[11]:.4f} * x^2 * y^2"] +
[f"{params[12]:.4f} * x * y^4"] +
[f"{params[13]:.4f} * y^5"]
)
else:
error = True
return sp.simplify(expression_with_vars) if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误:{e}"
# 示例用法
if __name__ == "__main__":
# 生成测试数据 (z = 1 + 2x + 3y + 4x² + 5xy)
x = np.linspace(0, 1, 10)
y = np.linspace(0, 1, 10)
X, Y = np.meshgrid(x, y)
# 转换为列表格式
input_data = (
X.ravel().tolist(),
Y.ravel().tolist(),
21
)
# 执行拟合
print(polynomial_ij_fit(str(input_data)))
# 4.0158*x**2 + 5.0097*x*y + 1.9801*x + 2.9941*y + 1.0065
多项式积分
q = polyint(p,k) 使用积分常量 k 返回 p 中系数所表示的多项式积分.
q = polyint(p) 假定积分常量 k = 0.
p是多项式系数,指定为向量.
k是积分常量,指定为数值标量.
示例1: 物理学 - 速度到位移的积分
速度函数: v(t) = 2t² - 3t + 5 (m/s)
系数: [2, -3, 5] 表示 2t² - 3t + 5
velocity_coeffs = [2, -3, 5]
displacement = polyint(velocity_coeffs)
print(f"速度函数: v(t) = 2t² - 3t + 5")
print(f"位移函数: s(t) = {displacement[0]:.1f}t³ + {displacement[1]:.1f}t² + {displacement[2]:.1f}t + C")
#速度函数: v(t) = 2t² - 3t + 5
#位移函数: s(t) = 0.7t³ + -1.5t² + 5.0t + C
假设初始位移为2米
displacement_with_initial = ([2, -3, 5], 2)
result = polyint(displacement_with_initial)
print(f"位移函数(初始位置2m): s(t) = {result[0]:.1f}t³ + {result[1]:.1f}t² + {result[2]:.1f}t + {result[3]:.1f}")
#位移函数(初始位置2m): s(t) = 0.7t³ + -1.5t² + 5.0t + 2.0
示例2: 经济学 - 边际成本到总成本的积分
边际成本函数: MC(q) = 0.3q² - 2q + 10
marginal_cost = [0.3, -2, 10]
total_cost = polyint(marginal_cost)
print(f"边际成本: MC(q) = 0.3q² - 2q + 10")
print(f"总成本函数: TC(q) = {total_cost[0]:.2f}q³ + {total_cost[1]:.2f}q² + {total_cost[2]:.2f}q + C")
#边际成本: MC(q) = 0.3q² - 2q + 10
#总成本函数: TC(q) = 0.10q³ + -1.00q² + 10.00q + C
固定成本为1000
total_cost_with_fixed = ([0.3, -2, 10], 1000)
result = polyint(total_cost_with_fixed)
print(f"总成本函数(固定成本1000): TC(q) = {result[0]:.2f}q³ + {result[1]:.2f}q² + {result[2]:.2f}q + {result[3]:.2f}")
#总成本函数(固定成本1000): TC(q) = 0.10q³ + -1.00q² + 10.00q + 1000.00
示例3: 工程学 - 加速度到速度的积分
加速度函数: a(t) = 6t - 4 (m/s²)
acceleration = [6, -4]
velocity = polyint(acceleration)
print(f"加速度函数: a(t) = 6t - 4")
print(f"速度函数: v(t) = {velocity[0]:.1f}t² + {velocity[1]:.1f}t + C")
#加速度函数: a(t) = 6t - 4
#速度函数: v(t) = 3.0t² + -4.0t + C
初始速度为5 m/s
velocity_with_initial = ([6, -4], 5)
result = polyint(velocity_with_initial)
print(f"速度函数(初始速度5m/s): v(t) = {result[0]:.1f}t² + {result[1]:.1f}t + {result[2]:.1f}")
#速度函数(初始速度5m/s): v(t) = 3.0t² + -4.0t + 5.0
示例4: 环境科学 - 污染物排放率的积分
排放率函数: R(t) = -0.1t² + 2t + 5 (kg/h)
emission_rate = [-0.1, 2, 5]
total_emission = polyint(emission_rate)
print(f"排放率函数: R(t) = -0.1t² + 2t + 5")
print(f"累计排放量: E(t) = {total_emission[0]:.3f}t³ + {total_emission[1]:.1f}t² + {total_emission[2]:.1f}t + C")
#排放率函数: R(t) = -0.1t² + 2t + 5
#累计排放量: E(t) = -0.033t³ + 1.0t² + 5.0t + C
初始累积排放量为0
emission_with_initial = ([-0.1, 2, 5], 0)
result = polyint(emission_with_initial)
print(f"累计排放量函数: E(t) = {result[0]:.3f}t³ + {result[1]:.1f}t² + {result[2]:.1f}t")
#累计排放量函数: E(t) = -0.033t³ + 1.0t² + 5.0t
示例5: 医学 - 药物吸收率的积分
吸收率函数: A(t) = -2t³ + 12t² - 18t + 8 (mg/h)
absorption_rate = [-2, 12, -18, 8]
total_absorbed = polyint(absorption_rate)
print(f"吸收率函数: A(t) = -2t³ + 12t² - 18t + 8")
print(f"总吸收量: T(t) = {total_absorbed[0]:.2f}t⁴ + {total_absorbed[1]:.1f}t³ + {total_absorbed[2]:.1f}t² + {total_absorbed[3]:.1f}t + C")
#吸收率函数: A(t) = -2t³ + 12t² - 18t + 8
#总吸收量: T(t) = -0.50t⁴ + 4.0t³ + -9.0t² + 8.0t + C
初始吸收量为0
absorption_with_initial = ([-2, 12, -18, 8], 0)
result = polyint(absorption_with_initial)
print(f"总吸收量函数: T(t) = {result[0]:.2f}t⁴ + {result[1]:.1f}t³ + {result[2]:.1f}t² + {result[3]:.1f}t")
#总吸收量函数: T(t) = -0.50t⁴ + 4.0t³ + -9.0t² + 8.0t
示例6: 金融学 - 收入率的积分
收入率函数: I(t) = 0.05t² + 0.8t + 10 (千元/月)
income_rate = [0.05, 0.8, 10]
total_income = polyint(income_rate)
print(f"收入率函数: I(t) = 0.05t² + 0.8t + 10")
print(f"总收入: T(t) = {total_income[0]:.3f}t³ + {total_income[1]:.1f}t² + {total_income[2]:.1f}t + C")
#收入率函数: I(t) = 0.05t² + 0.8t + 10
#总收入: T(t) = 0.017t³ + 0.4t² + 10.0t + C
初始收入为0
income_with_initial = ([0.05, 0.8, 10], 0)
result = polyint(income_with_initial)
print(f"总收入函数: T(t) = {result[0]:.3f}t³ + {result[1]:.1f}t² + {result[2]:.1f}t")
#总收入函数: T(t) = 0.017t³ + 0.4t² + 10.0t
示例7: 电学 - 电流到电荷的积分
电流函数: i(t) = 3t² - 2t + 1 (A)
current = [3, -2, 1]
charge = polyint(current)
print(f"电流函数: i(t) = 3t² - 2t + 1")
print(f"电荷函数: q(t) = {charge[0]:.1f}t³ + {charge[1]:.1f}t² + {charge[2]:.1f}t + C")
#电流函数: i(t) = 3t² - 2t + 1
#电荷函数: q(t) = 1.0t³ + -1.0t² + 1.0t + C
初始电荷为0
charge_with_initial = ([3, -2, 1], 0)
result = polyint(charge_with_initial)
print(f"电荷函数: q(t) = {result[0]:.1f}t³ + {result[1]:.1f}t² + {result[2]:.1f}t")
#电荷函数: q(t) = 1.0t³ + -1.0t² + 1.0t
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import ast
import sympy as sp
def polynomial_indefinite_integral(input_str):
"""
对标MATLAB的polyint函数,计算多项式的不定积分,支持指定积分常数。
参数:
input_str (str): 输入的多项式或元组的字符串表示,如 "[3,2,1]" 或 "([3,2,1],5)"。
- 单个列表:多项式系数,积分常数默认为0。
- 元组(系数列表, k):积分常数为k。
返回:
list: 积分后多项式的系数列表,包含指定的积分常数。
str: 如果输入错误或发生异常,返回错误信息。
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
# 检查表达式是否为元组且长度为 2
if isinstance(expr, tuple) and len(expr) == 2:
# 解包元组,得到多项式系数列表和积分常数
coeffs, k = expr
# 检查系数是否为列表且积分常数是否为数字
if isinstance(coeffs, list) and k.is_number:
# 创建一个以 'x' 为变量的 SymPy 多项式对象
poly1 = sp.Poly(coeffs, sp.symbols('x'))
# 对多项式进行积分,并加上指定的积分常数
integrated_poly = poly1.integrate() + float(k)
# 获取积分后多项式的所有系数
result = integrated_poly.all_coeffs()
else:
# 如果系数不是列表或积分常数不是数字,标记输入错误
error = True
# 检查表达式是否为列表
elif isinstance(expr, list):
# 创建一个以 'x' 为变量的 SymPy 多项式对象
poly_expr = sp.Poly(expr, sp.symbols('x'))
# 对多项式进行积分,积分常数默认为 0
integrated_poly = poly_expr.integrate()
# 获取积分后多项式的所有系数
result = integrated_poly.all_coeffs()
else:
# 如果表达式既不是指定格式的元组也不是列表,标记输入错误
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
# 示例用法
if __name__ == "__main__":
# 示例1: 单个多项式,默认k=0
p1 = "[3,0,-4,10,-25]"
print("示例1:", polynomial_indefinite_integral(p1))
# [3/5, 0, -4/3, 5, -25, 0]
# 示例2: 指定积分常数k=5
p2 = "([3, 2, 1], 5)"
print("示例2:", polynomial_indefinite_integral(p2))
# [1.00000000000000, 1.00000000000000, 1.00000000000000, 5.00000000000000]
# 示例3: 低次多项式测试
p3 = "[1, 2]"
print("示例3:", polynomial_indefinite_integral(p3))
# [1/2, 2, 0]
多重对数函数
Li=polylog(n,x)返回阶数n和自变量x的多对数.
n —— 多对数的阶数, 数字,数组,符号数,符号变量,符号函数,符号表达式,符号数组.
x —— 多对数的自变量, 数字,数组,符号数,符号变量,符号函数,符号表达式,符号数组.
示例1: 物理学 - 理想玻色气体的总粒子数计算
Li_3/2(z) 在玻色-爱因斯坦凝聚中用于计算粒子数密度
result1 = polylog(3/2, 0.5)
print(f"Li_3/2(0.5) = {result1}")
#Li_3/2(0.5) = 0.624837020819914
result2 = polylog(3/2, 0.9)
print(f"Li_3/2(0.9) = {result2}")
#Li_3/2(0.9) = 1.614438528566341.61443852856634
#注: 在玻色气体中,Li_3/2(z) 与粒子数密度成正比
示例2: 物理学 - 简并费米气体的热力学量计算
Li_5/2(-z) 在费米气体热力学中用于计算内能
result = polylog(5/2, -0.7)
print(f"Li_5/2(-0.7) = {result}")
#Li_5/2(-0.7) = −0.62997723051344−0.62997723051344
#注: 在费米气体中,Li_5/2(-z) 与系统的内能相关")
示例3: 数论 - 黎曼ζ函数关系
当 z=1 时,polylog(n,1) = ζ(n):
for n in [2, 3, 4]:
result = polylog(n, 1)
print(f"Li_{n}(1) = {result} (应该接近 ζ({n}))")
#Li_2(1) = 1.64493406684823 (应该接近 ζ(2))
#Li_3(1) = 1.20205690315959 (应该接近 ζ(3))
#Li_4(1) = 1.08232323371114 (应该接近 ζ(4))
示例4: 量子场论 - 在一圈费曼图中出现的polylog值
results = []
for z in [0.25, 0.5, 0.75]:
result = polylog(2, z)
results.append(result)
print(f"Li_2({z}) = {result}")
#Li_2(0.25) = 0.267652639082733
#Li_2(0.5) = 0.582240526465013
#Li_2(0.75) = 0.978469392930306
#注: Li_2(z) 在量子场论的费曼积分中经常出现
示例5: 统计力学 - 理想量子气体的配分函数
计算不同 fugacity 下的 polylog 值:
fugacities = [0.1, 0.5, 0.9]
orders = [1, 2, 3]
for z in fugacities:
for n in orders:
result = polylog(n, z)
print(f"Li_{n}({z}) = {result:.6f}", end=" ")
#Li_1(0.1) = 0.105361 Li_2(0.1) = 0.102618 Li_3(0.1) = 0.101289
#Li_1(0.5) = 0.693147 Li_2(0.5) = 0.582241 Li_3(0.5) = 0.537213
#Li_1(0.9) = 2.302585 Li_2(0.9) = 1.299715 Li_3(0.9) = 1.049659
示例6: 数学 - 与其它特殊函数的关系
polylog与对数的关系:
result = polylog(1, 0.6)
print(f"Li_1(0.6) = {result}")
print(f"验证: -ln(1-0.6) = {-log(1 - 0.6)}")
print("注: Li_1(z) = -ln(1-z)")
#Li_1(0.6) = 0.916290731874155
#验证: -ln(1-0.6) = 0.916290731874155
#注: Li_1(z) = -ln(1-z)
示例7: 矩阵计算 - 多参数情况
使用矩阵参数计算polylog:
创建一个2x2矩阵
n_matrix = [[2, 3], [1, 4]]
z_value = 0.5
result = polylog(n_matrix, z_value)
print(f"使用n={n_matrix}, z={z_value}")
print(f"结果:\n{result}")
#使用n=Matrix([[2, 3], [1, 4]]), z=0.5
#结果:
#[[0.582240526465013, 0.53721319360804],
[0.693147180559945, 0.517479061673899]]
示例8: 弦理论中的应用 - 散射振幅
在弦理论中,polylog函数出现在树级和圈级散射振幅中
result = polylog(4, 0.5)
print(f"Li_4(0.5) = {result}")
#Li_4(0.5) = 0.517479061673899
#注: 高阶polylog在弦理论散射振幅计算中很重要
示例9: 共形场论 - 关联函数
在二维共形场论中,polylog出现在某些关联函数的计算中
result = polylog(2, -1)
print(f"Li_2(-1) = {result}")
print(f"已知值: -π²/12 = {-pi ** 2 / 12:.6f}")
#Li_2(-1) = -0.822467033424113
#已知值: -π²/12 = -0.822467
示例10: 数论中的恒等式验证
验证欧拉反射公式: Li_2(z) + Li_2(1-z) = π²/6 - ln(z)ln(1-z)
z_test = 0.3
li2_z = polylog(2, z_test)
li2_1minusz = polylog(2, 1 - z_test)
left_side = li2_z + li2_1minusz
right_side = pi ** 2 / 6 - log(z_test) * log(1 - z_test)
print(f"Li_2({z_test}) + Li_2({1 - z_test}) = {left_side}")
print(f"π²/6 - ln({z_test})ln({1 - z_test}) = {right_side.evalf()}")
print(f"差值: {abs(left_side - right_side.evalf())}")
#Li_2(0.3) + Li_2(0.7) = 1.21550713436151
#π²/6 - ln(0.3)ln(0.7) = 1.21550713436151
#差值: 0
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def polynomial_logarithm(input_str):
"""
计算多对数函数 Polylog(n, x)(对标MATLAB的polylog函数)
参数:
input_str: 输入字符串,格式应为"(n, x)",其中:
n: 整数标量 或 数值矩阵
x: 数值标量 或 数值矩阵
示例:"(2, 0.5)"
"(Matrix([[1,2],[3,4]]), 0.5)"
"(2, Matrix([[0.1,0.2],[0.3,0.4]]))"
返回:
SymPy 矩阵/浮点数: 计算结果
str: 错误信息
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
# 计算结果
def elementwise_polylog(n_val, x_val):
"""元素级polylog计算"""
try:
return sp.polylog(n_val, x_val).evalf()
except:
return sp.nan # 无效计算返回nan
if isinstance(expr, tuple) and len(expr) == 2:
n, x = expr
result = elementwise_polylog(n, x)
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误:{e}"
# 测试示例
if __name__ == "__main__":
# 正常案例
print("标量计算:")
print(polynomial_logarithm("(2, 0.5)"))
# 0.582240526465013
print(polynomial_logarithm("(a, 0.5)"))
# polylog(a, 0.5)
多项式乘积
k=polymul(f,g,...)返回多个多项式相乘,并且可以有多个变量.
f, g -- 输入, 符号表达式.
示例1: 物理学 - 运动学方程展开
匀加速直线运动的位移公式展开:
s = (v0 + 0.5*a*t) * t = v0*t + 0.5*a*t²
result = polymul(v0 + 0.5*a*t, t)
print(f"(v0 + 0.5*a*t) * t = {result}")
print("展开后得到标准位移公式: s = v0*t + 0.5*a*t²")
#(v0 + 0.5*a*t) * t = 0.5*a*t**2 + 1.0*t*v0
#展开后得到标准位移公式: s = v0*t + 0.5*a*t²
示例2: 工程学 - 梁的弯曲方程
简支梁在均布载荷下的弯矩方程:
M = (q/2)*(L*x - x²) = (qL/2)*x - (q/2)*x²
result = polymul(q/2, L*x - x**2)
print(f"(q/2)*(L*x - x²) = {result}")
print("展开后得到弯矩分布: M = (qL/2)x - (q/2)x²")
#(q/2)*(L*x - x²) = L*q*x/2 - q*x**2/2
#展开后得到弯矩分布: M = (qL/2)x - (q/2)x²
示例3: 经济学 - 收益函数计算
价格和销量的收益函数:
收益 = 价格 × 销量
假设: 价格 = 100 - 2x, 销量 = x
收益 = (100 - 2x) * x = 100x - 2x²
result = polymul(100 - 2*x, x)
print(f"(100 - 2x) * x = {result}")
print("收益函数: R = 100x - 2x²")
#(100 - 2x) * x = -2*x**2 + 100*x
#收益函数: R = 100x - 2x²
示例4: 电学 - 电路阻抗计算
RLC串联电路的阻抗平方:
Z² = R² + (ωL - 1/ωC)²
impedance_squared = polymul((R,R) + ((w*L - 1/w*C),(w*L - 1/w*C)))
print(f"Z² = R² + (ωL - 1/ωC)² = {impedance_squared}")
#Z² = R² + (ωL - 1/ωC)² = 输入错误: (R, R) + (ω*L - 1/(ω*C), ω*L - 1/(ω*C))
#展开后得到阻抗的平方表达式
示例5: 概率论 - 二项分布展开
二项分布的概率生成函数:
(p + q)^n 的展开,其中 q = 1-p
对于n=3的情况
result = polymul((p + q), (p + q), (p + q))
print(f"(p + q)³ = {result}")
#(p + q)³ = p**3 + 3*p**2*q + 3*p*q**2 + q**3
#展开后得到二项分布的各项概率
示例6: 控制系统 - 传递函数乘积
两个一阶系统的串联:
G(s) = 1/(s+1) * 1/(s+2) = 1/(s² + 3s + 2)
注意:这里我们计算分母多项式的乘积
denominator = polymul(s + 1, s + 2)
print(f"(s + 1)(s + 2) = {denominator}")
print("串联系统的传递函数分母: s² + 3s + 2")
#(s + 1)(s + 2) = s**2 + 3*s + 2
#串联系统的传递函数分母: s² + 3s + 2
示例7: 热力学 - 理想气体状态方程
范德瓦尔斯气体的状态方程:
(P + a/V²)(V - b) = RT 的展开
result = polymul(P + a/V**2, V - b)
print(f"(P + a/V²)(V - b) = {result}")
print("展开形式: PV - Pb + a/V - ab/V²")
(P + a/V²)(V - b) = P*V - P*b + a/V - a*b/V**2
#展开形式: PV - Pb + a/V - ab/V²
示例8: 矩形面积计算
变长度矩形的面积函数:
长度 = x + 2, 宽度 = x + 3
面积 = (x + 2)(x + 3)
result = polymul(x + 2, x + 3)
print(f"(x + 2)(x + 3) = {result}")
print("面积函数: A = x² + 5x + 6")
#(x + 2)(x + 3) = x**2 + 5*x + 6
#面积函数: A = x² + 5x + 6
示例9: 长方体体积计算
变尺寸长方体的体积:
长 = x + 1, 宽 = x + 2, 高 = x + 3
result = polymul(x + 1, x + 2, x + 3)
print(f"(x + 1)(x + 2)(x + 3) = {result}")
print("体积函数: V = x³ + 6x² + 11x + 6")
#(x + 1)(x + 2)(x + 3) = x**3 + 6*x**2 + 11*x + 6
#体积函数: V = x³ + 6x² + 11x + 6
示例10: 圆的面积与环的面积
外圆半径R, 内圆半径r的圆环面积:
圆环面积 = π(R² - r²) = π(R - r)(R + r)
result = polymul(R - r, R + r)
print(f"(R - r)(R + r) = {result}")
print("圆环面积因子: R² - r²")
#(R - r)(R + r) = R**2 - r**2
#圆环面积因子: R² - r²
示例11: 泰勒级数展开
sin(x)的泰勒级数前几项乘积:
sin(x) ≈ x - x³/6 + x⁵/120
计算 sin²(x) 的近似
sin_approx = (x - x**3/6 + x**5/120)
result = polymul(sin_approx, sin_approx)
print(f"sin²(x) ≈ {result}")
#sin²(x) ≈ x**10/14400 - x**8/360 + 2*x**6/45 - x**4/3 + x**2
示例12: 量子力学 - 波函数乘积
一维无限深势阱中波函数的概率密度:
ψ_n(x) = √(2/L) sin(nπx/L)
|ψ_n(x)|² = (2/L) sin²(nπx/L)
psi = sqrt(2/L) * sin(n*pi*x/L)
注意:这里我们只计算sin²部分
sin_part = sin(n*pi*x/L)
result = polymul(sin_part, sin_part)
print(f"sin²(nπx/L) = {result}")
print("概率密度包含 sin²(nπx/L) 项")
#sin²(nπx/L) = sin(pi*n*x/L)**2
#概率密度包含 sin²(nπx/L) 项
示例13: 信号处理 - 滤波器传递函数
两个一阶滤波器的级联:
H(z) = (1 - a₁z⁻¹)(1 - a₂z⁻¹)
result = polymul(1 - a1/z, 1 - a2/z)
print(f"(1 - a₁/z)(1 - a₂/z) = {result}")
print("级联滤波器的传递函数")
#(1 - a₁/z)(1 - a₂/z) = a1*a2/z**2 - a1/z - a2/z + 1
#级联滤波器的传递函数
示例14: 平方差公式
result = polymul(a + b, a - b)
print(f"(a + b)(a - b) = {result}")
print(f"验证: a² - b² = {result}")
#(a + b)(a - b) = a**2 - b**2
#验证: a² - b² = a**2 - b**2
示例15: 完全平方公式
result = polymul(a + b, a + b)
print(f"(a + b)² = {result}")
print(f"验证: a² + 2ab + b² = {result}")
#(a + b)² = a**2 + 2*a*b + b**2
#验证: a² + 2ab + b² = a**2 + 2*a*b + b**2
示例16: 立方和公式
result = polymul(a + b, a**2 - a*b + b**2)
print(f"(a + b)(a² - ab + b²) = {result}")
print(f"验证: a³ + b³ = {result}")
#(a + b)(a² - ab + b²) = a**3 + b**3
#验证: a³ + b³ = a**3 + b**3
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def poly_multivariate_product(input_str):
"""
多变量多项式的polymvp函数,实现多项式乘法,返回乘积多项式的系数列表(降幂排列)。
参数:
input_str (str): 输入字符串,表示多个多项式的元组,例如 "(x^2+1,x+2,x-2)"。
返回:
str: 乘积多项式表达式。
str: 如果输入错误,返回错误信息。
"""
try:
# 使用 sympy 的 sympify 函数将输入字符串转换为 SymPy 表达式,evaluate=False 表示不进行计算
expr = sp.sympify(input_str, evaluate=False)
# 初始化错误标志为 False,表示目前没有错误
error = False
# 初始化结果为 1,用于后续多项式相乘
result = 1
# 检查转换后的表达式是否为元组类型
if isinstance(expr, tuple):
# 遍历元组中的每个元素
for item in expr:
# 将当前元素转换为 SymPy 的多项式对象,并与结果相乘
result *= sp.Poly(item)
else:
# 如果表达式不是元组类型,将错误标志设为 True
error = True
return result.as_expr() if (not error or result != 1) else f"输入错误: {input_str}"
except Exception as e:
return f"Error: {e}"
# 测试示例
if __name__ == "__main__":
# 正常案例
print("单变量多项式:")
print(poly_multivariate_product("(x**2+1,x+2,x-2)"))
# x**4 - 3*x**2 - 4
print("\n多变量多项式:")
print(poly_multivariate_product("(x**2+3*x+4,x+y+2)"))
# x**3 + x**2*y + 5*x**2 + 3*x*y + 10*x + 4*y + 8
多项式次数
polynomialDegree(p)通过vars返回多项式p相对于p中所有变量的次数
polynomialDegree(p,vars)返回p相对于vars中变量的阶数.
p - 多项式,符号表达式.
vars - 多项式变量,符号变量向量.
示例1: 力学中的动能表达式
print("动能表达式的次数:", polynomialDegree(0.5*m*v**2))
#动能表达式的次数: 3
示例2: 量子力学中的波函数
print("波函数多项式的次数:", polynomialDegree(a*x**3 + b*x**2 + c*x + d, [x]))
#波函数多项式的次数: 3
示例3: 经济学中的成本函数
print("成本函数的次数:", polynomialDegree(0.1*q**3 - 2*q**2 + 15*q + 100))
#成本函数的次数: 3
示例4: 电磁学中的电势分布
print("电势分布的次数:", polynomialDegree(k*q1/r + k*q2/(r**2) + k*q3/(r**3)))
#电势分布的次数: 5
示例5: 控制理论中的特征方程
print("特征方程的次数:", polynomialDegree(s**3 + 5*s**2 + 8*s + 6, [s]))
#特征方程的次数: 3
示例6: 几何学中的曲面方程
print("椭球面方程的次数:", polynomialDegree(x**2/a**2 + y**2/b**2 + z**2/c**2 - 1))
#椭球面方程的次数: 4
示例7: 化学反应动力学
print("反应速率方程的总次数:", polynomialDegree(k*A*B**2))
#反应速率方程的总次数: 4
示例8: 流体力学中的速度分布
print("速度剖面的次数:", polynomialDegree(u0 + u1*y + u2*y**2 + u3*y**3, [y]))
#速度剖面的次数: 3
示例9: 光学中的透镜公式
print("透镜公式的次数:", polynomialDegree(1/f - 1/u - 1/v))
#透镜公式的次数: 1
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from sympy import Poly, Symbol, sympify
from ast import literal_eval
def polynomial_of_degree(input_str):
"""
对标 Wolfram 的 PolynomialDegree 函数,计算多项式的最高次数。
参数:
input_str (str): 输入字符串,支持两种格式:
1. 单个多项式表达式 (计算所有变量的总次数)
示例: "3*x**2 + 2*y**3 + 1"
2. 元组 (多项式表达式, 变量列表)
示例: "(3*x**2 + 2*y**3 + 1, ['x', 'y'])"
示例: "(x**2*y + x*y**2, [x, y])"
返回:
int: 多项式的最高次数
str: 错误信息(若输入无效)
"""
try:
# 解析输入字符串
expr = sp.sympify(input_str)
error = False
result = None
# 处理元组输入(多项式 + 变量列表)
if isinstance(expr, tuple) and len(expr) == 2:
# 处理元组输入(多项式 + 变量列表)
poly_expr, variables = expr
if isinstance(variables, list):
sym_vars = variables
elif variables.free_symbols:
sym_vars = [variables]
else:
error = True
poly = sp.poly(poly_expr, *sym_vars)
result = poly.total_degree()
# 处理单个多项式输入(自动检测所有变量)
elif expr.free_symbols:
expr_poly = sp.poly(expr)
result = expr_poly.total_degree()
else:
error = True
return result if not error else f"输入错误: {input_str}"
except SyntaxError:
return "语法错误: 输入字符串格式不正确"
except ValueError as ve:
return f"值错误: {str(ve)}"
except TypeError as te:
return f"类型错误: {str(te)}"
except Exception as e:
return f"未知错误: {str(e)}"
# 示例用法
if __name__ == "__main__":
# 示例1: 计算多变量多项式的总次数
input1 = "3*x**2 + 2*y**3 + 1"
print(f"示例1 输入: {input1}")
print("输出:", polynomial_of_degree(input1))
# 3
# 示例2: 指定变量子集计算次数
input2 = "(x**2*y + x*y**2, [x, y])"
print(f"\n示例2 输入: {input2}")
print("输出:", polynomial_of_degree(input2))
# 3
多项式计算
y = polyval(p,x) 计算多项式 p 在 x 的每个点处的值。参数 p 是长度为 n+1 的向量,其元素是 n 次多项式的系数(降幂排序)
p是多项式系数,指定为向量.
x是查询点,指定为向量.
示例1: 物理学 - 自由落体运动 - 计算不同时间点的位移
位移公式: s(t) = 0.5*g*t² + v₀*t + s₀
假设 g = 9.8 m/s², v₀ = 0, s₀ = 100m
系数: [4.9, 0, 100] 对应 4.9t² + 0t + 100
result1 = polyval([4.9, 0, 100], [0, 1, 2, 3, 4]) # 计算0-4秒的位移
print(f" 结果: {result1} (米)")
print(f" 解释: 物体从100米高度自由落体,4秒后位移为{result1[-1]:.1f}米\n")
#结果: [100, 104.9, 119.6, 144.1, 178.4] (米)
#解释: 物体从100米高度自由落体,4秒后位移为178.4米
示例2: 经济学 - 生产成本分析 - 计算不同产量下的总成本
总成本: C(q) = 0.01q³ - 0.5q² + 10q + 1000
result2 = polyval([0.01, -0.5, 10, 1000], [0, 50, 100, 150, 200])
print(f" 结果: {result2}")
print(f" 解释: 固定成本为{result2[0]},生产200单位总成本为{result2[-1]:.1f}\n")
#结果: [1000, 1500, 7000, 25000, 63000]
#解释: 固定成本为1000,生产200单位总成本为63000.0
示例3: 工程学 - 计算梁在不同位置的挠度
简支梁中点挠度: δ(x) = -x⁴/24 + x³/6 - x²/4 (简化模型)
result3 = polyval([-1/24, 1/6, -1/4, 0, 0], [0, 0.25, 0.5, 0.75, 1.0])
print(f" 结果: {[f'{x:.4f}' for x in result3]}")
print(f" 解释: 梁中点(0.5位置)挠度最大,为{result3[2]:.4f}\n")
#结果: [0, -0.0132, -0.0443, -0.0835, -0.1250]
#解释: 梁中点(0.5位置)挠度最大,为-0.0443
示例4: 化学 - 计算不同温度下的反应速率常数
阿伦尼乌斯方程近似: k(T) = aT² + bT + c
result4 = polyval([0.002, -0.5, 25], [273, 298, 323, 348, 373]) # 温度(K)
print(f" 结果: {[f'{x:.2f}' for x in result4]}")
print(f" 解释: 温度从273K升到373K,反应速率增加约{result4[-1]/result4[0]:.1f}倍\n")
#结果: [37.56, 53.61, 72.16, 93.21, 116.76]
#解释: 温度从273K升到373K,反应速率增加约3.1倍
示例5: 金融学 - 计算不同年份的投资价值
复利近似: A(t) = P(1 + r)ᵗ ≈ P(rt²/2 + rt + 1) (二阶泰勒展开)
principal = 1000 # 本金
rate = 0.08 # 年化收益率8%
result5 = polyval([principal*rate**2/2, principal*rate, principal], [0, 1, 5, 10, 20])
print(f" 结果: {[f'${x:.2f}' for x in result5]}")
print(f" 解释: 1000美元投资20年,预计价值约为${result5[-1]:.2f}\n")
#结果: [$1000, $1083.20, $1480, $2120, $3880]
#解释: 1000美元投资20年,预计价值约为$3880.00
示例6: 气象学 - 计算一天中不同时间的温度
日温度变化: T(h) = -0.5h² + 12h + 10 (h为小时)
result6 = polyval([-0.5, 12, 10], [6, 9, 12, 15, 18, 21]) # 6AM-9PM
print(f" 结果: {[f'{x:.1f}°C' for x in result6]}")
print(f" 解释: 正午12点温度最高,达到{max(result6):.1f}°C\n")
#结果: [64.0°C, 77.5°C, 82.0°C, 77.5°C, 64.0°C, 41.5°C]
#解释: 正午12点温度最高,达到82.0°C
示例7: 电子学 - 计算滤波器在不同频率的响应
二阶低通滤波器: H(f) = 1/(1 + f²) ≈ 1 - f² + f⁴ (近似展开)
result7 = polyval([1, 0, -1, 0, 1], [0, 0.2, 0.4, 0.6, 0.8, 1.0]) # 归一化频率
print(f" 结果: {[f'{x:.3f}' for x in result7]}")
print(f" 解释: 频率为0时响应为1,频率为1时响应为{result7[-1]:.3f}\n")
#结果: [1, 0.962, 0.866, 0.77, 0.77, 1]
#解释: 频率为0时响应为1,频率为1时响应为1.000
示例8: 医学 - 计算服药后不同时间的血药浓度
血药浓度: C(t) = 50e^(-0.1t) ≈ 50 - 5t + 0.25t² (二阶近似)
result8 = polyval([0.25, -5, 50], [0, 2, 4, 6, 8, 10]) # 时间(小时)
print(f" 结果: {[f'{x:.2f} mg/L' for x in result8]}")
print(f" 解释: 初始浓度50mg/L,10小时后降至{result8[-1]:.2f}mg/L\n")
#结果: [50.00 mg/L, 41.00 mg/L, 34.00 mg/L, 29.00 mg/L, 26.00 mg/L, 25.00 mg/L]
#解释: 初始浓度50mg/L,10小时后降至25.00mg/L
示例9: 机械工程 - 计算弹簧振子在不同时间的位置
简谐运动: x(t) = A*cos(ωt) ≈ A(1 - ω²t²/2) (小角度近似)
amplitude = 0.1 # 振幅10cm
omega = 2 # 角频率
result9 = polyval([-amplitude*omega**2/2, 0, amplitude], [0, 0.1, 0.2, 0.3, 0.4])
print(f" 结果: {[f'{x:.4f} m' for x in result9]}")
print(f" 解释: 振子在平衡位置附近振动,最大位移{amplitude}m\n")
#结果: [0.1000 m, 0.0980 m, 0.0920 m, 0.0820 m, 0.0680 m]
#解释: 振子在平衡位置附近振动,最大位移0.1m
示例10: 计算机图形学 - 计算贝塞尔曲线上的点
二次贝塞尔曲线: B(t) = (1-t)²P₀ + 2(1-t)tP₁ + t²P₂
对于x坐标: x(t) = (1-2t+t²)x₀ + (2t-2t²)x₁ + t²x₂
控制点: P₀=(0,0), P₁=(0.5,1), P₂=(1,0) 的x坐标多项式
result10 = polyval([1, -2, 1], [0, 0.25, 0.5, 0.75, 1.0]) # 参数t
print(f" 结果: {[f'{x:.3f}' for x in result10]}")
print(f" 解释: 贝塞尔曲线从x=0开始,到x=1结束,中点x={result10[2]:.3f}")
#结果: [1, 0.562, 0.25, 0.062, 0]
#解释: 贝塞尔曲线从x=0开始,到x=1结束,中点x=0.250
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
def polynomial_value(input_str):
"""
计算多项式在给定点的值,对标MATLAB的polyval函数。
参数:
input_str (str): 输入字符串,表示多项式系数和计算点。格式应为SymPy可解析的元组,
例如:"([3, 0, 1], 2)" 或 "([1, -2], [5, 6])"。
返回:
float/list/str: 计算结果。若输入错误或计算异常,返回错误信息字符串。
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
# 检查表达式是否为元组且长度为2
if isinstance(expr, tuple) and len(expr) == 2:
# 从元组中提取多项式系数部分和计算点部分
c_part, x_part = expr[0], expr[1]
# 使用numpy的poly1d函数根据多项式系数创建多项式对象
p = np.poly1d(c_part)
# 检查计算点部分是否为列表
if isinstance(x_part, list):
# 如果是列表,对列表中的每个元素计算多项式的值
result = [np.polyval(p, item) for item in x_part]
# 检查计算点部分是否为一个数字
elif x_part.is_number:
# 如果是数字,计算该点处多项式的值
result = np.polyval(p, x_part)
else:
# 如果计算点既不是列表也不是数字,标记为输入错误
error = True
else:
# 如果表达式不是长度为2的元组,标记为输入错误
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
# 示例代码
if __name__ == "__main__":
# 示例1:计算多项式 3x² + 1 在x=2处的值
input_str1 = "([3, 0, 1], 2)"
print(f"输入: {input_str1} -> 结果: {polynomial_value(input_str1)}")
# 13
# 示例2:计算多项式 x - 2 在x=5和x=6处的值
input_str2 = "([1, -2], [5, 6])"
print(f"输入: {input_str2} -> 结果: {polynomial_value(input_str2)}")
# [3, 4]
# 示例3:符号输入(符号系数)
input_str3 = "([a, 1], 2)"
print(f"输入: {input_str3} -> 结果: {polynomial_value(input_str3)}")
# 2*a + 1
矩阵多项式计算
Y = polyvalm(p,X) 以矩阵方式返回多项式p的计算值.此计算方式等同于使用多项式p替换矩阵X
p是多项式系数,指定为向量.
x是方阵,指定为矩阵.
示例1: 控制系统 - 系统矩阵的特征多项式计算
计算系统矩阵A的特征多项式: P(A) = A² - tr(A)·A + det(A)·I
A1 = [[2, 1], [1, 2]]
特征多项式: λ² - 4λ + 3,系数为 [1, -4, 3]
result1 = polyvalm([1, -4, 3], [[2, 1], [1, 2]])
print(f" 系统矩阵 A = {A1}")
print(f" 特征多项式 P(λ) = λ² - 4λ + 3")
print(f" 计算结果 P(A):\n{result1}")
#系统矩阵 A = [[2, 1], [1, 2]]
#特征多项式 P(λ) = λ² - 4λ + 3
#计算结果 P(A):
#[[0, 0],
[0, 0]]
#验证: 根据Cayley-Hamilton定理,P(A)应为零矩阵
示例2: 量子力学 - 计算量子演化算符的近似
时间演化算符 U(t) = exp(-iHt/ħ) ≈ I - iHt/ħ - (Ht/ħ)²/2 (二阶近似)
简化哈密顿量 H = [[1, 0], [0, -1]] (泡利Z矩阵)
H = [[1, 0], [0, -1]]
t = 0.1 # 时间
近似: U ≈ I - iHt - (Ht)²/2
注意: 这里我们只计算实数部分,忽略虚数单位i
result2 = polyvalm([-0.5*t**2, -t, 1], H)
print(f" 哈密顿量 H = {H}")
print(f" 时间 t = {t}")
print(f" 演化算符近似 U ≈ I - Ht - (Ht)²/2:")
print(f" 计算结果:\n{result2}")
#哈密顿量 H = [[1, 0], [0, -1]]
#时间 t = 0.1
#演化算符近似 U ≈ I - Ht - (Ht)²/2:
#计算结果:
#[[0.895, 0],
[0, 1.095]]
#应用: 用于量子系统的时间演化模拟
示例3: 计算机图形学 - 计算旋转矩阵的多项式函数
2D旋转矩阵 R(θ) = [[cosθ, -sinθ], [sinθ, cosθ]]
利用恒等式 cos(nθ) = T_n(cosθ) 其中 T_n 是切比雪夫多项式
对于90度旋转: R(π/2) = [[0, -1], [1, 0]]
R = [[0, -1], [1, 0]]
计算 R⁴ = (R²)²,应该等于单位矩阵
result3 = polyvalm([1, 0, 0, 0, 1], [[0, -1], [1, 0]]) # 多项式: x⁴ + 1
print(f" 旋转矩阵 R(90°) = {R}")
print(f" 计算 R⁴ + I (应该等于 2I):")
print(f" 计算结果:\n{result3}")
#旋转矩阵 R(90°) = [[0, -1], [1, 0]]
#计算 R⁴ + I (应该等于 2I):
#计算结果:
#[[2, 0],
[0, 2]]
#验证: R⁴ = I,所以 R⁴ + I = 2I
示例4: 网络分析 - 计算图的连通性矩阵多项式
邻接矩阵A的k次幂(A^k)的(i,j)元素表示从i到j长度为k的路径数
简单图的邻接矩阵
A4 = [[0, 1, 1, 0],
[1, 0, 1, 1],
[1, 1, 0, 1],
[0, 1, 1, 0]]
计算长度为0-3的路径总数: I + A + A² + A³
result4 = polyvalm([1, 1, 1, 1], [[0, 1, 1, 0], [1, 0, 1, 1], [1, 1, 0, 1], [0, 1, 1, 0]])
print(f" 图的邻接矩阵 A = {A4}")
print(f" 计算 I + A + A² + A³ (长度为0-3的路径总数):")
print(f" 计算结果:\n{result4}")
#图的邻接矩阵 A = [[0, 1, 1, 0], [1, 0, 1, 1], [1, 1, 0, 1], [0, 1, 1, 0]]
#计算 I + A + A² + A³ (长度为0-3的路径总数):
#计算结果:
#[[5, 7, 7, 4],
[7, 8, 8, 7],
[7, 8, 8, 7],
[4, 7, 7, 5]]
#解释: 结果矩阵的(i,j)元素表示从节点i到j的长度≤3的路径总数
示例5: 机械工程 - 计算结构系统的柔度矩阵多项式
简化刚度矩阵 K (2自由度系统)
K = [[2, -1], [-1, 2]]
计算柔度矩阵的近似: C ≈ αI + βK + γK²
result5 = polyvalm([0.1, 0.2, 0.05], [[2, -1], [-1, 2]])
print(f" 刚度矩阵 K = {K}")
print(f" 计算柔度矩阵近似 C ≈ 0.1I + 0.2K + 0.05K²:")
print(f" 计算结果:\n{result5}")
#刚度矩阵 K = [[2, -1], [-1, 2]]
#计算柔度矩阵近似 C ≈ 0.1I + 0.2K + 0.05K²:
#计算结果:
#[[0.95, -0.6],
[-0.6, 0.95]]
#应用: 用于结构变形分析
示例6: 经济学 - 投入产出模型的逆矩阵近似
Leontief逆矩阵的近似: (I-A)⁻¹ ≈ I + A + A² + A³ + ...
技术系数矩阵 A
A6 = [[0.2, 0.1, 0.0],
[0.1, 0.3, 0.2],
[0.0, 0.1, 0.2]]
计算三阶近似: I + A + A² + A³
result6 = polyvalm([1, 1, 1, 1], [[0.2, 0.1, 0.0], [0.1, 0.3, 0.2], [0.0, 0.1, 0.2]])
print(f" 技术系数矩阵 A = {A6}")
print(f" Leontief逆矩阵的三阶近似 (I + A + A² + A³):")
print(f" 计算结果:\n{result6}")
#技术系数矩阵 A = [[0.2, 0.1, 0.0], [0.1, 0.3, 0.2], [0.0, 0.1, 0.2]]
#Leontief逆矩阵的三阶近似 (I + A + A² + A³):
#计算结果:
#[[1.265, 0.172, 0.034],
[0.172, 1.471, 0.344],
[0.017, 0.172, 1.282]]
#应用: 用于经济系统的需求分析
示例7: 电网络分析 - 导纳矩阵的多项式函数
简单电路的导纳矩阵
Y = [[2, -1, 0],
[-1, 3, -1],
[0, -1, 2]]
计算阻抗矩阵的近似: Z ≈ Y⁻¹ ≈ αI + βY + γY²
result7 = polyvalm([0.5, -0.3, 0.1], [[2, -1, 0], [-1, 3, -1], [0, -1, 2]])
print(f" 导纳矩阵 Y = {Y}")
print(f" 计算阻抗矩阵近似 Z ≈ 0.5I - 0.3Y + 0.1Y²:")
print(f" 计算结果:\n{result7}")
#导纳矩阵 Y = [[2, -1, 0], [-1, 3, -1], [0, -1, 2]]
#计算阻抗矩阵近似 Z ≈ 0.5I - 0.3Y + 0.1Y²:
#计算结果:
#[[2, -2.2, 0.5],
[-2.2, 4.7, -2.2],
[0.5, -2.2, 2]]
#应用: 用于电路分析和设计
示例8: 机器学习 - 图神经网络中的多项式滤波器
图拉普拉斯矩阵 L
L = [[2, -1, 0, -1],
[-1, 3, -1, -1],
[0, -1, 2, -1],
[-1, -1, -1, 3]]
Chebyshev多项式滤波器: T₀(L) + T₁(L) + T₂(L)
其中 T₀(x)=1, T₁(x)=x, T₂(x)=2x²-1
因此多项式为: 1 + x + (2x²-1) = 2x² + x
result8 = polyvalm([2, 1, 0], [[2, -1, 0, -1], [-1, 3, -1, -1], [0, -1, 2, -1], [-1, -1, -1, 3]])
print(f" 图拉普拉斯矩阵 L = {L}")
print(f" Chebyshev多项式滤波器 T₀(L) + T₁(L) + T₂(L):")
print(f" 计算结果:\n{result8}")
# 图拉普拉斯矩阵 L = [[2, -1, 0, -1], [-1, 3, -1, -1], [0, -1, 2, -1], [-1, -1, -1, 3]]
#Chebyshev多项式滤波器 T₀(L) + T₁(L) + T₂(L):
#计算结果:
#[[14, -9, 4, -9],
[-9, 27, -9, -9],
[4, -9, 14, -9],
[-9, -9, -9, 27]]
#应用: 用于图卷积神经网络的特征提取
示例9: 振动分析 - 质量-弹簧系统的特征值问题
质量矩阵 M 和刚度矩阵 K
M = [[2, 0], [0, 1]]
K = [[3, -1], [-1, 2]]
对于广义特征值问题 Kx = λMx
特征多项式为 det(K - λM) = 0
result9 = polyvalm([1, -2, 1], [[3, -1], [-1, 2]]) # 示例多项式
print(f" 刚度矩阵 K = {K}")
print(f" 质量矩阵 M = {M}")
print(f" 计算矩阵多项式 P(K) = K² - 2K + I:")
print(f" 计算结果:\n{result9}")
#刚度矩阵 K = [[3, -1], [-1, 2]]
#质量矩阵 M = [[2, 0], [0, 1]]
#计算矩阵多项式 P(K) = K² - 2K + I:
#计算结果:
#[[5, -3],
[-3, 2]]
#应用: 用于振动模态分析
示例10: 密码学 - 矩阵幂运算的多项式优化
用于某些密码系统的矩阵
A10 = [[1, 1], [1, 0]]
计算 A¹⁰ 使用多项式方法
result10 = polyvalm([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [[1, 1], [1, 0]]) # x¹⁰
print(f" 基础矩阵 A = {A10}")
print(f" 计算 A¹⁰ 使用多项式方法:")
print(f" 计算结果:\n{result10}")
print(f" 应用: 在公钥密码系统中优化矩阵运算\n")
#基础矩阵 A = [[1, 1], [1, 0]]
#计算 A¹⁰ 使用多项式方法:
#计算结果:
#[[90, 55],
[55, 35]]
#应用: 在公钥密码系统中优化矩阵运算
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def polynomial_val_matrix(input_str):
"""
计算矩阵多项式的值,对标MATLAB的polyvalm函数。
参数:
input_str (str): 输入字符串,格式应为 "([c0, c1, ..., cn], [[m11, m12,...], ...])",
其中系数列表表示多项式,矩阵为方阵。
返回:
SymPy矩阵/str: 计算结果。若输入错误或计算异常,返回错误信息字符串。
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
def eval_poly_matrix(P, A):
"""
核心计算函数:计算矩阵多项式的值 P(A)
参数:
P (sp.Poly): 多项式对象
A (sp.Matrix): 方阵
返回:
sp.Matrix: 计算结果矩阵
"""
# 初始化结果矩阵为同型零矩阵
res = sp.zeros(*A.shape)
# 获取系数列表(从最高次到常数项)并反转,以便从x^0开始处理
coefficients = P.all_coeffs()[::-1]
for power, coeff in enumerate(coefficients):
res += coeff * (A ** power) # 累加每一项:coeff * A^power
return res
# 检查输入是否为包含两个元素的SymPy元组
if isinstance(expr, tuple) and len(expr) == 2:
coeff_part, matrix_part = expr[0], expr[1]
# 处理多项式系数部分
if isinstance(coeff_part, list):
try:
# 将SymPy列表转换为Python浮点数列表
coefficients = [float(c) for c in coeff_part]
except TypeError:
error = True # 包含非数值型系数
else:
error = True # 系数部分不是列表
# 处理矩阵部分
A = sp.Matrix(matrix_part) if isinstance(matrix_part, list) else None
if A is None:
error = True # 矩阵无效或非方阵
elif A.is_square == False:
error = True
if not error:
try:
# 创建多项式对象(例如 [3,0,1] -> 3x² + 1)
poly = sp.Poly(coefficients, sp.symbols('x'))
result = eval_poly_matrix(poly, A)
except Exception as e:
return f"计算错误: {e}"
else:
error = True
else:
error = True # 输入结构不符合要求
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
# 示例代码
if __name__ == "__main__":
# 示例1:计算 3A² + I,其中A = [[1,2],[3,4]]
input_str1 = "([3,0,1],[[1,2],[3,4]])"
A = sp.Matrix([[1, 2], [3, 4]])
print(f"输入: {input_str1}")
print("函数计算结果:\n", polynomial_val_matrix(input_str1))
# Matrix([[22.0000000000000, 30.0000000000000],
# [45.0000000000000, 67.0000000000000]])
多边形顶点角度
Angles = PolygonAngle([(x,y),(x1,y1),(x2,y2)...])计算多边形各顶点内角.
x, y -- 数值,多边形顶点的平面坐标。
示例1: 建筑学 - 房屋平面图角度分析
house_plan = [(0, 0), (10, 0), (10, 8), (8, 8), (8, 12), (0, 12)]
house_angles = PolygonAngle(house_plan)
print(f" 各顶点内角: {[f'{a:.1f}°' for a in house_angles]}")
#各顶点内角: [90.0°, 90.0°, 270.0°, 90.0°, 90.0°, 90.0°]
#应用: 分析建筑结构的稳定性,确保所有角度符合建筑规范
示例2: 机器人导航 - 路径规划中的转角分析
robot_path = [(0, 0), (5, 0), (5, 3), (8, 3), (8, 6), (3, 6)]
path_angles = PolygonAngle(robot_path)
print(f" 路径转角角度: {[f'{a:.1f}°' for a in path_angles]}")
#路径转角角度: [90.0°, 270.0°, 90.0°, 90.0°, 116.6°, 63.4°]
#应用: 规划机器人转向,避免急转弯确保平稳移动
示例3: 地理信息系统 - 地块边界角度测量
land_parcel = [(0, 0), (100, 0), (120, 50), (80, 80), (20, 60)]
parcel_angles = PolygonAngle(land_parcel)
print(f" 边界转角: {[f'{a:.1f}°' for a in parcel_angles]}")
#边界转角: [111.8°, 105.1°, 124.7°, 126.9°, 71.6°]
#应用: 土地测量、产权界定和城市规划
示例4: 计算机图形学 - 3D模型底面多边形
model_base = [(0, 0), (4, 0), (6, 2), (4, 4), (0, 4), (-2, 2)]
base_angles = PolygonAngle(model_base)
print(f" 底面内角: {[f'{a:.1f}°' for a in base_angles]}")
#底面内角: [135.0°, 90.0°, 135.0°, 135.0°, 90.0°, 135.0°]
#应用: 确保3D模型底面适合打印,避免支撑结构问题
示例5: 机械工程 - 机械零件角度检验
machine_part = [(0, 0), (8, 0), (8, 4), (6, 4), (6, 6), (0, 6)]
part_angles = PolygonAngle(machine_part)
print(f" 轮廓角度: {[f'{a:.1f}°' for a in part_angles]}")
#轮廓角度: [90.0°, 90.0°, 270.0°, 90.0°, 90.0°, 90.0°]
#应用: 验证零件设计是否符合制造要求,避免锐角导致应力集中
示例6: 游戏开发 - 碰撞体边界角度
collision_mesh = [(0, 0), (3, 0), (5, 2), (3, 4), (0, 4), (-2, 2)]
mesh_angles = PolygonAngle(collision_mesh)
print(f" 网格角度: {[f'{a:.1f}°' for a in mesh_angles]}")
#网格角度: [135.0°, 90.0°, 135.0°, 135.0°, 90.0°, 135.0°]
#应用: 优化物理引擎中的碰撞检测,提高游戏性能
示例7: 农业规划 - 农田地块角度
farmland = [(0, 0), (200, 0), (250, 150), (150, 200), (0, 100)]
farm_angles = PolygonAngle(farmland)
print(f" 农田角度: {[f'{a:.1f}°' for a in farm_angles]}")
#农田角度: [108.4°, 98.1°, 119.7°, 123.7°, 90.0°]
#应用: 规划灌溉系统和农机作业路径
示例8: 城市规划 - 街区多边形角度
city_block = [(0, 0), (80, 0), (100, 20), (100, 60), (60, 80), (0, 50)]
block_angles = PolygonAngle(city_block)
print(f" 街区角度: {[f'{a:.1f}°' for a in block_angles]}")
#街区角度: [135.0°, 135.0°, 116.6°, 126.9°, 116.6°, 90.0°]
#应用: 优化交通流线,提高城市空间利用率
示例9: 考古学 - 遗址边界角度记录
archeological_site = [(0, 0), (15, 0), (20, 10), (15, 20), (5, 25), (-5, 15)]
site_angles = PolygonAngle(archeological_site)
print(f" 边界角度: {[f'{a:.1f}°' for a in site_angles]}")
#边界角度: [116.6°, 126.9°, 143.1°, 108.4°, 116.6°, 108.4°]
#应用: 记录遗址几何特征,辅助历史建筑复原
示例10: 材料科学 - 晶体结构角度分析
crystal_grain = [(0, 0), (1, 0), (1.5, 0.866), (1, 1.732), (0, 1.732), (-0.5, 0.866)]
crystal_angles = PolygonAngle(crystal_grain)
print(f" 晶界角度: {[f'{a:.1f}°' for a in crystal_angles]}")
#晶界角度: [120.0°, 120.0°, 120.0°, 120.0°, 120.0°, 120.0°]
#应用: 分析材料微观结构,预测材料性能
示例11: 电子工程 - PCB板形状角度
pcb_shape = [(0, 0), (10, 0), (12, 2), (12, 8), (10, 10), (0, 10), (-2, 8), (-2, 2)]
pcb_angles = PolygonAngle(pcb_shape)
print(f" PCB角度: {[f'{a:.1f}°' for a in pcb_angles]}")
#PCB角度: [135.0°, 135.0°, 135.0°, 135.0°, 135.0°, 135.0°, 135.0°, 135.0°]
#应用: 确保电路板形状适合安装,避免锐角导致信号干扰
示例12: 服装设计 - 服装版型角度
garment_pattern = [(0, 0), (4, 0), (5, 3), (4, 6), (0, 6), (-1, 3)]
pattern_angles = PolygonAngle(garment_pattern)
print(f" 版型角度: {[f'{a:.1f}°' for a in pattern_angles]}")
#版型角度: [108.4°, 143.1°, 108.4°, 108.4°, 143.1°, 108.4°]
#应用: 优化服装剪裁,确保穿着舒适性和美观性
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import math
import ast
def polygon_area(points):
"""计算多边形有向面积以判断顶点方向(正数为逆时针,负数为顺时针)"""
area = 0.0
n = len(points)
for i in range(n):
x1, y1 = points[i]
x2, y2 = points[(i + 1) % n]
area += (x2 - x1) * (y2 + y1) # Shoelace公式简化版
return area / 2.0
def vector_angle(v1, v2, is_ccw):
"""计算两个向量间的内角(考虑多边形方向)"""
# 计算向量长度
len1 = math.hypot(*v1)
len2 = math.hypot(*v2)
# 处理零向量
if len1 == 0 or len2 == 0:
return 0.0
# 计算点积和叉积
dot = (v1[0] * v2[0] + v1[1] * v2[1]) / (len1 * len2)
cross = (v1[0] * v2[1] - v1[1] * v2[0]) / (len1 * len2)
# 基础夹角(0~π)
base_angle = math.acos(max(min(dot, 1), -1)) # 防止浮点误差
# 根据叉积符号判断转向
if is_ccw:
return base_angle if cross > 0 else 2 * math.pi - base_angle
else:
return base_angle if cross < 0 else 2 * math.pi - base_angle
def shapely_polygon_angles(input_str):
"""
计算多边形各顶点内角(单位:度)
输入格式示例:[[x1,y1], [x2,y2], ...]
"""
try:
# 输入解析与校验
polygon = ast.literal_eval(input_str)
if not isinstance(polygon, (list, tuple)) or len(polygon) < 3:
return "错误:需要至少3个顶点的列表"
# 转换坐标并拷贝首节点处理环形结构
points = [tuple(map(float, p)) for p in polygon]
points.append(points[0]) # 闭合多边形
# 计算多边形方向
area = polygon_area(points[:-1])
is_ccw = area > 0
# 计算各顶点角度
angles = []
for i in range(len(points) - 1):
# 获取三点坐标
a, b, c = points[i], points[i + 1], points[(i + 2) % (len(points) - 1)]
# 计算向量
v_prev = (a[0] - b[0], a[1] - b[1]) # BA向量
v_next = (c[0] - b[0], c[1] - b[1]) # BC向量
# 计算带方向的内角
angle = vector_angle(v_prev, v_next, is_ccw)
angles.append(math.degrees(angle))
return angles
except Exception as e:
return f"错误: {str(e)}"
# 示例测试
if __name__ == "__main__":
# 案例1:正六边形(逆时针)
hexagon = [[1, 0], [0.5, 0.866], [-0.5, 0.866],
[-1, 0], [-0.5, -0.866], [0.5, -0.866]]
print("正六边形角度:", shapely_polygon_angles(str(hexagon)))
# [120.00072778082736, 120.00072778082736, 119.99854443834525, 120.00072778082736, 120.00072778082736, 119.99854443834525]
# 案例2:凹多边形(星形)
star = [(0, 0), (2, 3), (5, 0), (2, -3), (-1, 0)]
print("\n凹多边形角度:", shapely_polygon_angles(str(star)))
# [78.69006752597979, 90.0, 90.0, 45.00000000000001, 236.30993247402026]
多边形的面积
PolygonArea([[x1,y1], [x2,y2], ..., [xn,yn]])返回多边形的面积。
示例1: 房地产 - 计算房屋占地面积
house_lot = [(0, 0), (15, 0), (15, 10), (10, 10), (10, 20), (0, 20)]
house_area = PolygonArea(house_lot)
print(f" 占地面积: {house_area} 平方米")
#占地面积: 250.0 平方米
#应用: 房产评估、土地交易和建筑规划
示例2: 农业 - 计算农田面积
farmland = [(0, 0), (200, 0), (180, 150), (50, 180), (-20, 100)]
farm_area = PolygonArea(farmland)
print(f" 农田面积: {farm_area} 平方米")
print(f" 换算为亩: {farm_area / 666.67:.2f} 亩")
#农田面积: 31750.0 平方米
#换算为亩: 47.62 亩
#应用: 农作物产量估算、灌溉系统设计和补贴申请
示例3: 城市规划 - 计算公园绿地面积
park_boundary = [(0, 0), (100, 0), (120, 80), (80, 120), (20, 100), (-10, 60)]
park_area = PolygonArea(park_boundary)
print(f" 公园面积: {park_area} 平方米")
#公园面积: 11900.0 平方米
#应用: 城市绿化率计算、公园设施规划和维护预算
示例4: 工业工程 - 计算工厂车间面积
factory_floor = [(0, 0), (50, 0), (50, 30), (40, 30), (40, 20), (10, 20), (10, 30), (0, 30)]
factory_area = PolygonArea(factory_floor)
print(f" 车间面积: {factory_area} 平方米")
#车间面积: 1200.0 平方米
#应用: 生产线布局、设备安置和空间利用率分析
示例5: 地理学 - 计算湖泊表面积
lake_shape = [(0, 0), (3, 1), (5, 3), (4, 6), (1, 7), (-2, 5), (-2, 2)]
lake_area = PolygonArea(lake_shape)
print(f" 湖泊面积: {lake_area} 平方单位")
#湖泊面积: 34.5 平方单位
#应用: 水资源管理、生态环境研究和洪水预测
示例6: 建筑学 - 计算不规则屋顶面积
roof_polygon = [(0, 0), (12, 0), (10, 4), (12, 8), (8, 10), (4, 10), (2, 8), (0, 4)]
roof_area = PolygonArea(roof_polygon)
print(f" 屋顶面积: {roof_area} 平方米")
#屋顶面积: 98.0 平方米
#应用: 建筑材料估算、太阳能板安装和防水处理
示例7: 考古学 - 考古遗址保护区域面积
archaeological_site = [(0, 0), (80, 0), (100, 40), (80, 80), (20, 100), (-20, 60)]
site_area = PolygonArea(archaeological_site)
print(f" 保护区域面积: {site_area} 平方米")
#保护区域面积: 8800.0 平方米
#应用: 遗址保护规划、发掘区域划分和文化遗产管理
示例8: 体育场设计 - 计算运动场地面积
sports_field = [(0, 0), (100, 0), (110, 50), (100, 100), (0, 100), (-10, 50)]
field_area = PolygonArea(sports_field)
print(f" 场地面积: {field_area} 平方米")
#场地面积: 11000.0 平方米
#应用: 场地规划、草坪维护和观众席位设计
示例9: 林业 - 计算森林地块面积
forest_plot = [(0, 0), (150, 0), (180, 120), (120, 200), (30, 180), (-20, 100)]
forest_area = PolygonArea(forest_plot)
print(f" 森林面积: {forest_area} 平方米")
print(f" 换算为公顷: {forest_area / 10000:.2f} 公顷")
#森林面积: 30900.0 平方米
#换算为公顷: 3.09 公顷
#应用: 木材产量估算、生态保护和碳汇计算
示例10: 海洋学 - 计算海湾面积
bay_area_points = [(0, 0), (5, 0), (8, 3), (7, 6), (4, 8), (0, 5), (-2, 3)]
bay_area = PolygonArea(bay_area_points)
print(f" 海湾面积: {bay_area} 平方千米")
#海湾面积: 52.0 平方千米
#应用: 潮汐研究、航运规划和海洋生态保护
示例11: 灾害管理 - 计算洪水淹没区域
flood_zone = [(0, 0), (2, 0), (3, 1), (3, 3), (2, 4), (0, 3), (-1, 2)]
flood_area = PolygonArea(flood_zone)
print(f" 淹没面积: {flood_area} 平方千米")
#淹没面积: 11.5 平方千米
#应用: 灾害评估、应急响应和保险理赔
示例12: 商业规划 - 计算购物中心租赁面积
mall_space = [(0, 0), (30, 0), (30, 20), (25, 20), (25, 25), (15, 25), (15, 20), (0, 20)]
mall_area = PolygonArea(mall_space)
print(f" 可租赁面积: {mall_area} 平方米")
#可租赁面积: 650.0 平方米
#应用: 租金计算、商铺布局和商业价值评估
示例13: 军事 - 计算军事基地安全区域
military_base = [(0, 0), (500, 0), (600, 300), (400, 500), (100, 400), (-50, 200)]
base_area = PolygonArea(military_base)
print(f" 安全区域面积: {base_area} 平方米")
#安全区域面积: 240000.0 平方米
#应用: 安全防护、设施布局和防御规划
示例14: 环境科学 - 湿地保护区面积计算
wetland = [(0, 0), (3, 0), (4, 2), (3, 4), (1, 5), (-1, 3), (-1, 1)]
wetland_area = PolygonArea(wetland)
print(f" 湿地面积: {wetland_area} 平方千米")
#湿地面积: 18.5 平方千米
#应用: 生态保护、生物多样性研究和环境监测
示例15: 室内设计 - 计算房间地板面积
room_layout = [(0, 0), (5, 0), (5, 4), (4, 4), (4, 6), (0, 6)]
room_area = PolygonArea(room_layout)
print(f" 房间面积: {room_area} 平方米")
#房间面积: 28.0 平方米
#应用: 地板材料购买、家具布置和装修预算
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import ast
import shapely.geometry as sh
def shapely_polygon_area(input_str):
"""
计算多边形的面积,对标Wolfram的PolygonArea函数。
参数:
input_str (str): 表示多边形顶点列表的字符串,格式应为[[x1,y1], [x2,y2], ..., [xn,yn]]或类似结构。
返回:
float/str: 计算成功返回面积(浮点数),否则返回错误信息字符串。
示例:
>>> shapely_polygon_area("[[0,0], [0,1], [1,1]]")
0.5
>>> shapely_polygon_area("[(0,0), (1,0), (1,1), (0,1)]")
1.0
"""
try:
# 解析输入字符串为Python对象(列表或元组)
vertices = ast.literal_eval(input_str)
# 检查输入是否为顶点集合
if not isinstance(vertices, (list, tuple)):
return f"输入错误: 需要顶点列表,例如 [[0,0], [0,1], [1,1]],当前输入类型为 {type(vertices).__name__}"
# 验证每个顶点的格式
for i, point in enumerate(vertices):
# 检查是否为二维坐标
if not isinstance(point, (list, tuple)) or len(point) != 2:
return f"顶点格式错误: 第{i + 1}个顶点{point}应为包含两个数值的列表/元组"
# 检查坐标值是否为数字
try:
x, y = float(point[0]), float(point[1])
except (TypeError, ValueError):
return f"坐标值错误: 第{i + 1}个顶点{point}包含非数值类型"
# 创建多边形并计算面积
polygon = sh.Polygon(vertices)
return abs(polygon.area) # 返回绝对值以保持与Wolfram一致
except (SyntaxError, ValueError) as e:
return f"解析错误: 输入格式无效 - {str(e)}"
except Exception as e:
return f"计算错误: {str(e)}"
# 示例测试
if __name__ == "__main__":
test_cases = [
("[[0,0], [0,1], [1,1]]"),
# 0.5
("[(0,0), (1,0), (1,1), (0,1)]"),
# 1.0
("[[0,0], [0,2], [2,2], [2,0]]"),
# 4.0
]
for input_str in test_cases:
result = shapely_polygon_area(input_str)
print(f"输入: {input_str}")
print(f"实际: {result}\n")
两个几何体的差异面积
PolygonDiffArea(A, B, type)返回两个多边形AB的交集面积。
type为不同的交集面积:
0 -- A-B的差集面积
1 -- A∩B的交集面积
2 -- AΔB的对称差面积
3 -- A∪B的并集面积
示例1: 城市规划 - 计算可用建筑用地面积
total_land = [(0, 0), (100, 0), (100, 80), (0, 80)] # 总地块
protected_zone = [(20, 20), (80, 20), (80, 60), (20, 60)] # 保护区
result1 = PolygonDiffArea(total_land, protected_zone, 0) # 差集:总地块 - 保护区
print(f" 可用建筑用地面积: {result1} 平方米")
#可用建筑用地面积: 5600.0 平方米
#应用: 城市规划中确定可开发区域
示例2: 农业 - 计算灌溉重叠区域
sprinkler1 = [(0, 0), (0, 30), (30, 30), (30, 0)] # 喷灌机1覆盖范围
sprinkler2 = [(15, 15), (15, 45), (45, 45), (45, 15)] # 喷灌机2覆盖范围
result2 = PolygonDiffArea(sprinkler1, sprinkler2, 1) # 交集:重叠灌溉区域
print(f" 重叠灌溉面积: {result2} 平方米")
#重叠灌溉面积: 225.0 平方米
#应用: 优化灌溉系统布局,避免水资源浪费
示例3: 环境保护 - 计算生态保护区变化
old_reserve = [(0, 0), (50, 0), (50, 40), (0, 40)] # 原有保护区
new_reserve = [(10, 10), (60, 10), (60, 50), (10, 50)] # 新规划保护区
result3 = PolygonDiffArea(new_reserve, old_reserve, 2) # 对称差:新增+减少区域
print(f" 保护区变化面积: {result3} 平方米")
#保护区变化面积: 1600.0 平方米
#应用: 评估生态保护政策的效果
示例4: 房地产 - 计算合并地块总面积
plot_a = [(0, 0), (30, 0), (30, 20), (0, 20)] # 地块A
plot_b = [(30, 0), (50, 0), (50, 20), (30, 20)] # 地块B
result4 = PolygonDiffArea(plot_a, plot_b, 3) # 并集:合并后总面积
print(f" 合并后总面积: {result4} 平方米")
#合并后总面积: 1000.0 平方米
#应用: 房地产开发中的土地整合
示例5: 工业安全 - 计算危险区域隔离面积
factory_area = [(0, 0), (100, 0), (100, 80), (0, 80)] # 工厂区域
danger_zone = [(20, 20), (60, 20), (60, 60), (20, 60)] # 危险区域
result5 = PolygonDiffArea(factory_area, danger_zone, 0) # 差集:安全作业区域
print(f" 安全作业面积: {result5} 平方米")
#安全作业面积: 6400.0 平方米
#应用: 制定工业安全规程和疏散路线
示例6: 水资源管理 - 计算水库淹没区
valley_area = [(0, 0), (200, 0), (200, 100), (0, 100)] # 山谷区域
residential_area = [(50, 20), (150, 20), (150, 60), (50, 60)] # 居民区
result6 = PolygonDiffArea(valley_area, residential_area, 1) # 交集:将被淹没的居民区
print(f" 将被淹没的居民区面积: {result6} 平方米")
#将被淹没的居民区面积: 4000.0 平方米
#应用: 水库建设规划和居民搬迁补偿
示例7: 交通规划 - 计算道路扩建影响
old_road = [(0, 45), (100, 45), (100, 55), (0, 55)] # 原有道路
new_road = [(0, 40), (100, 40), (100, 60), (0, 60)] # 扩建后道路
result7 = PolygonDiffArea(new_road, old_road, 0) # 差集:新增道路面积
print(f" 新增道路面积: {result7} 平方米")
#新增道路面积: 1000.0 平方米
#应用: 道路扩建工程规划和征地补偿
示例8: 商业分析 - 计算商圈重叠区域
mall_a_coverage = [(0, 0), (0, 50), (50, 50), (50, 0)] # 商场A辐射范围
mall_b_coverage = [(30, 30), (30, 80), (80, 80), (80, 30)] # 商场B辐射范围
result8 = PolygonDiffArea(mall_a_coverage, mall_b_coverage}, 1) # 交集:重叠客户区域
print(f" 重叠客户区域面积: {result8} 平方公里")
#重叠客户区域面积: 400.0 平方公里
#应用: 商业竞争分析和市场定位
示例9: 林业管理 - 可持续采伐规划
forest_area = [(0, 0), (100, 0), (100, 100), (0, 100)] # 森林总面积
protected_trees = [(20, 20), (80, 20), (80, 80), (20, 80)] # 保护树木区域
result9 = PolygonDiffArea(forest_area, protected_trees, 0) # 差集:可采伐区域
print(f" 可采伐区域面积: {result9} 公顷")
#可采伐区域面积: 6400.0 公顷
#应用: 可持续林业管理和采伐许可
示例10: 军事防御 - 计算雷达覆盖盲区
radar_coverage = [(0, 0), (0, 100), (100, 100), (100, 0)] # 雷达覆盖范围
terrain_block = [(30, 30), (70, 30), (70, 70), (30, 70)] # 地形阻挡区域
result10 = PolygonDiffArea(radar_coverage, terrain_block, 0) # 差集:有效覆盖区域
print(f" 有效覆盖面积: {result10} 平方公里")
#有效覆盖面积: 8400.0 平方公里
#应用: 军事防御系统部署和盲区补偿
示例11: 灾害管理 - 计算安全疏散区域
city_area = [(0, 0), (100, 0), (100, 80), (0, 80)] # 城市区域
flood_risk = [(20, 20), (80, 20), (80, 50), (20, 50)] # 洪水风险区域
result11 = PolygonDiffArea(city_area, flood_risk, 0) # 差集:安全区域
print(f" 安全疏散区域面积: {result11} 平方公里")
#安全疏散区域面积: 6200.0 平方公里
#应用: 灾害应急规划和疏散路线设计
示例12: 考古学 - 计算发掘区域重叠
site_boundary = [(0, 0), (50, 0), (50, 40), (0, 40)] # 遗址边界
previous_digs = [(10, 10), (30, 10), (30, 30), (10, 30)] # 已发掘区域
result12 = PolygonDiffArea(site_boundary, previous_digs, 0) # 差集:未发掘区域
print(f" 未发掘区域面积: {result12} 平方米")
#未发掘区域面积: 1600.0 平方米
#应用: 考古工作计划和资源分配
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import ast
import shapely.geometry as sh
from shapely.errors import TopologicalError
def shapely_difference_area(input_str):
"""
计算两个几何图形的指定操作面积(支持点/线/多边形)
参数:
input_str (str): 格式为 "([[x1,y1],...], [[x1,y1],...], 操作码)" 的字符串,其中操作码:
0 -> A-B的差集面积
1 -> A∩B的交集面积
2 -> AΔB的对称差面积
3 -> A∪B的并集面积
返回:
float/str: 成功返回面积值,失败返回错误描述
示例:
>>> shapely_difference_area('([[0,0],[0,1],[1,1]], [[0.5,0.5],[0.5,1.5],[1.5,1.5]], 0)')
0.25
"""
try:
# 解析输入字符串
data = ast.literal_eval(input_str)
# 验证输入结构
if not (isinstance(data, tuple) and len(data) == 3):
return "输入格式错误:需要三元组 (几何体A, 几何体B, 操作码)"
a_points, b_points, operation = data
operation = int(operation) # 确保操作码是整数
# 定义几何体构建函数
def build_geometry(points):
"""将顶点列表转换为Shapely几何对象"""
if not isinstance(points, (list, tuple)):
raise ValueError("顶点数据必须是列表/元组")
# 验证单个几何体的顶点数据
if len(points) == 0:
raise ValueError("空几何体")
for i, p in enumerate(points):
if not isinstance(p, (list, tuple)) or len(p) != 2:
raise ValueError(f"顶点{i}格式错误:{p}")
try:
float(p[0]), float(p[1])
except ValueError:
raise ValueError(f"顶点{i}包含非数值坐标:{p}")
# 根据顶点数量创建几何对象
if len(points) == 1:
return sh.Point(points[0])
elif len(points) == 2:
return sh.LineString(points)
else:
return sh.Polygon(points)
# 创建几何对象
try:
a = build_geometry(a_points)
b = build_geometry(b_points)
except ValueError as e:
return f"几何体错误:{str(e)}"
# 执行几何操作
try:
if operation == 0:
result = a.difference(b)
elif operation == 1:
result = a.intersection(b)
elif operation == 2:
result = a.symmetric_difference(b)
elif operation == 3:
result = a.union(b)
else:
return f"操作码错误:支持0-3,当前是{operation}"
except TopologicalError:
return "几何操作失败:请检查几何体有效性"
return abs(result.area) # 返回绝对值保持结果稳定
except (SyntaxError, ValueError) as e:
return f"解析错误:{str(e)}"
except Exception as e:
return f"未知错误:{str(e)}"
# 测试案例
if __name__ == "__main__":
tests = [
# 有效输入测试
('([[0,0],[0,1],[1,1]], [[0.5,0.5],[0.5,1.5],[1.5,1.5]], 0)'),
# 0.375
('([(0,0),(1,1)], [[0,0],[0,1],[1,0]], 1)'),
# 0.0
('([[0,0],[0,2],[2,2],[2,0]], [[1,1],[1,3],[3,3]], 2)'),
# 5.0
('([[0,0],[0,1],[1,1]], [[0.5,0],[0.5,1],[1.5,1]], 3)'),
# 0.875
]
for input_str in tests:
print(f"输入: {input_str}")
result = shapely_difference_area(input_str)
print(f"实际: {result}\n")
多边形的周长
PolygonLength(A)返回多边形A的周长
示例1. 建筑地块测量
building_lot = [(0,0), (0,50), (30,50), (30,0)] # 30x50米的地块
result = PolygonLength(building_lot)
print(f"矩形地块周长: {result} 米") # 160.0米
#矩形地块周长: 160.0 米
示例2. 农田边界计算
farmland = [(0,0), (100,0), (120,50), (80,80), (20,60)] # 不规则农田
result = PolygonLength(farmland)
print(f"农田围栏长度: {result} 米")
#农田围栏长度: 330.3427544780802 米
示例3. 城市规划 - 公园边界
park_boundary = [(0,0), (0,200), (150,200), (180,150), (150,100), (180,50), (150,0)]
result = PolygonLength(park_boundary)
print(f"公园围墙长度: {result} 米")
#公园围墙长度: 733.2380757938121 米
示例4. 湖泊海岸线测量
lake_shoreline = [(0,0), (-20,30), (-10,60), (20,80), (60,70), (80,40), (60,10), (30,0)]
result = PolygonLength(lake_shoreline)
print(f"湖泊岸线长度: {result} 米")
#湖泊岸线长度: 278.69866047810376 米
示例5. 运动场地划线
basketball_court = [(0,0), (0,28), (15,28), (15,0)] # 标准篮球场15x28米
result = PolygonLength(basketball_court)
print(f"篮球场边界线长度: {result} 米") # 86.0米
#篮球场边界线长度: 86.0 米
示例6. 工业园区地块
industrial_zone = [(0,0), (0,300), (200,300), (200,100), (150,100), (150,0)]
result = PolygonLength(industrial_zone)
print(f"工业园围栏长度: {result} 米")
#工业园围栏长度: 1000.0 米
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import ast
import shapely.geometry as sh
from shapely.errors import TopologicalError
def shapely_polygon_length(input_str):
"""
计算多边形的周长。
参数:
input_str (str): 表示多边形顶点的字符串,格式应为列表,例如 "[(0,0), (0,1), (1,1)]"。
返回:
float/str: 成功时返回多边形周长,失败时返回错误信息字符串。
示例:
>>> shapely_polygon_length("[(0,0), (0,1), (1,1)]")
3.414213562373095
"""
try:
# 将输入字符串转换为Python列表
coords = ast.literal_eval(input_str)
# 验证输入格式
if not (isinstance(coords, list) and
all(isinstance(p, (tuple, list)) and len(p) == 2 for p in coords)):
return f"输入格式错误: 需要二维坐标点列表,例如 [(x1,y1), (x2,y2), ...]"
# 创建多边形对象(Shapely会自动闭合多边形)
polygon = sh.Polygon(coords)
# 返回计算后的周长
return polygon.length
except (SyntaxError, ValueError) as e:
# 处理格式解析错误
return f"输入解析错误: {str(e)}"
except TopologicalError as e:
# 处理无效几何图形(如自相交)
return f"几何错误: {str(e)}"
except Exception as e:
# 处理其他未知错误
return f"计算错误: {str(e)}"
# ----------------------
# 示例测试代码
# ----------------------
if __name__ == "__main__":
# 有效输入测试
test_cases = [
("三角形", "[(0,0), (0,1), (1,1)]"),
# 3.414213562373095
("正方形", "[(0,0), (0,1), (1,1), (1,0)]"),
# 4.0
("五边形", "[(0,0), (1,0), (2,1), (1,2), (0,1)]")
# 6.242640687119285
]
for name, input_str in test_cases:
result = shapely_polygon_length(input_str)
print(f"输入: {input_str}")
print(f"输出: {result}\n")
多项式的商和余数
q, r = polydiv(f,g)返回分子f和分母g多项式相除的商和余数.分子和分母都应该是多项式函数.返回的结果是一个列表,其中第一项为商,第二项为余数.
f, g -- 输入, 符号表达式
示例1. 控制系统分析 - 传递函数简化
control_system = (s**3 + 2*s**2 + 2*s + 1, s**2 + s + 1)
result = polydiv(control_system)
print(f"传递函数分解: {control_system}")
print(f"结果: {result}\n") # (s + 1, 0)
#传递函数分解: (s**3 + 2*s**2 + 2*s + 1, s**2 + s + 1)
#结果: (s + 1, 0)
示例2. 信号处理 - 滤波器设计
filter_design = (z**4 - 1.8*z**3 + 1.2*z**2 - 0.4*z + 0.05, z**2 - 0.9*z + 0.2)
result = polydiv(filter_design)
print(f"滤波器分解: {filter_design}")
print(f"结果: {result}\n")
#滤波器分解: (z**4 - 1.8*z**3 + 1.2*z**2 - 0.4*z + 0.05, z**2 - 0.9*z + 0.2)
#结果: (1.0*z**2 - 0.9*z + 0.19, 0.012 - 0.049*z)
示例3. 电路分析 - 阻抗计算
circuit_analysis = (s**3 + 5*s**2 + 8*s + 4, s**2 + 3*s + 2)
result = polydiv(circuit_analysis)
print(f"电路阻抗分解: {circuit_analysis}")
print(f"结果: {result}\n") # (s + 2, 0)
#电路阻抗分解: (s**3 + 5*s**2 + 8*s + 4, s**2 + 3*s + 2)
#结果: (s + 2, 0)
示例4. 机械振动 - 特征方程分析
vibration_analysis = (m*s**4 + c*s**3 + k*s**2, s**2 + 2*ζ*ω*s + ω**2)
result = polydiv(vibration_analysis)
print(f"振动系统分解: {vibration_analysis}")
print(f"结果: {result}\n")
#振动系统分解: (m*s**4 + c*s**3 + k*s**2, s**2 + 2*ζ*ω*s + ω**2)
#结果: (c*s - 2*c*ζ*ω + k + m*s**2 - 2*m*s*ζ*ω + 4*m*ζ**2*ω**2 - m*ω**2,
4*c*s*ζ**2*ω**2 - c*s*ω**2 + 2*c*ζ*ω**3 - 2*k*s*ζ*ω - k*ω**2 - 8*m*s*ζ**3*ω**3 + 4*m*s*ζ*ω**3 - 4*m*ζ**2*ω**4 + m*ω**4)
示例5. 多项式因式分解验证
factorization_test = (x**3 - 6*x**2 + 11*x - 6, x - 1)
result = polydiv(factorization_test)
print(f"因式验证: {factorization_test}")
print(f"结果: {result}\n")
#因式验证: (x**3 - 6*x**2 + 11*x - 6, x - 1)
#结果: (x**2 - 5*x + 6, 0)
示例6. 有限域多项式运算
finite_field = (x**5 + x**3 + 1, x**2 + x + 1)
result = polydiv(finite_field)
print(f"有限域除法: {finite_field}")
print(f"结果: {result}\n")
#有限域除法: (x**5 + x**3 + 1, x**2 + x + 1)
#结果: (x**3 - x**2 + x, 1 - x)
示例7. 欧几里得算法步骤
euclidean_step = (x**4 - 1, x**3 - x**2 + x - 1)
result = polydiv(euclidean_step)
print(f"欧几里得算法: {euclidean_step}")
print(f"结果: {result}\n")
#欧几里得算法: (x**4 - 1, x**3 - x**2 + x - 1)
#结果: (x + 1, 0)
示例8. 错误校正编码 - Reed-Solomon码
error_correction = (x**6 + 3*x**5 + 2*x**4 + x**3, x**2 + x + 1)
result = polydiv(error_correction)
print(f"编码多项式: {error_correction}")
print(f"结果: {result}\n")
#编码多项式: (x**6 + 3*x**5 + 2*x**4 + x**3, x**2 + x + 1)
#结果: (x**4 + 2*x**3 - x**2 + 1, -x - 1)
示例9. 密码学 - 多项式哈希
crypto_hash = (a*x**3 + b*x**2 + c*x + d, x - p)
result = polydiv(crypto_hash)
print(f"哈希构造: {crypto_hash}")
print(f"结果: {result}\n")
#哈希构造: (a*x**3 + b*x**2 + c*x + d, x - p)
#结果: (a*p**2 + a*p*x + a*x**2 + b*p + b*x + c, a*p**3 + b*p**2 + c*p + d)
示例10. 计算机图形学 - 贝塞尔曲线分解
bezier_curve = (t**3 - 3*t**2 + 3*t - 1, t - 1)
result = polydiv(bezier_curve)
print(f"曲线参数化: {bezier_curve}")
print(f"结果: {result}\n") # (t**2 - 2*t + 1, 0)
#曲线参数化: (t**3 - 3*t**2 + 3*t - 1, t - 1)
#结果: (t**2 - 2*t + 1, 0)
示例11. 量子力学 - 波函数分析
quantum_oscillator = (x**4 - 6*x**2 + 3, x**2 - 1)
result = polydiv(quantum_oscillator)
print(f"谐振子分解: {quantum_oscillator}")
print(f"结果: {result}\n")
#谐振子分解: (x**4 - 6*x**2 + 3, x**2 - 1)
#结果: (x**2 - 5, -2)
示例12. 热力学 - 范德瓦尔斯方程分析
vanderwaals = (P*V**3 - (P*b + R*T)*V**2 + a*V - a*b, V - b)
result = polydiv(vanderwaals)
print(f"状态方程: {vanderwaals}")
print(f"结果: {result}\n")
#状态方程: (P*V**3 - (P*b + R*T)*V**2 + a*V - a*b, V - b)
#结果: (a, P*V**3 - P*V**2*b - R*T*V**2)
示例13. 经济学 - 成本收益分析
economic_model = (0.1*x**3 - 2*x**2 + 15*x + 100, x - 10)
result = polydiv(economic_model)
print(f"经济模型: {economic_model}")
print(f"结果: {result}\n")
#经济模型: (0.1*x**3 - 2*x**2 + 15*x + 100, x - 10)
#结果: (0.1*x**2 - 1.0*x + 5.0, 150.0)
示例14. 金融工程 - 期权定价
option_pricing = (σ**2*x**2 + μ*x - r, x - x0)
result = polydiv(option_pricing)
print(f"定价模型: {option_pricing}")
print(f"结果: {result}\n")
#定价模型: (σ**2*x**2 + μ*x - r, x - x0)
#结果: (0, -r + x**2*σ**2 + x*μ)
示例15. 数学教育 - 多项式除法教学
teaching_example = (3*x**4 - 4*x**3 + 2*x**2 - 5*x + 1, x - 2)
result = polydiv(teaching_example)
print(f"教学示例: {teaching_example}")
print(f"结果: {result}\n")
#教学示例: (3*x**4 - 4*x**3 + 2*x**2 - 5*x + 1, x - 2)
#结果: (3*x**3 + 2*x**2 + 6*x + 7, 15)
示例16. 科学研究 - 实验数据多项式拟合
data_fitting = (2.5*x**3 - 1.8*x**2 + 0.9*x - 0.2, x - 0.5)
result = polydiv(data_fitting)
print(f"数据拟合: {data_fitting}")
print(f"结果: {result}\n")
#数据拟合: (2.5*x**3 - 1.8*x**2 + 0.9*x - 0.2, x - 0.5)
#结果: (2.5*x**2 - 0.55*x + 0.625, 0.1125)
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def polynomial_division(input_str):
"""
执行多项式长除法运算
参数:
input_str (str): 表示多项式对的字符串,格式为"(被除式, 除式)",例如:"(x**2 + 1, x - 1)"
返回:
tuple/str: 成功时返回(商, 余式)元组,失败时返回错误信息字符串
示例:
>>> polynomial_division("(x**3 - 1, x - 1)")
(x**2 + x + 1, 0)
>>> polynomial_division("(2*x**4 + 3*x, x**2 + 1)")
(2*x**2 - 2, 3*x + 2)
"""
try:
# 解析输入表达式
expr = sp.sympify(input_str, evaluate=False)
# 验证输入格式
if not (isinstance(expr, tuple) and len(expr) == 2):
return f"输入格式错误: 需要包含两个多项式的元组,例如 (被除式, 除式)"
# 转换为多项式对象
dividend = sp.Poly(expr[0])
divisor = sp.Poly(expr[1])
# 检查除数有效性
if divisor.degree() < 0:
return "错误: 除式不能为零多项式"
# 执行多项式除法
quotient, remainder = dividend.div(divisor)
# 转换为标准表达式形式返回
return (quotient.as_expr(), remainder.as_expr())
except sp.SympifyError:
return f"表达式解析失败: 请检查输入格式是否正确"
except sp.PolynomialError as pe:
return f"多项式错误: {str(pe)}"
except Exception as e:
return f"未知错误: {str(e)}"
# ----------------------
# 示例测试代码
# ----------------------
if __name__ == "__main__":
# 有效输入测试
x = sp.symbols('x')
test_cases = [
("一次式相除", "(x**2 - 1, x - 1)"),
# (x + 1, 0)
("高次式相除", "(x**5 + 1, x**2 + 1)"),
# (x**3 - x, x + 1)
("带余数情况", "(2*x**3 + 3*x + 1, x**2 + 1)"),
# (2*x, x + 1)
("低次除高次", "(x + 1, x**2 + 1)")
# (0, x + 1)
]
for name, input_str in test_cases:
print(f"{name}测试:")
result = polynomial_division(input_str)
if isinstance(result, tuple):
print(f"结果: {result}\n")
else:
print(f"错误结果: {result}\n")
多项式的最大公约数
p = polygcd(a,b)返回a,b两个表达式之间的最大公约数
a, b -- 输入, 符号表达式
示例1. 分数简化 - 有理函数化简
rational_function = (x**2 - 1, x**3 - x**2 - x + 1)
result = polygcd(rational_function)
print(f"有理函数分子分母GCD: {rational_function}")
print(f"GCD结果: {result}\n")
#有理函数分子分母GCD: (x**2 - 1, x**3 - x**2 - x + 1)
#GCD结果: x**2 - 1
示例2. 多项式因式分解辅助
factorization = (x**4 - 16, x**3 - 2*x**2 - 4*x + 8)
result = polygcd(factorization)
print(f"多项式公共因式: {factorization}")
print(f"GCD结果: {result}\n") # x - 2
#多项式公共因式: (x**4 - 16, x**3 - 2*x**2 - 4*x + 8)
#GCD结果: x**2 - 4
示例3. 线性代数 - 矩阵特征多项式分析
characteristic_poly = (x**3 - 6*x**2 + 11*x - 6, x**2 - 5*x + 6)
result = polygcd(characteristic_poly)
print(f"特征多项式GCD: {characteristic_poly}")
print(f"GCD结果: {result}\n") # x - 2
#特征多项式GCD: (x**3 - 6*x**2 + 11*x - 6, x**2 - 5*x + 6)
#GCD结果: x**2 - 5*x + 6
示例4. 数论应用 - 多项式环中的理想生成
polynomial_ring = (x**5 + x**3 + x + 1, x**4 + x**2 + 1)
result = polygcd(polynomial_ring)
print(f"多项式理想生成元: {polynomial_ring}")
print(f"GCD结果: {result}\n")
#多项式理想生成元: (x**5 + x**3 + x + 1, x**4 + x**2 + 1)
#GCD结果: 1
示例5. 控制系统 - 传递函数简化
control_system = (s**3 + 3*s**2 + 3*s + 1, s**2 + 2*s + 1)
result = polygcd(control_system)
print(f"传递函数GCD: {control_system}")
print(f"GCD结果: {result}\n") # s + 1
#传递函数GCD: (s**3 + 3*s**2 + 3*s + 1, s**2 + 2*s + 1)
#GCD结果: s**2 + 2*s + 1
示例6. 电路分析 - 电路网络函数分析
circuit_analysis = (s**2 + 3*s + 2, s**2 + 5*s + 6)
result = polygcd(circuit_analysis)
print(f"网络函数GCD: {circuit_analysis}")
print(f"GCD结果: {result}\n") # s + 2
#网络函数GCD: (s**2 + 3*s + 2, s**2 + 5*s + 6)
#GCD结果: s + 2
示例7. 信号处理 - 数字滤波器公共零点
filter_design = (z**2 - 1.5*z + 0.5, z**2 - 1.8*z + 0.8)
result = polygcd(filter_design)
print(f"滤波器多项式GCD: {filter_design}")
print(f"GCD结果: {result}\n")
#滤波器多项式GCD: (z**2 - 1.5*z + 0.5, z**2 - 1.8*z + 0.8)
#GCD结果: 1.0*z - 1.0
示例8. 量子力学 - 量子态正交性检验
quantum_states = (x**2 - 1, x**3 - x)
result = polygcd(quantum_states)
print(f"波函数多项式GCD: {quantum_states}")
print(f"GCD结果: {result}\n") # x
#波函数多项式GCD: (x**2 - 1, x**3 - x)
#GCD结果: x**2 - 1
示例9. 编码理论 - 循环码生成多项式
cyclic_code = (x**7 + 1, x**3 + x + 1)
result = polygcd(cyclic_code)
print(f"循环码多项式GCD: {cyclic_code}")
print(f"GCD结果: {result}\n")
#循环码多项式GCD: (x**7 + 1, x**3 + x + 1)
#GCD结果: 1
示例10. 密码学 - 有限域上的多项式运算
finite_field = (x**8 + x**4 + x**3 + x + 1, x**4 + x + 1)
result = polygcd(finite_field)
print(f"有限域多项式GCD: {finite_field}")
print(f"GCD结果: {result}\n")
#有限域多项式GCD: (x**8 + x**4 + x**3 + x + 1, x**4 + x + 1)
#GCD结果: 1
示例11. 计算机代数系统 - 符号表达式自动简化
symbolic_simplify = (2*x**3 + 4*x**2 + 2*x, x**2 + 2*x + 1)
result = polygcd(symbolic_simplify)
print(f"符号表达式GCD: {symbolic_simplify}")
print(f"GCD结果: {result}\n") # x + 1
#符号表达式GCD: (2*x**3 + 4*x**2 + 2*x, x**2 + 2*x + 1)
#GCD结果: x**2 + 2*x + 1
示例12. 算法分析 - 算法复杂度多项式分析
complexity_analysis = (n**3 + 3*n**2 + 2*n, n**2 + n)
result = polygcd(complexity_analysis)
print(f"复杂度多项式GCD: {complexity_analysis}")
print(f"GCD结果: {result}\n") # n
#复杂度多项式GCD: (n**3 + 3*n**2 + 2*n, n**2 + n)
#GCD结果: n**2 + n
示例13. 经济模型 - 经济模型公共因子
economic_model = (0.5*x**3 + 1.5*x**2 + x, 0.25*x**2 + 0.5*x)
result = polygcd(economic_model)
print(f"经济模型多项式GCD: {economic_model}")
print(f"GCD结果: {result}\n")
#经济模型多项式GCD: (0.5*x**3 + 1.5*x**2 + x, 0.25*x**2 + 0.5*x)
#GCD结果: 1.0*x**2 + 2.0*x
示例14. 社会科学 - 社会趋势多项式分析
trend_analysis = (t**4 - 10*t**2 + 9, t**3 - 3*t**2 - t + 3)
result = polygcd(trend_analysis)
print(f"趋势多项式GCD: {trend_analysis}")
print(f"GCD结果: {result}\n") # t - 1
#趋势多项式GCD: (t**4 - 10*t**2 + 9, t**3 - 3*t**2 - t + 3)
#GCD结果: t**3 - 3*t**2 - t + 3
special_cases = [
# 示例15. 互质多项式
("互质多项式", "(x**2 + 1, x**2 - 1)"),
# 1 (无公共因子)
# 示例16. 相同多项式
("相同多项式", "(x**3 + 2*x**2 + x, x**3 + 2*x**2 + x)"),
# x**3 + 2*x**2 + x
# 示例17. 包含常数项
("包含常数项", "(2*x**2 + 4*x + 2, 4*x + 4)"),
# 2*x + 2
# 示例18. 高次与低次
("高次与低次多项式", "(x**5 + x**3 + x, x**2 + 1)"),
# x**2 + 1
# 示例19. 数值系数
("数值系数多项式", "(3*x**2 + 6*x + 3, 6*x + 6)"),
# 3*x + 3
# 示例20. 多元多项式(单变量GCD)
("多元多项式单变元GCD", "(x**2*y + x*y**2, x*y + y**2)"),
# y (将x视为变量,y视为常数)
]
for name, case in special_cases:
print(f"{name}: {case}")
result = polynomial_gcd(case)
print(f"GCD结果: {result}\n")
#互质多项式: (x**2 + 1, x**2 - 1)
#GCD结果: 1
#相同多项式: (x**3 + 2*x**2 + x, x**3 + 2*x**2 + x)
#GCD结果: x**3 + 2*x**2 + x
#包含常数项: (2*x**2 + 4*x + 2, 4*x + 4)
#GCD结果: 2*x + 2
#高次与低次多项式: (x**5 + x**3 + x, x**2 + 1)
#GCD结果: 1
#数值系数多项式: (3*x**2 + 6*x + 3, 6*x + 6)
#GCD结果: 3*x + 3
#多元多项式单变元GCD: (x**2*y + x*y**2, x*y + y**2)
#GCD结果: x*y + y**2
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def polynomial_gcd(input_str):
"""
计算两个多项式的最大公约数(GCD)(对标MATLAB的gcd函数)
参数:
input_str (str): 表示两个多项式的字符串,格式应为"(poly1, poly2)"
示例:"(x**2 - 1, x + 1)"
返回:
sp.Expr: 多项式GCD的符号表达式
str: 错误信息(当输入无效时)
示例:
>>> polynomial_gcd("(x**2 - 1, x + 1)")
x + 1
>>> polynomial_gcd("(x**3 - 1, x**2 - 1)")
x - 1
"""
try:
# 尝试解析输入字符串为SymPy表达式
expr = sp.sympify(input_str, evaluate=False)
# 检查输入是否为包含两个元素的元组
if not isinstance(expr, tuple) or len(expr) != 2:
return f"输入错误:需要两个多项式组成的元组,当前输入:{input_str}"
# 尝试将两个表达式转换为多项式
poly1 = sp.Poly(expr[0])
poly2 = sp.Poly(expr[1])
# 检查多项式是否有效
if poly1.is_number or poly2.is_number:
return "错误:输入必须为符号多项式,不能仅为数值"
# 计算最大公约数
gcd_poly = sp.gcd(poly1, poly2)
# 返回化简后的表达式形式
return gcd_poly.as_expr()
except sp.SympifyError:
return f"解析错误:无法解析输入字符串 - {input_str}"
except ValueError as ve:
return f"多项式转换错误:{str(ve)}"
except Exception as e:
return f"运行时错误:{str(e)}"
# 测试示例
if __name__ == "__main__":
# 正常案例
test_cases = [
("(x**2 - 1, x + 1)"),
# x + 1
("(x**3 - 1, x**2 - 1)"),
# x - 1
("(2*x**2 + 4*x, x**2 - 4)")
# x + 2
]
print("正常案例测试:")
for input_str in test_cases:
result = polynomial_gcd(input_str)
print(f"输入:{input_str}")
print(f"实际:{result}\n")
多项式的最小公倍数
p = polylcm(a,b)返回a,b两个表达式之间的最小公倍数
a, b -- 输入, 符号表达式
示例1. 有理函数运算 - 通分计算
rational_ops = (x**2 - 1, x**2 - 4*x + 4)
result = polylcm(rational_ops)
print(f"有理函数分母LCM: {rational_ops}")
print(f"LCM结果: {result}\n")
#有理函数分母LCM: (x**2 - 1, x**2 - 4*x + 4)
#LCM结果: x**4 - 4*x**3 + 3*x**2 + 4*x - 4
示例2. 多项式方程求解 - 消去公因子
equation_system = (x**3 - 8, x**2 - 4)
result = polylcm(equation_system)
print(f"方程组多项式LCM: {equation_system}")
print(f"LCM结果: {result}\n")
#方程组多项式LCM: (x**3 - 8, x**2 - 4)
#LCM结果: x**4 + 2*x**3 - 8*x - 16
示例3. 代数扩展 - 域扩张构造
field_extension = (x**2 + 1, x**2 - 2)
result = polylcm(field_extension)
print(f"扩域多项式LCM: {field_extension}")
print(f"LCM结果: {result}\n")
#扩域多项式LCM: (x**2 + 1, x**2 - 2)
#LCM结果: x**4 - x**2 - 2
示例4. 多项式插值 - 公共节点处理
interpolation = ((x-1)*(x-2), (x-2)*(x-3))
result = polylcm(interpolation)
print(f"插值多项式LCM: {interpolation}")
print(f"LCM结果: {result}\n")
#插值多项式LCM: ((x-1)*(x-2), (x-2)*(x-3))
#LCM结果: x**3 - 6*x**2 + 11*x - 6
示例5. 控制系统 - 复合系统分析
control_system = (s**2 + 3*s + 2, s**2 + 5*s + 6)
result = polylcm(control_system)
print(f"控制系统多项式LCM: {control_system}")
print(f"LCM结果: {result}\n")
#控制系统多项式LCM: (s**2 + 3*s + 2, s**2 + 5*s + 6)
#LCM结果: s**3 + 6*s**2 + 11*s + 6
示例6. 电路理论 - 网络综合
circuit_synthesis = (s**2 + 2*s + 1, s**2 + 4*s + 4)
result = polylcm(circuit_synthesis)
print(f"网络综合LCM: {circuit_synthesis}")
print(f"LCM结果: {result}\n")
#网络综合LCM: (s**2 + 2*s + 1, s**2 + 4*s + 4)
#LCM结果: s**4 + 6*s**3 + 13*s**2 + 12*s + 4
示例7. 信号处理 - 多速率系统
multirate_system = (z**2 - 1, z**3 - 1)
result = polylcm(multirate_system)
print(f"多速率系统LCM: {multirate_system}")
print(f"LCM结果: {result}\n")
#多速率系统LCM: (z**2 - 1, z**3 - 1)
#LCM结果: z**4 + z**3 - z - 1
示例8. 机械振动 - 多自由度振动系统
vibration_system = (m1*s**2 + k1, m2*s**2 + k2)
result = polylcm(vibration_system)
print(f"振动系统LCM: {vibration_system}")
print(f"LCM结果: {result}\n")
#振动系统LCM: (m1*s**2 + k1, m2*s**2 + k2)
#LCM结果: k1*k2 + k1*m2*s**2 + k2*m1*s**2 + m1*m2*s**4
示例9. 电磁学 - 波导模式
waveguide = (k**2 - kx**2, k**2 - ky**2)
result = polylcm(waveguide)
print(f"波导模式LCM: {waveguide}")
print(f"LCM结果: {result}\n")
#波导模式LCM: (k**2 - kx**2, k**2 - ky**2)
#LCM结果: k**4 - k**2*kx**2 - k**2*ky**2 + kx**2*ky**2
示例10. 编码理论 - 复合错误校正码
error_correction = (x**4 + x + 1, x**3 + x + 1)
result = polylcm(error_correction)
print(f"纠错码多项式LCM: {error_correction}")
print(f"LCM结果: {result}\n")
#纠错码多项式LCM: (x**4 + x + 1, x**3 + x + 1)
#LCM结果: x**7 + x**5 + 2*x**4 + x**3 + x**2 + 2*x + 1
示例11. 密码学 - RSA多项式变体
cryptography = ((x-2)*(x-3), (x-3)*(x-5))
result = polylcm(cryptography)
print(f"密码学多项式LCM: {cryptography}")
print(f"LCM结果: {result}\n")
#密码学多项式LCM: ((x-2)*(x-3), (x-3)*(x-5))
#LCM结果: x**3 - 10*x**2 + 31*x - 30
示例12. 计算机代数 - 符号计算
symbolic_computation = (2*x**2 + 4*x + 2, 3*x**2 + 6*x + 3)
result = polylcm(symbolic_computation)
print(f"符号表达式LCM: {symbolic_computation}")
print(f"LCM结果: {result}\n")
#符号表达式LCM: (2*x**2 + 4*x + 2, 3*x**2 + 6*x + 3)
#LCM结果: 6*x**2 + 12*x + 6
示例13. 算法分析 - 复杂度合并
complexity_merge = (n**2 + n, n**3 - n)
result = polylcm(complexity_merge)
print(f"复杂度多项式LCM: {complexity_merge}")
print(f"LCM结果: {result}\n")
#复杂度多项式LCM: (n**2 + n, n**3 - n)
#LCM结果: n**3 - n
示例14. 经济预测 - 多模型整合
economic_forecast = (0.1*x**2 + 0.5*x + 1, 0.2*x**2 + 0.3*x + 2)
result = polylcm(economic_forecast)
print(f"经济模型LCM: {economic_forecast}")
print(f"LCM结果: {result}\n")
#经济模型LCM: (0.1*x**2 + 0.5*x + 1, 0.2*x**2 + 0.3*x + 2)
#LCM结果: 1.0*x**4 + 6.5*x**3 + 27.5*x**2 + 65.0*x + 100.0
示例15. 运筹学 - 资源分配优化
resource_allocation = ((t-7)*(t-14), (t-14)*(t-21))
result = polylcm(resource_allocation)
print(f"资源分配LCM: {resource_allocation}")
print(f"LCM结果: {result}\n")
#资源分配LCM: ((t-7)*(t-14), (t-14)*(t-21))
#LCM结果: t**3 - 42*t**2 + 539*t - 2058
示例16. 金融工程 - 衍生品定价
financial_engineering = ((r-0.02)*(r-0.05), (r-0.05)*(r-0.08))
result = polylcm(financial_engineering)
print(f"金融模型LCM: {financial_engineering}")
print(f"LCM结果: {result}\n")
#金融模型LCM: ((r-0.02)*(r-0.05), (r-0.05)*(r-0.08))
#LCM结果: 1.0*r**3 - 0.15*r**2 + 0.0066*r - 8.0e-5
示例17. 数学教学 - 最小公倍数概念
teaching_example = (x**2 - 4, x**2 + 4*x + 4)
result = polylcm(teaching_example)
print(f"教学示例LCM: {teaching_example}")
print(f"LCM结果: {result}\n")
#教学示例LCM: (x**2 - 4, x**2 + 4*x + 4)
#LCM结果: x**3 + 2*x**2 - 4*x - 8
示例18. 科学研究 - 实验数据拟合
research_data = ((x-1)*(x-3), (x-2)*(x-3))
result = polylcm(research_data)
print(f"实验数据LCM: {research_data}")
print(f"LCM结果: {result}\n")
#实验数据LCM: ((x-1)*(x-3), (x-2)*(x-3))
#LCM结果: x**3 - 6*x**2 + 11*x - 6
示例19. 数值分析 - 插值基函数
numerical_analysis = ((x-x1)*(x-x2), (x-x2)*(x-x3))
result = polylcm(numerical_analysis)
print(f"插值基函数LCM: {numerical_analysis}")
print(f"LCM结果: {result}\n")
#插值基函数LCM: ((x-x1)*(x-x2), (x-x2)*(x-x3))
#LCM结果: x**3 - x**2*x1 - x**2*x2 - x**2*x3 + x*x1*x2 + x*x1*x3 + x*x2*x3 - x1*x2*x3
示例20. 控制系统 - 观测器设计
observer_design = ((s+1)*(s+2), (s+2)*(s+3))
result = polylcm(observer_design)
print(f"观测器多项式LCM: {observer_design}")
print(f"LCM结果: {result}\n")
#观测器多项式LCM: ((s+1)*(s+2), (s+2)*(s+3))
#LCM结果: s**3 + 6*s**2 + 11*s + 6
示例21. 通信系统 - 多载波调制
multicarrier = ((f-f1)*(f-f2), (f-f2)*(f-f3))
result = polylcm(multicarrier)
print(f"多载波LCM: {multicarrier}")
print(f"LCM结果: {result}\n")
#多载波LCM: ((f-f1)*(f-f2), (f-f2)*(f-f3))
#LCM结果: f**3 - f**2*f1 - f**2*f2 - f**2*f3 + f*f1*f2 + f*f1*f3 + f*f2*f3 - f1*f2*f3
示例22. 图像处理 - 多项式滤波器
image_filter = ((u**2 + v**2), (u**2 + 4*v**2))
result = polylcm(image_filter)
print(f"图像滤波器LCM: {image_filter}")
print(f"LCM结果: {result}\n")
#图像滤波器LCM: ((u**2 + v**2), (u**2 + 4*v**2))
#LCM结果: u**4 + 5*u**2*v**2 + 4*v**4
示例23. 机器人学 - 轨迹规划
trajectory_planning = ((t-t1)**2, (t-t2)**2)
result = polylcm(trajectory_planning)
print(f"轨迹多项式LCM: {trajectory_planning}")
print(f"LCM结果: {result}\n")
#轨迹多项式LCM: ((t-t1)**2, (t-t2)**2)
#LCM结果: t**4 - 2*t**3*t1 - 2*t**3*t2 + t**2*t1**2 + 4*t**2*t1*t2 + t**2*t2**2 - 2*t*t1**2*t2 - 2*t*t1*t2**2 + t1**2*t2**2
示例24. 量子计算 - 量子门分解
quantum_gates = ((θ-π/2)*(θ-π), (θ-π)*(θ-3*π/2))
result = polylcm(quantum_gates)
print(f"量子门多项式LCM: {quantum_gates}")
print(f"LCM结果: {result}\n")
#量子门多项式LCM: ((θ-π/2)*(θ-π), (θ-π)*(θ-3*π/2))
#LCM结果: θ**3 - 3*θ**2*π + 11*θ*π**2/4 - 3*π**3/4
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def polynomial_lcm(input_str):
"""
计算两个多项式的最小公倍数(LCM)(对标MATLAB的lcm函数)
参数:
input_str (str): 表示两个多项式的字符串,格式应为"(poly1, poly2)"
示例:"(x**2 - 1, x + 1)"
返回:
sp.Expr: 多项式LCM的符号表达式
str: 错误信息(当输入无效时)
示例:
>>> polynomial_lcm("(x**2 - 1, x + 1)")
x**2 - 1
>>> polynomial_lcm("(x**3 - 1, x**2 - 1)")
x**4 - x**3 - x + 1
"""
try:
# 解析输入字符串为SymPy表达式(禁用自动化简保持原始形式)
expr = sp.sympify(input_str, evaluate=False)
# 检查输入是否为包含两个元素的元组
if not isinstance(expr, tuple) or len(expr) != 2:
return f"输入错误:需要两个多项式组成的元组,当前输入:{input_str}"
# 尝试将两个表达式转换为多项式
try:
poly1 = sp.Poly(expr[0])
poly2 = sp.Poly(expr[1])
except (sp.PolynomialError, ValueError) as e:
return f"多项式转换错误:{str(e)}"
# 检查是否为有效多项式
if poly1.is_number and poly2.is_number:
return sp.lcm(poly1.as_expr(), poly2.as_expr())
# 计算最小公倍数
lcm_poly = sp.lcm(poly1, poly2)
# 返回标准化的表达式形式
return sp.simplify(lcm_poly.as_expr())
except sp.SympifyError:
return f"解析错误:无法解析输入字符串 - {input_str}"
except Exception as e:
return f"运行时错误:{str(e)}"
# 测试示例
if __name__ == "__main__":
# 正常案例
test_cases = [
("(x**2 - 1, x + 1)"),
# x**2 - 1
("(x**3 - 1, x**2 - 1)"),
# x**4 + x**3 - x - 1
("(2*x**2 + 4*x, x**2 - 4)")
# 2*x*(x**2 - 4)
]
print("正常案例测试:")
for input_str in test_cases:
result = polynomial_lcm(input_str)
print(f"输入:{input_str}")
print(f"实际:{result}\n")
向量场的势
potential(V,X) 计算矢量场 V 相对于笛卡尔坐标系中的矢量 X 的势. 矢量场 V 必须是梯度场.
potential(V,X,Y) 使用 Y 作为积分基点来计算矢量场 V 相对于 X 的势.
V — 矢量场,符号表达式或函数的三维符号向量(默认)
X — 输入,三个符号变量的向量
Y — 输入,数值向量
示例1. 物理场示例 - 重力场 (保守场)
gravity_field = ([0, 0, -g], [x, y, z])
print(f"重力场: {gravity_field}")
#重力场: ([0, 0, -g], [x, y, z])
result = potential(gravity_field)
print(f"标量势: {result}")
#标量势: -g*z
#物理意义: 重力势能 φ = -g·z
示例2. 弹簧力场 - 胡克定律 (保守场)
spring_field = ([-k*x, -k*y, -k*z], [x, y, z])
print(f"弹簧力场: {spring_field}")
#弹簧力场: ([-k*x, -k*y, -k*z], [x, y, z])
result = potential(spring_field)
print(f"标量势: {result}")
#标量势: -k*x**2/2 - k*y**2/2 - k*z**2/2
#物理意义: 弹性势能 φ = ½k(x²+y²+z²)
示例3. 二维调和场 (保守场)
harmonic_field = ([2*x, 2*y], [x, y])
print(f"二维调和场: {harmonic_field}")
#二维调和场: ([2*x, 2*y], [x, y])
result = potential(harmonic_field)
print(f"标量势: {result}")
#标量势: x**2 + y**2
示例4. 带基点的重力场
gravity_with_base = ([0, 0, -g], [x, y, z], [0, 0, 10])
print(f"重力场(基点在z=10): {gravity_with_base}")
#重力场(基点在z=10): ([0, 0, -g], [x, y, z], [0, 0, 10])
result = potential(gravity_with_base)
print(f"标量势: {result}")
#标量势: -g*z + 10*g
示例5. 无旋流动速度势
flow_field = ([2*x - y, -x + 2*y], [x, y])
print(f"流动场: {flow_field}")
#流动场: ([2*x - y, -x + 2*y], [x, y])
result = potential(flow_field)
print(f"速度势: {result}")
#速度势: x**2 - x*y + y**2
示例6. 带物理参数的场
param_field = ([E_x, E_y, E_z], [x, y, z])
print(f"参数化电场: {param_field}")
#参数化电场: ([E_x, E_y, E_z], [x, y, z])
result = potential(param_field)
print(f"电势: {result}")
#电势: E_x*x + E_y*y + E_z*z
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from sympy.vector import CoordSys3D, scalar_potential
def potential_vector_field(input_str):
"""
计算向量场的标量势(对标MATLAB的potential函数)
参数格式要求:
输入应为字符串,格式为:
- 二维场: (([F1, F2], [x, y]) 或 (([F1, F2], [x, y], [x0, y0])
- 三维场: (([F1, F2, F3], [x, y, z]) 或 (([F1, F2, F3], [x, y, z], [x0, y0, z0]))
返回:
- 成功:标量势表达式(带积分常数)或带基点的数值结果
- 失败:错误信息字符串
"""
try:
expr = sp.sympify(input_str, evaluate=False)
error = False
result = None
# 输入格式验证
if not isinstance(expr, tuple) or len(expr) not in (2, 3):
return f"输入错误:需要格式为 (分量列表, 变量列表) 或 (分量列表, 变量列表, 基点),当前输入:{input_str}"
# 解析输入参数
V_components = expr[0] # 向量场分量
X_vars = expr[1] # 变量列表
base_points = expr[2] if len(expr) == 3 else None # 基点(可选)
# 维度验证
dim = len(X_vars)
if dim not in (2, 3) or len(V_components) != dim:
return f"维度错误:支持2D/3D向量场,当前输入维度:分量数={len(V_components)}, 变量数={dim}"
# 创建坐标系
N = CoordSys3D('N') # 使用3D坐标系处理2D/3D场
# 构建向量场表达式
subs_dict = {X_vars[0]: N.x, X_vars[1]: N.y}
vec_components = [
V_components[0].subs(subs_dict),
V_components[1].subs(subs_dict)
]
if dim == 3:
subs_dict[X_vars[2]] = N.z
vec_components.append(V_components[2].subs(subs_dict))
# 创建向量场对象
if dim == 2:
V = vec_components[0] * N.i + vec_components[1] * N.j
else:
V = vec_components[0] * N.i + vec_components[1] * N.j + vec_components[2] * N.k
# 计算标量势
try:
phi = scalar_potential(V, N)
except ValueError as e:
return sp.nan
# 还原原始变量符号
reverse_subs = {N.x: X_vars[0], N.y: X_vars[1]}
if dim == 3:
reverse_subs[N.z] = X_vars[2]
phi = phi.subs(reverse_subs)
# 处理基点(修正部分)
if base_points:
if len(base_points) != dim:
return f"基点维度错误:需要{dim}个基点值,当前收到{len(base_points)}"
# 计算基点处的势值
phi_base = phi.subs(dict(zip(X_vars, base_points)))
# 消除积分常数,使基点处的势为0
phi = phi - phi_base
return phi
except sp.SympifyError:
return f"解析错误:无效输入格式 - {input_str}"
except Exception as e:
return f"运行时错误:{str(e)}"
# 测试示例
if __name__ == "__main__":
# 有效案例
# 案例1:二维保守场
print("案例1:二维保守场")
input_2d = "([x,y,z*exp(z)],[x,y,z])"
print(potential_vector_field(input_2d))
# x**2/2 + y**2/2 + (z - 1)*exp(z)
# 案例2:三维带基点
print("\n案例2:三维带基点计算")
input_3d_base = "([x,y,z*exp(z)],[x,y,z],[0,0,0])"
print(potential_vector_field(input_3d_base))
# x**2/2 + y**2/2 + (z - 1)*exp(z) + 1
# 案例3:非保守场
print("\n案例3:非保守场")
input_nonconservative = "(([y, x + y], [x, y]))"
print(potential_vector_field(input_nonconservative))
# x*y + y**2/2
浮点数的以2为底的幂运算和缩放
Y = pow2(E) 计算2的E次方
Y = pow2(X,E) 计算X乘以2的E次方
E是标量,向量,矩阵
示例1. 计算机科学 - 内存容量计算
print("2^10 (1KB):", powTwo(10))
print("2^20 (1MB):", powTwo(20))
print("2^30 (1GB):", powTwo(30))
#2^10 (1KB): 1024.0
#2^20 (1MB): 1048576.0
#2^30 (1GB): 1073741824.0
示例2. 数字信号处理 - ADC量化电平计算
print("8位ADC的量化级别数:", powTwo(8))
print("12位ADC的最大值:", powTwo(12) - 1)
#8位ADC的量化级别数: 256.0
#12位ADC的最大值: 4095.0
示例3. 浮点数表示 - 尾数计算
单精度浮点数的尾数范围: 1.0 * 2^0 到 2.0 * 2^0
mantissa = 1.5
exponent = 3
print(f"规格化数: {mantissa} * 2^{exponent} =", powTwo(mantissa, exponent))
#规格化数: 1.5 * 2^3 = 12.0
示例4. 图像处理 - 像素值缩放
print("像素值128放大2^2倍:", powTwo(128, 2))
print("像素值64缩小2^-1倍:", powTwo(64, -1))
#像素值128放大2^2倍: 512.0
#像素值64缩小2^-1倍: 32.0
示例5. 通信系统 - 信号功率
print("3dB功率增益对应的线性倍数:", powTwo(1, 3/10))
print("6dB功率增益:", powTwo(1, 6/10))
#3dB功率增益对应的线性倍数: 1.2311444133449163
#6dB功率增益: 1.5157165665103982
示例6. 金融计算 - 复利增长
principal = 1000
periods = 10
print(f"本金{principal},翻倍次数{periods}后的金额:", powTwo(principal, periods))
#本金1000,翻倍次数10后的金额: 1024000.0
示例7. 物理学 - 放射性衰变
initial_amount = 100
half_lives = 3
print(f"初始量{initial_amount},经过{half_lives}个半衰期剩余:", powTwo(initial_amount, -half_lives))
#初始量100,经过3个半衰期剩余: 12.5
示例8. 符号计算
print("2^x:", powTwo(x))
print("a * 2^b:", powTwo(a, b))
#2^x: 2**x
#a * 2^b: 2.0**b*a
示例9. 音频处理 - 分贝计算
print("0dB对应的参考电平:", powTwo(1, 0))
print("-6dB对应的电平:", powTwo(1, -6/10))
#0dB对应的参考电平: 1.0
#-6dB对应的电平: 0.6597539553864471
示例10. 神经网络 - 神经网络中的指数运算
print("Sigmoid函数的指数部分近似:", powTwo(-x))
#Sigmoid函数的指数部分近似: 2**(-x)
示例11. 概率论 - 二项分布
print("抛10次硬币的所有可能结果数:", powTwo(10))
#抛10次硬币的所有可能结果数: 1024.0
示例12. 密码学 - 密码强度分析
print("128位密钥的可能组合数:", powTwo(128))
print("256位密钥的可能组合数:", powTwo(256))
#128位密钥的可能组合数: 3.402823669209385e+38
#256位密钥的可能组合数: 1.157920892373162e+77
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.special import exp2
def pow_2_e(input_str):
"""
对标 MATLAB 的 pow2 函数,实现两种计算模式:
模式1:pow2(X) = 2.^X
模式2:pow2(F,E) = F.*2.^E
参数:
input_str: 输入字符串,支持以下格式:
- 单个数值/矩阵: "2" 或 "Matrix([[1,2],[3,4]])"
- 元组模式: "(F, E)",其中F和E可为标量或矩阵
返回:
SymPy 矩阵/数值 或 错误信息字符串
"""
try:
# 解析输入字符串为 SymPy 表达式
expr = sp.sympify(input_str)
error = False
result = None
if isinstance(expr, tuple) and len(expr) == 2:
if all(e.is_number for e in expr):
params = tuple(float(e.evalf()) for e in expr)
f, e = params
result = f * exp2(e)
elif any(e.free_symbols for e in expr):
"""元素级计算 f * 2^e"""
f, e = expr
try:
result = f * sp.Pow(2, e).evalf()
except:
return sp.nan
else:
error = True
elif expr.is_number:
z = float(expr)
result = exp2(z)
elif expr.free_symbols:
result = sp.Pow(2, expr)
else:
error = True
return result if not error else f"输入错误: {input_str}"
except sp.SympifyError:
return f"解析错误:无效输入格式 - {input_str}"
except Exception as e:
return f"运行时错误:{str(e)}"
# 测试示例
if __name__ == "__main__":
# 模式1测试
print("模式1:2^X")
print(pow_2_e("3"))
# 8.0
# 模式2测试
print("\n模式2:F*2^E")
print(pow_2_e("(2, 3)"))
# 16.0
print(pow_2_e("(x, y)"))
# 2.0**y*x
幂扩展
PowerExpand(x)是power_exp提示的包装扩展
x -- 输入,符号表达式
示例1. 代数展开 - 二项式定理
test_cases = [
((x + y)**2, "完全平方公式"),
((a + b)**3, "立方公式"),
((x + 1)**4, "四次方展开"),
]
for expr, desc in test_cases:
print(f"{desc}: {expr}")
result = PowerExpand(expr)
print(f"展开结果: {result}")
#完全平方公式: (x + y)**2
#展开结果: (x + y)**2
#立方公式: (a + b)**3
#展开结果: (a + b)**3
#四次方展开: (x + 1)**4
#展开结果: (x + 1)**4
示例2. 分数指数展开
test_cases = [
((x**2 * y**3)**(1/2), "平方根展开"),
((a*b*c)**(1/3), "立方根展开"),
((x**4 / y**2)**(1/2), "分式平方根"),
]
for expr, desc in test_cases:
print(f"{desc}: {expr}")
result = PowerExpand(expr)
print(f"展开结果: {result}")
#平方根展开: (x**2 * y**3)**(1/2)
#展开结果: sqrt(x**2)*sqrt(y**3)
#立方根展开: (a*b*c)**(1/3)
#展开结果: a**(1/3)*b**(1/3)*c**(1/3)
#分式平方根: (x**4 / y**2)**(1/2)
#展开结果: sqrt(x**4)*sqrt(y**(-2))
示例3. 负指数展开
test_cases = [
((x*y)**(-1), "乘积的负一次方"),
((a/b)**(-2), "分式的负二次方"),
(x**(-n), "变量的负n次方"),
]
for expr, desc in test_cases:
print(f"{desc}: {expr}")
result = PowerExpand(expr)
print(f"展开结果: {result}")
#乘积的负一次方: (x*y)**(-1)
#展开结果: 1/(x*y)
#分式的负二次方: (a/b)**(-2)
#展开结果: b**2/a**2
#变量的负n次方: x**(-n)
#展开结果: x**(-n)
示例4. 多重幂展开
test_cases = [
(((x**2)**3), "幂的幂"),
((a**(1/2))**(1/3), "分数幂的分数幂"),
(((x*y)**2)**n, "乘积幂的n次方"),
]
for expr, desc in test_cases:
print(f"{desc}: {expr}")
result = PowerExpand(expr)
print(f"展开结果: {result}")
#幂的幂: ((x**2)**3)
#展开结果: x**6
#分数幂的分数幂: (a**(1/2))**(1/3)
#展开结果: a**(1/6)
#乘积幂的n次方: ((x*y)**2)**n
#展开结果: (x**2)**n*(y**2)**n
示例5. 复杂表达式展开
test_cases = [
((x + y)*(x - y), "平方差公式"),
((a + b + c)**2, "三项式平方"),
((x**2 + y**2)**(1/2), "平方和的平方根"),
]
for expr, desc in test_cases:
print(f"{desc}: {expr}")
result = PowerExpand(expr)
print(f"展开结果: {result}")
#平方差公式: (x + y)*(x - y)
#展开结果: (x - y)*(x + y)
#三项式平方: (a + b + c)**2
#展开结果: (a + b + c)**2
#平方和的平方根: (x**2 + y**2)**(1/2)
#展开结果: sqrt(x**2 + y**2)
示例6. 物理应用 - 动能公式
动能公式: (1/2)*m*v**2
kinetic_energy = (1/2)*m*v**2
result = PowerExpand(kinetic_energy)
print(f"展开结果: {result}")
#展开结果: m*v**2/2
示例7. 几何应用 - 体积公式
立方体体积: (a + b)**3
volume = (a + b)**3
result = PowerExpand(volume)
print(f"展开结果: {result}")
#展开结果: (a + b)**3
示例8. 概率论应用
二项分布: (p + q)**n 其中 q = 1-p
binomial = (p + (1-p))**n
result = PowerExpand(binomial)
print(f"展开结果: {result}")
#展开结果: 1
示例9. 复数运算
test_cases = [
((a + b*I)**2, "复数平方"),
((x + y*I)*(x - y*I), "复数乘积"),
]
for expr, desc in test_cases:
print(f"{desc}: {expr}")
result = PowerExpand(expr)
print(f"展开结果: {result}")
#复数平方: (a + b*I)**2
#展开结果: (a + I*b)**2
#复数乘积: (x + y*I)*(x - y*I)
#展开结果: (x - I*y)*(x + I*y)
示例10. 工程应用 - 电阻公式
并联电阻: (1/R1 + 1/R2)**(-1)
parallel_resistance = (1/R1 + 1/R2)**(-1)
result = PowerExpand(parallel_resistance)
print(f"展开结果: {result}")
#展开结果: 1/(1/R2 + 1/R1)
示例11. 微积分预备 - 极限计算
test_cases = [
((1 + x/n)**n, "自然对数定义中的表达式"),
(((x + h)**2 - x**2)/h, "导数定义中的表达式"),
]
for expr, desc in test_cases:
print(f"{desc}: {expr}")
result = PowerExpand(expr)
print(f"展开结果: {result}")
#自然对数定义中的表达式: (1 + x/n)**n
#展开结果: (1 + x/n)**n
#导数定义中的表达式: ((x + h)**2 - x**2)/h
#展开结果: (-x**2 + (h + x)**2)/h
示例12. 三角函数与幂的结合
test_cases = [
((sin(x) + cos(x))**2, "正弦余弦和的平方"),
((1 + tan(x))**2, "1加正切的平方"),
]
for expr, desc in test_cases:
print(f"{desc}: {expr}")
result = PowerExpand(expr)
print(f"展开结果: {result}")
#正弦余弦和的平方: (sin(x) + cos(x))**2
#展开结果: (sin(x) + cos(x))**2
#1加正切的平方: (1 + tan(x))**2
#展开结果: (tan(x) + 1)**2
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def power_expand(input_str):
"""
将输入的数学表达式字符串展开幂表达式,对标MathStudio的powerExpand函数。
参数:
input_str (str): 要展开的数学表达式字符串。
返回:
sp.Expr 或 str: 展开后的表达式,如果输入错误则返回错误信息字符串。
"""
try:
# 将输入字符串转换为SymPy表达式
expr = sp.sympify(input_str)
error = False
result = None
# 检查表达式是否包含符号或是纯数值
if expr.free_symbols or expr.is_number:
# 第一步:展开指数中的加法和减法,例如 exp(x + y) -> exp(x)*exp(y)
result = sp.expand_power_exp(expr)
# 第二步:展开幂的基底,例如 (a^b)^c -> a^(b*c),force=True强制展开不考虑假设条件
result = sp.expand_power_base(result, force=True)
else:
error = True
# 返回处理后的结果或错误信息
return result if not error else f"输入错误: {input_str}"
except Exception as e:
# 捕获异常并返回错误信息
return f"Error: {e}"
# 示例代码
if __name__ == "__main__":
# 测试案例列表,每个案例为元组(输入表达式, 期望输出)
test_cases = [
("exp(x + y)"),
# exp(x)*exp(y)
("(x**2)**(1/2)"),
# sqrt(x**2)
("(3*a)**n"),
# 3**n*a**n
]
# 遍历测试案例并验证结果
for input_expr in test_cases:
print(f"输入: {input_expr}")
output = power_expand(input_expr)
print(f"实际输出: {output}\n")
多项式ij曲线拟合
p = powerfit(x,y,n) 返回次数为n的多项式 p(x) 的系数.
x是查询点,指定为一个向量.
y是查询点位置的拟合值,指定为向量.
n是多幂拟合的次数, 正整数标量.
power1: Y = a*x^b
power2: Y = a*x^b+c
示例1. 物理学 - 自由落体距离
距离公式: s = 0.5*g*t² (g≈9.8)
time_data = [1, 2, 3, 4, 5] # 时间(s)
distance_data = [4.9, 19.6, 44.1, 78.4, 122.5] # 距离(m)
result1 = powerfit(time_data, distance_data, 1)
print("自由落体拟合:", result1)
#自由落体拟合: 4.9*x**2.0
示例2. 生物学 - 生物生长模型
生长模型: y = a*t^b + c
time_bio = [1, 2, 3, 4, 5, 6, 7, 8] # 时间(周)
size_bio = [2.1, 3.5, 5.2, 7.1, 9.3, 11.6, 13.8, 15.9] # 尺寸(cm)
result2 = powerfit(time_bio, size_bio, 2)
print("生物生长拟合:", result2)
#生物生长拟合: 1.0832*x**1.2677 + 0.9314
示例3. 经济学 - 学习曲线效应
学习曲线: 单位成本 = a*累计产量^b (b通常为负)
production = [100, 200, 400, 800, 1600] # 累计产量
cost_per_unit = [100, 85, 72, 61, 52] # 单位成本
result3 = powerfit(production, cost_per_unit, 1)
print("学习曲线拟合:", result3)
#学习曲线拟合: 297.59/x**0.2367
示例4. 化学 - 反应速率
反应速率与浓度: r = k*C^n
concentration = [0.1, 0.2, 0.4, 0.8, 1.6] # 浓度(mol/L)
reaction_rate = [0.05, 0.12, 0.32, 0.85, 2.25] # 反应速率
result5 = powerfit(concentration, reaction_rate, 1)
print("反应速率拟合:", result5)
#反应速率拟合: 1.1626*x**1.4049
示例5. 天文学 - 行星轨道周期
开普勒第三定律: T² ∝ a³
semi_major_axis = [0.39, 0.72, 1.00, 1.52, 5.20, 9.58] # 半长轴(AU)
orbital_period = [0.24, 0.62, 1.00, 1.88, 11.86, 29.46] # 轨道周期(年)
result6 = powerfit(semi_major_axis, orbital_period, 1)
print("开普勒定律拟合:", result6)
#开普勒定律拟合: 1.0141*x**1.491
示例6. 流体力学 - 管道流量
复杂流动: Q = a*D^b + c*ΔP^d
diameter_flow = [0.1, 0.2, 0.3, 0.4, 0.5] # 管径(m)
pressure_drop = [10, 20, 30, 40, 50] # 压降(Pa)
flow_rate = [0.8, 3.5, 8.2, 15.1, 24.5] # 流量(L/s)
result7 = powerfit(diameter_flow, flow_rate, 1)
print("管道流量拟合:", result7)
#管道流量拟合: 107.9482*x**2.1415
示例7. 心理学 - 学习记忆曲线
艾宾浩斯遗忘曲线近似
time_days = [1, 2, 4, 7, 14, 30] # 时间(天)
retention = [34, 28, 23, 19, 16, 14] # 记忆保持率(%)
result8 = powerfit(time_days, retention, 2)
print("记忆曲线拟合:", result8)
#记忆曲线拟合: 69499.6922 - 69467.3626*x**0.0001
示例8. 医学 - 药物代谢
药物浓度随时间衰减
time_hours = [1, 2, 4, 6, 8, 12] # 时间(小时)
concentration_drug = [95, 78, 52, 35, 23, 9] # 血药浓度(μg/mL)
result9 = powerfit(time_hours, concentration_drug, 1)
print("药物代谢拟合:", result9)
#药物代谢拟合: 101.7466/x**0.6096
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.optimize import curve_fit
import numpy as np
def power_fit_nonlinear(input_str):
"""
使用幂函数对数据进行非线性拟合,对标MATLAB的powerfit函数。
参数:
input_str: 输入字符串,格式为"(x_data, y_data, n)",其中n为模型类型(1或2)。
返回:
拟合的SymPy表达式或错误信息。
"""
try:
expr = sp.sympify(input_str)
error = False
expression = None
maxfev = 10000 # 最大函数评估次数
# 定义幂函数模型
def power_law1(x, a, b):
"""基础幂函数: y = a*x^b"""
return a * x ** b
def power_law2(x, a, b, c):
"""带常数项的幂函数: y = a*x^b + c"""
return a * x ** b + c
if isinstance(expr, tuple):
# 解析输入参数
if len(expr) > 2:
x, y, n = expr[0], expr[1], int(expr[2])
else:
x, y = expr[0], expr[1]
n = 1 # 默认为基础幂函数模型
# 转换为矩阵并获取数据
X = sp.Matrix(x) if isinstance(x, list) else None
Y = sp.Matrix(y) if isinstance(y, list) else None
if X is None or Y is None:
return "错误: 无法转换输入数据为矩阵"
x_data = np.array(X, dtype=float).flatten()
y_data = np.array(Y, dtype=float).flatten()
# 根据模型类型进行拟合
if n == 1:
initial_guess = [1.0, 1.0]
params, _ = curve_fit(power_law1, x_data, y_data, p0=initial_guess, maxfev=maxfev)
a, b = params
expression = f"{a:.4f} * x**{b:.4f}"
elif n == 2:
initial_guess = [1.0, 1.0, 0.0]
params, _ = curve_fit(power_law2, x_data, y_data, p0=initial_guess, maxfev=maxfev)
a, b, c = params
expression = f"{a:.4f} * x**{b:.4f} + {c:.4f}"
else:
return f"错误: 不支持的模型类型 n={n},仅支持1或2"
return sp.sympify(expression) # 直接转换为SymPy表达式
else:
return "错误: 输入格式应为 (x_data, y_data, n)"
except Exception as e:
return f"错误: {str(e)}"
# 示例用法
if __name__ == "__main__":
# 示例1:y = 2x² 拟合
example1 = "([1, 2, 3, 4], [2, 8, 18, 32], 1)"
print("拟合结果1:", power_fit_nonlinear(example1))
# 2.0*x**2.0
# 示例2:y = 3x^1.5 + 4 拟合
example2 = "([1, 2, 3, 4], [7.0, 8.2426, 11.588, 16.0], 2)"
print("拟合结果2:", power_fit_nonlinear(example2))
# 0.3904*x**2.3044 + 6.5197
计算分段多项式
v = ppval(pp,xq) 在查询点 xq 处计算分段多项式 pp
pp — 分段多项式, 结构体
xq — 查询点, 向量
v — 查询点处的分段多项式值, 向量 | 矩阵
示例1. 机械工程 - 凸轮轮廓设计
凸轮在不同角度区间使用不同的多项式轮廓
cam_breaks = [0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330, 360] # 角度(度)
cam_coefs = [
[0, 0, 0, 10], # 0-30°: 静止段
[0.001, -0.05, 1.5, 10], # 30-60°: 上升段
[-0.002, 0.2, -4, 25], # 60-90°: 快速上升
[0, 0, 0, 40], # 90-120°: 高位静止
[0.001, -0.1, 3, 40], # 120-150°: 下降段
[-0.0005, 0.08, -3, 25], # 150-180°: 快速下降
[0, 0, 0, 10], # 180-210°: 静止
[0.002, -0.12, 3.6, 10], # 210-240°: 二次上升
[0, 0, 0, 25], # 240-270°: 高位
[0.001, -0.15, 10, 25], # 270-300°: 下降
[0, 0, 0, 10], # 300-330°: 静止
[0.0005, -0.03, 0.9, 10] # 330-360°: 微调
]
cam_query = [15, 45, 75, 135, 195, 255, 315] # 查询角度
result_cam = ppval(cam_breaks, cam_coefs, len(cam_coefs), 4, cam_query)
print("凸轮轮廓在查询点的位移:", result_cam)
#凸轮轮廓在查询点的位移: [10,24.625,3.25,65.875,10,25,10]
示例2. 汽车工程 - 悬挂系统特性
悬挂力与位移的非线性关系,分段近似
suspension_breaks = [0, 20, 40, 60, 80, 100] # 位移(mm)
suspension_coefs = [
[0.5, 0, 0], # 0-20mm: 线性段
[0.8, -6, 60], # 20-40mm: 渐进硬化
[1.2, -24, 240], # 40-60mm: 进一步硬化
[2.0, -60, 600], # 60-80mm: 高刚度
[3.0, -120, 1200] # 80-100mm: 极限刚度
]
suspension_query = [10, 30, 50, 70, 90] # 查询位移
result_suspension = ppval(suspension_breaks, suspension_coefs, len(suspension_coefs), 3, suspension_query)
print("悬挂力在查询点的值:", result_suspension)
#悬挂力在查询点的值: [50,80,120,200,300]
示例3. 经济学 - 分段税收函数
不同收入区间的税率计算
income_breaks = [0, 50000, 100000, 200000, 500000, 1000000] # 收入($)
tax_coefs = [
[0.1, 0], # 0-50k: 10%
[0.2, -5000], # 50-100k: 20%
[0.3, -15000], # 100-200k: 30%
[0.4, -35000], # 200-500k: 40%
[0.5, -85000] # 500k-1M: 50%
]
income_query = [25000, 75000, 150000, 350000, 750000] # 查询收入
result_tax = ppval(income_breaks, tax_coefs, len(tax_coefs), 2, income_query)
print("各收入水平的税额:", result_tax)
#各收入水平的税额: [2500,0,0,25000,40000]
示例4. 物理学 - 材料应力应变曲线
材料在不同应变阶段的力学行为
strain_breaks = [0, 0.002, 0.01, 0.02, 0.05, 0.1] # 应变
stress_coefs = [
[200000, 0], # 弹性段: σ = Eε
[150000, 100], # 屈服过渡
[50000, 1500], # 塑性段
[20000, 2300], # 应变硬化
[10000, 2800] # 颈缩段
]
strain_query = [0.001, 0.005, 0.015, 0.03, 0.08] # 查询应变
result_stress = ppval(strain_breaks, stress_coefs, len(stress_coefs), 2, strain_query)
print("各应变点的应力值(MPa):", result_stress)
#各应变点的应力值(MPa): [200,550,1750,2500,3100]
示例5. 计算机图形学 - 动画缓动函数
不同时间区间的运动缓动效果
time_breaks = [0, 0.3, 0.7, 1.0] # 归一化时间
easing_coefs = [
[2, 0, 0, 0], # 开始加速
[0, 1, 0, 0.09], # 匀速
[-2, 3, -1.5, 0.7] # 结束减速
]
time_query = [0.1, 0.5, 0.9] # 查询时间
result_easing = ppval(time_breaks, easing_coefs, len(easing_coefs), 4, time_query)
print("缓动函数在查询点的位置:", result_easing)
#缓动函数在查询点的位置: [0.002,0.13,0.504]
示例6. 气象学 - 温度日变化模型
一天中不同时段的温度变化模式
hour_breaks = [0, 6, 12, 18, 24] # 小时
temperature_coefs = [
[-0.2, 15], # 深夜到清晨: 缓慢降温
[0.5, 13], # 上午: 快速升温
[0.1, 20], # 下午: 缓慢变化
[-0.3, 22] # 傍晚到深夜: 降温
]
hour_query = [3, 9, 15, 21] # 查询时间
result_temp = ppval(hour_breaks, temperature_coefs, len(temperature_coefs), 2, hour_query)
print("各时刻的温度预测(°C):", result_temp)
#各时刻的温度预测(°C): [14.4,14.5,20.3,21.1]
示例7. 医学 - 药物浓度时间曲线
药物在体内的吸收、分布、代谢过程
time_pharma_breaks = [0, 1, 4, 8, 12, 24] # 时间(小时)
concentration_coefs = [
[10, 0, 0], # 0-1h: 快速吸收
[-2, 12, -1], # 1-4h: 峰值附近
[-1, 8, 4], # 4-8h: 分布阶段
[-0.5, 4, 8], # 8-12h: 缓慢下降
[-0.2, 2, 10] # 12-24h: 消除阶段
]
time_pharma_query = [0.5, 2, 6, 10, 18] # 查询时间
result_concentration = ppval(time_pharma_breaks, concentration_coefs, len(concentration_coefs), 3, time_pharma_query)
print("各时间点的血药浓度(μg/mL):", result_concentration)
#各时间点的血药浓度(μg/mL): [2.5,9,16,14,14.8]
示例8. 金融工程 - 期权定价
不同执行价格区间的期权价格
strike_breaks = [80, 90, 100, 110, 120] # 执行价格
option_coefs = [
[0, 20], # 深度实值: 内在价值
[0.5, -25], # 实值区
[1.0, -50], # 平价附近
[0.5, -25] # 虚值区
]
strike_query = [85, 95, 105, 115] # 查询执行价
result_option = ppval(strike_breaks}, {option_coefs, len(option_coefs), 2, strike_query)
print("各执行价的期权价格:", result_option)
#各执行价的期权价格: [20,-22.5,-45,-22.5]
示例9. 声学 - 音频均衡器响应
不同频率段的增益特性
freq_breaks = [20, 100, 500, 2000, 8000, 20000] # 频率(Hz)
eq_coefs = [
[0.001, 0, 0, 0], # 超低频
[0.005, -0.5, 25, -250], # 低频
[0, 0, 0, 0], # 中频平坦
[-0.002, 4, -2000, 20000], # 中高频
[-0.001, 8, -32000, 256000] # 高频
]
freq_query = [50, 250, 1000, 5000, 15000] # 查询频率
result_eq = ppval(freq_breaks, eq_coefs, len(eq_coefs), 4, freq_query)
print("各频率点的增益(dB):", result_eq)
#各频率点的增益(dB): [2.70000e+01,9.12500e+03,0.00000e+00,-2.39800e+07,-1.74744e+08]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy.interpolate import PPoly
def polynomials_segmented(input_str):
"""
实现MATLAB ppval函数,计算分段多项式在给定点的值
参数格式:
"(breaks, coefs, pieces, order, xi)" -> 返回插值结果
或
"(breaks, coefs, pieces, order)" -> 返回符号表达式
输入要求:
- breaks: 分段区间断点,单调递增
- coefs: 多项式系数矩阵,形状(pieces, order)
- pieces: 分段数
- order: 多项式阶数
- xi: 查询点
返回:
符号表达式/数值结果 或 错误信息
"""
try:
# 解析输入字符串
expr = sp.sympify(input_str)
# 提取参数
params = []
if isinstance(expr, tuple):
params = list(expr)
else:
params = [expr]
# 参数验证
if len(params) < 4:
return "错误:至少需要breaks, coefs, pieces, order四个参数"
# 转换数据类型
breaks = np.array(params[0], dtype=np.float64)
coefs = np.array(params[1], dtype=np.float64)
pieces = int(params[2])
order = int(params[3])
xi = params[4] if len(params) > 4 else None
# 输入验证
if len(breaks) != pieces + 1:
return f"错误:breaks长度应为pieces+1 ({pieces + 1}), 实际为{len(breaks)}"
if not np.all(np.diff(breaks) > 0):
return "错误:breaks必须单调递增"
if coefs.shape != (pieces, order):
return f"错误:coefs形状应为({pieces}, {order}), 实际为{coefs.shape}"
# 构造分段多项式对象(兼容MATLAB的系数排列顺序)
pp = PPoly(coefs.T, breaks) # Scipy需要转置系数矩阵
# 符号表达式构造
t = sp.symbols('t')
piecewise_expr = []
for i in range(pieces):
# 提取当前区间的系数(注意MATLAB的系数顺序)
coeff = coefs[i, :]
# 构造多项式表达式:coeff[0]*(t-break_i)^{order-1} + ... + coeff[-1]
poly_terms = [
coeff[j] * (t - breaks[i]) ** (order - 1 - j)
for j in range(order)
]
poly = sum(poly_terms)
# 定义区间条件
if i == pieces - 1:
cond = (t >= breaks[i]) & (t <= breaks[i + 1])
else:
cond = (t >= breaks[i]) & (t < breaks[i + 1])
piecewise_expr.append((poly, cond))
# 构建完整表达式
final_expr = sp.Piecewise(*piecewise_expr)
# 根据输入类型返回结果
if xi is not None:
# 数值计算
xi = np.asarray(xi, dtype=np.float64)
return pp(xi)
else:
return final_expr
except Exception as e:
return f"错误:{str(e)}"
if __name__ == "__main__":
# ================== 测试用例 ==================
# 测试1:符号表达式
input1 = "([0, 1, 2], [[1, 2], [3, 4]], 2, 2)"
expr = polynomials_segmented(input1)
print("测试1 符号表达式:\n", expr)
# Piecewise((1.0*t + 2.0, (t < 1.0) & (t >= 0)),
# (3.0*t + 1.0, (t >= 1.0) & (t <= 2.0)))
# 测试2:数值计算
input2 = "([0, 1, 2, 3], [[1,2], [3,4], [5,6]], 3, 2, [0.5,1.5,2.5])"
print("\n测试2 插值结果:", polynomials_segmented(input2))
# [2.5 5.5 8.5]
# 测试3:复杂分段多项式
input3 = (
"([0, 1, 3, 4], "
"[[2, 3, 1, 5], [4, 1, 6, 2], [7, 3, 2, 1]], "
"3, 4, [0.5, 2.0, 3.5])"
)
print("\n测试3 插值结果:", polynomials_segmented(input3))
# [ 6.5 13. 3.625]
数据集的百分比
P = prctile(A,p)返回区间[0,100]中百分比P的输入数据A中元素的百分位数.
如果A是一个向量,那么p是一个标量.
如果A是矩阵,那么p是行向量或矩阵,其中P的行数等于长度(P).
P = prctile(A, p, 0)返回包含每列百分比的行向量.
P = median(A, p, 1)返回包含每行百分比的行向量.
A - 输入数组, 向量, 矩阵.
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import numpy as np
import sympy as sp
def percentiles_cal_array(input_str):
"""
对标 MATLAB 的 prctile 函数,计算数据的百分位数。
参数:
input_str: 输入字符串,格式为 SymPy 可解析的元组或矩阵表达式。
示例:
- 矩阵和百分位: "(Matrix([[1,2],[3,4]]), 50)"
- 指定轴: "(Matrix([[1,2],[3,4]]), 50, 1)" (MATLAB的dim=1对应axis=0)
返回:
计算结果的列表或数值,出错时返回错误信息。
"""
try:
# 修正输入表达式
# 将输入字符串转换为 SymPy 表达式
expr = sp.sympify(input_str)
result = None
# 检查表达式是否为元组
if isinstance(expr, tuple):
if len(expr) == 3:
M = sp.Matrix(expr[0]) if isinstance(expr[0], list) else None
# 检查是否为矩阵,百分位数是否在 0 到 100 之间,轴是否为 0 或 1
if M is not None and 0 <= int(expr[1]) <= 100 and int(expr[2]) in [0, 1]:
a = np.array(M)
p = int(expr[1])
axis = int(expr[2])
# 计算百分位数
result = np.percentile(a, p, axis=axis, method="hazen")
elif len(expr) == 2:
M = sp.Matrix(expr[0]) if isinstance(expr[0], list) else None
# 检查是否为矩阵,百分位数是否在 0 到 100 之间
if M is not None and 0 <= int(expr[1]) <= 100:
a = np.array(M)
p = int(expr[1])
# 计算百分位数
result = np.percentile(a, p, method="hazen")
return result if result is not None else f"输入错误: {input_str}"
except Exception as e:
return f"Error: {e}"
# 示例测试
if __name__ == "__main__":
# 示例1: 计算矩阵各列的中位数 (对标MATLAB prctile(A, 50, 1))
input_str = "([0.5377,1.8339,-2.2588,0.8622,0.3188,-1.3077,-0.4336],42)"
print(percentiles_cal_array(input_str))
# -0.102544000000000
采用银行贴现率计算收益率的折价证券价格
Price = prdisc(Settle,Maturity,Face,Discount)返回收益率以银行贴现率报价的证券的价格(例如,美国国库券)。
Settle - 结算日期
Maturity - 到期日
Discount - 证券银行贴现率
Face - 赎回(面值)值,指定为数值。
Basis - 用于时间因素计算的天数基础
Price - 折扣证券的价格,以数值形式返回。
示例1. 美国国库券 (T-Bill) - 短期政府债券(91天期限)
result1 = prdisc(Settle=2024-01-15,Maturity=2024-04-15,Face=10000,Discount=0.0475,Basis=2)
print(f"91天国库券价格: ${result1:.2f}")
#91天国库券价格: $9879.93
#应用: 投资者购买面值$10,000的91天国库券,贴现率4.75%
示例2. 商业票据 - 公司短期融资工具
result2 = prdisc(Settle=2024-02-01,Maturity=2024-08-01,Face=1000000,Discount=0.0525,Basis=0)
print(f"商业票据价格: ${result2:,.2f}")
#商业票据价格: $973,750.00
示例3. 银行承兑汇票 - 国际贸易融资(90天期限)
result3 = prdisc(Settle=2024-03-01,Maturity=2024-05-30,Face=50000,Discount=0.039,Basis=0)
print(f"银行承兑汇票价格: ${result3:.2f}")
#银行承兑汇票价格: $49517.92
示例4. 市政贴现债券 - 地方政府短期债务(1年期)
result4 = prdisc(Settle=2024-01-01,Maturity=2025-01-01,Face=25000,Discount=0.028,Basis=0)
print(f"市政债券价格: ${result4:.2f}")
#市政债券价格: $24300.00
示例5. 回购协议 - 隔夜融资
result5 = prdisc(Settle=2024-03-15,Maturity=2024-03-16,Face=10000000,Discount=0.035,Basis=2)
print(f"隔夜回购价格: ${result5:,.2f}")
#隔夜回购价格: $9,999,027.78
示例6. 大额可转让存单 - 银行融资工具(6个月期限)
result6 = prdisc(Settle=2024-02-01,Maturity=2024-08-01,Face=250000,Discount=0.0488,Basis=2)
print(f"大额存单价格: ${result6:,.2f}")
#大额存单价格: $243,832.22
示例7. 欧洲美元存款 - 离岸美元市场(3个月期限)
result7 = prdisc(Settle=2024-01-10,Maturity=2024-04-10,Face=5000000,Discount=0.0495,Basis=2)
print(f"欧洲美元存款价格: ${result7:,.2f}")
#欧洲美元存款价格: $4,937,437.50
示例8. 零息公司债券 - 长期贴现证券(2年期)
result8 = prdisc(Settle=2024-01-01,Maturity=2026-01-01,Face=1000,Discount=0.042,Basis=1)
print(f"零息债券价格: ${result8:.2f}")
#零息债券价格: $915.88
示例9. 不同日计数基准比较(日计数基准对价格的影响)
face = 1000
discount = 0.05
settle = "2024-01-01"
maturity = "2024-12-31"
Basis 0: 美国30/360
result_b0 = prdisc(f"Settle={settle},Maturity={maturity},Face={face},Discount={discount},Basis=0")
print(f"Basis 0 (美国30/360): ${result_b0:.4f}")
#Basis 0 (美国30/360): $950.1389
Basis 1: 实际/实际
result_b1 = prdisc(f"Settle={settle},Maturity={maturity},Face={face},Discount={discount},Basis=1")
print(f"Basis 1 (实际/实际): ${result_b1:.4f}")
#Basis 1 (实际/实际): $950.0000
Basis 2: 实际/360
result_b2 = prdisc(f"Settle={settle},Maturity={maturity},Face={face},Discount={discount},Basis=2")
print(f"Basis 2 (实际/360): ${result_b2:.4f}")
#Basis 2 (实际/360): $949.3056
Basis 3: 实际/365
result_b3 = prdisc(f"Settle={settle},Maturity={maturity},Face={face},Discount={discount},Basis=3")
print(f"Basis 3 (实际/365): ${result_b3:.4f}")
#Basis 3 (实际/365): $950.0000
Basis 4: 欧洲30/360
result_b4 = prdisc(f"Settle={settle},Maturity={maturity},Face={face},Discount={discount},Basis=4")
print(f"Basis 4 (欧洲30/360): ${result_b4:.4f}")
#Basis 4 (欧洲30/360): $950.1389
示例10. 贴现率敏感性分析
base_params = "Settle=2024-01-01,Maturity=2024-07-01,Face=1000"
discount_rates = [0.03, 0.04, 0.05, 0.06, 0.07]
for rate in discount_rates:
input_str = f"{base_params},Discount={rate},Basis=2"
price = prdisc(input_str)
print(f"贴现率 {rate:.1%}: 价格 ${price:.2f}")
#贴现率 3.0%: 价格 $984.83
#贴现率 4.0%: 价格 $979.78
#贴现率 5.0%: 价格 $974.72
#贴现率 6.0%: 价格 $969.67
#贴现率 7.0%: 价格 $964.61
小于等于输入值的质数
p = primes(n) 返回包含所有小于或等于n的质数的行向量. p与n具有相同的数据类型.
n — 输入值,标量、实整数值
示例1. 密码学应用 - RSA加密算法
primes_1000 = primes(1000)
large_primes = [p for p in primes_1000 if p > 500]
print(f"可用于RSA的大质数: {large_primes[:5]}")
#可用于RSA的大质数: [503, 509, 521, 523, 541]
#应用: RSA加密需要两个大质数的乘积作为公钥的一部分,质数越大,加密越安全。
示例2. 计算机科学 - 哈希表设计
def optimal_hash_size(min_size):
primes = primes(min_size * 2)
return min([p for p in primes if p >= min_size])
print(f"最接近100的质数哈希表大小: {optimal_hash_size(100)}")
#最接近100的质数哈希表大小: 101
#应用: 哈希表使用质数大小可以减少哈希冲突,提高性能。
示例3. 数学研究 - 质数间隔研究
primes_100 = primes(100)
gaps = [primes_100[i + 1] - primes_100[i] for i in range(len(primes_100) - 1)]
print(f"质数间隔: {gaps}")
print(f"最大间隔: {max(gaps)}")
#质数间隔: [1, 2, 2, 4, 2, 4, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4, 2, 6, 4, 6, 8]
#最大间隔: 8
#应用: 研究质数分布规律,验证质数定理。
示例4. 算法测试 - 验证不同质数生成算法
def sieve_of_eratosthenes(n):
# 埃拉托斯特尼筛法实现
primes = []
is_prime = [True] * (n + 1)
for i in range(2, n + 1):
if is_prime[i]:
primes.append(i)
for j in range(i * i, n + 1, i):
is_prime[j] = False
return primes
# 对比验证
n = 100
primes1 = primes(n)
primes2 = sieve_of_eratosthenes(n)
print(f"结果一致: {primes1 == primes2}")
#结果一致: True
#应用: 验证自定义质数生成算法的正确性。
示例5. 金融建模 - 蒙特卡洛模拟
import random
def monte_carlo_simulation(iterations, seed_prime):
random.seed(seed_prime)
# 使用质数种子确保结果可重现
results = []
for _ in range(iterations):
results.append(random.random())
return results
primes_1000 = primes(1000)
simulation_seeds = [p for p in primes_1000 if p > 100][:10]
print(f"可用的模拟种子: {simulation_seeds}")
#可用的模拟种子: [101, 103, 107, 109, 113, 127, 131, 137, 139, 149]
#应用: 使用质数作为随机数生成器种子,确保模拟结果的可重现性。
示例6. 网络安全 - 质性测试
def is_prime_miller_rabin(n, primes_list):
"""使用小质数进行初步筛选"""
if n < 2:
return False
if n in primes_list:
return True
# 更复杂的质性测试...
return None
test_numbers = [91, 97, 101, 121]
primes_150 = primes(150)
for num in test_numbers:
result = is_prime_miller_rabin(num, primes_150)
print(f"{num} 是质数: {result}")
#91 是质数: None
#97 是质数: True
#101 是质数: True
#121 是质数: None
#应用: 在复杂质性测试前先用简单方法筛选。
示例7. 游戏开发 - 随机地图生成
def generate_map(width, height, seed_prime):
random.seed(seed_prime)
# 使用质数尺寸减少模式重复
map_data = []
for y in range(height):
row = []
for x in range(width):
row.append(random.choice(['.', '#', 'T', '~']))
map_data.append(row)
return map_data
good_map_sizes = primes(500)
large_primes = [p for p in good_map_sizes if p > 200]
print(f"推荐的地图尺寸: {large_primes[:5]}")
#推荐的地图尺寸: [211, 223, 227, 229, 233]
#应用: 质数尺寸的地图可以减少视觉上的重复模式。
示例8. 数据分析 - 系统采样
def systematic_sampling(data, interval_prime):
"""使用质数间隔进行系统采样"""
sampled_data = []
for i in range(0, len(data), interval_prime):
if i < len(data):
sampled_data.append(data[i])
return sampled_data
data = list(range(1000))
sampling_intervals = primes(50)
print(f"可用的采样间隔: {sampling_intervals}")
#可用的采样间隔: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
#应用: 使用质数采样间隔避免数据中的周期性偏差。
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from sympy.core.sympify import SympifyError
def prime_range_list(input_str):
"""
对标MATLAB的primes函数,生成所有小于等于输入值的质数列表
参数:
input_str: 输入字符串,应能被SymPy解析为整数表达式
返回:
质数列表 (若输入有效)
错误信息 (若输入无效或无法解析)
示例:
prime_range_list("10") 返回 [2, 3, 5, 7]
prime_range_list("5.5") 返回 "输入错误:请输入非负整数,当前输入为5.5"
"""
try:
# 尝试将输入字符串解析为SymPy表达式
expr = sp.sympify(input_str)
# 检查是否为数值类型
if not expr.is_number:
return f"输入错误:'{input_str}' 不是有效数字"
# 检查是否为整数
if not expr.is_integer:
return f"输入错误:请输入非负整数,当前输入为{input_str}"
# 转换为Python整数
n = int(expr)
# 检查是否为非负数
if n < 0:
return f"输入错误:负数 {n} 无效"
# MATLAB primes(n) 当n<2时返回空数组
if n < 2:
return []
# 生成质数列表 (使用primerange包含上限需要+1)
return list(sp.primerange(2, n + 1))
# 处理表达式解析错误
except SympifyError:
return f"解析错误:'{input_str}' 不是有效表达式"
# 处理其他意外错误
except Exception as e:
return f"运行时错误:{str(e)}"
# 示例测试
if __name__ == "__main__":
# 测试正常输入
print(prime_range_list("10"))
# [2, 3, 5, 7]
print(prime_range_list("2"))
# [2]
print(prime_range_list("1"))
# []
# 测试边界值
print(prime_range_list("0"))
# []
print(prime_range_list("1+2"))
# [2, 3]
质数阶乘
primorial(n)返回所有小于或等于n的素数的乘积
n -- 输入, 标量, 整数
示例1. 数论研究 - 前n个质数的乘积
for n in range(1, 11):
result = primorial(n)
print(f"前{n}个质数的乘积: {result}")
#前1个质数的乘积: 1
#前2个质数的乘积: 2
#前3个质数的乘积: 6
#前4个质数的乘积: 6
#前5个质数的乘积: 30
#前6个质数的乘积: 30
#前7个质数的乘积: 210
#前8个质数的乘积: 210
#前9个质数的乘积: 210
#前10个质数的乘积: 210
示例2. 密码学应用 - RSA模数大小
rsa_sizes = [50, 100, 150]
for size in rsa_sizes:
result = primorial(size, False)
print(f"小于等于{size}的质数乘积位数: {len(str(result))} 位")
#小于等于50的质数乘积位数: 92 位
#小于等于100的质数乘积位数: 220 位
#小于等于150的质数乘积位数: 362 位
#应用: 理解大质数乘积在RSA加密中的重要性
示例3. 计算机科学 - 哈希函数参数
hash_primes = [10, 20, 30]
for n in hash_primes:
result = primorial(n)
print(f"前{n}个质数乘积: {result}")
print(f" 二进制位数: {result.bit_length()} bits")
#前10个质数乘积: 210
# 二进制位数: 8 bits
#前20个质数乘积: 9699690
# 二进制位数: 24 bits
#前30个质数乘积: 6469693230
# 二进制位数: 33 bits
#应用: 哈希函数中使用质数乘积减少冲突
示例4. 数学常数 - 质数乘积序列
sequences = [5, 7, 11]
for n in sequences:
result1 = primorial(n)
result2 = primorial(n, False)
print(f"n={n}: 前n个质数积={result1}, 小于等于n质数积={result2}")
#n=5: 前n个质数积=30, 小于等于n质数积=2310
#n=7: 前n个质数积=210, 小于等于n质数积=510510
#n=11: 前n个质数积=2310, 小于等于n质数积=200560490130
示例5. 数值分析 - 大数计算测试
test_values = [15, 25, 35]
for n in test_values:
result = primorial(n)
digit_count = len(result)
print(f"前{n}个质数乘积: {digit_count} 位数")
#前15个质数乘积: 5 位数
#前25个质数乘积: 9 位数
#前35个质数乘积: 12 位数
示例6. 组合数学 - 质数阶乘性质研究
for n in [4, 6, 8]:
primorial_n = primorial(n)
factorial_n = factorial(n)
ratio = factorial_n / primorial_n
print(f"n={n}: {n}! = {factorial_n}, p#{n} = {primorial_n}, 比值: {ratio:.2f}")
#n=4: 4! = 24, p#4 = 6, 比值: 4.00
#n=6: 6! = 720, p#6 = 30, 比值: 24.00
#n=8: 8! = 40320, p#8 = 210, 比值: 192.00
示例7. 算法复杂度 - 质数生成效率
sizes = [10, 20, 30, 40, 50]
for n in sizes:
result = primorial(n)
bits = result.bit_length()
print(f"前{n}个质数乘积: {bits} bits")
#前10个质数乘积: 8 bits
#前20个质数乘积: 24 bits
#前30个质数乘积: 33 bits
#前40个质数乘积: 43 bits
#前50个质数乘积: 60 bits
示例8. 密码分析 - 质数乘积的因子分解难度
security_levels = [25, 50, 75, 100]
for n in security_levels:
result = primorial(n)
print(f"前{n}个质数乘积的分解难度: 极高")
print(f" 数字位数: {len(str(result))}")
#前25个质数乘积的分解难度: 极高
# 数字位数: 9
#前50个质数乘积的分解难度: 极高
# 数字位数: 18
#前75个质数乘积的分解难度: 极高
# 数字位数: 29
#前100个质数乘积的分解难度: 极高
# 数字位数: 37
示例9. 数学教育 - 质数概念教学
educational_values = [3, 5, 7]
for n in educational_values:
result = primorial(n)
primes = list(primerange(2, prime(n) + 1))
print(f"前{n}个质数: {primes}")
print(f"它们的乘积: {result}")
#前3个质数: [2, 3, 5]
#它们的乘积: 6
#前5个质数: [2, 3, 5, 7, 11]
#它们的乘积: 30
#前7个质数: [2, 3, 5, 7, 11, 13, 17]
#它们的乘积: 210
示例10. 计算机安全 - 加密种子生成
seed_sizes = [8, 12, 16]
for n in seed_sizes:
result = primorial(n)
seed_value = result % (2**32) # 取32位种子
print(f"前{n}个质数乘积的32位种子: {seed_value}")
#前8个质数乘积的32位种子: 210
#前12个质数乘积的32位种子: 2310
#前16个质数乘积的32位种子: 30030
示例11. 数值范围 - 不同模式的对比
comparison_n = 10
mode1 = primorial(comparison_n)
mode2 = primorial(comparison_n, False)
print(f"前{comparison_n}个质数乘积: {mode1}")
print(f"小于等于{comparison_n}的质数乘积: {mode2}")
#前10个质数乘积: 210
#小于等于10的质数乘积: 6469693230
示例12. 大数据应用 - 分布式计算测试
distributed_tests = [18, 22, 26]
for n in distributed_tests:
result = primorial(n)
print(f"前{n}个质数乘积计算完成, 结果位数: {len(str(result))}")
#前18个质数乘积计算完成, 结果位数: 6
#前22个质数乘积计算完成, 结果位数: 7
#前26个质数乘积计算完成, 结果位数: 9
示例13. 数学研究 - 质数乘积增长率
for n in [5, 10, 15, 20]:
primorial = primorial(n)
log_value = log(primorial)
print(f"前{n}个质数乘积的自然对数: {log_value:.2f}")
#前5个质数乘积的自然对数: 3.40
#前10个质数乘积的自然对数: 5.35
#前15个质数乘积的自然对数: 10.31
#前20个质数乘积的自然对数: 16.09
示例14. 计算机体系结构 - 大数运算测试
arch_tests = [28, 32, 36]
for n in arch_tests:
result = primorial(n)
print(f"前{n}个质数乘积: {result.bit_length()} bits")
#前28个质数乘积: 28 bits
#前32个质数乘积: 38 bits
#前36个质数乘积: 38 bits
示例15. 密码协议 - 迪菲-赫尔曼参数
dh_params = [40, 60, 80]
for n in dh_params:
result = primorial(n, False)
print(f"小于等于{n}的质数乘积可作为大素数域的参考")
#小于等于40的质数乘积可作为大素数域的参考
#小于等于60的质数乘积可作为大素数域的参考
#小于等于80的质数乘积可作为大素数域的参考
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from sympy.core.sympify import SympifyError
def prime_product(input_str):
"""
对标MATLAB的primorial函数,计算质数阶乘
参数:
input_str: 输入字符串,支持两种模式:
- 单个整数n: 计算前n个质数的乘积 (MATLAB默认行为)
- 元组(n, False): 计算所有≤n的质数的乘积
返回:
计算结果数值 (若输入有效)
错误信息 (若输入无效或无法解析)
示例:
prime_product("5") 返回 2310 (2×3×5×7×11)
prime_product("(5, False)") 返回 30 (2×3×5)
"""
try:
expr = sp.sympify(input_str)
nth_flag = True # 默认MATLAB模式:前n个质数的乘积
n = None
# 解析输入参数
if isinstance(expr, tuple):
if len(expr) != 2:
return f"输入错误:需要(数值, 模式)格式,当前长度{len(expr)}"
# 提取数值部分
n_expr = expr[0]
if not n_expr.is_integer or n_expr < 0:
return f"数值错误:{n_expr} 应为非负整数"
# 提取模式标识
mode = expr[1]
if mode == sp.false:
nth_flag = False
elif mode == sp.true:
nth_flag = True
else:
return f"模式错误:{mode} 应为True/False"
n = int(n_expr)
elif expr.is_integer and expr >= 0:
n = int(expr)
else:
return f"输入错误:'{input_str}' 应为整数或元组"
# 执行计算
if nth_flag:
# MATLAB模式:前n个质数的乘积
if n == 0:
return 1 # 空乘积约定
return sp.primorial(n, nth=False)
else:
# 所有≤n的质数的乘积
if n < 2:
return 1
return sp.primorial(n)
except SympifyError:
return f"解析错误:'{input_str}' 不是有效表达式"
except Exception as e:
return f"运行时错误:{str(e)}"
# 示例测试
if __name__ == "__main__":
# 测试前n个质数模式
print(prime_product("3"))
# 6
print(prime_product("5"))
# 30
print(prime_product("0"))
# 1
到期含息价格
[Price,AccruInterest] = prmat(Settle,Maturity,Issue,Face,CouponRate,Yield) 返回到期支付利息的证券的价格和应计利息。
Settle - 证券结算日期
Maturity - 证券到期日
Issue - 证券发行日期
Face - 赎回价值(票面价值)
CouponRate - 息票率
Yield - 年产量,年收益
Basis - 用于时间因素计算的天数基础
Price - 证券价格,以数值形式返回
AccruInterest - 担保应计利息
示例1. 短期公司债券 - 商业票据
result1 = prmat(Settle=2024-02-01,Maturity=2024-08-01,Issue=2024-02-01,Face=1000000,CouponRate=0.0525,Yield=0.0525,Basis=2)
print(f"商业票据 - 净价: ${result1[0]:,.2f}, 应计利息: ${result1[1]:,.2f}")
#商业票据 - 净价: $1,000,000.00, 应计利息: $0.00
#应用: 公司发行180天商业票据,面值$1,000,000,票面利率5.25%
示例2. 中期国债 - 2年期零息债券
result2 = prmat(Settle=2024-01-15,Maturity=2026-01-15,Issue=2024-01-15,Face=10000,CouponRate=0.042,Yield=0.042,Basis=1)
print(f"零息国债 - 净价: ${result2[0]:,.2f}, 应计利息: ${result2[1]:,.2f}")
#零息国债 - 净价: $10,000.00, 应计利息: $0.00
#应用: 2年期零息国债,面值$10,000,到期收益率4.2%
示例3. 市政债券 - 地方政府基础设施债券
result3 = prmat(Settle=2024-03-01,Maturity=2025-03-01,Issue=2024-01-01,Face=25000,CouponRate=0.028,Yield=0.028,Basis=0)
print(f"市政债券 - 净价: ${result3[0]:,.2f}, 应计利息: ${result3[1]:,.2f}")
#市政债券 - 净价: $24,996.87, 应计利息: $115.07
#应用: 地方政府基础设施债券,面值$25,000,票面利率2.8%
示例4. 企业债券 - 投资级公司债
result4 = prmat(Settle=2024-02-15,Maturity=2027-02-15,Issue=2024-01-01,Face=1000,CouponRate=0.055,Yield=0.055,Basis=1)
print(f"企业债券 - 净价: ${result4[0]:,.2f}, 应计利息: ${result4[1]:,.2f}")
#企业债券 - 净价: $999.05, 应计利息: $6.72
#应用: 投资级公司债券,面值$1,000,票面利率5.5%
示例5. 银行资本债券 - 额外一级资本债
result5 = prmat(Settle=2024-03-01,Maturity=2029-03-01,Issue=2024-01-01,Face=1000000,CouponRate=0.065,Yield=0.065,Basis=1)
print(f"银行资本债 - 净价: ${result5[0]:,.2f}, 应计利息: ${result5[1]:,.2f}")
#银行资本债 - 净价: $997,342.77, 应计利息: $10,833.33
#应用: 银行额外一级资本债,面值$1,000,000,票面利率6.5%
示例6. 可赎回债券 - 含发行人赎回权
result6 = prmat(Settle=2024-04-01,Maturity=2026-04-01,Issue=2024-01-01,Face=50000,CouponRate=0.048,Yield=0.048,Basis=1)
print(f"可赎回债券 - 净价: ${result6[0]:,.2f}, 应计利息: ${result6[1]:,.2f}")
#可赎回债券 - 净价: $49,947.45, 应计利息: $600.00
#应用: 含发行人赎回权的公司债券,面值$50,000,票面利率4.8%
示例7. 高收益债券 - 垃圾债券
result7 = prmat(Settle=2024-02-20,Maturity=2025-02-20,Issue=2024-01-01,Face=1000,CouponRate=0.095,Yield=0.095,Basis=1)
print(f"高收益债券 - 净价: ${result7[0]:,.2f}, 应计利息: ${result7[1]:,.2f}")
#高收益债券 - 净价: $998.88, 应计利息: $12.93
#应用: 信用评级较低的公司债券,面值$1,000,票面利率9.5%
示例8. 浮动利率债券 - 基准利率挂钩
result8 = prmat(Settle=2024-03-15,Maturity=2025-03-15,Issue=2024-01-15,Face=100000,CouponRate=0.0375,Yield=0.0375,Basis=2)
print(f"浮动利率债 - 净价: ${result8[0]:,.2f}, 应计利息: ${result8[1]:,.2f}")
#浮动利率债 - 净价: $99,977.11, 应计利息: $625.00
#应用: 与基准利率挂钩的浮动利率债券,面值$100,000
示例9. 通胀挂钩债券 - TIPS
result9 = prmat(Settle=2024-02-01,Maturity=2026-02-01,Issue=2024-01-01,Face=10000,CouponRate=0.015,Yield=0.015,Basis=1)
print(f"通胀保护债 - 净价: ${result9[0]:,.2f}, 应计利息: ${result9[1]:,.2f}")
#通胀保护债 - 净价: $9,999.64, 应计利息: $12.50
#应用: 通胀保值国债(TIPS),面值$10,000,实际利率1.5%
示例10. 永续债券 - 无到期日(模拟10年)
result10 = prmat(Settle=2024-01-01,Maturity=2034-01-01,Issue=2024-01-01,Face=1000000,CouponRate=0.045,Yield=0.045,Basis=1)
print(f"永续债券 - 净价: ${result10[0]:,.2f}, 应计利息: ${result10[1]:,.2f}")
#永续债券 - 净价: $1,000,000.00, 应计利息: $0.00
#应用: 永续债券10年价格模拟,面值$1,000,000,票面利率4.5%
示例11. 不同日计数基准比较
base_params = "Settle=2024-03-01,Maturity=2025-03-01,Issue=2024-01-01,Face=1000,CouponRate=0.05,Yield=0.05"
for basis in [0, 1, 2, 3]:
input_str = f"{base_params},Basis={basis}"
clean_price, accrued_interest = prmat(input_str)
basis_names = {0: "实际/实际", 1: "30/360", 2: "实际/360", 3: "实际/365"}
print(f"Basis {basis} ({basis_names[basis]}): 净价=${clean_price:.4f}, 应计利息=${accrued_interest:.4f}")
#Basis 0 (实际/实际): 净价=$999.6086, 应计利息=$8.2192
#Basis 1 (30/360): 净价=$999.6032, 应计利息=$8.3333
#Basis 2 (实际/360): 净价=$999.5979, 应计利息=$8.3333
#Basis 3 (实际/365): 净价=$999.6086, 应计利息=$8.2192
示例12. 收益率变动敏感性分析
base_case = "Settle=2024-02-01,Maturity=2025-02-01,Issue=2024-01-01,Face=1000,CouponRate=0.05,Basis=1"
yield_rates = [0.03, 0.04, 0.05, 0.06, 0.07]
for yld in yield_rates:
input_str = f"{base_case},Yield={yld}"
clean_price, accrued_interest = prmat(input_str)
print(f"收益率 {yld:.1%}: 净价=${clean_price:.2f}, 应计利息=${accrued_interest:.2f}")
#收益率 3.0%: 净价=$1019.30, 应计利息=$4.17
#收益率 4.0%: 净价=$1009.46, 应计利息=$4.17
#收益率 5.0%: 净价=$999.80, 应计利息=$4.17
#收益率 6.0%: 净价=$990.33, 应计利息=$4.17
#收益率 7.0%: 净价=$981.04, 应计利息=$4.17
国库券价格
Price = prtbill(Settle,Maturity,Face,Discount) 返回国库券价格。
Settle - 国库券结算日期
Maturity - 国库券到期日,
Face - 国库券的赎回价值(票面价值)
Discount - 国库券贴现率
Price - 国库券价格
示例1. 91天国库券 - 典型短期品种
result1 = prtbill(Settle=2024-01-15,Maturity=2024-04-15,Face=100,Discount=0.0175)
print(f"91天国库券价格: {result1}")
print("应用: 投资者购买面值100元的91天国库券,贴现率1.75%")
print(f"投资金额: {result1}元, 到期收益: {100 - result1:.4f}元")
#91天国库券价格: 99.5637
#应用: 投资者购买面值100元的91天国库券,贴现率1.75%
#投资金额: 99.5637元, 到期收益: 0.4363元
示例2. 182天国库券 - 半年期品种
result2 = prtbill(Settle=2024-02-01,Maturity=2024-08-01,Face=100,Discount=0.0192)
print(f"182天国库券价格: {result2}")
print("应用: 半年期国库券,贴现率1.92%,适合中期现金管理")
#182天国库券价格: 99.0426
#应用: 半年期国库券,贴现率1.92%,适合中期现金管理
示例3. 273天国库券 - 9个月期品种
result3 = prtbill(Settle=2024-03-01,Maturity=2024-12-01,Face=100,Discount=0.0205)
print(f"273天国库券价格: {result3}")
print("应用: 9个月期国库券,贴现率2.05%,收益率略高于短期品种")
#273天国库券价格: 98.4555
#应用: 9个月期国库券,贴现率2.05%,收益率略高于短期品种
示例4. 1年期国库券 - 长期贴现品种
result4 = prtbill(Settle=2024-01-01,Maturity=2025-01-01,Face=100,Discount=0.0218)
print(f"1年期国库券价格: {result4}")
print("应用: 1年期贴现国库券,贴现率2.18%,适合长期现金配置")
#1年期国库券价格: 97.814
#应用: 1年期贴现国库券,贴现率2.18%,适合长期现金配置
示例5. 大额投资 - 机构投资者
result5 = prtbill(Settle=2024-02-15,Maturity=2024-05-15,Face=1000000,Discount=0.0180)
print(f"大额91天国库券价格: {result5:,.2f}元")
print("应用: 机构投资者购买100万元91天国库券,贴现率1.80%")
print(f"投资金额: {result5:,.2f}元, 到期收益: {1000000 - result5:,.2f}元")
#大额91天国库券价格: 995,561.64元
#应用: 机构投资者购买100万元91天国库券,贴现率1.80%
#投资金额: 995,561.64元, 到期收益: 4,438.36元
示例6. 不同贴现率比较 - 市场利率变动
base_params = "Settle=2024-03-01,Maturity=2024-09-01,Face=100"
discount_rates = [0.015, 0.018, 0.021, 0.024, 0.027]
for rate in discount_rates:
price = prtbill(base_params,Discount=rate)
print(f"贴现率 {rate * 100:.1f}%: 价格 = {price:.4f}元")
#贴现率 1.5%: 价格 = 99.2438元
#贴现率 1.8%: 价格 = 99.0926元
#贴现率 2.1%: 价格 = 98.9414元
#贴现率 2.4%: 价格 = 98.7901元
#贴现率 2.7%: 价格 = 98.6389元
示例7. 节假日前后 - 特殊时点投资
春节前发行,节后到期
result7 = prtbill(Settle=2024-01-20,Maturity=2024-02-20,Face=100,Discount=0.0165)
print(f"春节前后31天国库券价格: {result7}")
#春节前后31天国库券价格: 99.8599
#应用: 节假日短期现金管理,贴现率1.65%
示例8. 季度末 - 流动性紧张时期
result8 = prtbill(Settle=2024-03-25,Maturity=2024-04-25,Face=100,Discount=0.0195)
print(f"季度末31天国库券价格: {result8}")
#季度末31天国库券价格: 99.8344
#应用: 季度末市场流动性紧张,贴现率相对较高1.95%
示例9. 货币政策宽松期 - 低利率环境
result9 = prtbill(Settle=2024-04-01,Maturity=2024-07-01,Face=100,Discount=0.0145)
print(f"宽松期91天国库券价格: {result9}")
#宽松期91天国库券价格: 99.6385
#应用: 货币政策宽松时期,贴现率较低1.45%
示例10. 货币政策紧缩期 - 高利率环境
result10 = prtbill(Settle=2024-05-01,Maturity=2024-08-01,Face=100,Discount=0.0255)
print(f"紧缩期92天国库券价格: {result10}")
#紧缩期92天国库券价格: 99.3573
#应用: 货币政策紧缩时期,贴现率较高2.55%
示例11. 原始示例验证
original_result = prtbill(Settle=2002-02-10,Maturity=2002-08-06,Face=1000,Discount=0.0377)
print(f"原始示例结果: {original_result}")
#原始示例结果: 981.7181
示例12. 不同期限收益率曲线
settle_date = "2024-01-01"
face_value = 100
durations = [
("1个月", "2024-02-01", 0.0160),
("3个月", "2024-04-01", 0.0175),
("6个月", "2024-07-01", 0.0190),
("9个月", "2024-10-01", 0.0205),
("1年", "2025-01-01", 0.0218)
]
for name, maturity_date, discount_rate in durations:
input_str = f"Settle={settle_date},Maturity={maturity_date},Face={face_value},Discount={discount_rate}"
price = prtbill(input_str)
print(f"{name}国库券: 价格 = {price:.4f}, 贴现率 = {discount_rate * 100:.2f}%")
#1年国库券: 价格 = 97.8140, 贴现率 = 2.18%
digamma和polygamma函数
Y = psi(X) 为数组X的每个元素计算digamma函数,各元素必须为非负实数.
Y = psi(k,X) 计算X的polygamma函数,计算的值是在X处的digamma函数的k阶导数.因此,psi(0,X)是digamma函数,psi(1,X)是trigamma函数,psi(2,X)是tetragamma函数,以此类推.
X是标量,向量,矩阵,多维数组
k是导数的阶,非负整数标量.
示例1:基础数值计算
计算 digamma 函数
print("digamma(1):", psi(1))
print("digamma(0.5):", psi(0.5))
print("digamma(10):", psi(10))
#digamma(1): -0.5772156649015331
#digamma(0.5): -1.9635100260214229
#digamma(10): 2.2517525890667205
计算 polygamma 函数
print("polygamma(1, 0.5):", psi(1, 0.5))
print("polygamma(2, 3):", psi(2, 3))
#polygamma(1, 0.5): 4.93480220054468
#polygamma(2, 3): -0.15411380631918856
示例2:统计学应用(Beta 分布的导数)
Beta 分布的对数似然函数的导数涉及 digamma 函数
对于 Beta(α,β) 分布,对数似然的导数包含 ψ(α) - ψ(α+β)
alpha, beta = 2, 3
print(f"d/dα log Beta({alpha},{beta}):",
float(psi(alpha)) -
float(psi(alpha + beta)))
#d/dα log Beta(2,3): -1.0833333333333333
示例3:复数计算
计算复数的 digamma 函数
print("digamma(1+2j):", psi(1+2@i))
print("digamma(0.5-0.5j):", psi(0.5-0.5@i))
#digamma(1+2j): 0.7145915153739777+1.3208072826422304i
#digamma(0.5-0.5j): -0.8681073626454777-1.4406595199775145i
示例4:矩阵/数组计算
对矩阵元素计算 digamma 函数
matrix_input = [[1, 2], [0.5, 3]]
result = psi(matrix_input)
print(result)
#[[-0.57721566,0.42278434]
[-1.96351003,0.92278434]]
对向量计算 polygamma 函数
vector_input = (1, [0.5, 1, 1.5])
print(psi(vector_input))
#[4.9348022,1.64493407,0.9348022]
示例5:符号计算
符号变量的 digamma 函数
print("digamma(x):", psi(x))
#digamma(x): polygamma(0, x)
符号变量的 polygamma 函数
print("polygamma(1, y):", psi(1, y))
#polygamma(1, y): polygamma(1, y)
混合表达式
print("digamma(2*x+1):", psi(2*x+1))
#digamma(2*x+1): polygamma(0, 2*x + 1)
示例6:数论应用
黎曼 zeta 函数与 polygamma 的关系
ζ(2) = -ψ'(1) = polygamma(1,1)
print("ζ(2) ≈", -float(psi(1, 1)))
#ζ(2) ≈ -1.6449340668482266
示例7:物理学应用(量子力学)
在量子力学中,谐振子的能级涉及 digamma 函数
计算谐振子波函数的归一化常数相关项
n = 3 # 量子数
print(f"谐振子 n={n} 的相关项:", psi(n + 0.5))
#谐振子 n=3 的相关项: 1.1031566406452438
示例8:数值分析验证
验证 digamma 函数的递推关系:ψ(z+1) = ψ(z) + 1/z
z = 2.5
psi_z = psi(z)
psi_z_plus_1 = psi(z + 1)
print(f"验证递推关系: ψ({z + 1}) - ψ({z}) = {float(psi_z_plus_1) - float(psi_z)}")
print(f"1/{z} = {1 / z}")
print(f"误差: {abs((float(psi_z_plus_1) - float(psi_z)) - 1 / z)}")
#验证递推关系: ψ(3.5) - ψ(2.5) = 0.4
#1/2.5 = 0.4
#误差: 0.0
示例9:特殊值计算
计算一些特殊点的值
special_points = [0.25, 0.5, 1, 2, 3]
for point in special_points:
result = psi(point)
print(f"ψ({point}) = {result}")
#ψ(0.25) = -4.2274535333762655
#ψ(0.5) = -1.9635100260214229
#ψ(1) = -0.5772156649015331
#ψ(2) = 0.4227843350984666
#ψ(3) = 0.9227843350984666
示例10:高维数组处理
处理 3D 数组
array_3d = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
result = psi(array_3d)
print(result)
#[[[-0.57721566,0.42278434]
[0.92278434,1.25611767]]
[[1.50611767,1.70611767]
[1.87278434,2.01564148]]]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.special import polygamma, digamma
def psi_digamma_polygamma_func(input_str):
"""
对标 MATLAB 的 psi 函数,计算双伽玛函数 (digamma) 或多伽玛函数 (polygamma)。
参数:
input_str: 输入的字符串表达式,可以是数值、矩阵、符号表达式,或形如 "(n, x)" 的元组。
返回:
计算结果 (数值、符号表达式、矩阵) 或错误信息。
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
# 确定阶数 n 和变量 x
if isinstance(expr, tuple) and len(expr) == 2:
# 处理元组输入,如 "(n, x)"
if all(e.is_number for e in expr):
k = int(expr[0])
p = float(expr[1])
result = polygamma(k, p)
else:
result = sp.polygamma(*expr).evalf()
elif expr.is_number:
z = complex(expr)
result = digamma(z)
elif expr.free_symbols:
k = 0
p = expr
result = sp.polygamma(k, p).evalf()
else:
error = True
return result if not error else f"输入错误:{input_str}"
except Exception as e:
return f"错误: {e}"
# 示例代码
if __name__ == "__main__":
# 示例 1: 计算 digamma(5)
print("digamma(5):", psi_digamma_polygamma_func("5"))
# (1.5061176684317998+0j)
# 示例 2: 计算 polygamma(1, 0.5)
print("polygamma(1, 0.5):", psi_digamma_polygamma_func("(1, 0.5)"))
# 4.93480220054468
# 示例 3: 计算 polygamma(1, x)
print("polygamma(1, x):", psi_digamma_polygamma_func("1, x"))
# polygamma(1, x)