锯齿波或三角波
x = sawtooth(t)为时间数组t的元素生成周期为2π的锯齿波. sawtooth类似于正弦函数,但会创建峰值为-1和1的锯齿波.锯齿波定义为在2π的倍数处为-1,而在所有其他时间处以斜率为1/π 随时间呈现线性增加.
x = sawtooth(t,xmax) 生成修正三角波,其每个周期的最大值位置由xmax控制, 默认值1.
t — 时间数组,向量,矩阵
示例1:电子学 - 扫描信号发生器
应用: 示波器时基扫描、频率扫描源
x1, y1 = sawtooth(t)
plt.subplot(3, 2, 1)
plt.plot(x1, y1)
plt.title("扫描信号发生器 (锯齿波)")
plt.grid(True)
plt.ylabel("电压 (V)")
示例2:通信工程 - 对称调制信号
应用: 调频调制、测试信号
x2, y2 = sawtooth(t, 0.5)
plt.subplot(3, 2, 2)
plt.plot(x2, y2)
plt.title("对称三角波 (占空比=0.5)")
plt.grid(True)
plt.ylabel("幅度")
示例3:非对称三角波 - PWM控制信号
应用: 电机速度控制、电源调节
x3, y3 = sawtooth(t, 0.2)
plt.subplot(3, 2, 3)
plt.plot(x3, y3)
plt.title("非对称三角波 (占空比=0.2)")
plt.grid(True)
plt.ylabel("控制信号")
示例4:高频锯齿波 - 时钟信号
应用: 数字系统时钟、定时器
x4, y4 = sawtooth(5t) # 5倍频率
plt.subplot(3, 2, 4)
plt.plot(x4, y4)
plt.title("高频时钟信号")
plt.grid(True)
plt.ylabel("逻辑电平")
示例5:音频工程 - 音乐合成
应用: 电子音乐、声音合成
x5, y5 = sawtooth(2@pi*440*t) # A4音调 (440Hz)
plt.subplot(3, 2, 5)
plt.plot(x5[:100], y5[:100]) # 只显示前100个点以便观察波形
plt.title("音频合成 (A4=440Hz)")
plt.grid(True)
plt.xlabel("时间")
plt.ylabel("声压")
示例6:复杂调制 - 线性调频信号
应用: 雷达距离测量、频率扫描
x6, y6 = sawtooth(t + 0.1*t^2) # 频率随时间变化
plt.subplot(3, 2, 6)
plt.plot(x6, y6)
plt.title("线性调频信号")
plt.grid(True)
plt.xlabel("时间")
plt.ylabel("发射信号")
plt.tight_layout()
plt.show()
示例7:机械工程 - 位置控制信号
应用: CNC机床、机器人轨迹控制
x7, y7 = sawtooth(2t, 0.5)
plt.figure(figsize=(10, 4))
plt.plot(x7, y7)
plt.title("机械位置控制信号")
plt.xlabel("时间")
plt.ylabel("位置指令")
plt.grid(True)
plt.show()
示例8:医疗设备 - 生理信号模拟
应用: 医疗设备校准、信号测试
x8, y8 = sawtooth(0.5t, 0.8)
plt.figure(figsize=(10, 4))
plt.plot(x8, y8)
plt.title("心电图测试信号")
plt.xlabel("时间 (s)")
plt.ylabel("电压 (mV)")
plt.grid(True)
plt.show()
示例9:汽车电子 - 转速传感器信号
应用: 发动机控制、ABS系统
x9, y9 = sawtooth(10t) # 高频信号
plt.figure(figsize=(10, 4))
plt.plot(x9, y9)
plt.title("发动机转速传感器信号")
plt.xlabel("时间")
plt.ylabel("脉冲信号")
plt.grid(True)
plt.show()
示例10:电力系统 - 电压调节波形
应用: 开关电源、逆变器控制
x10, y10 = sawtooth(t, 0.3)
plt.figure(figsize=(10, 4))
plt.plot(x10, y10)
plt.title("电压调节控制信号")
plt.xlabel("时间")
plt.ylabel("控制电压")
plt.grid(True)
plt.show()
示例11:通信系统 - 载波信号
应用: 调制解调、频移键控
x11, y11 = sawtooth(20t) # 高频载波
plt.figure(figsize=(10, 4))
plt.plot(x11[:50], y11[:50]) # 只显示部分以便观察
plt.title("通信载波信号")
plt.xlabel("时间")
plt.ylabel("载波幅度")
plt.grid(True)
plt.show()
示例12:测试测量 - 仪器校准信号
应用: 示波器校准、信号发生器
x12, y12 = sawtooth(t, 0.6)
plt.figure(figsize=(10, 4))
plt.plot(x12, y12)
plt.title("测试仪器校准信号")
plt.xlabel("时间")
plt.ylabel("标准信号")
plt.grid(True)
plt.show()
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
def sawtooth_wave(input_str):
"""
根据输入生成锯齿波或三角波,对标MATLAB的sawtooth函数。
参数:
input_str: 字符串输入,可以是以下形式:
- 时间变量,如 "t"
- 时间数组,如 "[0, 0.1, 0.2]"
- 元组形式的时间和占空比,如 "(t, 0.5)"(占空比必须在0到1之间)
返回:
tuple: (x_values, y_values) 分别为时间数组和对应的波形值。
错误时返回错误信息字符串。
"""
try:
expr = sp.sympify(input_str)
duty = 1.0 # 默认占空比为1(锯齿波)
x_values = None
# 处理元组输入(时间和占空比)
if isinstance(expr, tuple):
if len(expr) != 2:
raise ValueError("输入元组必须包含两个元素:时间和占空比")
t_expr, duty_expr = expr
# 解析占空比
try:
duty = float(duty_expr.evalf())
if not (0 <= duty <= 1):
raise ValueError("占空比必须在0到1之间")
except:
raise ValueError("无效的占空比")
# 解析时间表达式
matrix = sp.Matrix(t_expr) if isinstance(t_expr, list) else None
if matrix is not None:
x_values = np.array(matrix).astype(float).ravel()
elif isinstance(t_expr, sp.Expr):
# 生成默认时间序列(0到2π,500个点)以匹配MATLAB的周期
var = next(iter(t_expr.free_symbols)) if t_expr.free_symbols else None
t = np.linspace(0, 2 * np.pi, 500, endpoint=False)
x_values = sp.lambdify(var, t_expr, 'numpy')(t)
else:
raise ValueError("无法解析时间表达式")
# 处理非元组输入
else:
matrix = sp.Matrix(expr) if isinstance(expr, list) else None
if matrix is not None:
x_values = np.array(matrix).astype(float).ravel()
elif isinstance(expr, sp.Expr):
# 生成默认时间序列(0到2π,500个点)
var = next(iter(expr.free_symbols)) if expr.free_symbols else None
t = np.linspace(0, 2 * np.pi, 500, endpoint=False)
x_values = sp.lambdify(var, expr, 'numpy')(t)
else:
raise ValueError("无法解析输入表达式")
# 生成波形(不再额外乘以2π)
y_values = signal.sawtooth(x_values, width=duty)
return x_values, y_values
except Exception as e:
return f"错误: {str(e)}"
# 示例代码
if __name__ == "__main__":
# 示例1:基本锯齿波(width=1)
x, y = sawtooth_wave("t")
plt.figure(figsize=(10, 4))
plt.plot(x, y)
plt.title("Sawtooth Wave (duty=1)")
plt.grid(True)
plt.show()
# 示例2:复杂表达式
x, y = sawtooth_wave("t*pi/2*sin(t/5)")
plt.figure(figsize=(10, 4))
plt.plot(x, y)
plt.title("Custom Waveform: t*pi/2*sin(t/5)")
plt.grid(True)
plt.show()
舒尔分解
[U,T] = schur(A,mode) 返回酉矩阵U, 舒尔矩阵T. 并满足 A = U*T*U'.
如果mode为"real", U, T = schur(A,mode)(其中 A 为实矩阵),返回实数拟三角舒尔矩阵T. 如果mode为"complex",则返回复数三角舒尔矩阵.
如果A为复矩阵,则不管mode的值是多少,schur都返回复数舒尔形式.
t — 时间数组,向量,矩阵
示例1:控制系统稳定性分析
状态空间矩阵,特征值实部决定稳定性
A_control = [
[-2, 1, 0],
[0, -1, 2],
[1, 0, -3]
]
Z1, T1 = schur(A_control)
舒尔分解上三角矩阵 T (对角线为特征值):
print(T1)
#[[-2.76068985340228, 0.461218792350156, 0.714369684509237],
[-1.59565735701600, -2.76068985340228, 1.12202337766324],
[0, 0, -0.478620293195433]]
print("特征值实部:", [T1[i,i] for i in range(3)])
#特征值实部: [-2.76068985340228, -2.76068985340228, -0.478620293195433]
#结论: 所有特征值实部为负,系统稳定
示例2:结构动力学 - 模态分析
质量-弹簧系统矩阵
A_structure = [
[2, -1, 0],
[-1, 2, -1],
[0, -1, 1]
]
Z2, T2 = schur(A_structure)
舒尔分解结果:
print("特征值 (固有频率平方):", [T2[i,i] for i in range(3)])
#特征值 (固有频率平方): [3.24697960371747, 1.55495813208737, 0.198062264195162]
模态形状 (Z矩阵列向量):
for i in range(3):
print(f"模态 {i+1}: {[float(Z2[j,i]) for j in range(3)]}")
#模态 1: [-0.5910090485061033, 0.7369762290995782, -0.32798527760568175]
#模态 2: [-0.7369762290995783, -0.3279852776056815, 0.5910090485061034]
#模态 3: [0.3279852776056817, 0.5910090485061033, 0.7369762290995783]
示例3:量子力学 - 哈密顿量对角化
简单量子系统哈密顿量
A_quantum = [
[2, 1, 0],
[1, 1, 1],
[0, 1, 2]
]
Z3, T3 = schur(A_quantum, complex)
复数舒尔分解:
print("能级 (特征值):", [T3[i,i] for i in range(3)])
#能级 (特征值): [-2.50140208989734e-17, 2, 3]
本征态 (Z矩阵):
print(Z3.evalf(4))
#[[-0.4082, -0.7071, -0.5773],
[0.8165, 2.168e-16, -0.5773],
[-0.4082, 0.7071, -0.5773]]
示例4:电力系统 - 小信号稳定分析
发电机动态系统矩阵
A_power = [
[-0.5, 1.0, 0.0],
[-1.0, -0.2, 0.5],
[0.0, -0.5, -0.3]
]
Z4, T4 = schur(A_power)
eigenvalues = [T4[i,i] for i in range(3)]
print("\n特征值:", eigenvalues)
#特征值: [-0.329634826808644, -0.329634826808644, -0.340730346382713]
damping_ratios = [-float(sp.re(eig))/abs(eig) if float(sp.re(eig)) < 0 else 0
for eig in eigenvalues]
print("阻尼比:", [f"{ratio:.3f}" for ratio in damping_ratios])
#阻尼比: ['1.000', '1.000', '1.000']
示例5:化学工程 - 反应动力学稳定性
化学反应网络矩阵
A_chemical = [
[-1.2, 0.5, 0.3],
[0.8, -0.9, 0.2],
[0.1, 0.4, -0.7]
]
Z5, T5 = schur(A_chemical)
eigenvals_chem = [T5[i,i] for i in range(3)]
print("\n特征值 (时间常数倒数):", eigenvals_chem)
#特征值 (时间常数倒数): [-1.66195455511498, -0.150493548178159, -0.987551896706862]
time_constants = [-1/float(eig) if float(eig) < 0 else float('inf')
for eig in eigenvals_chem]
print("时间常数:", [f"{tau:.3f}" if tau != float('inf') else "∞"
for tau in time_constants])
#时间常数: ['0.602', '6.645', '1.013']
示例6:经济学 - 投入产出分析
Leontief 投入产出矩阵
A_economics = [
[0.2, 0.1, 0.3],
[0.3, 0.2, 0.1],
[0.1, 0.3, 0.2]
]
Z6, T6 = schur(A_economics)
eigenvals_econ = [T6[i,i] for i in range(3)]
print("\n特征值:", eigenvals_econ)
#特征值: [0.600000000000001, -3.46944695195361e-18, -3.46944695195361e-18]
print("经济系统稳定性:", "稳定" if max(float(eig) for eig in eigenvals_econ) < 1 else "不稳定")
#经济系统稳定性: 稳定
示例7:机械振动 - 阻尼系统
阻尼振动系统状态矩阵
A_vibration = [
[0, 0, 1, 0],
[0, 0, 0, 1],
[-2, 1, -0.3, 0.1],
[1, -2, 0.1, -0.3]
]
Z7, T7 = schur(A_vibration, complex)
eigenvals_vib = [T7[i,i] for i in range(4)]
复特征值 (包含频率和阻尼信息):
for i, eig in enumerate(eigenvals_vib):
print(f"λ{i+1} = {eig.evalf(4)}")
#λ1 = -0.2 + 1.72*I
#λ2 = -0.1 + 0.995*I
#λ3 = -0.2 - 1.72*I
#λ4 = -0.1 - 0.995*I
示例8:神经网络 - 动态稳定性分析
神经网络连接权重矩阵
A_neural = [
[0.8, -0.2, 0.1],
[0.3, 0.6, -0.4],
[-0.1, 0.5, 0.7]
]
Z8, T8 = schur(A_neural)
eigenvals_neural = [T8[i,i] for i in range(3)]
print("\n特征值:", eigenvals_neural)
#特征值: [0.796539478891559, 0.651730260554221, 0.651730260554221]
print("网络动态:", "收敛" if max(abs(float(eig)) for eig in eigenvals_neural) < 1 else "发散")
#网络动态: 收敛
示例9:声学 - 房间声学模态分析
房间声学波动方程离散化
A_acoustic = [
[-0.1, 0.05, 0, 0.05],
[0.05, -0.15, 0.05, 0],
[0, 0.05, -0.1, 0.05],
[0.05, 0, 0.05, -0.1]
]
Z9, T9 = schur(A_acoustic, complex)
eigenvals_acoustic = [T9[i,i] for i in range(4)]
复特征值 (共振频率):
for i, eig in enumerate(eigenvals_acoustic):
freq = abs(eig) / (2 * 3.14159)
print(f"模态 {i+1}: 频率 ≈ {float(freq):.3f} Hz")
#模态 1: 频率 ≈ 0.001 Hz
#模态 2: 频率 ≈ 0.035 Hz
#模态 3: 频率 ≈ 0.016 Hz
#模态 4: 频率 ≈ 0.020 Hz
示例10:机器人学 - 动力学系统线性化
机器人动力学线性化矩阵
A_robotics = [
[0, 1, 0, 0],
[-5, -2, 3, 1],
[0, 0, 0, 1],
[2, 1, -4, -1]
]
Z10, T10 = schur(A_robotics)
eigenvals_robot = [T10[i,i] for i in range(4)]
print("\n特征值:", eigenvals_robot)
#特征值: [-1.30162291256622, -1.30162291256622, -0.198377087433783, -0.198377087433783]
natural_freqs = [abs(eig) for eig in eigenvals_robot]
print("自然频率:", [f"{freq:.3f}" for freq in natural_freqs])
#自然频率: ['1.302', '1.302', '0.198', '0.198']
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy.linalg import schur as scipy_schur
def schur_decomposition(input_expr):
"""
执行舒尔分解(Schur Decomposition),对标 MATLAB 的 schur 函数。
参数:
input_expr: 输入可以是以下形式之一:
- SymPy 矩阵
- 列表或嵌套列表表示的矩阵
- 元组 (矩阵, 'real') 或 (矩阵, 'complex') 指定输出类型
返回:
若成功,返回 (Z, T),其中:
Z: 酉矩阵(SymPy 矩阵)
T: 上三角矩阵(SymPy 矩阵)
若失败,返回错误信息字符串。
示例:
>>> schur_decomposition([[1, 2], [3, 4]])
(Matrix(...), Matrix(...))
"""
try:
# 解析输入
if isinstance(input_expr, tuple) and len(input_expr) == 2:
matrix_part, output_type = input_expr
output_type = str(output_type).lower()
if output_type not in ['real', 'complex']:
return "错误: 分解类型必须为 'real' 或 'complex'"
else:
matrix_part = input_expr
output_type = 'real' # 默认实数分解
# 转换为 SymPy 矩阵
A = sp.Matrix(matrix_part) if isinstance(matrix_part, list) else None
if A is None:
return "错误: 输入不是有效矩阵"
# 检查矩阵是否为数值矩阵
if not all(val.is_number for val in A):
return "错误: 矩阵包含符号变量,仅支持数值矩阵"
# 转换为 NumPy 数组进行舒尔分解
A_np = np.array(A, dtype=float)
# 调用 SciPy 的舒尔分解
T_np, Z_np = scipy_schur(A_np, output=output_type)
# 转换回 SymPy 矩阵
Z = sp.Matrix(Z_np)
T = sp.Matrix(T_np)
return (Z, T)
except Exception as e:
return f"错误: {e}"
# --------------------- 示例用法 ---------------------
if __name__ == "__main__":
# 示例 1: 实数分解 (默认)
matrix = [[1, 2], [3, 4]]
Z, T = schur_decomposition(matrix)
print("示例1 实数分解:")
print("Z =\n", Z)
# Matrix([[-0.824564840132394, -0.565767464968992],
# [0.565767464968992, -0.824564840132394]])
print("T =\n", T)
# Matrix([[-0.372281323269014, -1.00000000000000],
# [0, 5.37228132326901]])
print("验证 Z*T*Z.T ≈ A:\n", Z * T * Z.T)
# Matrix([[1.00000000000000, 2.00000000000000],
# [3.00000000000000, 4.00000000000000]])
# 示例 2: 复数分解
input_tuple = ([[0, -1], [1, 0]], 'complex')
Z, T = schur_decomposition(input_tuple)
print("\n示例2 复数分解:")
print("Z =\n", Z)
# Matrix([[-0.707106781186547*I, -0.531446838683691 + 0.466437839002273*I],
# [-0.707106781186547, -0.466437839002273 - 0.531446838683691*I]])
print("T =\n", T)
# Matrix([[1.0*I, -2.2677956401069e-16 + 3.09244860014577e-17*I],
# [0, 2.77555756156289e-17 - 1.0*I]])
角的正割(以弧度为单位)
Y = sec(X) 返回X的元素的正割. sec函数按元素处理数组.该函数同时接受实数和复数输入.
对于X的实数值,sec(X)返回区间 [-∞, - 1] 和 [1, ∞] 内的实数值.
对于X的复数值,sec(X)返回复数值
X — 输入角(以弧度为单位),标量,向量,矩阵
示例1:物理学 - 光的折射定律
根据斯涅尔定律,临界角计算涉及正割函数
临界角计算: θ_c = arcsec(n2/n1)
n1, n2 = 1.5, 1.0 # 从玻璃到空气
critical_angle = sec(acos(n2/n1))
print(f"玻璃到空气的临界角相关值: sec(θ_c) = {critical_angle}")
#玻璃到空气的临界角相关值: sec(θ_c) = 1.5
#应用: 光纤通信、透镜设计
示例2:工程学 - 悬索桥分析
悬链线方程涉及双曲函数,正割函数用于近似计算
悬链线近似中的正割项
cable_tension = sec(0.5) # 小角度近似
print(f"悬索张力系数: sec(0.5) ≈ {cable_tension}")
#悬索张力系数: sec(0.5) ≈ 1.13949392732455
#应用: 桥梁设计、电缆张力计算
示例3:电子工程 - 交流电路
在RLC电路中,阻抗计算涉及正割函数
阻抗角的正割
impedance_angle = sec(@pi/6)
print(f"阻抗角为π/6时的正割值: sec(π/6) = {impedance_angle}")
#阻抗角为π/6时的正割值: sec(π/6) = 1.15470053837925
#应用: 滤波器设计、功率因数校正
示例4:天文学 - 天体坐标转换
赤道坐标系到水平坐标系转换涉及正割函数
declination = 45 # 赤纬45度
lat_secz = sec(np.radians(declination))
print(f"赤纬{declination}°时的天顶距相关值: sec(δ) = {lat_secz}")
#赤纬45°时的天顶距相关值: sec(δ) = 1.41421356237309
#应用: 天文导航、望远镜定位
示例5:机械工程 - 渐开线齿轮
渐开线函数计算涉及正割函数
pressure_angle = 20 # 压力角20度
gear_secz = sec(np.radians(pressure_angle))
print(f"压力角{pressure_angle}°时的正割值: sec(α) = {gear_secz}")
#压力角20°时的正割值: sec(α) = 1.06417777247591
#应用: 齿轮传动设计、接触应力分析
示例6:建筑学 - 屋顶坡度
屋顶坡度与正割函数相关
roof_angle = 30 # 30度坡度
roof_length_factor = sec(np.radians(roof_angle))
print(f"{roof_angle}°坡度对应的长度系数: sec(θ) = {roof_length_factor}")
#30°坡度对应的长度系数: sec(θ) = 1.15470053837925
#应用: 屋顶材料计算、排水设计
示例7:地理学 - 地图投影
墨卡托投影的纬度变换涉及正割函数
latitude = 60 # 北纬60度
mercator_secz = sec(np.radians(latitude))
print(f"纬度{latitude}°在墨卡托投影中的缩放因子: sec(φ) = {mercator_secz}")
#纬度60°在墨卡托投影中的缩放因子: sec(φ) = 2.0
#应用: 地图制作、GPS导航
示例8:声学 - 声波传播
声波在不同介质中的折射计算
incident_angle = 30 # 入射角30度
acoustic_secz = sec(np.radians(incident_angle))
print(f"入射角{incident_angle}°的声波路径系数: sec(θ) = {acoustic_secz}")
#入射角30°的声波路径系数: sec(θ) = 1.15470053837925
#应用: 声纳系统、建筑声学
示例9:计算机图形学 - 透视校正
3D到2D投影中的透视校正
fov_angle = 60 # 视场角60度
perspective_secz = sec(np.radians(fov_angle/2))
print(f"半视场角{fov_angle/2}°的透视校正因子: sec(θ) = {perspective_secz}")
#半视场角30.0°的透视校正因子: sec(θ) = 1.15470053837925
#应用: 3D渲染、虚拟现实
示例10:经济学 - 周期性波动分析
经济周期分析中的三角函数应用
economic_phase = sec(0.8) # 经济周期相位
print(f"经济周期相位0.8 rad的波动系数: sec(0.8) = {economic_phase}")
#经济周期相位0.8 rad的波动系数: sec(0.8) = 1.43532419967224
#应用: 经济预测、周期分析
示例11:矩阵计算 - 矩阵形式的多个角度计算
angle_matrix = [[0, @pi/6], [@pi/4, @pi/3]]
matrix_result = sec(angle_matrix)
print("正割值矩阵:", matrix_result)
#正割值矩阵: [[1.0, 1.15470053837925],
[1.41421356237309, 2.0]]
#应用: 有限元分析、结构动力学
示例12:符号计算 - 符号表达式推导
symbolic_expr = sec(2*x + @pi/3)
代入具体数值验证
x_val = 0.5
numeric_result = sec(2*x_val + @pi/3)
print(f"当 x = {x_val} 时, sec(2*{x_val} + π/3) = {numeric_result}")
#当 x = 0.5 时, sec(2*0.5 + π/3) = -2.18062511920013
#应用: 理论物理推导、工程公式验证
示例13:信号处理 - 数字滤波器相位响应
filter_angles = [0, @pi/8, @pi/4, 3*@pi/8]
sec_values = [sec(angle) for angle in filter_angles]
不同相位角的滤波器响应:
for angle, sec_val in zip(filter_angles, sec_values):
print(f"θ = {angle:.3f} rad, sec(θ) = {sec_val}")
#θ = 0.000 rad, sec(θ) = 1.00000000000000
#θ = 0.393 rad, sec(θ) = 1.08239220029239
#θ = 0.785 rad, sec(θ) = 1.41421356237309
#θ = 1.178 rad, sec(θ) = 2.61312592975275
#应用: 数字滤波器设计、信号调理
示例14:航空航天 - 轨迹计算
椭圆轨道中的真近点角计算
eccentric_anomaly = 1.2 # 偏近点角
orbit_secz = sec(eccentric_anomaly)
print(f"偏近点角{eccentric_anomaly} rad的轨道参数: sec(E) = {orbit_secz}")
#偏近点角1.2 rad的轨道参数: sec(E) = 2.75970360133241
#应用: 卫星轨道计算、航天器导航
示例15:海洋学 - 波浪理论
波浪折射和浅水效应计算
wave_angle = 45 # 波浪入射角45度
wave_secz = sec(np.radians(wave_angle))
print(f"波浪入射角{wave_angle}°的传播系数: sec(θ) = {wave_secz}")
print("应用: 海岸工程、波浪能利用")
#波浪入射角45°的传播系数: sec(θ) = 1.41421356237309
#应用: 海岸工程、波浪能利用
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
def secant_of_radians(input_str):
"""
计算角的正割(以弧度为单位),对标MATLAB的sec函数
参数:
input_str: 输入字符串,可以是:
- 数值 (如 "0", "pi/3")
- 矩阵 (如 "[[1, 0], [pi/4, pi/6]]")
- 包含符号的表达式 (如 "t", "2*x + pi/2")
返回:
计算结果 (标量/矩阵/符号表达式) 或错误信息字符串
特征:
- 支持符号计算
- 支持矩阵元素级运算
- 自动数值求值
- 完善的错误处理
"""
try:
# 解析输入字符串为SymPy表达式
expr = sp.sympify(input_str)
error = False
result = None
if expr.is_number:
z = complex(expr)
result = 1 / np.cos(z)
elif expr.free_symbols:
# 符号运算后数值求值
result = sp.sec(expr).evalf()
else:
error = True
# 处理无法识别的输入类型
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
# 示例代码
if __name__ == "__main__":
# 初始化美化打印
sp.init_printing(use_unicode=True)
# 示例1:基本数值计算
print("示例1:标量计算")
print("sec(0) =", secant_of_radians("0")) #
# (1+0j)
print("sec(pi/3) =", secant_of_radians("pi/3"))
# (2.0000000000000004+0j)
print("sec(pi/2) =", secant_of_radians("pi/2"))
# (1.633123935319537e+16+0j)
# 示例3:符号运算
print("\n示例3:符号表达式")
t = secant_of_radians("t")
print("sec(t) =", t)
# sec(t)
expr = secant_of_radians("2*x + pi/3")
print("复合表达式:", expr)
# sec(2*x + pi/3)
参量的正割(以度为单位)
Y = secd(X)返回X的元素的正割(以度为单位).
X — 以度为单位的角,标量值,向量,矩阵
示例1:建筑工程 - 屋顶坡度计算
屋顶坡度通常以度数表示,正割用于计算实际长度
roof_angle = 30 # 30度坡度
roof_secd = secd(roof_angle)
print(f"{roof_angle}°屋顶坡度的长度系数: secd({roof_angle}) = {roof_secd}")
#30°屋顶坡度的长度系数: secd(30) = 1.15470053837925
#应用: 屋顶材料计算、斜梁长度确定
示例2:导航系统 - 方位角计算
球面三角学中,大圆航线计算涉及正割函数
bearing_angle = 45 # 45度方位角
nav_secd = secd(bearing_angle)
print(f"{bearing_angle}°方位角的导航系数: secd({bearing_angle}) = {nav_secd}")
#45°方位角的导航系数: secd(45) = 1.41421356237309
#应用: 航空导航、航海导航
示例3:机械工程 - 斜面力学
物体在斜面上的受力分析需要正割函数
incline_angle = 20 # 20度斜面
force_secd = secd(incline_angle)
print(f"{incline_angle}°斜面的力分解系数: secd({incline_angle}) = {force_secd}")
#20°斜面的力分解系数: secd(20) = 1.06417777247591
#应用: 传送带设计、斜坡装载
示例4:电子工程 - 交流电路相位分析
三相电路中,相位差通常以度数表示
phase_angle = 120 # 120度相位差
phase_secd = secd(phase_angle)
print(f"{phase_angle}°相位差的电路参数: secd({phase_angle}) = {phase_secd}")
#120°相位差的电路参数: secd(120) = -2.0
#应用: 电机控制、电力系统分析
示例5:地理学 - 地图投影
墨卡托投影中纬度线的间距计算
latitude = 60 # 北纬60度
map_secd = secd(latitude)
print(f"纬度{latitude}°的投影缩放因子: secd({latitude}) = {map_secd}")
#纬度60°的投影缩放因子: secd(60) = 2.0
#应用: 地图制作、GIS系统
示例6:摄影学 - 透视校正
广角镜头产生的畸变校正计算
fov_angle = 84 # 84度视场角
photo_secd = secd(fov_angle / 2)
print(f"半视场角{fov_angle / 2}°的透视校正: secd({fov_angle / 2}) = {photo_secd}")
#半视场角42.0°的透视校正: secd(42.0) = 1.34563272960638
#应用: 摄影测量、图像处理
示例7:结构工程 - 桁架分析
桁架结构中杆件力的三角函数计算
truss_angle = 45 # 45度斜杆
truss_secd = secd(truss_angle)
print(f"{truss_angle}°斜杆的力传递系数: secd({truss_angle}) = {truss_secd}")
#45°斜杆的力传递系数: secd(45) = 1.41421356237309
#应用: 桥梁设计、屋顶桁架
示例8:天文学 - 天体高度计算
天体在地平坐标系中的高度角计算
altitude = 30 # 30度高度角
astro_secd = secd(altitude)
print(f"高度角{altitude}°的大气折射修正: secd({altitude}) = {astro_secd}")
#高度角30°的大气折射修正: secd(30) = 1.15470053837925
#应用: 天文观测、导航定位
示例9:汽车工程 - 阿克曼转向几何
汽车转向系统中内外轮角度关系
steering_angle = 30 # 30度转向角
auto_secd = secd(steering_angle)
print(f"{steering_angle}°转向角的几何参数: secd({steering_angle}) = {auto_secd}")
#30°转向角的几何参数: secd(30) = 1.15470053837925
#应用: 车辆设计、转向系统优化
示例10:体育科学 - 投掷角度
抛射体运动中的最优角度计算
throw_angle = 45 # 45度投掷角(理论最优)
sports_secd = secd(throw_angle)
print(f"{throw_angle}°投掷角的运动参数: secd({throw_angle}) = {sports_secd}")
#45°投掷角的运动参数: secd(45) = 1.41421356237309
#应用: 运动训练、弹道分析
示例11:矩阵计算 - 多个角度同时处理
angles_matrix = [[0, 30], [45, 60]]
matrix_result = secd(angles_matrix)
print("正割值矩阵:", matrix_result)
#正割值矩阵: [[1.0, 1.15470053837925],
[1.41421356237309, 2.0]]
#应用: 有限元分析、结构优化
示例12:符号计算 - 理论公式推导
symbolic_expr = secd(2*alpha + 30)
代入具体数值验证
alpha_val = 15
numeric_result = secd(2*alpha_val + 30)
print(f"当 α = {alpha_val}° 时, secd(2*{alpha_val} + 30) = {numeric_result}")
#当 α = 15° 时, secd(2*15 + 30) = 2.0
#应用: 理论推导、工程设计公式
示例13:太阳能工程 - 太阳角度
太阳能板倾角优化涉及正割函数
sun_angle = 50 # 50度太阳高度角
solar_secd = secd(sun_angle)
print(f"太阳高度角{sun_angle}°的能量接收系数: secd({sun_angle}) = {solar_secd}")
#太阳高度角50°的能量接收系数: secd(50) = 1.55572382686041
#应用: 太阳能板布置、光热系统设计
示例14:声学工程 - 声波反射
声波在不同表面的反射路径计算
reflection_angle = 60 # 60度反射角
acoustic_secd = secd(reflection_angle)
print(f"{reflection_angle}°反射角的声波路径: secd({reflection_angle}) = {acoustic_secd}")
#60°反射角的声波路径: secd(60) = 2.0
#应用: 音乐厅设计、噪声控制
示例15:地质学 - 地层倾角
地层倾角对勘探和工程的影响
dip_angle = 35 # 35度地层倾角
geo_secd = secd(dip_angle)
print(f"{dip_angle}°地层倾角的工程参数: secd({dip_angle}) = {geo_secd}")
#35°地层倾角的工程参数: secd(35) = 1.22077458876146
#应用: 石油勘探、地质灾害评估
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
def secant_degree_radians(input_str):
"""
计算角度的正割(以度为单位),对标MATLAB的secd函数
参数:
input_str: 输入字符串,可以是:
- 数值角度 (如 "30", "45")
- 矩阵 (如 "[[0, 60], [90, 180]]")
- 符号表达式 (如 "theta", "2*x + 45")
返回:
计算结果 (数值/矩阵/符号表达式) 或错误信息字符串
特征:
- 自动将度数转换为弧度
- 支持符号计算
- 支持矩阵元素级运算
- 完善的错误处理
"""
try:
# 解析输入字符串为SymPy表达式
expr = sp.sympify(input_str)
# 定义核心计算函数
def sec_degree_sym(x):
"""实际计算函数,处理单个元素"""
# 转换为弧度:degree * π / 180
x_rad = x * sp.pi / 180
return sp.sec(x_rad).evalf()
def sec_degree_num(x):
"""
计算以度数为单位的角度的正割值(secant)
等效于 MATLAB 的 secd 函数
参数:
x : 角度(度数),可以是标量或NumPy数组
返回:
正割值,当 cos(radians) = 0 时返回无穷大(inf)
"""
# 将角度转换为弧度
x_rad = x * np.pi / 180
# 计算余弦值
cos_vals = np.cos(x_rad)
# 计算正割 = 1 / 余弦,避免除零警告
with np.errstate(divide='ignore', invalid='ignore'):
sec_vals = np.where(np.abs(cos_vals) > np.finfo(float).eps,
1.0 / cos_vals,
np.inf)
return sec_vals
# 处理元组输入的特殊情况
if isinstance(expr, tuple):
raise ValueError("不支持元组输入,请使用数值、矩阵或符号表达式")
# 处理标量或符号表达式
if expr.is_number:
z = complex(expr)
return sec_degree_num(z)
else:
return sec_degree_sym(expr)
# 处理未知类型
except Exception as e:
return f"错误: {str(e)}"
# 示例代码
if __name__ == "__main__":
# 初始化美化打印
sp.init_printing(use_unicode=True)
# 示例1:基本数值计算
print("示例1:标量计算")
print("secd(0) =", secant_degree_radians("0"))
# (1+0j)
print("secd(60) =", secant_degree_radians("60"))
# (1.9999999999999996+0j)
print("secd(90) =", secant_degree_radians("90"))
# (inf+0j)
# 示例3:符号运算
print("\n示例3:符号表达式")
theta = secant_degree_radians("theta")
print("secd(theta) =", theta)
# sec(pi*theta/180)
expr = secant_degree_radians("2*x + 45")
print("复合表达式:", expr)
# sec(pi*(x/90 + 1/4))
双曲正割
Y = sech(X) 返回X的元素的双曲正割.sech函数按元素处理数组.该函数同时接受实数和复数输入.所有的角度都以弧度表示.
X — 输入角(以弧度为单位),标量值,向量,矩阵
示例1:物理学 - 悬链线方程
悬挂电缆或链条的自然形状由双曲函数描述
cable_position = 0.5 # 距离悬挂点0.5单位
cable_sech = sech(cable_position)
print(f"位置{cable_position}处的悬链线参数: sech({cable_position}) = {cable_sech}")
#位置0.5处的悬链线参数: sech(0.5) = 0.886818883970074
#应用: 悬索桥设计、电缆铺设
示例2:工程学 - 拱形结构
拱形结构的力学分析涉及双曲函数
arch_parameter = 0.8 # 拱形参数
arch_sech = sech(arch_parameter)
print(f"拱形参数{arch_parameter}的结构系数: sech({arch_parameter}) = {arch_sech}")
#拱形参数0.8的结构系数: sech(0.8) = 0.747699918237420
#应用: 桥梁设计、建筑拱顶
示例3:电子工程 - 传输线理论
高频传输线的阻抗和传播常数计算
line_parameter = 1.2 # 传输线参数
transmission_sech = sech(line_parameter)
print(f"传输线参数{line_parameter}的特性: sech({line_parameter}) = {transmission_sech}")
#传输线参数1.2的特性: sech(1.2) = 0.552286154278205
#应用: 射频电路、天线设计
示例4:流体力学 - 自由表面波
重力波在浅水中的传播特性
wave_parameter = 0.6 # 波浪参数
fluid_sech = sech(wave_parameter)
print(f"波浪参数{wave_parameter}的传播特性: sech({wave_parameter}) = {fluid_sech}")
#波浪参数0.6的传播特性: sech(0.6) = 0.843550687621807
#应用: 海洋工程、水波能量提取
示例5:相对论 - 狭义相对论
洛伦兹变换中的双曲函数关系
velocity_ratio = 0.8 # v/c比值
rel_sech = sech(acosh(1/sqrt(1-velocity_ratio**2)))
print(f"速度比{velocity_ratio}c的相对论参数: sech(rapidity) = {rel_sech}")
#速度比0.8c的相对论参数: sech(rapidity) = 0.6
#应用: 粒子物理、宇宙学
示例6:热传导 - 散热片设计
散热片的温度分布计算
fin_parameter = 1.5 # 散热片参数
thermal_sech = sech(fin_parameter)
print(f"散热片参数{fin_parameter}的效率因子: sech({fin_parameter}) = {thermal_sech}")
#散热片参数1.5的效率因子: sech(1.5) = 0.425096034942280
#应用: 电子设备冷却、热交换器
示例7:概率论 - 双曲分布
在统计学中用于建模重尾分布
prob_parameter = 0.7 # 分布参数
prob_sech = sech(prob_parameter)
print(f"分布参数{prob_parameter}的概率密度: sech({prob_parameter}) = {prob_sech}")
print("应用: 金融风险管理、信号处理")
#分布参数0.7的概率密度: sech(0.7) = 0.796705459992875
#应用: 金融风险管理、信号处理
示例8:声学 - 声波导
波导中的声波传播模式分析
acoustic_parameter = 0.9 # 声学参数
acoustic_sech = sech(acoustic_parameter)
print(f"声学参数{acoustic_parameter}的波导特性: sech({acoustic_parameter}) = {acoustic_sech}")
#声学参数0.9的波导特性: sech(0.9) = 0.697794641100332
#应用: 声纳系统、建筑声学
示例9:数学 - 积分计算
某些积分的结果包含双曲正割函数
integral_parameter = 1.0 # 积分参数
math_sech = sech(integral_parameter)
print(f"积分参数{integral_parameter}的结果: sech({integral_parameter}) = {math_sech}")
#积分参数1.0的结果: sech(1.0) = 0.648054273663885
#应用: 特殊函数理论、数学物理
示例10:密码学 - 双曲线密码
在某些密码算法中使用双曲函数
crypto_parameter = 0.5 # 密码参数
crypto_sech = sech(crypto_parameter)
print(f"密码参数{crypto_parameter}的算法参数: sech({crypto_parameter}) = {crypto_sech}")
#密码参数0.5的算法参数: sech(0.5) = 0.886818883970074
#应用: 安全通信、数字签名
示例11:矩阵计算 - 多个参数处理
params_matrix = [[0, 0.5], [1.0, 1.5]]
matrix_result = sech(params_matrix)
print("双曲正割值矩阵:", matrix_result)
#双曲正割值矩阵: [[1.0, 0.886818883970074],
[0.648054273663885, 0.42509603494228]]
#应用: 有限元分析、参数扫描
示例12:符号计算 - 理论推导
symbolic_expr = sech(a*x + b)
代入具体数值验证
a_val, b_val, x_val = 2, 1, 0.5
numeric_result = sech(a_val*x_val + b_val)
print(f"当 a={a_val}, b={b_val}, x={x_val} 时, sech({a_val}*{x_val} + {b_val}) = {numeric_result}")
#当 a=2, b=1, x=0.5 时, sech(2*0.5 + 1) = 0.265802228834080
#应用: 理论推导、模型建立
示例13:电磁学 - 波导模式
电磁波在波导中的传播模式分析
waveguide_parameter = 1.2 # 波导参数
em_sech = sech(waveguide_parameter)
print(f"波导参数{waveguide_parameter}的模式特性: sech({waveguide_parameter}) = {em_sech}")
#波导参数1.2的模式特性: sech(1.2) = 0.552286154278205
#应用: 微波工程、雷达系统
示例14:量子力学 - 势垒穿透
量子隧穿效应的概率计算
quantum_parameter = 0.8 # 量子参数
quantum_sech = sech(quantum_parameter)
print(f"量子参数{quantum_parameter}的隧穿概率: sech({quantum_parameter}) = {quantum_sech}")
#量子参数0.8的隧穿概率: sech(0.8) = 0.747699918237420
#应用: 扫描隧道显微镜、半导体物理
示例15:神经网络 - 激活函数
双曲正割作为激活函数的变体
nn_parameter = 0.6 # 神经网络参数
nn_sech = sech(nn_parameter)
print(f"神经网络参数{nn_parameter}的激活值: sech({nn_parameter}) = {nn_sech}")
#神经网络参数0.6的激活值: sech(0.6) = 0.843550687621807
#应用: 深度学习、人工智能
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
def secant_hyperbolic_radians(input_str):
"""
计算双曲正割函数(sech),对标MATLAB的sech函数
参数:
input_str: 输入字符串,可以是:
- 数值 (如 "0", "1")
- 矩阵 (如 "[[0, 1], [2, 3]]")
- 符号表达式 (如 "x", "2*y + 1")
返回:
计算结果 (数值/矩阵/符号表达式) 或错误信息字符串
特征:
- 支持符号计算
- 自动处理矩阵元素级运算
- 数值计算自动转换为浮点数
- 兼容NumPy数组输入
"""
try:
# 解析输入并替换特殊字符
expr = sp.sympify(input_str)
# 检查元组输入类型
if isinstance(expr, tuple):
raise ValueError("不支持元组输入,请使用数值、矩阵或符号表达式")
# 处理标量和符号表达式
if expr.is_number:
# 数值优化处理
z = complex(expr)
return 1 / np.cosh(z)
elif expr.free_symbols:
# 符号运算
return sp.sech(expr).evalf()
# 处理未知类型
raise TypeError("无法识别的输入类型")
except Exception as e:
return f"错误: {str(e)}"
# 示例代码
if __name__ == "__main__":
sp.init_printing(use_unicode=True) # 美化打印
# 示例1:标量计算
print("示例1:标量计算")
print("sech(0) =", secant_hyperbolic_radians("0"))
# (1+0j)
print("sech(1) =", secant_hyperbolic_radians("1"))
# (0.6480542736638855+0j)
# 示例3:符号运算
print("\n示例3:符号表达式")
x = secant_hyperbolic_radians("x")
print("sech(x) =", x)
# sech(x)
expr = secant_hyperbolic_radians("2*y + 1")
print("复合表达式:", expr)
# sech(2*y + 1)
以列表形式返回序列
Sequence(f,x,start,end,step)依据输入字符串构建一个序列,并依据输入的不同参数对序列进行切片操作.
f -- 符号表达式
x -- 符号标量
start, end, step -- 标量, 切片参数
示例1:数学序列 - 等差数列
生成从1到10的自然数序列
result1 = Sequence(i, i, 1, 10)
print(f"自然数序列: {result1}")
#自然数序列: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#应用: 数学计算、算法测试
示例2:数学序列 - 平方数列
生成前10个平方数
result2 = Sequence(i**2, i, 1, 10)
print(f"平方数列: {result2}")
#平方数列: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
#应用: 数论研究、模式识别
示例3:数学序列 - 斐波那契数列
生成前10个斐波那契数
result3 = Sequence(fibonacci(i), i, 1, 10)
print(f"斐波那契数列: {result3}")
#斐波那契数列: [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
#应用: 算法设计、自然界建模
示例4:物理学 - 等间隔时间序列
生成0到1秒内的时间采样点,间隔0.1秒
result4 = Sequence(t, t, 0, 1, 10)
print(f"时间采样序列: {result4}")
#时间采样序列: [0]
#应用: 物理实验数据采集、信号处理
示例5:工程学 - 频率扫描序列
生成对数间隔的频率点,用于频率响应测试
result5 = Sequence(10**i, i, 1, 5, 1)
print(f"频率扫描序列: {result5}")
#频率扫描序列: [10, 100, 1000, 10000, 100000]
#应用: 滤波器测试、系统辨识
示例6:计算机科学 - 二进制位序列
生成2的幂次序列,表示二进制位权重
result6 = Sequence(2**i, i, 0, 7, 1)
print(f"二进制位权重序列: {result6}")
#二进制位权重序列: [1, 2, 4, 8, 16, 32, 64, 128]
#应用: 数字电路、数据编码
示例7:金融学 - 复利计算
生成年化5%利率的复利增长序列
result7 = Sequence(1000*(1.05)**i, i, 0, 10, 1)
print(f"复利增长序列: {result7}")
#复利增长序列: [1000, 1050, 1102.5, 1157.625, 1215.50625, 1276.2815625, 1340.095640625, 1407.10042265625, 1477.45544378906, 1551.32821597852, 1628.89462677744]
#应用: 投资分析、财务规划
示例8:统计学 - 概率分布
生成二项分布B(10,0.5)的概率质量函数
result8 = Sequence(binomial(10, i)*0.5**i*0.5**(10-i), i, 0, 10, 1)
print(f"二项分布概率序列: {result8}")
#二项分布概率序列: [0.0009765625, 0.009765625, 0.0439453125, 0.1171875, 0.205078125, 0.24609375, 0.205078125, 0.1171875, 0.0439453125, 0.009765625, 0.0009765625]
#应用: 概率建模、假设检验
示例9:信号处理 - 正弦波采样
生成正弦波的离散采样点
result9 = Sequence(sin(2*pi*i/10), i, 0, 9, 1)
print(f"正弦波采样序列: {result9}")
#正弦波采样序列: [0, sqrt(5/8 - sqrt(5)/8), sqrt(sqrt(5)/8 + 5/8), sqrt(sqrt(5)/8 + 5/8), sqrt(5/8 - sqrt(5)/8), 0, -sqrt(5/8 - sqrt(5)/8),
-sqrt(sqrt(5)/8 + 5/8), -sqrt(sqrt(5)/8 + 5/8), -sqrt(5/8 - sqrt(5)/8)]
#应用: 数字信号处理、通信系统
示例10:化学 - 元素周期表
生成前20个元素的原子序数
result10 = Sequence(i, i, 1, 20, 1)
print(f"原子序数序列: {result10}")
#原子序数序列: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
#应用: 化学计算、元素分析
示例11:带步长的序列 - 奇数序列
生成前10个奇数
result11 = Sequence(i, i, 1, 20, 2)
print(f"奇数序列: {result11}")
#奇数序列: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
#应用: 数论、算法优化
示例12:物理学 - 简谐运动位置序列
生成简谐运动在多个周期的位置序列
result14 = Sequence(cos(2*pi*i/8), i, 0, 32, 1)
print(f"简谐运动位置序列: {result14}")
#简谐运动位置序列: [1, sqrt(2)/2, 0, -sqrt(2)/2, -1, -sqrt(2)/2, 0, sqrt(2)/2, 1, sqrt(2)/2, 0, -sqrt(2)/2, -1, -sqrt(2)/2,
0, sqrt(2)/2, 1, sqrt(2)/2, 0, -sqrt(2)/2, -1, -sqrt(2)/2, 0, sqrt(2)/2, 1, sqrt(2)/2, 0, -sqrt(2)/2, -1, -sqrt(2)/2, 0, sqrt(2)/2, 1]
#应用: 机械振动分析、波动研究
示例13:经济学 - GDP增长序列
生成模拟的GDP年增长率序列
result15 = Sequence(1.03 + 0.02*sin(pi*i/2), i, 0, 10, 1)
print(f"GDP增长率序列: {result15}")
#GDP增长率序列: [1.03, 1.05, 1.03, 1.01, 1.03, 1.05, 1.03, 1.01, 1.03, 1.05, 1.03]
#应用: 经济预测、政策分析
示例14:生物学 - 种群增长序列
生成逻辑斯蒂增长模型的种群数量序列
result16 = Sequence(1000/(1+9*exp(-0.5*i)), i, 0, 10, 1)
print(f"种群增长序列: {result16}")
#种群增长序列: [100, 154.828098960255, 231.969316684074, 332.427861743119, 450.853060379284, 575.120851364515, 690.567857703016,
786.301711570675, 858.486449758214, 909.106637590978, 942.825618574015]
#应用: 生态学、资源管理
示例15:计算机图形学 - 颜色渐变
生成从黑到白的灰度渐变序列
result17 = Sequence(i*25.5, i, 0, 10, 1)
print(f"灰度渐变序列: {result17}")
#灰度渐变序列: [0, 25.5, 51, 76.5, 102, 127.5, 153, 178.5, 204, 229.5, 255]
#应用: 图像处理、UI设计
示例16:音乐 - 十二平均律音高序列
生成C大调音阶的频率序列
result18 = Sequence(440*2**(i/12), i, 0, 7, 1)
print(f"音高频率序列: {result18}")
#音高频率序列: [440, 440*2**(1/12), 440*2**(1/6), 440*2**(1/4), 440*2**(1/3), 440*2**(5/12), 440*sqrt(2), 440*2**(7/12)]
#应用: 音乐合成、乐器调音
示例17:天文学 - 行星轨道半径序列
生成太阳系行星的相对轨道半径
result19 = Sequence(0.4 + 0.3*2**i, i, 0, 7, 1) # 提丢斯-波得定则的简化
print(f"行星轨道半径序列: {result19}")
#行星轨道半径序列: [0.7, 1, 1.6, 2.8, 5.2, 10, 19.6, 38.8]
#应用: 天体力学、行星科学
示例18:机器学习 - 训练轮次指标
生成模拟的训练损失下降序列
result20 = Sequence(1/(i+1) + 0.1*exp(-i/5), i, 0, 20, 1)
print(f"训练损失序列: {result20}")
#训练损失序列: [1.1, 0.1*exp(-1/5) + 1/2, 0.1*exp(-2/5) + 1/3, 0.1*exp(-3/5) + 1/4, 0.1*exp(-4/5) + 1/5, 0.1*exp(-1) + 1/6,
0.1*exp(-6/5) + 1/7, 0.1*exp(-7/5) + 1/8, 0.1*exp(-8/5) + 1/9, 0.1*exp(-9/5) + 1/10, 0.1*exp(-2) + 1/11,
0.1*exp(-11/5) + 1/12, 0.1*exp(-12/5) + 1/13, 0.1*exp(-13/5) + 1/14, 0.1*exp(-14/5) + 1/15, 0.1*exp(-3) + 1/16,
0.1*exp(-16/5) + 1/17, 0.1*exp(-17/5) + 1/18, 0.1*exp(-18/5) + 1/19, 0.1*exp(-19/5) + 1/20, 0.1*exp(-4) + 1/21]
#应用: 模型训练监控、超参数调优
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def squence_list(input_str):
"""
此函数的作用是依据输入字符串构建一个序列,并依据输入的不同参数对序列进行切片操作。
参数:
input_str (str): 包含序列定义和切片参数的字符串。
返回:
list 或者 str: 如果输入无误,返回切片后的序列列表;若输入有误,返回错误信息。
"""
try:
# 把输入字符串转换为 SymPy 表达式
expr = sp.sympify(input_str)
error = False
result = None
# 检查输入表达式的长度是否小于 4,若小于 4 则判定为输入错误
if len(expr) < 4:
error = True
# 若输入表达式长度为 4,构建一个完整的序列
elif len(expr) == 4:
# 构建序列,第一个参数是序列的通项公式,后面三个参数分别是变量、起始值、结束值
s = sp.sequence(expr[0], (expr[1], expr[2], expr[3]))
# 获取序列的所有元素
result = s[:]
# 若输入表达式长度为 5,构建序列并按指定步长切片
elif len(expr) == 5:
s = sp.sequence(expr[0], (expr[1], expr[2], expr[3]))
# 获取步长
step = expr[4]
# 按步长对序列进行切片
result = s[::step]
# 若输入表达式长度为 6,构建序列,按指定步长切片,再从指定起始索引开始取元素
elif len(expr) == 6:
s = sp.sequence(expr[0], (expr[1], expr[2], expr[3]))
step = expr[4]
# 获取起始索引
start_index = expr[5]
my_list = s[::step]
result = my_list[start_index:]
# 若输入表达式长度为 7,构建序列,按指定步长切片,从指定起始索引开始取指定数量的元素
elif len(expr) == 7:
s = sp.sequence(expr[0], (expr[1], expr[2], expr[3]))
step = expr[4]
start_index = expr[5]
# 获取要取的元素数量
num_elements = expr[6]
my_list = s[::step]
if start_index > 0:
result = my_list[start_index:start_index + num_elements]
else:
result = my_list[start_index - num_elements:start_index][::-1]
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
# 示范代码
if __name__ == "__main__":
# 测试输入,构建一个从 1 到 10 的整数序列
input1 = "(i, i, 1, 10)"
print(squence_list(input1))
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 测试输入,构建一个从 1 到 10 的整数序列,步长为 2
input2 = "(i, i, 1, 10, 2)"
print(squence_list(input2))
# [1, 3, 5, 7, 9]
# 测试输入,构建一个从 1 到 10 的整数序列,步长为 2,从索引 1 开始取元素
input3 = "(i, i, 1, 10, 2, 1)"
print(squence_list(input3))
# [3, 5, 7, 9]
# 测试输入,构建一个从 1 到 10 的整数序列,步长为 2,从索引 1 开始取 2 个元素
input4 = "(i, i, 1, 10, 2, 1, 2)"
print(squence_list(input4))
# [3, 5]
皮瑟级数
series(f,var)用f的Puiseux级数展开逼近f,直到在点var=0处的五阶.如果不指定var,那么series将使用由f确定默认变量.
f —— 近似输入, 符号表达式,符号函数
var —— 符号变量
示例1:物理学 - 单摆运动的小角度近似
单摆周期公式在小角度下的泰勒展开
result1 = series(1/sqrt(1 - k*sin(theta)**2), theta)
print(f"椭圆积分的级数展开: {result1}")
#椭圆积分的级数展开: k*theta**2/2 + theta**4*(3*k**2/8 - k/6) + 1
#应用: 单摆周期计算、振动分析
示例2:工程学 - 梁的小变形分析
梁的弯曲微分方程的级数解
result2 = series(sqrt(1 + (dy/dx)**2), x)
print(f"弧长微分项的展开: {result2}")
#弧长微分项的展开: sqrt((dy/dx)**2 + 1)
#应用: 结构力学、变形分析
示例3:电子工程 - 非线性元件特性
二极管I-V特性的小信号近似
result3 = series(exp(q*V/(k*T)) - 1, V)
print(f"二极管特性的级数展开: {result3}")
#二极管特性的级数展开: V*q/(T*k) + V**2*q**2/(2*T**2*k**2) + V**3*q**3/(6*T**3*k**3) + V**4*q**4/(24*T**4*k**4)
#应用: 电路分析、放大器设计
示例4:量子力学 - 谐振子势的微扰
非简谐振子势的级数展开
result4 = series(sqrt(1 + alpha*x**2), x)
print(f"势能项的级数展开: {result4}")
#势能项的级数展开: -alpha**2*x**4/8 + alpha*x**2/2 + 1
#应用: 分子振动、光谱分析
示例5:流体力学 - 边界层方程
边界层方程的相似解展开
result5 = series(sqrt(x)*f(eta), x)
print(f"相似变量的级数展开: {result5}")
#相似变量的级数展开: sqrt(x)*f(eta)
#应用: 空气动力学、传热分析
示例6:光学 - 透镜像差
球面像差的级数表示
result6 = series(1/sqrt(1 - (r/R)**2), r)
print(f"球面波前的展开: {result6}")
#球面波前的展开: 1 + r**2/(2*R**2) + 3*r**4/(8*R**4)
#应用: 光学设计、像差校正
示例7:相对论 - 洛伦兹因子的低速展开
相对论效应的牛顿近似
result7 = series(1/sqrt(1 - v**2/c**2), v)
print(f"洛伦兹因子的级数展开: {result7}")
#洛伦兹因子的级数展开: 1 + v**2/(2*c**2) + 3*v**4/(8*c**4)
#应用: GPS校正、粒子加速器
示例8:热力学 - 实际气体状态方程
维里方程的级数形式
result8 = series(P*V/(R*T) - 1, P)
print(f"压缩因子的展开: {result8}")
#压缩因子的展开: P*V/(R*T) - 1
#应用: 气体性质计算、化工过程
示例9:电磁学 - 非线性介质极化
电介质极化强度的场强展开
result10 = series(epsilon0*chi*E + epsilon0*chi2*E**2, E)
print(f"极化强度的级数展开: {result10}")
#极化强度的级数展开: E*chi*epsilon0 + chi2*epsilon0*exp(2)
#应用: 非线性光学、激光物理
示例10:数学 - 代数函数的局部行为
代数曲线在奇点附近的展开
result11 = series(sqrt(x**3 + x**2 + x), x)
print(f"代数函数的Puiseux展开: {result11}")
#代数函数的Puiseux展开: 3*x**(9/2)/128 - 3*x**(7/2)/16 + 3*x**(5/2)/8 + x**(3/2)/2 + sqrt(x)
#应用: 代数几何、奇点理论
示例11:控制理论 - 非线性系统线性化
非线性控制系统在工作点附近的展开
result12 = series(sin(theta) + 0.1*theta**3, theta)
print(f"非线性项的级数展开: {result12}")
#非线性项的级数展开: -0.0666666666666667*theta**3 + theta
#应用: 控制器设计、稳定性分析
示例12:天体力学 - 轨道振动分析
受摄动轨道的级数解
result13 = series(1/sqrt(r**2 - 2*r*a + a**2), r)
print(f"引力势的展开: {result13}")
#引力势的展开: 1/sqrt(a**2) + r/(a*sqrt(a**2)) + r**2/(a**2*sqrt(a**2)) + r**3/(a**3*sqrt(a**2)) + r**4/(a**4*sqrt(a**2))
#应用: 行星轨道计算、卫星导航
示例13:材料科学 - 应力应变关系
超弹性材料本构关系的展开
result14 = series(sqrt(1 + 2*epsilon + epsilon**2), epsilon)
print(f"有限应变的展开: {result14}")
#有限应变的展开: epsilon + 1
#应用: 橡胶力学、生物组织建模
示例14:经济学 - 风险厌恶效用函数
期望效用理论中的函数展开
result15 = series((1 - exp(-alpha*x))/alpha, x)
print(f"指数效用函数的展开: {result15}")
#指数效用函数的展开: -alpha**3*x**4/24 + alpha**2*x**3/6 - alpha*x**2/2 + x
#应用: 金融决策、保险定价
示例15:计算机科学 - 复杂度分析
递归算法复杂度的渐近展开
result18 = series(sqrt(n*log(n)), n)
print(f"复杂度的级数展开: {result18}")
#复杂度的级数展开: sqrt(n)*sqrt(log(n))
#应用: 算法设计、性能优化
示例16:地球科学 - 重力场
地球引力势的球谐展开
result19 = series(1/sqrt(1 - 2*(R/r)*cos(theta) + (R/r)**2), r)
print(f"引力势的展开: {result19}")
#引力势的展开: r**4*(-(-cos(theta)**2/(2*R**2) + 1/(2*R**2))*cos(theta)/R + (3*cos(theta)**2/(2*R**2) \
- 1/(2*R**2))*cos(theta)/R + cos(theta)**3/(2*R**3) - cos(theta)/(2*R**3))/sqrt(R**2) \
+ r**3*(3*cos(theta)**2/(2*R**2) - 1/(2*R**2))/sqrt(R**2) + r/sqrt(R**2) + r**2*cos(theta)/(R*sqrt(R**2))
#应用: 大地测量学、卫星轨道
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def series_puiseux(input_str):
"""
计算给定表达式在指定变量处的Puiseux级数展开(支持分数指数)。
参数:
input_str (str): 输入的表达式字符串,格式为"表达式, 变量",例如"sqrt(x),x"。
如果未指定变量且表达式只有一个变量,则自动选择该变量。
返回:
sympy.Expr 或 str: 级数展开结果,若出错则返回错误信息字符串。
"""
try:
# 尝试将输入的字符串转换为 sympy 表达式,evaluate=False 表示不进行求值
expr = sp.sympify(input_str, evaluate=False)
# 初始化错误标志
error = False
# 如果表达式是一个元组且长度为 2,说明输入格式为"表达式, 变量"
if isinstance(expr, tuple) and len(expr) == 2:
# 尝试判断第一个元素是否为函数,如果不是则直接使用该元素作为表达式
f = expr[0]
# 第二个元素作为展开变量
variable = expr[1]
# 如果表达式有自由变量
elif expr.free_symbols:
# 直接使用表达式
f = expr
# 获取表达式中的自由变量
variables = f.free_symbols
# 若有自由变量,选择第一个作为展开变量
variable = tuple(variables)[0]
else:
# 若表达式没有自由变量,设置错误标志
error = True
# 默认展开的项数为 5
n = 5
# 生成级数展开并移除无穷小量
series_exp = f.series(variable, n=n).removeO()
# 如果没有错误则返回展开结果,否则返回错误信息
return series_exp if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误:{e}"
# 示例代码
if __name__ == "__main__":
# 示例1:展开sin(x)到5阶
input1 = "sin(x), x"
print(f"输入:{input1}")
print("输出:", series_puiseux(input1))
# -x**3/6 + x
# 示例2:展开sqrt(x)到5阶
input2 = "sqrt(x), x"
print(f"\n输入:{input2}")
print("输出:", series_puiseux(input2))
# sqrt(x)
# 示例3:多变量未指定
input3 = "x*y + y"
print(f"\n输入:{input3}")
print("输出:", series_puiseux(input3))
# x*y + y
移动数组维度
B = shiftdim(A,n) 将数组 A 的维度移动 n 个位置。当 n 为正整数时,shiftdim 向左移动维度;当 n 为负整数时,向右移动维度。
A — 输入数组, 向量 | 矩阵
n — 位置的数量, 整数
B — 输出数组, 向量 | 矩阵
var —— 符号变量
示例1:图像处理 - RGB通道重排
将图像数据从(height, width, channels)重排为(channels, height, width)
image_data = [[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]] # 2x2x3图像
shifted_image = shiftdim(image_data, 2)
原图像维度: 2x2x3 (高度x宽度x通道)
print(f"移动后维度: {np.array(shifted_image).shape}")
#移动后维度: (3, 2, 2)
#应用: 深度学习图像预处理、计算机视觉
示例2:机器学习 - 特征矩阵变换
将特征矩阵从(样本, 特征)转换为(特征, 样本)用于某些算法
feature_matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]] # 4个样本,3个特征
shifted_features = shiftdim(feature_matrix, 1)
原特征矩阵: 4x3 (样本x特征)
print(f"移动后维度: {np.array(shifted_features).shape}")
#移动后维度: (3, 4)
#应用: 主成分分析、支持向量机
示例3:图像处理 - 批量图像数据重组
将批量图像从(batch, height, width, channels)转换为(channels, batch, height, width)
batch_images = [[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]] # 1个批次,2x2x2图像
shifted_batch = shiftdim(batch_images, 3)
原批量图像维度: 1x2x2x2
print(f"移动后维度: {np.array(shifted_batch).shape}")
#移动后维度: (2, 1, 2, 2)
#应用: PyTorch到TensorFlow模型转换
示例4:数值计算 - 矩阵运算内存布局优化
调整矩阵维度以优化缓存利用和计算效率
matrix_data = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
shifted_matrix = shiftdim(matrix_data, 1)
原矩阵: 3x4
print(f"移动后维度: {np.array(shifted_matrix).shape}")
#移动后维度: (4, 3)
#应用: 高性能计算、数值线性代数
示例5:数据可视化 - 三维坐标数据格式转换
将点云数据从(x, y, z)列表转换为分离的坐标数组
point_cloud = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
shifted_points = shiftdim(point_cloud, 1)
原点云数据: 4x3 (点x坐标)
print(f"移动后维度: {np.array(shifted_points).shape}")
#移动后维度: (3, 4)
#应用: 3D可视化、计算机图形学
示例6:机器人学 - 多传感器数据维度对齐
统一不同传感器的数据维度格式用于数据融合
sensor_data = [[1, 2, 3], [4, 5, 6]] # 2个传感器,3个测量值
shifted_sensors = shiftdim(sensor_data, 1)
原传感器数据: 2x3 (传感器x测量)
print(f"移动后维度: {np.array(shifted_sensors).shape}")
#移动后维度: (3, 2)
#应用: 传感器融合、状态估计
示例7:向右移位 - 添加前导维度
为单个数据样本添加批次维度以匹配批量处理接口
single_sample = [[1, 2, 3], [4, 5, 6]] # 2x3样本
batched_sample = shiftdim(single_sample, -1)
原样本维度: 2x3
print(f"移动后维度: {np.array(batched_sample).shape}")
#移动后维度: (1, 2, 3)
#应用: 深度学习推理、在线学习
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
def shift_arr_dim(input_str):
"""
实现类似 MATLAB shiftdim 函数的功能
:param arr: 输入的数组,可以是 sympy 矩阵或 numpy 数组
:param n: 移位的位数,正数表示向左移位,负数表示向右移位
:return: 移位后的数组
"""
try:
expr = sp.sympify(input_str)
result = None
error = False
if isinstance(expr, tuple) and isinstance(expr[0], list) and expr[1].is_integer:
arr = np.array(expr[0], dtype=object)
n = int(expr[1])
# 处理 n 为正数的情况(循环左移)
if n > 0:
ndim = arr.ndim
if ndim == 0:
pass # 标量无需处理
else:
n_shift = n % ndim # 处理 n 大于维度数的情况
if n_shift != 0:
new_order = list(range(n_shift, ndim)) + list(range(n_shift))
arr = np.transpose(arr, new_order)
# 处理 n 为负数的情况(添加前导单一维度)
elif n < 0:
for _ in range(-n):
arr = np.expand_dims(arr, axis=0)
else:
error = True
if not error:
if arr.ndim == 2:
# 如果输入是 sympy 矩阵且结果为二维,将结果转换回 sympy 矩阵
result = sp.Matrix(arr.tolist())
else:
result = arr
return result
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误:{e}"
# 示例使用
# 创建一个符号数组
# 向左移位 1 位
shifted_left = shift_arr_dim("[[x, y],[z,x+y]],1")
print("\n向左移位 1 位后的数组:")
print(shifted_left)
# Matrix([[x, z],
# [y, x + y]])
# 向左移位 1 位
shifted_left = shift_arr_dim("[[3, 4],[5,6]],1")
print("\n向左移位 1 位后的数组:")
print(shifted_left)
# Matrix([[3, 5],
# [4, 6]])
# 向右移位 1 位
shifted_right = shift_arr_dim("[[x, y],[z,x+y]],-1")
print("\n向右移位 1 位后的数组:")
print(shifted_right)
# [[[x y]
# [z x + y]]]
对数组执行符号函数
Y=sign(x)返回一个与x大小相同的数组Y,其中Y的每个元素为:
如果x的对应元素大于0,则为1.
如果x的相应元素等于0,则为0.
如果x的对应元素小于0,则为1.
如果x是复数, 返回x/abs(x).
a — 输入数组,标量,向量,矩阵
示例1:控制系统分析
系统状态矩阵的符号分析
system_matrix = [[-1, 2, 0], [-3, -1, 1], [0, 1, -2]]
系统状态矩阵的符号分析:
print(sign(system_matrix))
#[[-1.0, 1.0, 0],
[-1.0, -1.0, 1.0],
[0, 1.0, -1.0]]
示例2:优化问题
约束条件的符号分析
constraint_matrix = [[1, -1, 0], [0, 1, -1], [-1, 0, 1]]
约束矩阵符号分析:
print(sign(constraint_matrix))
#[[1.0, -1.0, 0],
[0, 1.0, -1.0],
[-1.0, 0, 1.0]]
示例3:物理系统建模
复数阻抗的相位信息
print(sign(1+1@i)) # 电感阻抗
#0.707106781186548 + 0.707106781186548*I
print(sign(1-1@i)) # 电容阻抗
#0.707106781186548 - 0.707106781186548*I
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def sign_function(input_str):
"""
符号函数计算,对标 MATLAB 的 sign 函数
定义:
对于实数 x:
sign(x) = 1 if x > 0
0 if x = 0
-1 if x < 0
对于复数 z = a + bi:
sign(z) = z / |z| (当 z ≠ 0 时)
0 (当 z = 0 时)
参数:
input_str (str): 输入表达式,可以是:
- 数值 (如 "2.5", "-3")
- 复数 (如 "1+2j")
- 符号表达式 (如 "x", "y**2")
- 矩阵 (如 "[[1, -2], [0, 3+4j]]")
返回:
[类型] 数值/符号表达式/矩阵 或 错误信息字符串
示例:
>>> sign_function("5")
1.0
>>> sign_function("-x")
-sign(x)
"""
try:
# 将输入字符串转换为 SymPy 表达式
expr = sp.sympify(input_str)
# 情况2:处理数值和符号输入
if expr.is_number or expr.free_symbols:
# 数值类型转换
# 符号表达式保持符号形式
return sp.sign(expr).evalf()
# 其他无法处理的情况
return f"输入错误: 不支持的类型 {type(expr)}"
except Exception as e:
return f"计算错误: {str(e)}"
# 示例测试
if __name__ == "__main__":
# 示例1:实数计算
print("示例1 实数计算:")
print(sign_function("5"))
# 1.00000000000000
print(sign_function("-3.2"))
# -1.00000000000000
print(sign_function("0"))
# 0
# 示例2:复数计算
print("\n示例2 复数计算:")
print(sign_function("3+4j"))
# 0.6 + 0.8*I
print(sign_function("0+0j"))
# 0
# 示例3:符号运算
print("\n示例3 符号运算:")
print(sign_function("x"))
# sign(x)
print(sign_function("-y**2"))
# -sign(y**2)
双曲正弦积分
如果x是浮点数,则sinhint(x)返回浮点结果.
Y = sinhint(x)返回算术表达式
x是标量,符号变量,表达式,向量,矩阵
示例1:电磁场理论
1.1 长直导线磁场计算
长直导线磁场中的积分:
print(sinhint(k*r)) # 波数乘以距离
#Shi(k*r)
print(sinhint(β*z)) # 传播常数乘以位置
#Shi(z*β)
1.2 波导模式分析
waveguide_params = [[0.5, 1.2], [0.8, 2.1], [1.5, 0.7]]
波导参数矩阵的Shi函数:
print(sinhint(waveguide_params))
#[[0.506996749819667, 1.30025036102206],
[0.828996563378934, 2.68792485058221],
[1.70065251576822, 0.7193380189289]]
1.3 天线辐射场计算
print(sinhint(α*d)) # 衰减系数乘以距离
#Shi(d*α)
示例2:热传导问题
2.1 瞬态热传导解
瞬态热传导中的积分项:
print(sinhint(α*t/L**2")) # 热扩散率×时间/特征长度平方
#Shi(t*α/L**2)
print(sinhint(β*x)) # 温度分布参数
#Shi(x*β)
2.2 热源分布问题
thermal_matrix = [[0.1, 0.3, 0.5], [0.2, 0.4, 0.6], [0.15, 0.25, 0.35]]
热源分布矩阵的Shi函数:
print(sinhint(thermal_matrix))
#[[0.100055572225057, 0.30150405620501, 0.506996749819667],
[0.200444978140746, 0.403572668742494, 0.612130396563381],
[0.150187626610941, 0.250869684890912, 0.352390716351195]]
2.3 边界热流计算
print(sinhint(q0*t/(ρ*c))) # 热流密度×时间/(密度×比热容)
#Shi(q0*t/(c*ρ))
示例3:流体力学
3.1 边界层流动
print(sinhint(Re*x/L)) # 雷诺数×位置/特征长度
#Shi(Re*x/L)
print(sinhint(U*y/ν)) # 速度×距离/运动粘度
#Shi(U*y/ν)
3.2 涡量分布计算
vorticity_params = [[0.5, 1.0], [1.5, 2.0], [2.5, 3.0]]
涡量参数矩阵的Shi函数:
print(sinhint(vorticity_params))
#[[0.506996749819667, 1.05725087537573],
[1.70065251576822, 2.50156743335498],
[3.54934040622444, 4.97344047585981]]
3.3 n可压缩流动马赫数相关
print(sinhint(M*x)) # 马赫数×位置
#Shi(M*x)
示例4:量子力学
4.1 波函数归一化
print(sinhint(k*r)) # 波矢×距离
#Shi(k*r)
print(sinhint(α*x)) # 衰减参数×位置
#Shi(x*α)
4.2 散射问题
scattering_matrix = [[0+0.5@i, 1], [0.5+0.5@i, 1@i]]
散射矩阵的Shi函数(复数):
print(sinhint(scattering_matrix))
#[[0.493107418043067*I, 1.05725087537573],
[0.48590455885256 + 0.513678793617608*I, 0.946083070367183*I]]
4.3 势场中的粒子运动
print(sinhint(V0*t/ħ)) # 势能×时间/约化普朗克常数
#Shi(V0*t/ħ)
示例5:信号处理
5.1 滤波器设计
print(sinhint(ω*tau)) # 角频率×时间常数
#Shi(tau*ω)
print(sinhint(s*T)) # 拉普拉斯变量×采样时间
#Shi(T*s)
5.2 信号失真分析
distortion_params = [[0.1, 0.2, 0.3], [0.4, 0.5, 0.6], [0.7, 0.8, 0.9]]
失真参数矩阵的Shi函数:
print(sinhint(distortion_params))
# 5.3 非线性系统分析
print("\n非线性系统响应:")
print(sinhint("a*t")) # 非线性参数×时间
#[[0.100055572225057, 0.200444978140746, 0.30150405620501],
[0.403572668742494, 0.506996749819667, 0.612130396563381],
[0.7193380189289, 0.828996563378934, 0.941497826511434]]
示例6:结构力学
6.1 梁的弯曲变形
print(sinhint(k*x)) # 曲率×位置
#Shi(k*x)
print(sinhint(β*L)) # 参数×梁长度
#Shi(L*β)
6.2 应力集中分析
stress_matrix = [[100, 150, 200], [120, 180, 240], [90, 135, 180]]
应力参数矩阵的Shi函数:
print(sinhint(stress_matrix))
#[[1.35777637242694e+41 + 3.14159265358979*I, 4.67709136413269e+62 + 3.14159265358979*I, 1.81561761657968e+84 + 3.14159265358979*I],
[5.48014531079016e+49 + 3.14159265358979*I, 4.16042239463051e+75 + 3.14159265358979*I, 3.5584054277459e+101 + 3.14159265358979*I],
[6.85708434753626e+36 + 3.14159265358979*I, 1.59090710861115e+56 + 3.14159265358979*I, 4.16042239463051e+75 + 3.14159265358979*I]]
6.3 振动模态分析
print(sinhint(ω_n*t)) # 固有频率×时间
#Shi(t*ω_n)
示例7:经济学和金融
7.1 增长模型
print(sinhint(g*t)) # 增长率×时间
#Shi(g*t)
print(sinhint(r*τ)) # 利率×时间
#Shi(r*τ)
7.2 波动率建模
volatility_params = [[0.05, 0.1], [0.15, 0.2], [0.25, 0.3]]
波动率参数矩阵的Shi函数:
print(sinhint(volatility_params))
#[[0.0500069449652999, 0.100055572225057],
[0.150187626610941, 0.200444978140746],
[0.250869684890912, 0.30150405620501]]
7.3 期权定价模型
print(sinhint(σ*sqrt(T))) # 波动率×sqrt(时间)
#Shi(sqrt(T)*σ)
示例8:材料科学
8.1 扩散过程
print(sinhint(D*t/L**2)) # 扩散系数×时间/长度平方
#Shi(D*t/L**2)
8.2 相变动力学
phase_change_matrix = [[300, 400, 500], [350, 450, 550], [320, 420, 520]]
相变温度矩阵的Shi函数:
print(sinhint(phase_change_matrix))
#[[3.24824125404433e+127 + 3.14159265358979*I, 6.54323640853714e+170 + 3.14159265358979*I, 1.40641069894315e+214 + 3.14159265358979*I],
[1.44283553490104e+149 + 3.14159265358979*I, 3.01469016214348e+192 + 3.14159265358979*I, 6.62772000463431e+235 + 3.14159265358979*I],
[1.47712696144629e+136 + 3.14159265358979*I, 3.02301892790884e+179 + 3.14159265358979*I, 6.56046850276688e+222 + 3.14159265358979*I]]
8.3 蠕变应变积分
print(sinhint(σ*t/η)) # 应力×时间/粘度
#Shi(t*σ/η)
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy.special import shichi
def shi_hyper_sine_integral(input_str):
"""
计算双曲正弦积分函数 Shi(z),对标 MATLAB 的 sinhint 函数
定义:
Shi(z) = ∫₀ᶻ (sinh(t)/t) dt
参数:
input_str (str): 输入表达式,可以是:
- 数值 (如 "0", "3.14")
- 符号表达式 (如 "x", "2*t+1")
- 矩阵 (如 "[[0, 1], [2, 3]]")
返回:
[类型] 数值/符号表达式/矩阵 或 错误信息字符串
示例:
>>> shi_hyper_sine_integral("0")
0.0
>>> shi_hyper_sine_integral("x")
Shi(x)
"""
try:
# 将输入字符串转换为 SymPy 表达式
expr = sp.sympify(input_str)
# 处理数值和符号输入
if expr.is_number:
z = complex(expr)
sin_arr, cos_arr = shichi(z)
return sin_arr
elif expr.free_symbols:
return sp.Shi(expr).evalf()
return f"输入错误: 无法处理类型 {type(expr)}"
except Exception as e:
return f"计算错误: {str(e)}"
if __name__ == "__main__":
# 示例 1:数值输入
print("示例1 数值计算:")
print(shi_hyper_sine_integral("0"))
# 0j
print(shi_hyper_sine_integral("1.0"))
# (1.0572508753757286+0j)
# 示例 2:符号计算
print("\n示例2 符号运算:")
print(shi_hyper_sine_integral("x"))
# Shi(x)
print(shi_hyper_sine_integral("2*t + 1"))
# Shi(2*t + 1)
正弦积分
sinint(X)返回X的正弦积分函数.
根据其参数,sinint返回浮点或精确的符号结果.
X是指定为符号数,变量,表达式或函数,或指定为符号,变量,公式或函数的矢量或矩阵.
示例1: 光学中的应用 - 单缝衍射强度分布
def single_slit_diffraction_intensity(a, wavelength, theta):
"""
计算单缝衍射的光强分布
I/I₀ = [Si(πa sinθ/λ)]²
"""
k = np.pi * a * np.sin(theta) / wavelength
si_value = sinint(k)
intensity = float(si_value) ** 2
return intensity
计算不同角度的衍射强度
a = 1e-6 # 缝宽 1微米
wavelength = 632.8e-9 # 氦氖激光波长
angles = np.linspace(-0.01, 0.01, 50) # 角度范围(弧度)
intensities = [single_slit_diffraction_intensity(a, wavelength, theta) for theta in angles]
print(f"缝宽: {a * 1e6} μm, 波长: {wavelength * 1e9} nm")
print(f"中心强度: {intensities[len(intensities) // 2]:.4f}")
print(f"第一极小值位置强度: {intensities[10]:.6f}")
#缝宽: 1.0 μm, 波长: 632.8 nm
#中心强度: 0.0000
#第一极小值位置强度: 0.000863
示例2: 信号处理 - 滤波器的阶跃响应
def ideal_lowpass_step_response(t, cutoff_freq):
"""
理想低通滤波器的阶跃响应包含正弦积分
h(t) = 0.5 + (1/π) * Si(2πf_c t)
"""
argument = 2 * np.pi * cutoff_freq * t
si_value = sinint(argument)
response = 0.5 + float(si_value) / np.pi
return response
计算阶跃响应
cutoff_freq = 1000 # 1kHz截止频率
time_points = np.linspace(0, 0.005, 100) # 0-5ms
responses = [ideal_lowpass_step_response(t, cutoff_freq) for t in time_points]
print(f"截止频率: {cutoff_freq} Hz")
print(f"t=0时的响应: {responses[0]:.4f}")
print(f"t=2.5ms时的响应: {responses[50]:.4f}")
#截止频率: 1000 Hz
#t=0时的响应: 0.5000
#t=2.5ms时的响应: 1.0199
示例3: 电磁学 - 有限长度天线的辐射场
def linear_antenna_field(L, wavelength, theta):
"""
计算中心馈电直线天线的辐射场
包含正弦积分项 Si(kL(1-cosθ)/2)
"""
k = 2 * np.pi / wavelength
argument = k * L * (1 - np.cos(theta)) / 2
si_value = sinint(argument)
return float(si_value)
L = 0.5 # 天线长度 0.5米
wavelength_antenna = 1.0 # 波长 1米
angles_antenna = np.linspace(0, np.pi, 8)
print(f"天线长度: {L} m, 波长: {wavelength_antenna} m")
for theta in angles_antenna:
field_strength = linear_antenna_field(L, wavelength_antenna, theta)
print(f"角度: {np.degrees(theta):6.1f}°, 场强系数: {field_strength:8.4f}")
#天线长度: 0.5 m, 波长: 1.0 m
#角度: 0.0°, 场强系数: 0.0000
#角度: 25.7°, 场强系数: 0.1553
#角度: 51.4°, 场强系数: 0.5800
#角度: 77.1°, 场强系数: 1.1245
#角度: 102.9°, 场强系数: 1.5678
#角度: 128.6°, 场强系数: 1.7900
#角度: 154.3°, 场强系数: 1.8480
#角度: 180.0°, 场强系数: 1.8519
示例4: 数值分析 - 矩阵输入处理
定义测试矩阵
test_matrix = [[0, 1, 2], [0.5, 1.5, 2.5], [1, 2, 3]]
matrix_result = sinint(test_matrix)
正弦积分结果矩阵:
print(matrix_result)
#[[0, 0.946083070367183, 1.60541297680269],
[0.493107418043067, 1.32468353117212, 1.77852017344383],
[0.946083070367183, 1.60541297680269, 1.84865252799947]]
示例5: 数学物理 - 特殊函数关系验证
验证 Si(∞) = π/2
large_x = 1000
si_large = sinint(large_x)
expected_limit = np.pi / 2
print(f"Si({large_x}) = {float(si_large):.8f}")
print(f"理论极限 π/2 = {expected_limit:.8f}")
print(f"相对误差: {abs(float(si_large) - expected_limit) / expected_limit * 100:.6f}%")
#Si(1000) = 1.57023312
#理论极限 π/2 = 1.57079633
#相对误差: 0.035855%
验证奇函数性质 Si(-x) = -Si(x)
x_test = 2.5
si_positive = sinint(x_test)
si_negative = sinint(-x_test)
print(f"\nSi({x_test}) = {float(si_positive):.8f}")
print(f"Si({-x_test}) = {float(si_negative):.8f}")
print(f"验证 Si(-x) = -Si(x): {abs(float(si_negative) + float(si_positive)) < 1e-10}")
#Si(2.5) = 1.77852017
#Si(-2.5) = -1.77852017
#验证 Si(-x) = -Si(x): True
示例6: 工程应用 - 通信系统中的相位失真
def group_delay_approximation(omega, tau):
"""
近似计算具有线性相位特性的系统的群延迟
涉及正弦积分函数
"""
arg = omega * tau
si_value = sinint(arg)
delay = float(si_value) / omega if omega != 0 else tau
return delay
frequencies = [100, 500, 1000, 2000] # Hz
tau = 1e-3 # 1ms 时间常数
print(f"系统时间常数: {tau * 1000:.1f} ms")
for freq in frequencies:
omega = 2 * np.pi * freq
delay = group_delay_approximation(omega, tau)
print(f"频率: {freq:4d} Hz, 群延迟: {delay * 1000:6.3f} ms")
#系统时间常数: 1.0 ms
#频率: 100 Hz, 群延迟: 0.978 ms
#频率: 500 Hz, 群延迟: 0.589 ms
#频率: 1000 Hz, 群延迟: 0.226 ms
#频率: 2000 Hz, 群延迟: 0.119 ms
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.special import sici
def si_sine_integral(input_str):
"""
计算正弦积分函数 Si(z),对标 MATLAB 的 sinint 函数
定义:
Si(z) = ∫₀ᶻ (sin(t)/t) dt
参数:
input_str (str): 输入表达式,可以是:
- 数值 (如 "0", "3.14")
- 符号表达式 (如 "x", "2*t+1")
- 矩阵 (如 "[[0, 1], [2, 3]]")
返回:
[类型] 数值/符号表达式/矩阵 或 错误信息字符串
示例:
>>> si_sine_integral("0")
0.0
>>> si_sine_integral("x")
Si(x)
"""
try:
# 将输入字符串转换为 SymPy 表达式
expr = sp.sympify(input_str)
result = None
error = False
# 处理元组输入
if isinstance(expr, tuple):
error = True
# 处理数值和符号输入
if expr.is_number:
z = complex(expr)
result = sici(z)[0]
elif expr.free_symbols:
result = sp.Si(expr.evalf())
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"计算错误: {str(e)}"
# 示例测试
if __name__ == "__main__":
# 示例 1:数值输入
print("示例1 数值计算:")
print(si_sine_integral("0"))
# 0j
print(si_sine_integral("1.0"))
# (0.946083070367183-0j)
# 示例 2:符号计算
print("\n示例2 符号运算:")
print(si_sine_integral("x"))
# Si(x)
print(si_sine_integral("2*t + 1"))
# Si(2.0*t + 1.0)
代数简化
S=simplify(expr)执行expr的代数简化. 如果expr是符号向量或矩阵,则此函数简化了expr的每个元素.
expr — 输入表达式, 符号表达式, 符号函数, 符号向量, 符号矩阵
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def simplify_function(input_str):
"""
简化输入的数学表达式或矩阵中的每个元素,对标Matlab的simplify函数。
参数:
input_str (str): 输入的数学表达式或矩阵的字符串表示。
返回:
SymPy对象或错误信息字符串: 简化后的表达式或矩阵,若出错则返回错误信息。
示例:
>>> simplify_function("x + x + 2*y - y")
2*x + y
>>> simplify_function("[[x + x, 2*y], [sin(pi/2), sqrt(4)]]")
Matrix([[2*x, 2*y], [1, 2]])
>>> simplify_function("3 + 4")
7
>>> simplify_function("(1, 2)")
'输入错误: (1, 2)'
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
def eval_expression(expr_item):
"""内部函数,用于简化单个表达式元素。"""
return sp.simplify(expr_item)
# 检查输入是否为元组(视为无效输入)
if isinstance(expr, tuple):
error = True
else:
# 处理普通标量或符号表达式
result = eval_expression(expr)
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误:{e}"
# 简化符号表达式
print(simplify_function("x + x + y - y/2"))
# 2*x + y/2
# 简化数值表达式
print(simplify_function("sqrt(9) + cos(pi)")) # 2
简化符号有理表达式
simplifyFraction(expr)简化有理表达式expr,使得分子和分母没有共同的除数.
simplifyFraction(expr,'Expand',true)将所得简化分数的分子和分母展开为无需分解的多项式.
expr — 输入数字,向量,矩阵,数组,符号数,符号变量,符号数组,符号函数,符号表达式
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def simplify_fraction(input_str):
"""
简化符号有理表达式,对标Matlab的simplifyFraction函数,支持矩阵输入。
参数:
input_str (str): 输入的有理表达式或矩阵的字符串表示。
返回:
SymPy对象或str: 简化后的表达式或矩阵,错误时返回错误信息。
示例:
>>> simplify_fraction("(x^2 - 1)/(x - 1)")
x + 1
>>> simplify_fraction("[[(x^2 - 1)/(x - 1), 6/3], [2*y/(y+y), (a+b)^2/(a+b)]]")
Matrix([[x + 1, 2], [1, a + b]])
>>> simplify_fraction("4/2 + 6/3")
4
>>> simplify_fraction("invalid expr")
错误:...
"""
try:
# 将输入字符串转换为SymPy表达式
expr = sp.sympify(input_str)
return sp.cancel(expr)
except Exception as e:
return f"错误:{e}"
print(simplify_fraction("((y+1)^2*(x^2-1))/((x+1)*(x-1)^2)"))
# (y**2 + 2*y + 1)/(x - 1)
以弧度为单位的参量的正弦.
Y = sin(X)返回X的每个元素的余弦.sin函数按元素处理数组.该函数同时接受实数和复数输入.
对于X的实数值,sin(X)返回区间[-1, 1]内的实数值.
对于X的复数值,sin(X)返回复数值.
X是标量,向量,数组,矩阵.
示例1: 简谐振动 - 物理中的基本应用
def harmonic_motion_displacement(t, amplitude, frequency, phase=0):
"""
简谐振动的位移公式: x(t) = A * sin(2πft + φ)
"""
argument = 2 * np.pi * frequency * t + phase
displacement = sin(argument)
return float(displacement) * amplitude
计算弹簧振子的位移
amplitude = 0.1 # 振幅 0.1米
frequency = 2 # 频率 2Hz
time_points = np.linspace(0, 2, 50) # 0-2秒
displacements = [harmonic_motion_displacement(t, amplitude, frequency)
for t in time_points]
print(f"振幅: {amplitude} m, 频率: {frequency} Hz")
print(f"t=0.25s时的位移: {displacements[6]:.4f} m")
print(f"t=0.5s时的位移: {displacements[12]:.4f} m")
#振幅: 0.1 m, 频率: 2 Hz
#t=0.25s时的位移: 0.0064 m
#t=0.5s时的位移: -0.0128 m
示例2: 交流电路分析
def ac_voltage(t, V_max, frequency, phase=0):
"""
交流电压: V(t) = V_max * sin(2πft + φ)
"""
argument = 2 * np.pi * frequency * t + phase
voltage = sin(argument)
return float(voltage) * V_max
计算家用交流电
V_max = 311 # 峰值电压 311V (对应220V有效值)
freq_ac = 50 # 50Hz 交流电
time_ac = np.linspace(0, 0.04, 20) # 0-40ms (2个周期)
voltages = [ac_voltage(t, V_max, freq_ac) for t in time_ac]
print(f"峰值电压: {V_max} V, 频率: {freq_ac} Hz")
print(f"t=5ms时的电压: {voltages[2]:.1f} V")
print(f"t=10ms时的电压: {voltages[5]:.1f} V")
#峰值电压: 311 V, 频率: 50 Hz
#t=5ms时的电压: 301.5 V
#t=10ms时的电压: -51.2 V
示例3: 信号处理 - 调制信号生成
def am_signal(t, carrier_freq, modulation_freq, modulation_index=0.5):
"""
振幅调制信号: s(t) = [1 + m*sin(2πf_m t)] * sin(2πf_c t)
"""
carrier_arg = 2 * np.pi * carrier_freq * t
modulation_arg = 2 * np.pi * modulation_freq * t
carrier = sin(carrier_arg)
modulation = sin(modulation_arg)
return float(carrier) * (1 + modulation_index * float(modulation))
生成AM信号
carrier_freq = 1000 # 载波频率 1kHz
mod_freq = 100 # 调制频率 100Hz
time_am = np.linspace(0, 0.02, 100) # 0-20ms
am_signals = [am_signal(t, carrier_freq, mod_freq) for t in time_am]
print(f"载波频率: {carrier_freq} Hz, 调制频率: {mod_freq} Hz")
print(f"t=2.5ms时的信号幅度: {am_signals[12]:.4f}")
print(f"t=5ms时的信号幅度: {am_signals[25]:.4f}")
#载波频率: 1000 Hz, 调制频率: 100 Hz
#t=2.5ms时的信号幅度: 0.6871
#t=5ms时的信号幅度: 0.3071
示例4: 机械工程 - 曲柄滑块机构
def slider_crank_displacement(theta, crank_length, connecting_rod_length):
"""
曲柄滑块机构的滑块位移: x = r*cosθ + √(l² - r²*sin²θ)
其中包含正弦函数项
"""
sin_theta = sin(theta)
cos_theta = sin(theta + np.pi / 2) # cosθ = sin(θ+π/2)
r_sin_theta_sq = (crank_length * float(sin_theta)) ** 2
displacement = (crank_length * float(cos_theta) +
np.sqrt(connecting_rod_length ** 2 - r_sin_theta_sq))
return displacement
计算滑块位移
crank_len = 0.1 # 曲柄长度 0.1m
rod_len = 0.3 # 连杆长度 0.3m
angles = np.linspace(0, 2 * np.pi, 8) # 0-360度
print(f"曲柄长度: {crank_len} m, 连杆长度: {rod_len} m")
for angle in angles:
displacement = slider_crank_displacement(angle, crank_len, rod_len)
print(f"角度: {np.degrees(angle):6.1f}°, 滑块位移: {displacement:.4f} m")
#曲柄长度: 0.1 m, 连杆长度: 0.3 m
#角度: 0.0°, 滑块位移: 0.4000 m
#角度: 51.4°, 滑块位移: 0.3520 m
#角度: 102.9°, 滑块位移: 0.2615 m
#角度: 154.3°, 滑块位移: 0.2067 m
#角度: 205.7°, 滑块位移: 0.2067 m
#角度: 257.1°, 滑块位移: 0.2615 m
#角度: 308.6°, 滑块位移: 0.3520 m
#角度: 360.0°, 滑块位移: 0.4000 m
示例5: 音频处理 - 音调生成
def generate_tone(frequency, duration=1.0, sample_rate=44100):
"""
生成指定频率的纯音调信号
"""
t = np.linspace(0, duration, int(sample_rate * duration))
tone = [sin(2 * np.pi * frequency * time)
for time in t]
return np.array(tone)
生成不同音调
A4_freq = 440 # A4标准音
C5_freq = 523.25 # C5音
tone_A4 = generate_tone(A4_freq, 0.1) # 0.1秒的A4音
tone_C5 = generate_tone(C5_freq, 0.1) # 0.1秒的C5音
print(f"A4音频率: {A4_freq} Hz")
print(f"C5音频率: {C5_freq} Hz")
print(f"A4音信号峰值: {np.max(np.abs(tone_A4)):.4f}")
print(f"C5音信号峰值: {np.max(np.abs(tone_C5)):.4f}")
#A4音频率: 440 Hz
#C5音频率: 523.25 Hz
#A4音信号峰值: 1
#C5音信号峰值: 1
示例6: 数值分析 - 矩阵运算
定义角度矩阵(弧度)
angle_matrix = [[0, @pi/6, @pi/4], [@pi/3, @pi/2, 2*@pi/3], [3*@pi/4, 5*@pi/6, @pi]]
matrix_result = sin(angle_matrix)
输入角度矩阵 (弧度):
input_matrix = np.array([[0, np.pi / 6, np.pi / 4],
[np.pi / 3, np.pi / 2, 2 * np.pi / 3],
[3 * np.pi / 4, 5 * np.pi / 6, np.pi]])
正弦函数结果矩阵:
print(matrix_result)
#[[0, 0.5, 0.707106781186547],
[0.866025403784439, 1.0, 0.866025403784438],
[0.707106781186548, 0.5, 1.22464679914735e-16]]
验证特殊角度
special_angles = [0, @pi/6, @pi/4, @pi/3, @pi/2]
for angle in special_angles:
result = sin(angle)
print(f"sin({angle:4}) = {float(result):8.4f}")
#sin(0 ) = 0.0000
#sin(pi/6) = 0.5000
#sin(pi/4) = 0.7071
#sin(pi/3) = 0.8660
#sin(pi/2) = 1.0000
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def sine_trig_function(input_str):
"""
对标 MATLAB 的 sin 函数,计算以弧度为单位的正弦值
参数:
input_str: 输入的数学表达式字符串,可以是数值、符号、矩阵等
返回:
计算结果(数值、符号表达式或矩阵),若输入不合法则返回错误信息
"""
try:
# 将输入字符串转换为 SymPy 表达式
expr = sp.sympify(input_str)
error = False
result = None
# 处理元组输入(视为非法)
if isinstance(expr, tuple):
error = True
elif expr.is_number or expr.free_symbols:
result = sp.sin(expr)
# 其他无法处理的类型
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
# 示例代码
if __name__ == "__main__":
# 示例 1: 数值输入
print("示例 1:", sine_trig_function("0"))
# 0
print("示例 1:", sine_trig_function("pi/2"))
# 1.00000000000000
# 示例 2: 符号输入
x = sp.symbols('x')
print("示例 2:", sine_trig_function("x"))
# sin(x)
print("示例 2:", sine_trig_function("x + pi"))
# -sin(x)
辛格函数
y = sinc(x) 返回数组 y,其元素是输入 x 的元素的 sinc。输出 y 与 x 的大小相同.
x是标量值,向量,矩阵或多维数组.
y是标量值,向量,矩阵
示例1: 信号处理 - 理想低通滤波器冲激响应
def ideal_lowpass_impulse_response(cutoff_freq, t):
"""
理想低通滤波器的冲激响应是sinc函数:
h(t) = 2f_c * sinc(2f_c t)
"""
argument = 2 * cutoff_freq * t
sinc_value = sinc(argument)
return 2 * cutoff_freq * float(sinc_value)
计算滤波器冲激响应
cutoff_freq = 1000 # 截止频率 1kHz
time_points = np.linspace(-0.005, 0.005, 100) # -5ms 到 5ms
impulse_response = [ideal_lowpass_impulse_response(cutoff_freq, t)
for t in time_points]
print(f"截止频率: {cutoff_freq} Hz")
print(f"t=0时的冲激响应: {impulse_response[50]:.4f}")
print(f"t=1ms时的冲激响应: {impulse_response[70]:.6f}")
#截止频率: 1000 Hz
#t=0时的冲激响应: 1966.6019
#t=1ms时的冲激响应: 66.068239
示例2: 通信系统 - 数字信号重构
def reconstruct_signal(samples, sampling_period, t):
"""
使用sinc函数重构连续信号:
x(t) = Σ x[n] * sinc((t - nT)/T)
"""
reconstructed = 0
for n, sample in enumerate(samples):
argument = (t - n * sampling_period) / sampling_period
sinc_value = sinc(argument)
reconstructed += sample * float(sinc_value)
return reconstructed
模拟采样和重构
sampling_freq = 10 # 采样频率 10Hz
sampling_period = 1 / sampling_freq
samples = [1, 2, 1.5, 0.5, -0.5, -1, -0.5, 0.5] # 采样值
reconstruction_time = np.linspace(0, 0.7, 100) # 重构时间点
reconstructed_signal = [reconstruct_signal(samples, sampling_period, t)
for t in reconstruction_time]
print(f"采样频率: {sampling_freq} Hz")
print(f"采样点数: {len(samples)}")
print(f"重构信号在t=0.35s时的值: {reconstructed_signal[50]:.4f}")
#采样频率: 10 Hz
#采样点数: 8
#重构信号在t=0.35s时的值: -0.0878
示例3: 光学 - 单缝衍射模式
def single_slit_diffraction_intensity(a, wavelength, distance, x):
"""
单缝衍射的强度分布是sinc函数的平方:
I(x) = I₀ * [sinc(πa x/(λL))]²
"""
argument = a * x / (wavelength * distance)
sinc_value = sinc(argument)
intensity = float(sinc_value) ** 2
return intensity
计算衍射强度
slit_width = 1e-6 # 缝宽 1微米
wavelength = 632.8e-9 # 氦氖激光波长
screen_distance = 1.0 # 屏幕距离 1米
x_positions = np.linspace(-0.01, 0.01, 50) # 屏幕位置 -1cm 到 1cm
intensities = [single_slit_diffraction_intensity(slit_width, wavelength,
screen_distance, x)
for x in x_positions]
print(f"缝宽: {slit_width * 1e6} μm, 波长: {wavelength * 1e9} nm")
print(f"中心强度: {intensities[25]:.4f}")
print(f"第一极小值强度: {intensities[10]:.6f}")
#缝宽: 1.0 μm, 波长: 632.8 nm
#中心强度: 1.0000
#第一极小值强度: 0.999712
示例4: 图像处理 - 图像缩放中的插值
def lanczos_kernel(x, a=3):
"""
Lanczos插值核,基于sinc函数:
L(x) = sinc(x) * sinc(x/a) for |x| < a, 0 otherwise
"""
if abs(x) >= a:
return 0
else:
sinc1 = sinc(x)
sinc2 = sinc(x / a)
return float(sinc1) * float(sinc2)
计算Lanczos核函数值
x_values = np.linspace(-4, 4, 17)
lanczos_values = [lanczos_kernel(x) for x in x_values]
Lanczos核函数值:
for i, (x, val) in enumerate(zip(x_values, lanczos_values)):
if i % 4 == 0: # 每4个点输出一次
print(f"x = {x:5.1f}, L(x) = {val:8.4f}")
#x = -4.0, L(x) = 0.0000
#x = -2.0, L(x) = -0.0000
#x = 0.0, L(x) = 1.0000
#x = 2.0, L(x) = -0.0000
#x = 4.0, L(x) = 0.0000
示例5: 数值分析 - 矩阵运算
定义测试矩阵
test_matrix = [[-2, -1, 0], [0.5, 1, 1.5], [2, 2.5, 3]]
matrix_result = sinc(test_matrix)
sinc函数结果矩阵:
print(matrix_result)
#[[-3.89817183251938e-17, 3.89817183251938e-17, 1.0],
[0.636619772367581, 3.89817183251938e-17, -0.212206590789194],
[-3.89817183251938e-17, 0.127323954473516, 3.89817183251938e-17]]
特殊点验证:
special_points = [0, 1, 2, 0.5, 1.5]
for point in special_points:
result = sinc(point)
print(f"sinc({point}) = {float(result):10.6f}")
#sinc(0) = 1.000000
#sinc(1) = 0.000000
#sinc(2) = -0.000000
#sinc(0.5) = 0.636620
#sinc(1.5) = -0.212207
示例6: 天线设计 - 均匀线性阵列方向图
def uniform_linear_array_pattern(N, d, wavelength, theta):
"""
均匀线性阵列的方向图包含sinc函数:
AF(θ) = sin(Nπ(d/λ)(sinθ - sinθ₀)) / sin(π(d/λ)(sinθ - sinθ₀))
对于大N,近似为sinc函数
"""
k = 2 * np.pi / wavelength
psi = k * d * np.sin(theta)
if abs(psi) < 1e-10: # 避免除以0
return N
else:
return np.sin(N * psi / 2) / np.sin(psi / 2)
近似使用sinc函数计算
def array_pattern_sinc_approx(N, d, wavelength, theta):
"""
使用sinc函数近似阵列方向图
"""
argument = N * d * np.sin(theta) / wavelength
sinc_value = sinc(argument)
return N * float(sinc_value)
计算阵列方向图
N_elements = 8 # 8个阵元
element_spacing = 0.5 # 半波长间距
wavelength_antenna = 1.0 # 波长1米
angles = np.linspace(-np.pi / 2, np.pi / 2, 50)
pattern_approx = [array_pattern_sinc_approx(N_elements, element_spacing,
wavelength_antenna, theta)
for theta in angles]
print(f"阵元数量: {N_elements}, 阵元间距: {element_spacing}λ")
print(f"主瓣方向增益: {max(pattern_approx):.2f}")
print(f"第一副瓣相对增益: {pattern_approx[15] / max(pattern_approx):.2f}")
#阵元数量: 8, 阵元间距: 0.5λ
#主瓣方向增益: 7.79
#第一副瓣相对增益: 0.11
示例7: 音频处理 - 抗混叠滤波
def resampling_filter(original_rate, target_rate, t):
"""
重采样滤波器基于sinc函数:
h(t) = sinc(t * min(f_original, f_target))
"""
cutoff_freq = min(original_rate, target_rate) / 2
argument = t * cutoff_freq
sinc_value = sinc(argument)
return 2 * cutoff_freq * float(sinc_value)
计算重采样滤波器响应
original_rate = 44100 # 原始采样率 44.1kHz
target_rate = 22050 # 目标采样率 22.05kHz
time_filter = np.linspace(-0.001, 0.001, 50) # -1ms 到 1ms
filter_response = [resampling_filter(original_rate, target_rate, t)
for t in time_filter]
print(f"原始采样率: {original_rate} Hz")
print(f"目标采样率: {target_rate} Hz")
print(f"滤波器在t=0时的响应: {filter_response[25]:.4f}")
print(f"滤波器在t=0.5ms时的响应: {filter_response[37]:.6f}")
#原始采样率: 44100 Hz
#目标采样率: 22050 Hz
#滤波器在t=0时的响应: 20259.1220
#滤波器在t=0.5ms时的响应: -1152.793556
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
def sinc_sampling_function(input_str):
"""
计算输入表达式的 sinc 采样函数值,对标 MATLAB 的 sinc 函数。
MATLAB 定义:sinc(x) = sin(πx)/(πx),且在 x=0 时值为 1
参数:
input_str (str): 输入表达式字符串,可以是:
- 数值(如 "0")
- 符号表达式(如 "x")
- 矩阵(如 "[[0, 1], [2, 3]]")
返回:
sympy 表达式/矩阵/浮点数 或 str: 计算结果或错误信息
"""
try:
# 将输入字符串转换为 SymPy 对象
expr = sp.sympify(input_str)
def sinc_numpy_style(x):
if x == 0:
return 1
else:
return sp.sin(sp.pi * x) / (sp.pi * x)
# 情况 2:处理数值输入
if expr.is_number:
z = complex(expr)
return np.sinc(z)
# 情况 3:处理符号表达式
elif expr.free_symbols:
return sinc_numpy_style(expr)
# 其他无法处理的情况
else:
return f"输入错误: 不支持的类型 {type(expr)}"
except Exception as e:
return f"错误: {str(e)}"
# 示例测试
if __name__ == "__main__":
# 示例 1:数值输入
print("示例 1:")
print(sinc_sampling_function("0"))
# (1+0j)
print(sinc_sampling_function("1.0"))
# (3.8981718325193755e-17-0j)
# 示例 2:符号输入
print("\n示例 2:")
x = sp.symbols('x')
print(sinc_sampling_function("x"))
# 0.318309886183791*sin(pi*x)/x
print(sinc_sampling_function("2*x + 1"))
# 0.318309886183791*sin(pi*(2*x + 1))/(2.0*x + 1.0)
以度为单位的参量的正弦.
Y = sind(X)返回X的每个元素的余弦.sind函数按元素处理数组.该函数同时接受实数和复数输入.
X是标量,向量,数组,矩阵.
示例1. 结构力学 - 桁架分析
节点力平衡方程
斜杆力F在水平和垂直方向的分量
F_horizontal = F * sind(90 - theta) # F*cos(θ)
F_vertical = F * sind(theta) # F*sin(θ)
桁架力分析
print(f"斜杆力F的水平分量: {F_horizontal}")
print(f"斜杆力F的垂直分量: {F_vertical}")
#斜杆力F的水平分量: F*cos(pi*theta/180)
#斜杆力F的垂直分量: F*sin(pi*theta/180)
数值示例:45度斜杆,承受10kN拉力
numerical_horizontal = F_horizontal.subs({F: 10, theta: 45})
numerical_vertical = F_vertical.subs({F: 10, theta: 45})
数值计算 (F=10kN, θ=45°):
print(f"水平分量: {numerical_horizontal:.3f} kN")
print(f"垂直分量: {numerical_vertical:.3f} kN")
#水平分量: 7.071 kN
#垂直分量: 7.071 kN
示例2. 机械工程 - 斜面力学分析
重力加速度 (m/s²)
g_val = 9.81
重力在斜面上的分力
parallel_force = m * g * sind(theta) # 平行于斜面的分力
normal_force = m * g * sind(90 - theta) # 垂直于斜面的分力
摩擦力 (μ * 法向力)
friction_force = mu * normal_force
净下滑力
net_force = parallel_force - friction_force
斜面力学分析:
print(f"平行分力: {parallel_force}")
print(f"法向分力: {normal_force}")
print(f"摩擦力: {friction_force}")
print(f"净下滑力: {net_force}")
#平行分力: g*m*sin(pi*theta/180)
#法向分力: g*m*cos(pi*theta/180)
#摩擦力: g*m*mu*cos(pi*theta/180)
#净下滑力: -g*m*mu*cos(pi*theta/180) + g*m*sin(pi*theta/180)
数值示例:质量2kg,斜面30度,摩擦系数0.2
example_net = net_force.subs({
m: 2, g: g_val, theta: 30, mu: 0.2
})
数值计算 (m=2kg, θ=30°, μ=0.2):
print(f"净下滑力: {example_net:.3f} N")
print(f"加速度: {example_net / 2:.3f} m/s²")
#净下滑力: 6.412 N
#加速度: 3.206 m/s²
示例3. 电气工程 - 交流电路分析
三相系统中,线电压 = √3 × 相电压 × sin(120°)
但更准确地说,线电压是相电压的矢量差
V_line = V_phase * sqrt(3) * sind(90) # sin(90°) = 1
相位差计算
phase_shift = sind(120) # 三相之间的120度相位差
三相交流电路分析
print(f"线电压表达式: {V_line}")
print(f"120度相位差的正弦值: {phase_shift}")
#线电压表达式: 1.0*sqrt(3)*V_phase
#120度相位差的正弦值: 0.866025403784439
数值示例:相电压220V
V_line_num = V_line.subs({V_phase: 220})
数值计算 (V_phase=220V):
print(f"线电压: {V_line_num:.3f} V")
print(f"理论值: 220×√3 = {220 * sp.sqrt(3):.3f} V")
#线电压: 381.051 V
#理论值: 220×√3 = 381.051 V
示例4. 机器人学 - 机械臂运动学
机械臂末端坐标 (正向运动学)
x = L1 * sind(90 - theta1) + L2 * sind(90 - theta1 - theta2) # cos项
y = L1 * sind(theta1) + L2 * sind(theta1 + theta2) # sin项
机械臂运动学分析
print(f"末端X坐标: {x}")
print(f"末端Y坐标: {y}")
#末端X坐标: L1*cos(pi*theta1/180) + L2*cos(pi*(theta1/180 + theta2/180))
#末端Y坐标: L1*sin(pi*theta1/180) + L2*sin(pi*(theta1/180 + theta2/180))
数值示例:L1=1m, L2=0.8m, θ1=30°, θ2=45°
x_num = x.subs({L1: 1.0, L2: 0.8, theta1: 30, theta2: 45})
y_num = y.subs({L1: 1.0, L2: 0.8, theta1: 30, theta2: 45})
数值计算 (L1=1m, L2=0.8m, θ1=30°, θ2=45°):
print(f"末端位置: ({x_num:.3f}, {y_num:.3f}) m")
#末端位置: (1.073, 1.273) m
示例5. 光学工程 - 折射定律应用
斯涅尔定律: n1 × sin(θ1) = n2 × sin(θ2)
因此: θ2 = arcsin((n1/n2) × sin(θ1))
计算折射角的正弦值
sin_theta2 = (n1 / n2) * sind(theta1)
光学折射分析
print(f"折射角正弦值: {sin_theta2}")
#折射角正弦值: n1*sin(pi*theta1/180)/n2
数值示例:空气到玻璃,入射角30度
空气折射率n1=1.0,玻璃折射率n2=1.5
example_sin = sin_theta2.subs({n1: 1.0, n2: 1.5, theta1: 30})
数值计算 (n1=1.0, n2=1.5, θ1=30°):
print(f"sin(θ2): {example_sin:.3f}")
#sin(θ2): 0.333
计算实际折射角
theta2_rad = asin(example_sin)
theta2_deg = theta2_rad * 180 / sp.pi
print(f"折射角: {theta2_deg:.3f}°")
#折射角: 19.471°
示例6. 航空航天 - 飞行力学
T, D, W, gamma # 推力、阻力、重量、爬升角
爬升率公式: RC = (T - D)/W × V × sin(γ)
简化版本:爬升角与推力的关系
climb_angle_sin = (T - D) / W # sin(γ) = (T - D)/W
飞机爬升性能分析
print(f"爬升角正弦值: {climb_angle_sin}")
#爬升角正弦值: (-D + T)/W
数值示例:推力=50kN,阻力=20kN,重量=100kN
example_sin = climb_angle_sin.subs({T: 50, D: 20, W: 100})
数值计算 (T=50kN, D=20kN, W=100kN):
print(f"sin(γ): {example_sin:.3f}")
#sin(γ): 0.300
计算爬升角
gamma_rad = asin(example_sin)
gamma_deg = gamma_rad * 180 / sp.pi
print(f"爬升角: {gamma_deg:.3f}°")
#爬升角: 17.458°
示例7. 海洋工程 - 波浪力计算
简化的波浪压力公式(线性波理论)
波浪引起的动压力: p = ρgH/2 × cos(kx - ωt) 的深度修正
在角度θ方向的波浪力分量
wave_pressure = (rho * g * H / 2) * sind(90 - theta) # cos项
海洋波浪力分析
print(f"波浪压力表达式: {wave_pressure}")
#波浪压力表达式: H*g*rho*cos(pi*theta/180)/2
数值示例:海水密度1025kg/m³,波高3m,波浪方向45度
example_pressure = wave_pressure.subs({
rho: 1025, g: 9.81, H: 3, theta: 45
})
数值计算 (ρ=1025kg/m³, H=3m, θ=45°):
print(f"波浪压力: {example_pressure:.3f} Pa")
print(f"相当于: {example_pressure / 1000:.3f} kPa")
#波浪压力: 10665.203 Pa
#相当于: 10.665 kPa
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
def sind_sine_degree(input_str):
try:
# 将输入字符串转换为 SymPy 表达式
expr = sp.sympify(input_str)
error = False
result = None
# 定义度数转弧度的正弦计算函数
def sine_deg(x_val):
return sp.sin(x_val * sp.pi / 180).evalf()
# 处理数值或符号表达式
if expr.is_number:
z = complex(expr)
result = np.sin(z * np.pi / 180)
elif expr.free_symbols:
result = sine_deg(expr)
# 其他无法处理的类型
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误:{e}"
# 示例代码
if __name__ == "__main__":
# 示例 1: 数值输入
print("示例 1:", sind_sine_degree("30"))
# (0.49999999999999994+0j)
# 示例 2: 符号输入
x = sp.symbols('x')
print("示例 2:", sind_sine_degree("x"))
# sin(pi*x/180)
正弦拟合
p = sinfit(x,y,n) 返回次数为n的正弦拟合 p(x) 的系数
x是查询点,指定为一个向量.
y是查询点位置的拟合值,指定为向量.
n是正弦拟合的次数, 正整数标量.
Y = a1*sin(b1*x+c1)
Y = a1*sin(b1*x+c1)+a2*sin(b2*x+c2)
Y = a1*sin(b1*x+c1)+...+a3*sin(b3*x+c3)
Y = a1*sin(b1*x+c1)+...+a8*sin(b8*x+c8)
以此类推,最大到 sin8
示例1. 机械振动分析
模拟振动传感器数据(包含两个主要频率分量)
t = np.linspace(0, 2, 200)
设备振动信号:1Hz和3Hz的混合振动
vibration_signal = (
2.5 * np.sin(2 * np.pi * 1 * t + 0.3) + # 基频振动
1.2 * np.sin(2 * np.pi * 3 * t - 0.5) + # 三倍频振动
0.3 * np.random.normal(0, 0.1, len(t)) # 噪声
)
进行二阶正弦拟合
expr = sinfit(list(t),list(vibration_signal),2)
机械振动分析
原始信号: 1Hz(2.5) + 3Hz(1.2) + 噪声
print(f"拟合结果: {expr}")
#拟合结果: 8.1973*sin(0.0199*x + 3.12) + 2.4404*sin(6.1586*x + 0.4318)
可视化
plt.figure(figsize=(10, 6))
plt.plot(t, vibration_signal, 'b-', alpha=0.7, label='原始信号')
计算拟合值
t_fit = np.linspace(0, 2, 200)
if hasattr(expr, 'subs'):
y_fit = [expr.subs('x', ti).evalf() for ti in t_fit]
plt.plot(t_fit, y_fit, 'r--', linewidth=2, label='拟合曲线')
plt.xlabel('时间 (s)')
plt.ylabel('振动幅度')
plt.title('机械振动信号分析')
plt.legend()
plt.grid(True)
plt.show()
示例2. 生物医学信号处理
t = np.linspace(0, 30, 1000) # 30秒数据
ECG R-R间期变化(心率变异性)
包含呼吸相关的0.25Hz调制和更慢的0.1Hz调制
rr_intervals = (
0.8 +
0.05 * np.sin(2 * np.pi * 0.25 * t) + # 呼吸调制
0.03 * np.sin(2 * np.pi * 0.1 * t + 0.5) # 低频调制
)
添加噪声模拟真实ECG
rr_noisy = rr_intervals + 0.01 * np.random.normal(0, 1, len(t))
进行二阶正弦拟合
expr = sinfit(list(t),list(rr_noisy),2)
生物医学信号分析
R-R间期变异性分析(心率变异性)
print(f"拟合结果: {expr}")
#拟合结果: 0.3358*sin(0.3055*x + 0.1493)
示例3. 天文观测数据分析
模拟造父变星的亮度观测数据
days = np.linspace(0, 100, 500) # 100天的观测
造父变星光变曲线:主周期 + 次级周期
magnitude = (
4.5 + # 平均星等
0.3 * np.sin(2 * np.pi * days / 5.3) + # 5.3天主周期
0.1 * np.sin(2 * np.pi * days / 2.1 + 1.2) + # 2.1天次级周期
0.02 * np.random.normal(0, 1, len(days)) # 观测误差
)
进行二阶正弦拟合
expr = sinfit(list(days),list(magnitude),2)
天文观测数据分析
造父变星脉动周期分析
拟合结果: {expr}
#拟合结果: 0.9451*sin(0.0918*x + 0.1255) + 0.945*sin(0.0918*x + 0.1277)
示例4. 经济周期分析
模拟季度GDP增长率数据(10年数据)
quarters = np.arange(0, 40) # 40个季度 = 10年
GDP增长率:趋势 + 季节性 + 周期性波动
gdp_growth = (
2.5 + # 长期趋势
0.8 * np.sin(2 * np.pi * quarters / 16) + # 4年经济周期
0.3 * np.sin(2 * np.pi * quarters / 4 + 0.5) + # 1年季节性
0.2 * np.random.normal(0, 1, len(quarters)) # 随机波动
)
进行二阶正弦拟合
expr = sinfit(list(quarters),list(gdp_growth),2)
经济周期分析
GDP增长率的周期性成分分析
print(f"拟合结果: {expr}")
#拟合结果: 19.2696*sin(0.0003*x + 3.0082) + 0.8381*sin(0.3923*x + 0.0656)
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
def sin_fit_nonlinear(input_str):
"""
使用非线性最小二乘法进行正弦曲线拟合,支持1到8阶正弦项。
参数:
x_data (array_like): 自变量数据数组
y_data (array_like): 因变量数据数组
n (int): 正弦项的数量(1到8)
maxfev (int): 最大函数评估次数
返回:
sympy.Expr: 拟合的正弦表达式
str: 错误信息(如果发生错误)
示例:
x = np.linspace(0, 10, 100)
y = 2.5 * np.sin(3 * x + 1) + 0.5 * np.sin(5 * x - 2)
expr = sin_fit_nonlinear(x, y, n=2)
print(expr) # 输出类似 2.5000*sin(3.0000*x + 1.0000) + 0.5000*sin(5.0000*x - 2.0000)
"""
try:
expr = sp.sympify(input_str)
error = False
maxfev = 100000
# 定义正旋拟合函数,从一阶到八阶
if isinstance(expr, tuple):
if len(expr) == 3:
x, y, n = expr[0], expr[1], int(expr[2])
elif len(expr) == 2:
x, y = expr
n = 1
else:
error = True
if isinstance(x, list):
x_data = np.array(x, dtype=float).ravel()
if isinstance(y, list):
y_data = np.array(y, dtype=float).ravel()
# 输入验证
if n < 1 or n > 8:
return None, "阶数n必须在1到8之间"
if len(x_data) != len(y_data):
return None, "x_data和y_data长度不一致"
else:
error = True
# 定义各阶正弦函数
func_dict = {
1: lambda x, *p: p[0] * np.sin(p[1] * x + p[2]),
2: lambda x, *p: sum(p[i * 3] * np.sin(p[i * 3 + 1] * x + p[i * 3 + 2]) for i in range(2)),
# ... 类似定义到n=8
}
# 生成初始猜测
a_guess = (np.max(y_data) - np.min(y_data)) / 2
b_guess = 2 * np.pi / (np.max(x_data) - np.min(x_data))
initial_guess = [a_guess, b_guess, 0] * n
params, _ = curve_fit(func_dict[n], x_data, y_data,
p0=initial_guess, maxfev=maxfev,
bounds=(0, [np.inf, np.inf, 2 * np.pi] * n))
# 构建表达式
terms = []
for i in range(n):
a, b, c = params[i * 3: (i + 1) * 3]
terms.append(f"{a:.4f}*sin({b:.4f}*x + {c:.4f})")
return sp.sympify("+".join(terms))
except Exception as e:
return f"错误:{e}"
# 生成测试数据
x = [1, 2, 3, 4, 5, 6, 7, 8]
y = [9, 10, 11, 12, 13, 14, 15, 16]
# 进行拟合
expr = sin_fit_nonlinear(f"{x},{y},2")
if expr:
print("拟合表达式:", expr)
# 5.1845*sin(1.0957*x)
else:
print("错误:")
双曲正弦
Y = sinh(X)返回X的每个元素的双曲正弦.sinh函数按元素处理数组.该函数同时接受实数和复数输入.
所有的角度都以弧度表示.
X是标量,向量,数组,矩阵.
示例1. 悬链线问题 - 桥梁与电缆设计
a # 悬链线参数
x # 水平距离
悬链线方程: y = a * cosh(x/a)
斜率 = sinh(x/a)
slope = sinh(x/a)
悬链线分析
print(f"悬链线在位置x处的斜率: {slope}")
#悬链线在位置x处的斜率: sinh(x/a)
数值示例:计算电缆在特定点的斜率
cable_param = 50 # 参数a (与张力、线密度相关)
position_x = 30 # 距离最低点的水平距离
slope_at_point = slope.subs({'a': cable_param, 'x': position_x})
angle_deg = atan(slope_at_point) * 180 / pi
电缆参数 a={cable_param}m, 在x={position_x}m处:
print(f"斜率: {slope_at_point:.4f}")
print(f"与水平面夹角: {angle_deg:.2f}°")
#斜率: 0.6367
#与水平面夹角: 32.48°
可视化悬链线
x_vals = np.linspace(-100, 100, 200)
y_vals = cable_param * np.cosh(x_vals / cable_param)
slope_vals = np.sinh(x_vals / cable_param)
import matplotlib.pyplot as plt
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(x_vals, y_vals, 'b-', linewidth=2)
plt.title('悬链线形状')
plt.xlabel('水平距离 (m)')
plt.ylabel('高度 (m)')
plt.grid(True)
plt.subplot(1, 2, 2)
plt.plot(x_vals, slope_vals, 'r-', linewidth=2)
plt.title('悬链线斜率变化')
plt.xlabel('水平距离 (m)')
plt.ylabel('斜率')
plt.grid(True)
plt.tight_layout()
plt.show()
示例2. 相对论速度叠加
u # 物体相对观察者的速度
v # 观察者相对参考系的速度
c # 光速
相对论速度叠加公式的快速推导版本
使用双曲正切:tanh(θ1 + θ2) = (tanhθ1 + tanhθ2)/(1 + tanhθ1*tanhθ2)
其中 rapidity θ = atanh(v/c)
theta_u = sinh(atanh(u/c)) # 实际上这里应该用tanh,但展示双曲正弦关系
theta_v = sinh(atanh(v/c))
相对论速度叠加
双曲函数在相对论中的应用
print(f"速度u对应的双曲正弦: {theta_u}")
print(f"速度v对应的双曲正弦: {theta_v}")
#速度u对应的双曲正弦: u/(c*(1.0 - u**2/c**2)**0.5)
#速度v对应的双曲正弦: v/(c*(1.0 - v**2/c**2)**0.5)
数值示例:计算0.6c和0.8c的速度叠加
u_val = 0.6 # 0.6倍光速
v_val = 0.8 # 0.8倍光速
经典力学结果 (错误的)
classical_result = u_val + v_val
相对论正确结果
relativistic_result = (u_val + v_val) / (1 + u_val * v_val)
速度叠加计算:
print(f"经典力学: {classical_result:.2f}c (错误!)")
print(f"相对论: {relativistic_result:.2f}c")
print(f"误差: {(classical_result - relativistic_result) / relativistic_result * 100:.1f}%")
#经典力学: 1.40c (错误!)
#相对论: 0.95c
#误差: 48.0%
示例3. 热传导问题
T1, T2 # 边界温度
L # 杆长度
k # 热传导系数
x # 位置
有内热源的一维热传导方程解
温度分布包含双曲函数项
temp_distribution = T1 + (T2 - T1) * sinh("x/L") / sinh("1")
热传导分析
有内热源的一维热传导温度分布
print(f"温度分布: {temp_distribution}")
#温度分布: T1 + 0.850918128239322*(-T1 + T2)*sinh(x/L)
数值示例:金属杆热传导
T1_val = 100 # 左端温度 °C
T2_val = 200 # 右端温度 °C
L_val = 1.0 # 杆长度 m
计算中点温度
mid_temp = temp_distribution.subs({
'T1': T1_val, 'T2': T2_val, 'L': L_val, 'x': 0.5
})
金属杆热传导 (T1={T1_val}°C, T2={T2_val}°C, L={L_val}m):
print(f"中点温度: {mid_temp.evalf():.2f}°C")
#中点温度: 144.34°C
可视化温度分布
x_vals = np.linspace(0, 1, 100)
temp_vals = T1_val + (T2_val - T1_val) * np.sinh(x_vals) / np.sinh(1)
plt.figure(figsize=(10, 6))
plt.plot(x_vals, temp_vals, 'r-', linewidth=2)
plt.xlabel('位置 (m)')
plt.ylabel('温度 (°C)')
plt.title('一维热传导温度分布')
plt.grid(True)
plt.show()
示例4. 电磁场理论
E0 # 电场幅值
k # 波数
z # 传播方向
x # 横向位置
a # 波导尺寸参数
矩形波导中的TE模电场分布
包含双曲函数项
E_field = E0 * sinh(k*x) * sp.cos(k * z)
电磁场分析
矩形波导中的电场分布
print(f"电场表达式: {E_field}")
#电场表达式: E0*cos(k*z)*sinh(k*x)
数值示例:计算特定点的场强
E0_val = 10.0 # V/m
k_val = 2.0 # 1/m
x_val = 0.3 # m
z_val = 0.5 # m
field_strength = E_field.subs({
'E0': E0_val, 'k': k_val, 'x': x_val, 'z': z_val
})
场强计算 (x={x_val}m, z={z_val}m):
print(f"电场强度: {field_strength:.4f} V/m")
#电场强度: 3.4399 V/m
可视化场分布
x_range = np.linspace(-1, 1, 50)
z_range = np.linspace(0, 2, 50)
X, Z = np.meshgrid(x_range, z_range)
E_strength = E0_val * np.sinh(k_val * X) * np.cos(k_val * Z)
plt.figure(figsize=(10, 6))
contour = plt.contourf(X, Z, E_strength, levels=20, cmap='RdBu_r')
plt.colorbar(contour, label='电场强度 (V/m)')
plt.xlabel('横向位置 x (m)')
plt.ylabel('传播方向 z (m)')
plt.title('波导中的电场分布')
plt.show()
示例5. 流体力学 - 边界层流动
U # 自由流速度
nu # 运动粘度
x # 流向位置
y # 法向位置
某些特定流动的相似解包含双曲函数
这里展示一个简化的例子
eta = y / sp.sqrt(nu * x / U) # 相似变量
velocity_profile = U * sinh(eta) / sinh(1)
流体力学分析
边界层速度分布
print(f"速度分布: {velocity_profile}")
#速度分布: 0.850918128239322*U*sinh(eta)
数值示例:平板边界层
U_val = 2.0 # m/s (自由流速度)
nu_val = 1e-6 # m²/s (水的运动粘度)
x_val = 0.1 # m (下游位置)
计算边界层内不同高度的速度
y_vals = np.linspace(0, 0.01, 50) # 法向高度
eta_vals = y_vals / np.sqrt(nu_val * x_val / U_val)
u_vals = U_val * np.sinh(eta_vals) / np.sinh(1)
plt.figure(figsize=(10, 6))
plt.plot(u_vals, y_vals * 1000, 'b-', linewidth=2) # y轴转换为mm
plt.xlabel('速度 (m/s)')
plt.ylabel('高度 (mm)')
plt.title('边界层速度分布')
plt.grid(True)
plt.show()
示例6. 控制系统 - 系统响应分析
K # 系统增益
tau1 # 时间常数1
tau2 # 时间常数2
t # 时间
二阶过阻尼系统的阶跃响应
响应包含双曲函数项
response = K * (1 - (tau2 / (tau2 - tau1)) * sp.exp(-t / tau1) - (tau1 / (tau1 - tau2)) * sp.exp(-t / tau2))
对于某些特定情况,响应可表示为双曲函数形式
简化版本用于演示
hyperbolic_response = K * (1 - sinh(t/tau) * exp(-t/tau))
控制系统分析
过阻尼系统时域响应
print(f"响应表达式: {hyperbolic_response}")
#响应表达式: K*(1 - exp(-0.159154943091895*t)*sinh(t/tau))
数值示例:机械系统响应
K_val = 1.0 # 稳态增益
tau_val = 0.5 # 时间常数 s
计算阶跃响应
t_vals = np.linspace(0, 3, 100)
response_vals = K_val * (1 - np.sinh(t_vals / tau_val) * np.exp(-t_vals / tau_val))
plt.figure(figsize=(10, 6))
plt.plot(t_vals, response_vals, 'g-', linewidth=2)
plt.xlabel('时间 (s)')
plt.ylabel('系统响应')
plt.title('过阻尼系统阶跃响应')
plt.grid(True)
plt.show()
计算性能指标
rise_time = 2.2 * tau_val # 上升时间估计
系统性能指标:
print(f"上升时间(10%-90%): {rise_time:.2f} s")
print(f"调节时间(2%准则): {4 * tau_val:.2f} s")
#上升时间(10%-90%): 1.10 s
#调节时间(2%准则): 2.00 s
示例7. 金融数学 - Black-Scholes期权定价模型
S # 标的资产价格
K # 行权价
T # 到期时间
r # 无风险利率
sigma # 波动率
在Black-Scholes的某些变体中,双曲函数可能出现
这里展示一个简化的关系式用于演示
d1 = (ln(S / K) + (r + sigma ** 2 / 2) * T) / (sigma * sqrt(T))
双曲正弦在风险中性测度变换中可能出现
risk_adjustment = sinh(sigma*sqrt(T))
期权定价中的数学工具
print(f"风险调整项: {risk_adjustment}")
print(f"d1参数: {d1}")
#风险调整项: sinh(sqrt(T)*sigma)
#d1参数: (T*(r + sigma**2/2) + log(S/K))/(sqrt(T)*sigma)
数值示例:欧式看涨期权
S_val = 100 # 标的资产现价
K_val = 105 # 行权价
T_val = 0.25 # 3个月到期
r_val = 0.05 # 5%无风险利率
sigma_val = 0.2 # 20%波动率
d1_val = (np.log(S_val / K_val) + (r_val + sigma_val ** 2 / 2) * T_val) / (sigma_val * np.sqrt(T_val))
from scipy.stats import norm
call_price = S_val * norm.cdf(d1_val) - K_val * np.exp(-r_val * T_val) * norm.cdf(
d1_val - sigma_val * np.sqrt(T_val))
欧式看涨期权定价:
print(f"标的资产: ${S_val}")
print(f"行权价: ${K_val}")
print(f"理论价格: ${call_price:.2f}")
print(f"d1参数值: {d1_val:.4f}")
#标的资产: $100
#行权价: $105
#理论价格: $2.48
#d1参数值: -0.3129
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
def sin_hyperbolic_sine(input_str):
"""
计算输入的双曲正弦值(对标MATLAB sinh函数)
参数:
expr: 输入数据,支持以下类型:
- 数值(int/float)
- SymPy符号表达式
- SymPy矩阵
- 嵌套列表(自动转换为SymPy矩阵)
返回:
SymPy对象(数值/矩阵/表达式)或错误信息字符串
示例:
1. 标量计算
>>> sin_hyperbolic_sine(0)
0
2. 符号计算
>>> x = sp.Symbol('x')
>>> sin_hyperbolic_sine(x)
sinh(x)
3. 矩阵计算
>>> sin_hyperbolic_sine([[0, 1], [2, 3]])
Matrix([
[0, sinh(1)],
[sinh(2), sinh(3)]])
4. 错误处理
>>> sin_hyperbolic_sine("invalid")
"错误: 不支持的类型: "
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
# 处理标量或符号表达式输入
if expr.is_number:
z = complex(expr)
result = np.sinh(z)
elif expr.free_symbols:
result = sp.sinh(expr).evalf()
# 其他类型错误
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
# 以下是测试用例
if __name__ == "__main__":
# 标量测试
print("标量测试:", sin_hyperbolic_sine(0))
# 0j
# 符号测试
x = sp.Symbol('x')
print("符号测试:", sin_hyperbolic_sine(x))
# sinh(x)
准确计算sin(x*pi)
Y = sinpi(X).该函数同时接受实数和复数输入.
X是标量,向量,数组,矩阵.
对于奇数,sinpi(n/2) 为+1或-1.
对于整数,sinpi(n) 为零
示例1. 信号处理 - 数字滤波器设计
设计一个简单的低通滤波器
n # 滤波器系数索引
M = 8 # 滤波器长度
fc = 0.2 # 归一化截止频率
理想低通滤波器的冲激响应 (sinc函数)
h[n] = 2fc * sinc(2fc * n)
其中 sinc(x) = sin(πx)/(πx)
使用sinpi计算,避免浮点误差
h_ideal = 2 * fc * sinpi(2*fc*n) / (pi * 2 * fc * n)
print(f"理想低通滤波器冲激响应: {h_ideal}")
#理想低通滤波器冲激响应: 1.0*sin(2*pi*fc*n)/(pi*n)
数值计算滤波器系数
coeffs = []
for i in range(-M // 2, M // 2):
if i == 0:
# n=0时的极限值
coeff = 2 * fc
else:
coeff = float(h_ideal.subs({'fc': fc, 'n': i}).evalf())
coeffs.append(coeff)
print(f"\n滤波器系数 (M={M}, fc={fc}):")
for i, coeff in enumerate(coeffs):
print(f"h[{i - M // 2}] = {coeff:.6f}")
#滤波器系数 (M=8, fc=0.2):
#h[-4] = -0.075683
#h[-3] = -0.062366
#h[-2] = 0.093549
#h[-1] = 0.302731
#h[0] = 0.400000
#h[1] = 0.302731
#h[2] = 0.093549
#h[3] = -0.062366
计算频率响应
H_freq = sum(coeffs[i] * sp.exp(-sp.I * omega * (i - M // 2))
for i in range(M))
在关键频率点评估响应
freq_points = [0, fc / 2, fc, 2 * fc, 0.5]
频率响应:
for freq in freq_points:
response = H_freq.subs(omega, 2 * sp.pi * freq)
magnitude = abs(response)
print(f"f = {freq:.3f}: |H| = {magnitude.evalf():.4f}")
#f = 0.000: |H| = 0.9921
#f = 0.100: |H| = 1.0484
#f = 0.200: |H| = 0.5183
#f = 0.400: |H| = 0.0455
#f = 0.500: |H| = 0.0307
示例2. 数值方法 - 有限差分法
import matplotlib.pyplot as plt
一维泊松方程: d²u/dx² = f(x), 边界条件 u(0)=u(1)=0
N = 20 # 网格点数
h = 1.0 / (N + 1) # 网格间距
构建有限差分矩阵
A = np.zeros((N, N))
for i in range(N):
A[i, i] = -2 / h ** 2
if i > 0:
A[i, i - 1] = 1 / h ** 2
if i < N - 1:
A[i, i + 1] = 1 / h ** 2
计算矩阵的特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(A)
理论特征值和特征函数(解析解)
特征值比较:
for k in range(1, min(6, N + 1)):
# 理论特征值
lambda_theoretical = -((k * np.pi) ** 2)
# 理论特征函数(在网格点上的值)
x_points = np.array([(i + 1) * h for i in range(N)])
u_theoretical = np.sqrt(2) * np.array([
float(sinpi(k*x)) for x in x_points
])
# 找到最接近的理论特征值的数值特征值
idx_closest = np.argmin(np.abs(eigenvalues - lambda_theoretical))
lambda_numerical = eigenvalues[idx_closest]
error = abs(lambda_numerical - lambda_theoretical) / abs(lambda_theoretical)
print(f"模式 {k}: 理论={lambda_theoretical:.4f}, "
f"数值={lambda_numerical:.4f}, 误差={error:.2e}")
#模式 1: 理论=-9.8696, 数值=-9.8512, 误差=1.86e-03
#模式 2: 理论=-39.4784, 数值=-39.1848, 误差=7.44e-03
#模式 3: 理论=-88.8264, 数值=-87.3455, 误差=1.67e-02
#模式 4: 理论=-157.9137, 数值=-153.2574, 误差=2.95e-02
#模式 5: 理论=-246.7401, 数值=-235.4482, 误差=4.58e-02
验证特征函数的正交性
for i in range(1, 4):
for j in range(1, 4):
if i != j:
# 理论内积应为0
u_i = np.sqrt(2) * np.array([
float(sinpi(i*x)) for x in x_points
])
u_j = np.sqrt(2) * np.array([
float(sinpi(j*x)) for x in x_points
])
inner_product = np.dot(u_i, u_j) * h
print(f"⟨u_{i}|u_{j}⟩ = {inner_product:.2e}")
#⟨u_1|u_2⟩ = -1.19e-17
#⟨u_1|u_3⟩ = 1.26e-16
#⟨u_2|u_1⟩ = -1.19e-17
#⟨u_2|u_3⟩ = -5.02e-17
#⟨u_3|u_1⟩ = 1.26e-16
#⟨u_3|u_2⟩ = -5.02e-17
可视化前几个特征函数
plt.figure(figsize=(12, 8))
x_fine = np.linspace(0, 1, 200)
for k in range(1, 4):
u_fine = np.sqrt(2) * np.array([
float(sinpi(k*x)) for x in x_fine
])
plt.plot(x_fine, u_fine, label=f'模式 {k}', linewidth=2)
plt.xlabel('位置 x')
plt.ylabel('特征函数 u_k(x)')
plt.title('泊松方程的特征函数')
plt.legend()
plt.grid(True)
plt.show()
示例3. 图像处理 - 精确的频域变换
二维DCT基函数
m, n = sp.symbols('m n', integer=True) # 频率索引
i, j = sp.symbols('i j', integer=True) # 空间索引
N = sp.Symbol('N', integer=True, positive=True) # 块大小
DCT-II 基函数
C(u,v) = α(u)α(v) ΣΣ f(i,j) cos[(2i+1)uπ/2N] cos[(2j+1)vπ/2N]
其中 α(w) = √(1/N) for w=0, √(2/N) otherwise
使用sinpi相关的恒等式来精确计算
dct_basis = sinpi((2*i+1)*m/(2*N) + 1/4) # 与cos相关的sinpi形式
8x8 DCT (JPEG标准)
N_val = 8
构建DCT变换矩阵
dct_matrix = np.zeros((N_val, N_val))
for u in range(N_val):
for x in range(N_val):
if u == 0:
alpha = np.sqrt(1 / N_val)
else:
alpha = np.sqrt(2 / N_val)
# 精确计算DCT系数
# cos[(2x+1)uπ/16] = sinpi[(2x+1)u/16 + 1/2] 的变体
angle = (2 * x + 1) * u * np.pi / (2 * N_val)
# 使用精确的sinpi计算
cos_val = float(sinpi((2 * x + 1) * u / (2 * N_val) + 1 / 2))
dct_matrix[u, x] = alpha * cos_val
DCT变换矩阵 (前4x4):
print(dct_matrix[:4, :4])
#[[0.35355339,0.35355339,0.35355339,0.35355339]
[0.49039264,0.41573481,0.27778512,0.09754516]
[0.46193977,0.19134172,-0.19134172,-0.46193977]
[0.41573481,-0.09754516,-0.49039264,-0.27778512]]
验证正交性
identity_approx = dct_matrix @ dct_matrix.T
正交性验证 (DCT @ DCTᵀ ≈ I):
print(f"最大非对角元素: {np.max(np.abs(identity_approx - np.eye(N_val))):.2e}")
#最大非对角元素: 8.88e-16
测试图像块压缩
test_block = np.random.randn(N_val, N_val)
测试图像块 (8x8):
print("原始数据范围: [{:.3f}, {:.3f}]".format(
np.min(test_block), np.max(test_block)))
#原始数据范围: [-2.054, 2.245]
DCT变换
dct_coeffs = dct_matrix @ test_block @ dct_matrix.T
print("DCT系数范围: [{:.3f}, {:.3f}]".format(
np.min(dct_coeffs), np.max(dct_coeffs)))
#DCT系数范围: [-2.147, 2.479]
能量压缩(模拟JPEG量化)
quantized_coeffs = np.round(dct_coeffs * 10) / 10 # 简单量化
compression_ratio = np.sum(quantized_coeffs != 0) / (N_val * N_val)
print(f"量化后非零系数比例: {compression_ratio:.1%}")
#量化后非零系数比例: 93.8%
示例4. 声学 - 精确的频率合成
t # 时间
f0 # 基频
harmonic # 谐波次数
乐器声音模型:基频 + 谐波
使用sinpi确保频率关系的精确性
钢琴声音模型(包含谐波)
piano_sound = sum(
(1 / harmonic) * sinpi(2*harmonic*f0*t)
for harmonic in range(1, 6) # 前5个谐波
)
print(f"钢琴声音模型: {piano_sound}")
#钢琴声音模型: 1.0*sin(2*pi*f0*t) + 0.5*sin(4*pi*f0*t) + 0.333333333333333*sin(6*pi*f0*t) + 0.25*sin(8*pi*f0*t) + 0.2*sin(10*pi*f0*t)
数值示例:A4音符 (440Hz)
f0_val = 440.0 # Hz
duration = 0.01 # 10ms
fs = 44100 # 采样率
t_vals = np.arange(0, duration, 1 / fs)
精确合成钢琴音
piano_waveform = np.zeros_like(t_vals)
for n in range(1, 6):
harmonic_component = (1 / n) * np.array([
float(sinpi(2*n*f0_val*t_val))
for t_val in t_vals
])
piano_waveform += harmonic_component
传统方法合成(可能引入频率误差)
piano_traditional = np.zeros_like(t_vals)
for n in range(1, 6):
harmonic_component = (1 / n) * np.sin(2 * np.pi * n * f0_val * t_vals)
piano_traditional += harmonic_component
比较两种方法的差异
difference = np.abs(piano_waveform - piano_traditional)
max_diff = np.max(difference)
print(f"\n合成方法比较 (A4 = {f0_val}Hz):")
print(f"最大差异: {max_diff:.2e}")
#合成方法比较 (A4 = 440.0Hz):
#最大差异: 1.30e-14
频谱分析
from scipy.signal import spectrogram
f, t_spec, Sxx = spectrogram(piano_waveform, fs)
找到峰值频率
peak_freqs = []
for i in range(Sxx.shape[1]):
idx_peaks = np.argsort(Sxx[:, i])[-5:] # 前5个峰值
peak_freqs.extend(f[idx_peaks])
peak_freqs = np.unique(np.round(peak_freqs, 1))
检测到的频率成分:
for freq in peak_freqs[:10]: # 显示前10个
if freq > 0:
theoretical = f0_val * np.arange(1, 6)
closest_theoretical = theoretical[np.argmin(np.abs(theoretical - freq))]
error = abs(freq - closest_theoretical)
print(f" {freq:6.1f} Hz (理论: {closest_theoretical:.1f} Hz, 误差: {error:.2f} Hz)")
# 172.3 Hz (理论: 440.0 Hz, 误差: 267.70 Hz)
# 344.5 Hz (理论: 440.0 Hz, 误差: 95.50 Hz)
# 516.8 Hz (理论: 440.0 Hz, 误差: 76.80 Hz)
# 861.3 Hz (理论: 880.0 Hz, 误差: 18.70 Hz)
# 1378.1 Hz (理论: 1320.0 Hz, 误差: 58.10 Hz)
可视化波形和频谱
plt.figure(figsize=(12, 8))
plt.subplot(2, 1, 1)
plt.plot(t_vals[:1000], piano_waveform[:1000])
plt.xlabel('时间 (s)')
plt.ylabel('振幅')
plt.title('钢琴声音波形 (A4 = 440Hz)')
plt.grid(True)
plt.subplot(2, 1, 2)
plt.specgram(piano_waveform, Fs=fs, NFFT=1024)
plt.xlabel('时间 (s)')
plt.ylabel('频率 (Hz)')
plt.title('频谱图')
plt.colorbar(label='强度 (dB)')
plt.tight_layout()
plt.show()
示例5. 通信系统 - 精确的调制解调
t # 时间
fc # 载波频率
data # 传输数据
QPSK调制:s(t) = A cos(2πfct + φ)
其中 φ ∈ {π/4, 3π/4, 5π/4, 7π/4}
使用sinpi精确表示相位
phases = [1 / 4, 3 / 4, 5 / 4, 7 / 4] # 以π为单位的相位
QPSK调制相位:
for i, phase in enumerate(phases):
symbol = sinpi(2*fc*t + phase)
print(f"符号 {i}: φ = {phase}π, s(t) = {symbol}")
#符号 0: φ = 0.25π, s(t) = sin(pi*(2*fc*t + 0.25))
#符号 1: φ = 0.75π, s(t) = sin(pi*(2*fc*t + 0.75))
#符号 2: φ = 1.25π, s(t) = sin(pi*(2*fc*t + 1.25))
#符号 3: φ = 1.75π, s(t) = sin(pi*(2*fc*t + 1.75))
数值示例
fc_val = 1000 # 载波频率 1kHz
symbol_rate = 100 # 符号率 100 symbols/s
duration = 0.1 # 100ms
生成随机QPSK符号
np.random.seed(42)
num_symbols = int(symbol_rate * duration)
symbols = np.random.randint(0, 4, num_symbols)
生成调制信号
t_vals = np.linspace(0, duration, int(10 * fc_val * duration))
modulated_signal = np.zeros_like(t_vals)
for i, symbol in enumerate(symbols):
phase = phases[symbol]
symbol_start = i / symbol_rate
symbol_end = (i + 1) / symbol_rate
# 在当前符号时段内生成信号
mask = (t_vals >= symbol_start) & (t_vals < symbol_end)
symbol_times = t_vals[mask] - symbol_start
symbol_waveform = np.array([
float(sinpi(2*fc_val*t_val + phase))
for t_val in symbol_times
])
modulated_signal[mask] = symbol_waveform
QPSK调制参数:
print(f"载波频率: {fc_val} Hz")
print(f"符号率: {symbol_rate} symbols/s")
print(f"传输符号数: {num_symbols}")
print(f"传输数据量: {num_symbols * 2} bits") # QPSK每符号2比特
#载波频率: 1000 Hz
#符号率: 100 symbols/s
#传输符号数: 10
#传输数据量: 20 bits
计算功率谱密度
from scipy.signal import welch
f, Pxx = welch(modulated_signal, fc_val * 10, nperseg=1024)
找到主瓣和旁瓣
main_lobe_mask = (f >= fc_val - symbol_rate) & (f <= fc_val + symbol_rate)
side_lobe_power = np.sum(Pxx[~main_lobe_mask]) / np.sum(Pxx)
频谱特性:
print(f"主瓣带宽: ±{symbol_rate} Hz")
print(f"旁瓣功率比例: {side_lobe_power:.1%}")
#主瓣带宽: ±100 Hz
#旁瓣功率比例: 8.0%
解调演示(相干解调)
I_component = modulated_signal * np.array([
float(sinpi(2*fc_val*t_val)) # cos(2πfct)
for t_val in t_vals
])
Q_component = modulated_signal * np.array([
float(sinpi(2*fc_val*t_val + 1/2)) # -sin(2πfct)
for t_val in t_vals
])
符号判决
detected_symbols = []
for i in range(num_symbols):
symbol_start = int(i * len(t_vals) / num_symbols)
symbol_end = int((i + 1) * len(t_vals) / num_symbols)
I_decision = np.mean(I_component[symbol_start:symbol_end])
Q_decision = np.mean(Q_component[symbol_start:symbol_end])
# 根据象限判决符号
if I_decision > 0 and Q_decision > 0:
detected_symbol = 0
elif I_decision < 0 and Q_decision > 0:
detected_symbol = 1
elif I_decision < 0 and Q_decision < 0:
detected_symbol = 2
else:
detected_symbol = 3
detected_symbols.append(detected_symbol)
计算误码率
error_count = np.sum(np.array(detected_symbols) != symbols)
ber = error_count / num_symbols
解调性能:
print(f"误码数: {error_count}/{num_symbols}")
print(f"误码率: {ber:.2e}")
#误码数: 0/10
#误码率: 0.00e+00
可视化
plt.figure(figsize=(12, 10))
plt.subplot(3, 1, 1)
plt.plot(t_vals[:2000], modulated_signal[:2000])
plt.xlabel('时间 (s)')
plt.ylabel('振幅')
plt.title('QPSK调制信号')
plt.grid(True)
plt.subplot(3, 1, 2)
plt.semilogy(f, Pxx)
plt.axvline(fc_val, color='r', linestyle='--', label='载波频率')
plt.xlabel('频率 (Hz)')
plt.ylabel('功率谱密度')
plt.title('信号频谱')
plt.legend()
plt.grid(True)
plt.subplot(3, 1, 3)
# 星座图
for i, phase in enumerate(phases):
angle = phase * np.pi
plt.plot(np.cos(angle), np.sin(angle), 'bo', markersize=10)
plt.text(np.cos(angle) * 1.1, np.sin(angle) * 1.1, f'S{i}', fontsize=12)
# 添加实际判决点
for i in range(min(100, num_symbols)):
symbol_start = int(i * len(t_vals) / num_symbols)
symbol_end = int((i + 1) * len(t_vals) / num_symbols)
I_point = np.mean(I_component[symbol_start:symbol_end])
Q_point = np.mean(Q_component[symbol_start:symbol_end])
plt.plot(I_point, Q_point, 'r.', alpha=0.5)
plt.axhline(0, color='k', linestyle='-', alpha=0.3)
plt.axvline(0, color='k', linestyle='-', alpha=0.3)
plt.xlabel('同相分量 (I)')
plt.ylabel('正交分量 (Q)')
plt.title('QPSK星座图')
plt.grid(True)
plt.axis('equal')
plt.tight_layout()
plt.show()
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
def sin_pi_sine(input_str):
"""
准确计算 sin(X*π) 的符号表达式和数值计算
对标MATLAB sinpi函数特性:
1. 精确处理符号表达式 (如 sin(pi*x))
2. 数值计算时不直接展开π,避免浮点误差
3. 支持矩阵元素级计算
参数:
input_str (str): 输入表达式,可以是:
- 数值 (如 "0.5")
- 符号表达式 (如 "x")
- 矩阵 (如 "[[1, 2], [x, 1/2]]")
返回:
float: 数值计算结果
MutableDenseMatrix: 矩阵计算结果
sp.Expr: 符号表达式结果
str: 错误信息
示例:
>>> sin_pi_sine("0.5")
1.0
>>> sin_pi_sine("x")
sin(pi*x)
>>> sin_pi_sine("[[1/2, 0], [x, 1/6]]")
Matrix([[1.0, 0], [sin(pi*x), 0.5]])
"""
try:
# 符号化输入(自动识别矩阵和表达式)
expr = sp.sympify(input_str)
# 处理标量数值/符号
if expr.is_number:
z = complex(expr)
result = np.sin(np.pi * z)
elif expr.free_symbols:
result = sp.sin(sp.pi * expr)
return result
except Exception as e:
return f"计算错误: {str(e)}"
# ----------------------------
# 测试案例
# ----------------------------
if __name__ == "__main__":
# 案例1: 数值计算
print(sin_pi_sine("0.5"))
# (1+0j)
print(sin_pi_sine("1/6"))
# (0.49999999999999994+0j)
# 案例2: 符号计算
print(sin_pi_sine("x"))
# sin(pi*x)
# 案例4: 复合表达式
print(sin_pi_sine("x + 1/2"))
# sin(pi*(x + 1/2))
求解优化问题或方程问题
sol = solve(prob) 求解优化问题或方程问题prob
prob — 优化问题或方程问题, 线性或非线性方程组,包括等式方程及不等式方程
sol — 解
将球面坐标转换为笛卡尔坐标
[x,y,z] = sph2cart(azimuth,elevation,r) 将球面坐标数组 azimuth,elevation和r的对应元素转换为笛卡尔坐标,即 xyz 坐标
azimuth — 方位角,标量,向量,矩阵
elevation — 仰角,标量,向量,矩阵
r — 半径,标量,向量,矩阵
x,y,z — 笛卡尔坐标,数组
示例1: 天文学 - 天体位置计算
计算北极星位置 (方位角0°, 仰角40°, 距离433光年)
ra_dec = sph2cart(0, 40*@pi/180, 433)
print(f"北极星笛卡尔坐标: {ra_dec}")
#北极星笛卡尔坐标: (331.69724387051747, 0.0, 278.3270349942715)
计算多个恒星位置
stars_az = [0, 45, 90, 135] # 方位角(度)
stars_el = [30, 45, 60, 75] # 仰角(度)
stars_r = [100, 150, 200, 250] # 距离
stars_cartesian = sph2cart(([np.deg2rad(a) for a in stars_az], [np.deg2rad(e) for e in stars_el], stars_r))
print(f"多个恒星位置: {stars_cartesian}")
#多个恒星位置: (array([8.66025404e+01, 7.50000000e+01, 6.12323400e-15, -4.57531755e+01]),
array([0, 75, 100, 45.75317547]),
array([50, 106.06601718, 173.20508076, 241.48145657]))
示例2: 机器人学 - 机械臂末端位置
机械臂关节角度到末端位置
joint_angles = sph2cart(@pi/6, @pi/4, 1.5)
print(f"机械臂末端位置: {joint_angles}")
#机械臂末端位置: (0.9185586535436918, 0.5303300858899107, 1.0606601717798212)
机械臂运动轨迹
trajectory_az = np.linspace(0, np.pi/2, 5) # 方位角轨迹
trajectory_el = np.linspace(0, np.pi/4, 5) # 仰角轨迹
trajectory_r = [1.0] * 5 # 固定臂长
trajectory = sph2cart((list(trajectory_az), list(trajectory_el), trajectory_r))
print(f"机械臂运动轨迹: {trajectory}")
#机械臂运动轨迹: (array([1.00000000e+00, 9.06127446e-01, 6.53281482e-01, 3.18189645e-01, 4.32978028e-17]),
array([0, 0.37533028, 0.65328148, 0.76817776, 0.70710678]),
array([0, 0.19509032, 0.38268343, 0.55557023, 0.70710678]))
示例3: 地理信息系统 - GPS坐标转换
将经纬度转换为地心直角坐标 (简化模型)
longitude = 116.4 # 北京经度
latitude = 39.9 # 北京纬度
height = 0.05 # 海拔(单位: 地球半径)
beijing_geo = sph2cart((np.deg2rad(longitude), np.deg2rad(latitude), 1+height))
print(f"北京地心坐标: {beijing_geo}")
#北京地心坐标: (-0.3581640454789194, 0.7215167909531593, 0.6735221131476157)
多个城市位置
cities_lon = [116.4, 121.5, 114.1, 87.6] # 经度
cities_lat = [39.9, 31.2, 22.2, 43.8] # 纬度
cities_r = [1.0] * 4 # 地球表面
cities_xyz = sph2cart(([np.deg2rad(lon) for lon in cities_lon], [np.deg2rad(lat) for lat in cities_lat], cities_r))
print(f"多个城市地心坐标: {cities_xyz}")
#多个城市地心坐标: (array([-0.34110861, -0.4469266 , -0.37806116, 0.03022418]),
array([0.68715885, 0.72931792, 0.84516631, 0.72112712]),
array([0.64144963, 0.51802701, 0.37784079, 0.69214317]))
示例4: 计算机图形学 - 3D模型顶点
生成球体顶点
sphere_az = np.linspace(0, 2*np.pi, 8) # 经度分段
sphere_el = np.linspace(-np.pi/2, np.pi/2, 5) # 纬度分段
sphere_r = 1.0 # 单位球体
创建网格
AZ, EL = np.meshgrid(sphere_az, sphere_el)
sphere_points = sph2cart((AZ.flatten(), EL.flatten(), sphere_r))
print(f"球体顶点数量: {len(sphere_points[0])}")
print(f"前5个顶点: x={sphere_points[0][:5]}, y={sphere_points[1][:5]}, z={sphere_points[2][:5]}")
#球体顶点数量: 40
#前5个顶点:
#x=[6.12323400e-17,3.81777395e-17,-1.36254775e-17,-5.51684320e-17,-5.51684320e-17],
y=[0.00000000e+00,4.78733711e-17,5.96971174e-17,2.65677166e-17,-2.65677166e-17],
z=[-1,-1,-1,-1,-1]
示例5: 物理学 - 电场/磁场方向
偶极子场方向
dipole_angles = sph2cart(@pi/3, @pi/6, 1)
print(f"偶极子场方向向量: {dipole_angles}")
#偶极子场方向向量: (0.4330127018922192, 0.75, 0.5)
多个电荷的电场方向
charges_az = [0, np.pi/2, np.pi, 3*np.pi/2]
charges_el = [np.pi/4, np.pi/4, np.pi/4, np.pi/4]
charges_dir = sph2cart((charges_az, charges_el, [1]*4))
print(f"多个电荷场方向: {charges_dir}")
#多个电荷场方向: (array([7.07106781e-01, 4.32978028e-17, -7.07106781e-01, -1.29893408e-16]),
array([0.00000000e+00, 7.07106781e-01, 8.65956056e-17, -7.07106781e-01]),
array([0.70710678, 0.70710678, 0.70710678, 0.70710678]))
示例6: 符号计算 - 通用公式推导
symbolic_result = sph2cart(az, el, r)
符号转换公式:
print(f" x = {symbolic_result[0]}")
print(f" y = {symbolic_result[1]}")
print(f" z = {symbolic_result[2]}")
#x = radius*cos(azimuth)*cos(elevation)
#y = radius*sin(azimuth)*cos(elevation)
#z = radius*sin(elevation)
示例7: 雷达系统 - 目标定位
雷达探测目标
radar_az = 30 # 方位角(度)
radar_el = 15 # 仰角(度)
radar_range = 10000 # 距离(米)
target_pos = sph2cart(np.deg2rad(radar_az), np.deg2rad(radar_el), radar_range)
print(f"雷达目标位置: {target_pos}")
#雷达目标位置: (8365.16303737808, 4829.629131445341, 2588.1904510252075)
多个目标跟踪
targets_az = [10, 25, 40, 55] # 度
targets_el = [5, 10, 8, 12] # 度
targets_r = [8000, 12000, 9500, 11000] # 米
targets_xyz = sph2cart([np.deg2rad(a) for a in targets_az], [np.deg2rad(e) for e in targets_el], targets_r)
print(f"多个目标位置: {targets_xyz}")
#多个目标位置: (array([ 7848.48209752, 10710.46722347, 7206.59883695, 6171.4665656 ]),
array([1383.8991514 , 4994.37288872, 6047.05442613, 8813.76767433]),
array([ 697.24594198, 2083.778132 , 1322.14445912, 2287.028599 ]))
示例8: 声学 - 声源定位
球形麦克风阵列中的声源
sound_az = 60 # 方位角(度)
sound_el = 30 # 仰角(度)
sound_dist = 5 # 距离(米)
sound_source = sph2cart(np.deg2rad(sound_az), np.deg2rad(sound_el), sound_dist)
print(f"声源位置: {sound_source}")
#声源位置: (2.1650635094610973, 3.75, 2.4999999999999996)
示例9: 医学成像 - 3D扫描数据
MRI球形扫描采样点
scan_angles_az = np.linspace(0, 2*np.pi, 12)
scan_angles_el = np.linspace(-np.pi/2, np.pi/2, 8)
scan_radius = 0.5 # 扫描半径
scan_points = sph2cart(scan_angles_az, scan_angles_el, scan_radius)
print(f"医学扫描点数量: {len(scan_points[0])}")
#医学扫描点数量: 1
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
def spherical_to_cartesian(input_str):
"""
球坐标转笛卡尔坐标 (对标 MATLAB sph2cart 函数)
参数:
input_str: 字符串形式的输入,支持三种格式:
1. 单独方位角 (az):返回 (x, y) 平面坐标
2. 方位角 (az) 和仰角 (el):假定 r=1
3. 方位角 (az), 仰角 (el), 半径 (r)
返回:
(x, y, z) 元组,元素类型与输入保持一致(标量/矩阵)
实现特性:
- 支持符号计算
- 自动广播标量到矩阵维度
- 输入验证和错误处理
"""
try:
# 解析输入表达式
expr = sp.sympify(input_str)
error = False
result = None
# 定义转换函数
def compute_coords(az_val, el_val, r_val):
x = r_val * sp.cos(el_val) * sp.cos(az_val)
y = r_val * sp.cos(el_val) * sp.sin(az_val)
z = r_val * sp.sin(el_val)
return x, y, z
def spherical_to_cartesian(az, el, r):
"""
将球面坐标转换为笛卡尔坐标,支持标量、向量和多维数组输入。
参数:
az: 方位角(弧度),可以是标量或NumPy数组
el: 仰角(弧度),可以是标量或NumPy数组
r: 半径,可以是标量或NumPy数组
返回:
x, y, z: 笛卡尔坐标,与输入具有相同的维度
"""
# 将输入转换为NumPy数组以支持广播
az = np.asarray(az)
el = np.asarray(el)
r = np.asarray(r)
# 执行坐标转换
x = r * np.cos(el) * np.cos(az)
y = r * np.cos(el) * np.sin(az)
z = r * np.sin(el)
return x, y, z
if isinstance(expr, tuple) and len(expr) == 3:
if all(e.is_number for e in expr):
params = tuple(float(e) for e in expr)
result = spherical_to_cartesian(*params)
elif any(e.free_symbols for e in expr):
result = compute_coords(*expr)
else:
error = True
return result if not error else f"输入错误:{input_str}"
except Exception as e:
return f"错误: {str(e)}"
# 示例测试
if __name__ == "__main__":
# 示例1: 标量输入
print("示例1 输入: (pi/4, pi/6, 2)")
print("输出:", spherical_to_cartesian("(pi/4, pi/6, 2)"))
# (1.2247448713915892, 1.224744871391589, 1.0)
# 示例2: 符号输入
a, e = sp.symbols('a e')
print("\n示例2 输入: (a, e, 1)")
print("输出:", spherical_to_cartesian(f"({a}, {e}, 1)"))
# (cos(a)*cos(e), sin(a)*cos(e), sin(e))
球面坐标3D绘图.
球面坐标θ和φ的半径绘制函数.
SphericalPlot3D(L,r1,r2,options)
L是具有两个变量的过程或表达式,或三个此类过程或表达式的列表
r1,r2是表达式变量的范围.
1. 地球形状近似(轴对称椭球):
描述地球的 两极扁平化(赤道半径 > 极半径)
赤道(θ=π/2)膨胀约 21.3 km
SphericalPlot3D(6371*(1+0.003*(1.5cos(theta)^2-0.5)), theta=[0,@pi])
2. 声学指向性模式(扬声器设计):
优化扬声器阵列的声波覆盖
抑制特定方向干扰(如舞台反馈啸叫)
输出特征:主瓣沿 z 轴 + 4个侧瓣
SphericalPlot3D(abs(sinc(3*sin(theta)*cos(phi))), theta=[0,@pi], phi=[0,2@pi])
3. 等离子体湍流(核聚变研究):
模拟托卡马克装置中磁流体不稳定性
预测等离子体破裂位置
输出特征:螺旋波纹结构(类似扭曲模)
SphericalPlot3D(1+0.1*(sin(theta+2phi)+sin(2theta+2phi)+sin(3theta+2phi)),theta=[0,@pi], phi=[0,2@pi])
4. 天线辐射方向图(通信工程):
设计 5G 基站天线覆盖范围
优化卫星通信链路
输出特征: 轮胎状辐射模式(最大增益在赤道面)
SphericalPlot3D(abs(cos((@pi/2)*cos(theta))/sin(theta)),theta=[0,@pi])
5. 液滴振动模式(轴对称基础模态):
赤道膨胀 + 两极扁平化的振荡
SphericalPlot3D(1+0.2*(1.5*cos(theta)^2-0.5),theta=[0,@pi])
6. 核物质分布(球形原子核):
沿旋转轴压缩的椭球形状
SphericalPlot3D(1.2*(1-0.05*(1.5*cos(theta)^2-0.5)),theta=[0,@pi])
多曲面球面坐标3D图
内球提供基准形状,外曲面突出相对变形,清晰显示表面与内部的对应
1. 行星大气环流模型:
内球:地球固体表面
外曲面:大气温度异常分布
5个经向波动 + 10个纬向波动表示大气环流模式
角度限制聚焦北半球中高纬度区域
SphericalPlot3D(6371,6371+8*sin(5phi)*sin(10theta), theta=[0,0.7@pi],phi=[0,1.8@pi])
2. 核聚变装置等离子体约束
内球:真空室边界
外曲面:等离子体密度分布
sin(5ϕ)sin(10θ) 模拟磁流体不稳定性
角度限制避免极区复杂物理现象
SphericalPlot3D(1,1.5+0.2*sin(@phi)*sin(10theta), theta=[0,0.7@pi],phi=[0,1.8@pi])
3. 脑皮层神经活动映射:
内球:基准脑皮层表面
外曲面:神经活动强度
5×10 振荡模式模拟不同功能区域
角度限制对应可观测的脑区
SphericalPlot3D(0.9,1+0.15*sin(5phi)*sin(10theta), theta=[0.2@pi,0.7@pi],phi=[0.1@pi,1.8@pi])
4. 多波束天线方向图
内球:参考单位增益
外曲面:实际辐射强度
5个方位角波束 + 10个仰角波束
φ范围限制表示天线机械旋转范围
SphericalPlot3D(1,1.5+0.3*sin(5phi)*sin(10theta), theta=[0,0.7@pi],phi=[0,1.8@pi])
5. 地幔对流模型
内球:地核-地幔边界
外曲面:地幔对流速度
5个经向对流单元 + 10个纬向结构
θ限制表示上地幔区域(深0-670km)
SphericalPlot3D(0.9,1+0.25*sin(5phi)*sin(10theta), theta=[0,0.7@pi],phi=[0,1.8@pi])
6. 蛋白质分子表面
内球:分子核心
外曲面:范德华表面
5×10 波动模拟结合口袋结构
角度限制聚焦功能活性区域
SphericalPlot3D(0.8,1+0.4*sin(5phi)*sin(10theta), theta=[0.1,0.6@pi],phi=[0.2,1.6@pi])
SpotPlot(list1, list2)
通过笛卡尔坐标系展示两个变量之间关系的图表。每个数据点由横坐标(X轴)和纵坐标(Y轴)的值共同定位,直观反映变量间的关联性、分布模式或趋势。
电商运营:价格与销量关系
确定最优定价区间(如$20时销量180件,总收入$3600 vs $30时销量150件,总收入$4500)
发现异常点:若$40时突然销量200件,可能需排查数据错误或促销活动影响
SpotPlot([10,20,30,40,50],[200,180,150,120,80])
医疗研究:药物剂量与疗效
确定安全剂量窗口(100–150mg)
警示毒性风险:>150mg时疗效骤降
SpotPlot([0,50,100,150,200],[10,40,75,80,30])
气候科学:CO₂浓度与温度
量化碳排放对变暖的影响(如CO₂每升50ppm,温度+0.8℃)
支持气候政策制定(如控制CO₂<450ppm以维持温度增幅<2℃)
SpotPlot([300,350,400,450],[14.0,14.5,15.2,15.8])
教育评估:学习时间与成绩
建议最佳学习时长(15-20小时)
识别低效学生:如投入25小时成绩仅82分,需学习方法干预
SpotPlot([5,10,15,20,25],[60,75,85,88,82])
工业制造:设备温度与故障率
设置温度报警阈值(80℃)
预测设备寿命:100℃时故障率15次/月,需提前更换
SpotPlot([60,70,80,90,100],[1,2,3,8,15])
金融分析:广告投入与ROI
优化预算:>30万时边际收益递减
止损点:40万后ROI<150%,应削减投入
SpotPlot([10,20,30,40,50],[120,150,170,160,140])
结构秩
r = sprank(A) 计算稀疏矩阵 A 的结构秩.
A — 输入矩阵,稀疏矩阵
示例1: 电力系统导纳矩阵(结构满秩但数值可能奇异)
在电力系统分析中,导纳矩阵通常有特定的零元素模式
power_system = [[ 2, -1, 0, -1, 0],[-1, 3, -1, 0, -1],[ 0, -1, 2, -1, 0],[-1, 0, -1, 3, -1],[ 0, -1, 0, -1, 2]]
print(f"结构秩: {sprank(power_system)}")
print(f"数值秩: {sp.Matrix(eval(power_system)).rank()}")
#结构秩: 5
#数值秩: 4
#实际意义: 电网节点连接性分析
示例2: 化学反应的计量矩阵
化学反应: 2H₂ + O₂ → 2H₂O
chemical_reaction = [[-2, 0], [ 0, -1], [ 2, 1]]
print(f"结构秩: {sprank(chemical_reaction)}")
print(f"数值秩: {sp.Matrix(eval(chemical_reaction)).rank()}")
#结构秩: 2
#数值秩: 2
#实际意义: 确定化学反应中的独立反应数
示例3: 结构力学中的刚度矩阵(边界条件处理)
简支梁的有限元离散
beam_stiffness = [[ 2, -1, 0, 0],[-1, 2, -1, 0],[ 0, -1, 2, -1],[ 0, 0, -1, 1]]
print(f"结构秩: {sprank(beam_stiffness)}")
print(f"数值秩: {sp.Matrix(eval(beam_stiffness)).rank()}")
#结构秩: 4
#数值秩: 4
#实际意义: 结构可动性分析
示例4: 交通网络的关联矩阵
4个节点,5条边的有向图
traffic_network = [[-1, 0, 0, 1, 0],[ 1, -1, 0, 0, 0],[ 0, 1, -1, 0, -1],[ 0, 0, 1, -1, 1]]
print(f"结构秩: {sprank(traffic_network)}")
print(f"数值秩: {sp.Matrix(eval(traffic_network)).rank()}")
#结构秩: 4
#数值秩: 3
#实际意义: 交通流独立路径分析
示例5: 经济投入产出表
3个部门的经济系统
input_output = [[0.2, 0.1, 0.0],[0.1, 0.3, 0.2],[0.0, 0.1, 0.4]]
print(f"结构秩: {sprank(input_output)}")
print(f"数值秩: {sp.Matrix(eval(input_output)).rank()}")
#结构秩: 3
#数值秩: 3
#实际意义: 经济部门关联性分析
示例6: 通信网络的邻接矩阵
communication_network = [[0, 1, 0, 1, 0],[1, 0, 1, 0, 1],[0, 1, 0, 1, 0],[1, 0, 1, 0, 1],[0, 1, 0, 1, 0]]
print(f"结构秩: {sprank(communication_network)}")
print(f"数值秩: {sp.Matrix(eval(communication_network)).rank()}")
#结构秩: 4
#数值秩: 2
#实际意义: 网络连通性分析
示例7: 数值奇异但结构满秩的典型例子
nearly_singular = [[1, 1, 0],[1, 1, 1e-15],[0, 1e-15, 1]]
print(f"结构秩: {sprank(nearly_singular)}")
matrix_11 = sp.Matrix(eval(nearly_singular))
print(f"数值秩: {matrix_11.rank()}")
print(f"行列式: {matrix_11.det()}")
#结构秩: 3
#数值秩: 3
#行列式: 0
#实际意义: 数值稳定性分析
示例8: 结构秩亏缺的典型模式
structurally_rank_deficient = [[1, 0, 1, 0],[0, 1, 0, 1],[1, 0, 1, 0],[0, 1, 0, 1]]
print(f"结构秩: {sprank(structurally_rank_deficient)}")
print(f"数值秩: {sp.Matrix(eval(structurally_rank_deficient)).rank()}")
#结构秩: 4
#数值秩: 2
#实际意义: 识别系统冗余
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy.sparse import csr_matrix
from scipy.sparse.csgraph import maximum_bipartite_matching
def sparse_rank_matrix(input_str):
"""
计算稀疏矩阵的结构秩,对标 MATLAB 的 sprank 函数
参数:
input_str: 字符串形式的矩阵输入,例如 "[[1, 0], [0, 1]]"
返回:
结构秩数值(整数)或错误信息字符串
实现原理:
1. 通过二分图匹配计算最大匹配数
2. 使用 SciPy 的 maximum_bipartite_matching 算法
3. 结构秩 = 最大匹配数
注意:
- 不支持符号矩阵
- 自动忽略复数元素
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
# 检查转换结果是否有效(sympify 转换失败返回元组)
if isinstance(expr, tuple):
error = True
else:
# 转换为 SymPy 矩阵
a = sp.Matrix(expr) if isinstance(expr, list) else None
if a is not None:
# 检查是否包含符号或复数
contains_symbols = any(element.free_symbols for element in a)
contains_complex = any(element.has(sp.I) for element in a)
if contains_symbols or contains_complex:
error = True
else:
# 转换为 SciPy 稀疏矩阵
A = csr_matrix(np.array(a, dtype=float))
try:
# 正确调用方式(SciPy≥1.4.0)
matching = maximum_bipartite_matching(A)
# 修正:直接统计匹配结果中不等于-1的元素个数
return int(np.sum(matching != -1))
except Exception as e:
result = sp.Matrix(A.toarray()).rank()
return result
else:
error = True # 非矩阵输入
# 生成错误信息
if error:
if contains_symbols:
return f"错误: 不支持符号矩阵输入"
elif contains_complex:
return f"错误: 不支持复数矩阵输入"
else:
return f"输入错误: {input_str}"
return result
except Exception as e:
return f"错误: {e}"
# 示例代码
if __name__ == "__main__":
# 示例1: 满秩对角矩阵
m1 = "[[1,0,2,0],[2,0,4,0]]"
print(f"示例1 输入: {m1}")
print(f"示例1 输出: {sparse_rank_matrix(m1)}\n")
# 2
# 示例2: 秩亏缺但结构满秩
m2 = "[[1, 1], [1, 1]]"
print(f"示例2 输入: {m2}")
print(f"示例2 输出: {sparse_rank_matrix(m2)}\n")
# 2
# 示例3: 结构秩小于数值秩
m3 = "[[0, 1], [1, 0]]"
print(f"示例3 输入: {m3}")
print(f"示例3 输出: {sparse_rank_matrix(m3)}\n")
# 2
# 示例4: 非方阵
m4 = "[[1, 0, 0], [0, 1, 0]]"
print(f"示例4 输入: {m4}")
print(f"示例4 输出: {sparse_rank_matrix(m4)}\n")
# 2
创建稀疏矩阵
r = sprank(A) 计算稀疏矩阵 A 的结构秩.
S = sparse(A) 通过挤出任何零元素将满矩阵转换为稀疏格式. 如果矩阵包含许多零, 将矩阵转换为稀疏存储空间可以节省内存.
S = sparse(m,n) 生成 m×n 全零稀疏矩阵.
S = sparse(i,j,v) 根据 i、j 和 v 三元组生成稀疏矩阵 S, 以便 S(i(k),j(k)) = v(k). max(i)×max(j) 输出矩阵为 length(v) 个非零值元素分配了空间. 如果输入 i, j 和 v 为向量或矩阵, 则它们必须具有相同数量的元素. 参量 v 和/或 i 或 j 其中一个参量可以使标量
A — 输入矩阵, 满矩阵, 稀疏矩阵
i,j — 下标对组(指定为单独的参量), 标量, 向量, 矩阵
v — 值, 标量, 向量, 矩阵
示例1: 图像处理中的拉普拉斯算子
4x4图像的离散拉普拉斯
laplacian = """
([0,0,0,1,1,1,2,2,2,3,3,3],
[0,1,3,0,1,2,1,2,3,0,2,3],
[-4,1,1,1,-4,1,1,-4,1,1,1,-4])
"""
result2 = sparse(laplacian)
print(f"矩阵大小: {result2.shape}")
#矩阵大小: (4, 4)
#实际意义: 图像边缘检测和增强
示例2: 社交网络邻接矩阵
6个用户,10条关注关系
social_network = """
([0,0,1,1,2,2,3,3,4,4,5,5],
[1,2,0,3,0,4,1,5,2,5,3,4],
[1,1,1,1,1,1,1,1,1,1,1,1])
"""
result3 = sparse(social_network)
print(f"社交网络矩阵大小: {result3.shape}")
print("非零元素数量:", np.count_nonzero(result3))
#社交网络矩阵大小: (6, 6)
#非零元素数量: 12
#实际意义: 社交网络分析和推荐系统
示例3: 有限元分析中的刚度矩阵
4节点单元的局部刚度矩阵
fem_stiffness = """
([0,0,0,1,1,1,2,2,2,3,3,3],
[0,1,3,0,1,2,1,2,3,0,2,3],
[2,-1,0,-1,2,-1,0,-1,2,-1,0,-1])
"""
result4 = sparse(fem_stiffness)
print(f"刚度矩阵大小: {result4.shape}")
#刚度矩阵大小: (4, 4)
#实际意义: 结构力学有限元分析
示例4: 推荐系统用户-物品交互矩阵
5个用户对6部电影的评分(0表示未评分)
ratings = """
[[4,0,0,5,0,0],
[0,0,3,0,4,0],
[0,5,0,0,0,2],
[3,0,0,0,0,4],
[0,4,0,0,5,0]]
"""
result5 = sparse(ratings)
print(f"评分矩阵大小: {result5.shape}")
print("稀疏度: {:.1f}%".format(100 * (1 - np.count_nonzero(result5) / result5.shape[0] / result5.shape[1])))
#评分矩阵大小: (5, 6)
#稀疏度: 66.7%
#实际意义: 协同过滤推荐算法
示例5: 文本处理中的词频矩阵
4篇文档,6个词汇的词频
document_term = """
([0,0,1,1,1,2,2,3,3,3],
[0,1,1,2,3,0,4,2,4,5],
[2,1,3,1,2,1,2,1,3,2])
"""
result7 = sparse(document_term)
print(f"文档-词项矩阵大小: {result7.shape}")
#文档-词项矩阵大小: (4, 6)
#实际意义: 文本挖掘和主题建模
示例6: 马尔可夫链转移概率矩阵
状态: 晴, 阴, 雨
weather_transition = """
[[0.7, 0.2, 0.1],
[0.3, 0.4, 0.3],
[0.2, 0.3, 0.5]]
"""
result8 = sparse(weather_transition)
print(f"转移矩阵大小: {result8.shape}")
#转移矩阵大小: (3, 3)
#实际意义: 马尔可夫过程建模和预测
示例7: 化学反应的化学计量矩阵
反应: A+B→C, C→D+E, D→F
chemical_stoichiometry = """
([-1,-1,1,0,0,0,
0,0,-1,1,1,0,
0,0,0,-1,0,1],
[0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5],
[-1,-1,1,0,0,0,0,0,-1,1,1,0,0,0,0,-1,0,1])
"""
result9 = sparse("([0,0,0,1,1,1,2,2,2], [0,1,2,2,3,4,3,5,5], [-1,-1,1,-1,1,1,-1,1,1])")
print(f"化学计量矩阵大小: {result9.shape}")
#化学计量矩阵大小: (3, 6)
#实际意义: 化学反应动力学分析
示例8: 图论中的拉普拉斯矩阵
5个节点的环状图
graph_laplacian = """
([0,0,1,1,2,2,3,3,4,4,0,1,2,3,4],
[1,4,0,2,1,3,2,4,0,3,0,1,2,3,4],
[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,2,2,2,2,2])
"""
result10 = sparse(graph_laplacian)
print(f"图拉普拉斯矩阵大小: {result10.shape}")
#图拉普拉斯矩阵大小: (5, 5)
#实际意义: 图分割和谱聚类
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy.sparse import csr_matrix
def sparse_matrix(input_str):
"""
对标 MATLAB 的 sparse 函数,创建稀疏矩阵
支持的输入格式:
1. 三数组格式: (行索引列表, 列索引列表, 值列表) 例如: "([0,1], [0,1], [1,2])"
2. 全矩阵转换: 嵌套列表或 SymPy 矩阵 例如: "[[1,0], [0,2]]"
3. 指定维度空矩阵: (行数, 列数) 例如: "(2,3)"
参数:
input_str: 输入字符串,描述矩阵的格式
返回:
SymPy 矩阵对象或错误信息字符串
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
# 情况1:处理三数组格式 (i, j, v)
if isinstance(expr, tuple):
if len(expr) >= 3 and all(isinstance(item, list) for item in expr[:3]):
# 提取前三个元素作为行索引、列索引和值
i = np.array(expr[0], dtype=int)
j = np.array(expr[1], dtype=int)
v = np.array(expr[2], dtype=float)
# 创建稀疏矩阵(自动处理重复索引的求和)
sparse_mat = csr_matrix((v, (i, j)))
result = sparse_mat.toarray()
# 情况2:处理指定维度的空矩阵 (m, n)
elif len(expr) == 2 and all(e.is_integer for e in expr):
rows, cols = map(int, expr)
sparse_mat = csr_matrix((rows, cols))
result = sparse_mat.toarray()
else:
error = True
# 情况3:处理全矩阵转换
elif isinstance(expr, list):
# 将 SymPy 矩阵转换为 NumPy 数组
dense_array = np.array(expr, dtype=float)
# 转换为稀疏格式后再转回密集数组(用于验证)
sparse_mat = csr_matrix(dense_array)
result = sparse_mat.toarray()
else:
error = True
# 返回 SymPy 矩阵或错误信息
return sp.Matrix(result) if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
# 示例代码
if __name__ == "__main__":
# 示例1:三数组格式创建对角矩阵
print("示例1:")
print(sparse_matrix("([0, 1], [0, 1], [1, 2])"))
# Matrix([[1.00000000000000, 0],
# [0, 2.00000000000000]])
# 示例2:全矩阵转换
print("\n示例2:")
print(sparse_matrix("[[1, 0], [0, 2]]"))
# Matrix([[1.00000000000000, 0],
# [0, 2.00000000000000]])
# 示例3:创建 2x3 空矩阵
print("\n示例3:")
print(sparse_matrix("(2, 3)"))
# Matrix([[0, 0, 0],
# [0, 0, 0]])
# 示例4:重复索引自动求和
print("\n示例4:")
print(sparse_matrix("([0, 0], [0, 0], [1, 2])"))
# Matrix([[3.00000000000000]])
三次方样条数据插值
s = spline(x,y,xq) 返回与 xq 中的查询点对应的插值 s 的向量。s 的值由 x 和 y 的三次样条插值确定。
pp = spline(x,y) 返回一个分段多项式结构体以用于 ppval 和样条实用工具 unmkpp。
x - x 坐标, 向量
y - x 坐标处的函数值, 向量 | 矩阵
xq - 查询点, 标量 | 向量 | 矩阵
s - 查询点位置的插值, 标量 | 向量 | 矩阵
pp - 分段多项式,结构体
示例1: 汽车悬架系统振动分析
模拟汽车经过不平路面的振动数据
time = np.array([0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0]) # 时间(秒)
displacement = np.array([0, 0.2, -0.1, 0.3, -0.2, 0.1, 0]) # 位移(cm)
插值到更细的时间网格
time_dense = np.linspace(0, 3, 100)
result1 = spline(list(time), list(displacement), list(time_dense))
print(f"原始数据点: {len(time)} 个")
print(f"插值后数据: {len(result1)} 个")
#原始数据点: 7 个
#插值后数据: 100 个
#实际意义: 汽车悬架系统动态响应分析
示例2: 气象温度预测
一天中每6小时的温度测量
hours = np.array([0, 6, 12, 18, 24]) # 时间(小时)
temperature = np.array([15, 18, 25, 20, 16]) # 温度(°C)
插值到每小时
hours_dense = np.arange(0, 25, 1)
result2 = spline(list(hours), list(temperature), list(hours_dense))
print(f"最高温度估计: {np.max(result2):.1f}°C")
print(f"最低温度估计: {np.min(result2):.1f}°C")
#最高温度估计: 25.0°C
#最低温度估计: 14.1°C
#实际意义: 气象数据连续化和预测
示例3: 股票价格平滑
一周内每日收盘价
days = np.array([1, 2, 3, 4, 5]) # 交易日
prices = np.array([100, 105, 98, 110, 108]) # 收盘价
插值到更细的时间点(模拟日内变化)
days_dense = np.linspace(1, 5, 50)
result3 = spline(list(days), list(prices), list(days_dense))
print(f"价格波动范围: {np.ptp(result3):.2f}")
#价格波动范围: 15.89
#实际意义: 金融时间序列平滑和趋势分析
示例4: 机械零件轮廓重建
测量得到的零件轮廓点
angles = np.array([0, 45, 90, 135, 180, 225, 270, 315]) # 角度(度)
radius = np.array([10.0, 10.2, 10.1, 9.9, 10.0, 10.3, 10.1, 9.8]) # 半径(mm)
插值到更密的角度
angles_dense = np.linspace(0, 315, 360)
result4 = spline(list(angles), list(radius), list(angles_dense))
print(f"最大半径偏差: {np.max(np.abs(result4 - 10.0)):.3f} mm")
#最大半径偏差: 0.305 mm
#实际意义: 精密制造中的轮廓测量和重建
示例5: 医学心电图信号插值
心电图采样点
ecg_time = np.array([0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]) # 时间(秒)
ecg_signal = np.array([0, 0.5, 1.2, 0.8, 0.1, -0.3, -0.1, 0.2, 0]) # 电压(mV)
插值到更高采样率
ecg_time_dense = np.linspace(0, 0.8, 100)
result5 = spline(list(ecg_time), list(ecg_signal), list(ecg_time_dense))
print(f"信号峰值: {np.max(result5):.2f} mV")
#信号峰值: 1.21 mV
#实际意义: 医学信号处理和特征提取
示例6: 地理地形高程插值
沿一条路径的高程测量
distance = np.array([0, 100, 200, 300, 400, 500]) # 距离(m)
elevation = np.array([100, 120, 110, 130, 125, 115]) # 高程(m)
插值到更密的距离点
distance_dense = np.linspace(0, 500, 100)
result6 = spline(list(distance), list(elevation), list(distance_dense))
print(f"总爬升高度: {np.sum(np.diff(result6)[np.diff(result6) > 0]):.1f} m")
#总爬升高度: 43.9 m
#实际意义: 地理信息系统和路径规划
示例7: 声音信号重建
稀疏采样的音频信号
audio_time = np.array([0, 0.01, 0.02, 0.03, 0.04, 0.05]) # 时间(秒)
audio_amplitude = np.array([0, 0.8, 0.2, -0.6, -0.1, 0]) # 幅度
重建完整信号
audio_time_dense = np.linspace(0, 0.05, 200)
result7 = spline(list(audio_time), list(audio_amplitude), list(audio_time_dense))
print(f"重建信号采样率: {len(result7)/0.05:.0f} Hz")
#重建信号采样率: 4000 Hz
#实际意义: 数字信号处理和音频重建
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy.interpolate import CubicSpline
def spline_cubic(input_str):
"""
对标MATLAB的spline函数,实现三次样条插值
参数:
input_str: 输入参数字符串,格式示例:
"x, y" -> 返回样条函数
"y" -> 自动生成x坐标并返回样条函数
"x, y, xq" -> 返回xq处的插值结果
"y, xq" -> 自动生成x坐标并返回xq处插值结果
返回:
样条函数对象或插值结果数组,错误时返回字符串信息
示例:
>>> spline_cubic("[1,2,3], [4,5,6]")
>>> spline_cubic("[1,2,3], [4,5,6], 2.5")
array(5.0)
"""
try:
# 符号解析与类型转换 ------------------------------------------------
def convert(param):
"""将SymPy对象转换为数值数组"""
if isinstance(param, list):
matrix = sp.Matrix(param)
if matrix.is_symbolic():
raise ValueError(f"Symbolic variable {param} not allowed")
else:
return np.array(matrix.tolist(), dtype=float).flatten()
elif param.is_Number:
return np.array([float(param)])
elif param.free_symbols:
raise ValueError(f"Symbolic variable {param} not allowed")
else: # 处理包含符号的表达式
try:
return np.array([float(param.evalf())])
except:
raise ValueError(f"Cannot convert {param} to numeric")
# 解析输入字符串
expr = sp.sympify(input_str, evaluate=False) # 强制转换为元组
params = [convert(p) for p in expr] if isinstance(expr, tuple) else [convert(expr)]
# 参数处理与插值计算 ------------------------------------------------
def validate_length(a, b):
if len(a) != len(b):
raise ValueError(f"Length mismatch: {len(a)} vs {len(b)}")
# 处理不同参数数量
if len(params) == 1: # spline(y)
y = params[0]
x = np.arange(len(y))
return CubicSpline(x, y, bc_type='not-a-knot')
elif len(params) == 2: # spline(x,y) 或 spline(y,xq)
a, b = params
if len(a) == len(b): # x,y模式
return CubicSpline(a, b, bc_type='not-a-knot')
else: # y,xq模式
y, xq = a, b
x = np.arange(len(y))
return CubicSpline(x, y)(xq)
elif len(params) == 3: # spline(x,y,xq)
x, y, xq = params
validate_length(x, y)
return CubicSpline(x, y, bc_type='not-a-knot')(xq)
else:
raise ValueError("Invalid number of parameters (1-3 required)")
except Exception as e:
return f"Error: {str(e)}"
# 示例测试
if __name__ == "__main__":
# 标准插值测试
print(spline_cubic("[1,2,3], [4,5,6], 2"))
# [5.]
print(spline_cubic("[0,1,2], [0,1,4], 1.5"))
# [2.25]
# 自动生成x坐标测试
print(spline_cubic("[3,1,4], [0.5, 1.5]"))
# [1.375 1.875]
平方根
B=sqrt(X)返回数组X中每个元素的平方根.对于X中为负或复数的元素,sqrt(X)会产生复数结果.
X —— 输入数组,标量,向量,矩阵
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def square_root(input_str):
"""
计算元素的平方根,对标 MATLAB 的 sqrt 函数。
参数:
input_str: 字符串形式的输入,可以是标量或矩阵,例如 "4" 或 "[[1, 4], [9, 16]]"
返回:
计算结果(SymPy 矩阵或数值),错误时返回字符串描述错误信息
示例:
>>> square_root("4")
2.0
>>> square_root("[[1, 4], [9, 16]]")
Matrix([
[1.0, 2.0],
[3.0, 4.0]])
>>> square_root("[[a, 4], [9, b]]")
Matrix([
[sqrt(a), 2.0],
[ 3.0, sqrt(b)]])
"""
try:
# 将输入字符串转换为 SymPy 表达式
expr = sp.sympify(input_str)
error = False
result = None
# 检查转换结果是否有效(sympify 转换失败返回元组)
if isinstance(expr, tuple):
error = True
else:
# 标量处理:直接计算平方根并数值化
result = sp.sqrt(expr).evalf()
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
# 示例代码
if __name__ == "__main__":
# 示例 1: 标量输入
print("示例1 输入: '4'")
print("示例1 输出:", square_root("4"), end="\n\n")
# 2.00000000000000
# 示例 2: 复数结果
print("示例2 输入: '-1'")
print("示例2 输出:", square_root("-1"), end="\n\n")
# 1.0*I
矩阵平方根
X = sqrtm(A)返回矩阵A的主平方根,即X*X=A.
X是每个特征值都有非负实部的唯一平方根.如果A有任何具有负实部的特征值,则会产生复结果.
如果A是单数,那么A可能没有平方根.
A —— 输入矩阵,方阵
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy import linalg as dense_linalg
def square_root_matrix(input_str):
"""
计算矩阵的平方根,对标 MATLAB 的 sqrtm 函数。
参数:
input_str: 字符串形式的矩阵输入,例如 "[[1, 0], [0, 4]]"。
返回:
如果输入合法且为方阵,返回 SymPy 矩阵;否则返回错误信息字符串。
"""
try:
# 将输入字符串转换为 SymPy 表达式
expr = sp.sympify(input_str)
error = False
result = None
# 检查转换后的表达式是否有效(如果转换失败,sympify 可能返回元组)
if isinstance(expr, tuple):
error = True
else:
# 转换为 SymPy 矩阵
A = sp.Matrix(expr) if isinstance(expr, list) else None
if A is not None:
# 检查矩阵是否包含符号或虚数单位 I
contains_symbols = A.is_symbolic() or any(element.has(sp.I) for element in A)
# 仅处理方阵
if A.is_square:
if contains_symbols:
# 符号矩阵:使用 SymPy 的矩阵幂运算
result = A ** sp.Rational(1, 2)
else:
# 数值矩阵:转换为 NumPy 数组并用 SciPy 计算平方根
N_A = np.array(A, dtype=float)
scipy_result = dense_linalg.sqrtm(N_A)
# 将结果转换回 SymPy 矩阵并四舍五入到合理精度
result = sp.Matrix(scipy_result.round(10))
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: 数值方阵
matrix1 = "[[1, 0], [0, 4]]"
print("示例1 输入:", matrix1)
print("示例1 输出:", square_root_matrix(matrix1))
# Matrix([[1.00000000000000, 0],
# [0, 2.00000000000000]])
# 示例 2: 符号矩阵
a, b = sp.symbols('a b')
matrix2 = f"[[{a}, 0], [0, {b}]]"
print("\n示例3 输入:", matrix2)
print("示例3 输出:", square_root_matrix(matrix2))
# Matrix([[sqrt(a), 0],
# [0, sqrt(b)]])
# 示例 3: 复数矩阵
matrix3 = "[[-1, 0], [0, -1]]"
print("\n示例4 输入:", matrix3)
print("示例4 输出:", square_root_matrix(matrix3))
# Matrix([[1.0*I, 0],
# [0, 1.0*I]])
格式化距离矩阵
ZOut = squareform(yIn) 将yIn(m个观测值的长度为m(m–1)/2的成对距离向量)转换为ZOut(对角线上有零的m乘m对称矩阵)
yIn是数值向量,逻辑向量.
ZOut是数值矩阵,逻辑矩阵
示例1: 分子结构中原子间距离
简化蛋白质结构中的4个关键原子距离(Å)
atom_distances = [2.1, 3.5, 4.2, 2.8, 3.9, 2.5]
distance_matrix = squareform(atom_distances)
原子距离矩阵:
print(distance_matrix)
#[[0, 2.1, 3.5, 4.2],
[2.1, 0, 2.8, 3.9],
[3.5, 2.8, 0, 2.5],
[4.2, 3.9, 2.5, 0]]
#实际意义: 结构生物学中的分子构象分析
示例2: 社交网络用户相似度
4个用户基于行为特征的Jaccard距离
user_similarity = [0.7, 0.3, 0.6, 0.2, 0.8, 0.4]
similarity_matrix = squareform(user_similarity)
用户相似度矩阵:
print(similarity_matrix)
#[[0, 0.7, 0.3, 0.6],
[0.7, 0, 0.2, 0.8],
[0.3, 0.2, 0, 0.4],
[0.6, 0.8, 0.4, 0]]
#实际意义: 推荐系统中的用户分群和相似度计算
示例3: 图像处理中的像素距离
图像分割后4个区域的中心点距离
region_distances = [15.3, 28.7, 42.1, 35.2, 56.8, 20.5]
region_matrix = squareform(region_distances)
图像区域距离矩阵:
print(region_matrix)
#[[0, 15.3, 28.7, 42.1],
[15.3, 0, 35.2, 56.8],
[28.7, 35.2, 0, 20.5],
[42.1, 56.8, 20.5, 0]]
#实际意义: 计算机视觉中的区域关系分析
示例4: 神经网络中的激活模式距离
3个不同输入在隐藏层的激活模式距离
activation_distances = [0.23, 0.45, 0.67]
activation_matrix = squareform(activation_distances)
激活模式距离矩阵:
print(activation_matrix)
#[[0, 0.23, 0.45],
[0.23, 0, 0.67],
[0.45, 0.67, 0]]
#实际意义: 深度学习模型的可解释性分析
示例5: 时间序列动态时间规整距离
4个时间序列之间的DTW距离
dtw_distances = [12.5, 18.3, 25.1, 15.7, 22.4, 9.8]
dtw_matrix = squareform(dtw_distances)
DTW距离矩阵:
print(dtw_matrix)
#[[0, 12.5, 18.3, 25.1],
[12.5, 0, 15.7, 22.4],
[18.3, 15.7, 0, 9.8],
[25.1, 22.4, 9.8, 0]]
#实际意义: 时间序列分析和模式识别
# 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_square_form(input_str):
"""
对标MATLAB的squareform函数,实现压缩向量与距离方阵的相互转换。
参数:
input_str (str): 输入字符串,可以是以下两种形式:
1. 压缩距离向量:如 "[0.5, 1.2, 2.3]"
2. 对称距离方阵:如 "[[0, 0.5, 1.2], [0.5, 0, 2.3], [1.2, 2.3, 0]]"
返回:
sympy.Matrix: 根据输入类型自动转换:
- 输入为向量时返回对称方阵
- 输入为方阵时返回压缩向量
如果输入格式错误,返回描述性错误信息
示例:
>>> distance_square_form("[1, 2, 3]")
Matrix([
[0, 1, 2],
[1, 0, 3],
[2, 3, 0]])
>>> distance_square_form("[[0, 1, 2], [1, 0, 3], [2, 3, 0]]")
Matrix([1.0, 2.0, 3.0])
"""
try:
# 将输入字符串解析为SymPy对象
expr = sp.sympify(input_str)
error = False
result = None
# 处理列表输入
if isinstance(expr, list):
arr = np.array(expr, dtype=float).ravel()
else:
error = True
# 检查数组维度有效性
if arr.ndim not in (1, 2):
raise ValueError("输入必须是向量(1D)或矩阵(2D)")
# 使用scipy进行格式转换
result = distance.squareform(arr)
# 转换为SymPy矩阵返回
return sp.Matrix(result) if not error else f"输入错误: {input_str}"
except ValueError as ve:
return f"数值错误: {str(ve)}"
except sp.SympifyError:
return "格式错误: 无法解析输入字符串"
except Exception as e:
return f"处理错误: {str(e)}"
input_str = "[1, 2, 3, 4, 5, 6]"
print(distance_square_form(input_str))
# Matrix([[0, 1.00000000000000, 2.00000000000000, 3.00000000000000],
# [1.00000000000000, 0, 4.00000000000000, 5.00000000000000],
# [2.00000000000000, 4.00000000000000, 0, 6.00000000000000],
# [3.00000000000000, 5.00000000000000, 6.00000000000000, 0]])
方波
x = square(t) 为时间数组t的元素生成周期为2π的方波.square类似于正弦函数,但会创建值为-1和1的方波.
x = square(t,duty) 生成指定占空比为duty的方波.占空比是方波为正的信号周期的百分比.
t — 时间数组,向量,矩阵
duty — 占空比,0到1之间
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy import signal
def square_wave(input_str):
"""
生成方波信号,对标MATLAB square函数
参数:
input_expr: 输入表达式,支持以下形式:
- 时间向量 (数值数组/矩阵)
- 符号表达式 (如 't',需包含单个符号变量)
- 元组 (时间向量, 占空比)
duty (可选): 占空比 (0到1之间,默认0.5)
freq (可选): 信号频率 (单位Hz,默认1)
sample_points (可选): 符号表达式采样点数 (默认500)
返回:
tuple: (时间向量, 方波信号) 或 错误信息字符串
示例:
>>> # 数值输入
>>> t = [0, 0.1, 0.2, 0.3]
>>> square_wave(t)
(array([0. , 0.1, 0.2, 0.3]), array([ 1., 1., 1., -1.]))
>>> # 符号表达式输入
>>> square_wave('t', duty=0.3)
(array([0. , 0.002,...,1.0]), array([1, 1,...,-1]))
>>> # 矩阵输入
>>> square_wave([[0, 0.5], [1, 1.5]])
(array([0. , 0.5, 1. , 1.5]), array([ 1., 1., -1., -1.]))
"""
try:
# 统一输入处理
expr = sp.sympify(input_str)
error = False
duty = 0.5
freq = 1
sample_points = 500
# 处理元组输入 (时间向量, 占空比)
if isinstance(expr, tuple) and len(expr) == 2:
t, custom_duty = expr
duty = float(custom_duty)
# 参数校验
if not 0 <= duty <= 1:
raise ValueError("占空比必须在0到1之间")
expr = t
# 矩阵/数组处理
if isinstance(expr, list):
t_values = np.array(expr).astype(float).ravel()
# 符号表达式处理
elif expr.free_symbols:
symbols = expr.free_symbols
if len(symbols) != 1:
raise ValueError("符号表达式必须包含单个变量")
var = symbols.pop()
t_values = np.linspace(0, 1 / freq, sample_points)
expr_func = sp.lambdify(var, expr, 'numpy')
t_values = expr_func(t_values)
# 数值处理
elif expr.is_number:
t_values = np.array(expr, dtype=float)
else:
error = True
# 生成方波 (MATLAB的2π周期对应频率f=1/(2π))
y_values = signal.square(2 * np.pi * freq * t_values, duty=duty)
return t_values, y_values if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {str(e)}"
# 处理各种输入类型
print(square_wave("[[0,0.5],[1,1.5]]"))
# (array([0. , 0.5, 1. , 1.5]),
# array([ 1., -1., 1., -1.]))
删除长度为 1 的维度
B = squeeze(A) 返回一个数组,其元素与输入数组 A 相同,但删除了长度为 1 的维度。例如,如果 A 是 3×1×2 数组,则 squeeze(A) 返回 3×2 矩阵。
如果 A 是行向量、列向量、标量或没有长度为 1 的维度的数组,则 squeeze 返回输入 A。
A — 输入数组,多维数组
示例1: 图像处理中的单通道数据
模拟单通道灰度图像数据 (1, 高度, 宽度)
gray_image = [[[128, 255, 64], [192, 32, 96], [160, 224, 80]]]
squeezed_gray = squeeze(gray_image)
print(f"压缩结果: {squeezed_gray}")
#压缩结果:
#[[128,255,64]
[192,32,96]
[160,224,80]]
#实际意义: 图像处理中去除不必要的单通道维度
示例2: 传感器数据批量处理
单个传感器的多批次测量数据 (批次, 1, 时间点)
sensor_data = [[[1.2, 1.3, 1.1, 1.4]], [[1.5, 1.6, 1.4, 1.7]]]
squeezed_sensor = squeeze(sensor_data)
print(f"压缩结果: {squeezed_sensor}")
#压缩结果:
#[[1.2, 1.3, 1.1, 1.4]
[1.5, 1.6, 1.4, 1.7]]
#实际意义: 物联网传感器数据预处理
示例3: 神经网络输出处理
多分类模型的预测输出 (批次大小, 1, 类别数)
model_output = [[[0.1, 0.8, 0.1]], [[0.7, 0.2, 0.1]], [[0.2, 0.3, 0.5]]]
squeezed_output = squeeze(model_output)
print(f"压缩结果: {squeezed_output}")
#压缩结果:
#[[0.1, 0.8, 0.1]
[0.7, 0.2, 0.1]
[0.2, 0.3, 0.5]]
#实际意义: 深度学习模型输出后处理
示例4: 科学计算中的测量数据
多次实验的单一测量结果 (实验次数, 1)
experiment_data = [[3.14], [2.71], [1.41], [0.58]]
squeezed_experiment = squeeze(experiment_data)
print(f"压缩结果: {squeezed_experiment}")
#压缩结果: [3.14, 2.71, 1.41, 0.58]
#实际意义: 科学实验数据整理和分析
示例5: 金融时间序列数据
单只股票的多日收盘价 (天数, 1)
stock_prices = [[100.5], [102.3], [98.7], [101.2], [99.8]]
squeezed_stock = squeeze(stock_prices)
print(f"压缩结果: {squeezed_stock}")
#压缩结果: [100.5, 102.3, 98.7, 101.2, 99.8]
#实际意义: 金融时间序列分析预处理
示例6: 文本处理中的词向量
单个文本的词向量序列 (1, 词数, 向量维度)
text_vectors = [[[0.1, 0.2, 0.3], [0.4, 0.5, 0.6], [0.7, 0.8, 0.9]]]
squeezed_text = squeeze(text_vectors)
print(f"压缩结果: {squeezed_text}")
#压缩结果:
#[[0.1, 0.2, 0.3]
[0.4, 0.5, 0.6]
[0.7, 0.8, 0.9]]
#实际意义: 自然语言处理中的文本表示
示例7: 医疗信号处理
单导联心电图信号 (1, 采样点数)
ecg_signal = [[-0.1, 0.5, 1.2, 0.8, 0.1, -0.3, -0.1, 0.2, 0.0]]
squeezed_ecg = squeeze(ecg_signal)
print(f"压缩结果: {squeezed_ecg}")
#压缩结果:
#[-0.1, 0.5, 1.2, 0.8, 0.1, -0.3, -0.1, 0.2, 0.0]
#实际意义: 医疗信号数据标准化处理
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
def squeeze_arr_dim(input_str):
"""
该函数的主要功能是将输入的字符串转换为数组,然后去除数组中长度为 1 的维度。
如果输入不是有效的矩阵格式,或者在处理过程中出现异常,会返回相应的错误信息。
参数:
input_str (str): 输入的字符串,预期为表示矩阵的字符串
返回:
numpy.ndarray 或 str: 如果处理成功,返回去除长度为 1 的维度后的数组;如果出现错误,返回错误信息字符串
"""
try:
# 这个函数可能用于处理字符串中的一些格式问题,使其符合后续处理的要求
# 使用 sympy 的 sympify 函数将修正后的字符串转换为 SymPy 表达式
expr = sp.sympify(input_str)
# 初始化结果变量,用于存储最终处理后的数组
result = None
# 初始化错误标志,用于标记是否出现错误
error = False
# 如果是矩阵,该函数会返回矩阵对象;否则返回 None
# 使用海象运算符(Python 3.8 及以上版本支持)将结果赋值给 matrix 变量
if isinstance(expr,list):
# 如果是矩阵,将矩阵对象转换为 NumPy 数组,数据类型为 object
arr = np.array(expr, dtype=object)
# 使用 NumPy 的 squeeze 函数去除数组中长度为 1 的维度
result = np.squeeze(arr)
else:
# 如果输入不是矩阵,将错误标志设置为 True
error = True
# 如果没有出现错误,返回处理后的数组;否则返回错误信息
return result if not error else f"输入错误: {input_str}"
except Exception as e:
# 如果在处理过程中出现异常,捕获异常并返回错误信息
return f"错误:{e}"
print(squeeze_arr_dim("[[[1,2]]]"))
# [1 2]
print(squeeze_arr_dim("[[[x,y]]]"))
# [x y]
状态空间模型
A,B,C,D,dt = ss(sys) 将线性系统转换为空间系统形式。始终创建一个新系统,即使sys已经是一个状态空间系统.
A - 装态数, 状态数是矩阵A的行(或列)数. 如果矩阵A是一个4×4的矩阵,因此有四个状态.
B - 输入数:输入数是矩阵B的列数. 比如矩阵B是一个4×2的矩阵,因此有两个输入.
C - 输出数:输出数是矩阵C的行数. 比如矩阵C是一个3×4的矩阵,因此有三个输出.
D - 矩阵D代表直接传递矩阵(Direct transmission matrix),也称为前馈矩阵(feedforward matrix).它描述了系统输入对系统输出的直接影响,而不经过系统的状态.
dt - 采样时间
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
import control.matlab as ct
def convert_to_numpy_or_float(expr):
"""
将表达式转换为 NumPy 数组或浮点数。
:param expr: 输入的表达式
:return: 转换后的 NumPy 数组或浮点数
"""
if isinstance(expr, list):
return np.array(expr, dtype=float)
elif expr.is_number:
return float(expr)
else:
# 如果既不是列表也不是数字,抛出类型错误
raise TypeError(f"不支持的类型: {type(expr).__name__}")
def state_space_system(input_str):
"""构建状态空间系统
参数格式示例:
- 连续系统: "[[-1,-2],[3,-4]],[[5],[7]],[[6, 8]],[[9]]"
- 离散系统: "[[-1.5,-2],[1,0]],[[0.5],[0]],[0,1],0,0.2"
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
# 检查表达式是否为元组
if not isinstance(expr, tuple):
return f"输入错误: 期望输入为元组,但得到 {type(expr).__name__}"
# 检查元组长度是否至少为 4
if len(expr) < 4:
return f"输入错误: 元组长度至少为 4,但得到 {len(expr)}"
# 提取 A, B, C, D 矩阵
A = convert_to_numpy_or_float(expr[0])
B = convert_to_numpy_or_float(expr[1])
C = convert_to_numpy_or_float(expr[2])
D = convert_to_numpy_or_float(expr[3])
# 检查是否有采样时间
if len(expr) > 4:
try:
dt = float(expr[4])
except ValueError:
return f"输入错误: 采样时间必须是数字,但得到 {expr[4]}"
# 创建连续时间状态空间系统
sys1 = ct.ss(A, B, C, D, dt)
result = sp.Matrix(sys1.A), sp.Matrix(sys1.B), sp.Matrix(sys1.C), sp.Matrix(sys1.D), sys1.dt
else:
# 创建离散时间状态空间系统
sys1 = ct.ss(A, B, C, D)
result = sp.Matrix(sys1.A), sp.Matrix(sys1.B), sp.Matrix(sys1.C), sp.Matrix(sys1.D)
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误:{e}"
# 测试案例
if __name__ == "__main__":
test_cases = [
"([[-1,-2],[3,-4]],[[5],[7]],[[6, 8]],[[9]])",
# A: Matrix([[-1.00000000000000, -2.00000000000000], [3.00000000000000, -4.00000000000000]])
# B: Matrix([[5.00000000000000], [7.00000000000000]])
# C: Matrix([[6.00000000000000, 8.00000000000000]])
# D: Matrix([[9.00000000000000]])
"([[-1.5,-2],[1,0]],[[0.5],[0]],[0,1],0,0.2)",
# A: Matrix([[-1.50000000000000, -2.00000000000000], [1.00000000000000, 0]])
# B: Matrix([[0.500000000000000], [0]])
# C: Matrix([[0, 1.00000000000000]])
# D: Matrix([[0]])
]
for case in test_cases:
print(f"测试输入: {case}")
result = state_space_system(case)
if isinstance(result, tuple):
if len(result) == 4:
A, B, C, D = result
else:
A, B, C, D, _ = result
print("A:", A)
print("B:", B)
print("C:", C)
print("D:", D)
else:
print("错误信息:", result)
print("─" * 50)
移位正弦积分
ssinint(X)返回移位后的正弦积分函数. ssiint(X)=sinint(X)-pi/2.
X —— 输入,符号数,符号变量,符号表达式,符号函数,符号向量,符号矩阵.
示例1: 光学单缝衍射强度分布
在夫琅禾费衍射中,强度分布与sinc函数的平方成正比
移位正弦积分可用于计算衍射图案的累积能量
x_optical = np.linspace(0.1, 10, 5) # 避免0点奇异性
optical_results = []
for x_val in x_optical:
result = ssinint(x_val)
optical_results.append(result)
print(f"衍射参数 x: {x_optical}")
print(f"移位正弦积分值: {optical_results}")
#衍射参数 x: [0.1,2.575,5.05,7.525,10]
#移位正弦积分值: [-1.47085186568662, 0.224514264435489, -0.0303322987142942, -0.0569792433219107, 0.0875512674239776]
#实际意义: 光学系统设计和衍射效率计算
示例2: 信号处理中的滤波器响应
理想低通滤波器的阶跃响应包含正弦积分项
t_values = [0.5, 1.0, 2.0, 5.0] # 归一化时间
filter_response = []
for t in t_values:
# 阶跃响应包含 Si(2πWt) 项,其中W为带宽
result = ssinint(2 * np.pi * t)
filter_response.append(0.5 + result/np.pi) # 转换为实际的阶跃响应
print(f"时间点: {t_values}")
print(f"归一化阶跃响应: {filter_response}")
#时间点: [0.5, 1.0, 2.0, 5.0]
#归一化阶跃响应: [0.589489872236084, 0.451411666790140, 0.474969669883655, 0.489888171153879]
#实际意义: 通信系统滤波器设计和分析
示例3: 天线辐射场积分
线天线的辐射场计算涉及正弦积分
antenna_params = [1.0, 2.0, 3.0] # 电长度参数
field_strength = []
for param in antenna_params:
result = ssinint(param)
field_strength.append(float(abs(result)))
print(f"天线参数: {antenna_params}")
print(f"相对场强: {field_strength}")
#天线参数: [1.0, 2.0, 3.0]
#相对场强: [0.6247132564277136, 0.03461665000779801, 0.277856201204572]
#实际意义: 天线设计和电磁场计算
示例4: 量子势垒穿透概率
某些势垒穿透问题的解涉及正弦积分
energy_params = [0.5, 1.0, 1.5] # 归一化能量参数
transmission_prob = []
for E in energy_params:
result = ssinint(np.pi * E)
# 简化的透射系数模型
prob = max(0, 1 - abs(float(result))/np.pi)
transmission_prob.append(prob)
print(f"能量参数: {energy_params}")
print(f"透射概率: {transmission_prob}")
#能量参数: [0.5, 1.0, 1.5]
#透射概率: [0.9363271497303014, 0.9105101277639162, 0.9880390517477889]
#实际意义: 量子隧穿效应和半导体器件物理
示例5: 声波衍射边界效应
声波遇到障碍物时的衍射场计算
acoustic_params = [0.8, 1.6, 2.4] # 声学参数
diffraction_effect = []
for param in acoustic_params:
result = ssinint(param)
diffraction_effect.append(float(abs(result)))
print(f"声学参数: {acoustic_params}")
print(f"衍射效应强度: {diffraction_effect}")
#声学参数: [0.8, 1.6, 2.4]
#衍射效应强度: [0.7987005413129, 0.18161584092445793, 0.18168917396687068]
#实际意义: 声学设计和噪声控制
示例6: 瞬态热传导积分
某些瞬态热传导问题的解涉及正弦积分
time_params = [0.2, 0.5, 1.0] # 归一化时间
temp_profile = []
for t in time_params:
result = ssinint(1/t if t > 0 else 1)
# 简化的温度分布模型
temp = 1 - abs(float(result))/np.pi
temp_profile.append(temp)
print(f"时间参数: {time_params}")
print(f"归一化温度: {temp_profile}")
#时间参数: [0.2, 0.5, 1.0]
#归一化温度: [0.99335843817104, 0.9889811780759536, 0.8011475944489892]
#实际意义: 热力学分析和热管理系统设计
示例7: 符号计算应用
symbolic_inputs = [x, a*x, sin(x)]
symbolic_results = []
for sym_input in symbolic_inputs:
result = ssinint(sym_input)
symbolic_results.append(result)
符号输入和对应的移位正弦积分:
for inp, res in zip(symbolic_inputs, symbolic_results):
print(f" Si({inp}) - π/2 = {res}")
# Si(x) - π/2 = Si(x) - pi/2
# Si(a*x) - π/2 = Si(a*x) - pi/2
# Si(sin(x)) - π/2 = Si(sin(x)) - pi/2
#实际意义: 解析推导和理论物理研究
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from sympy import Si, pi
import numpy as np
from scipy.special import sici
def shifted_sine_integral(input_str):
"""
对标 MATLAB 的 ssinint 函数,计算位移正弦积分 Si(x) - π/2。
参数:
input_str: 输入的字符串,可以表示数值、符号表达式或矩阵。
返回:
- 对于数值输入,返回浮点数结果。
- 对于符号输入,返回符号表达式。
- 对于矩阵输入,返回各元素对应的位移正弦积分结果的 SymPy 矩阵。
- 错误时返回错误消息字符串。
示例:
>>> shifted_sine_integral('2')
-0.110538260536646 # 示例值,实际结果可能不同
>>> shifted_sine_integral('x')
Si(x) - pi/2
>>> shifted_sine_integral('[[1, x], [2, y]]')
Matrix([
[Si(1) - pi/2, Si(x) - pi/2],
[Si(2) - pi/2, Si(y) - pi/2]])
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
# 处理单个数值或符号
if expr.is_number:
z = complex(expr)
"""计算位移正弦积分 Si(x) - π/2,仅处理数值标量输入。"""
si, _ = sici(z) # 仅取正弦积分部分
result = si - np.pi / 2
elif expr.free_symbols:
"""计算位移正弦积分 Si(x) - π/2,根据输入类型返回数值或符号表达式。"""
result = Si(expr) - pi / 2
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
# 示例测试
if __name__ == "__main__":
# 数值输入
print(shifted_sine_integral('2'))
# (0.03461665000779801-0j)
# 符号输入
print(shifted_sine_integral('x'))
# Si(x) - pi/2
stairs(Y) 绘制 Y 中元素的阶梯图.
如果Y为矩阵,则stairs为每个矩阵列绘制一个线条
示例1: 数字信号处理 - 采样保持电路
模拟ADC采样保持过程
t_analog = np.linspace(0, 2 * np.pi, 1000)
analog_signal = np.sin(t_analog) + 0.5 * np.sin(3 * t_analog)
采样点
sampling_rate = 20 # 20个采样点
t_sampled = np.linspace(0, 2 * np.pi, sampling_rate)
sampled_signal = np.sin(t_sampled) + 0.5 * np.sin(3 * t_sampled)
生成阶梯图(采样保持)
x_stairs, y_stairs = stairs(sampled_signal)
print(f"模拟信号点数: {len(t_analog)}")
print(f"采样点数: {len(t_sampled)}")
print(f"阶梯图点数: {len(x_stairs)}")
#模拟信号点数: 1000
#采样点数: 20
#阶梯图点数: 1000
#实际意义: 数字信号处理和采样保持电路模拟
示例2: 控制系统 - 数字控制器输出
模拟PID控制器的离散输出
time_steps = 10
control_output = [0, 2, 5, 3, 1, 4, 6, 5, 3, 2] # 控制器输出序列
x_control, y_control = stairs(control_output)
print(f"控制周期数: {time_steps}")
print(f"控制器输出范围: [{min(control_output)}, {max(control_output)}]")
#控制周期数: 10
#控制器输出范围: [0, 6]
#实际意义: 离散控制系统分析和设计
示例3: 数据采集系统 - 量化过程
模拟4位ADC的量化过程
analog_values = [0.1, 0.8, 1.5, 2.2, 1.8, 1.2, 0.5, 0.9]
quantized_values = [round(val * 4) / 4 for val in analog_values] # 4位量化
x_quant, y_quant = stairs(quantized_values)
print(f"原始模拟值: {analog_values}")
print(f"量化后值: {quantized_values}")
#原始模拟值: [0.1, 0.8, 1.5, 2.2, 1.8, 1.2, 0.5, 0.9]
#量化后值: [0.0, 0.75, 1.5, 2.25, 1.75, 1.25, 0.5, 1.0]
#实际意义: 数据采集系统设计和量化误差分析
示例4: 通信系统 - ASK调制信号
幅移键控调制
binary_data = [1, 0, 1, 1, 0, 1, 0, 0, 1] # 二进制数据
ask_signal = [3 if bit == 1 else 0.5 for bit in binary_data] # 高幅值代表1,低幅值代表0
x_ask, y_ask = stairs(ask_signal)
print(f"二进制数据: {binary_data}")
print(f"ASK信号电平: {ask_signal}")
#二进制数据: [1, 0, 1, 1, 0, 1, 0, 0, 1]
#ASK信号电平: [3, 0.5, 3, 3, 0.5, 3, 0.5, 0.5, 3]
#实际意义: 数字通信系统调制分析
示例5: 经济数据 - 股票日内价格变化
模拟股票在交易日的价格变化(每分钟一个价格)
stock_prices = [100, 101, 102, 101, 103, 105, 104, 106, 107, 105]
x_stock, y_stock = stairs(stock_prices)
print(f"价格序列: {stock_prices}")
print(f"价格变化范围: {max(stock_prices) - min(stock_prices)} 点")
#价格序列: [100, 101, 102, 101, 103, 105, 104, 106, 107, 105]
#价格变化范围: 7 点
#实际意义: 金融市场数据可视化和分析
示例6: 工业过程控制 - 水箱液位控制
模拟水箱液位的离散控制
water_levels = [0.5, 1.2, 2.0, 2.5, 2.2, 1.8, 2.1, 2.4, 2.5, 2.5] # 米
x_level, y_level = stairs(water_levels)
print(f"液位序列: {water_levels}")
print(f"目标液位: 2.5米")
#液位序列: [0.5, 1.2, 2.0, 2.5, 2.2, 1.8, 2.1, 2.4, 2.5, 2.5]
#目标液位: 2.5米
#实际意义: 过程控制系统监控和调试
示例7: 符号函数离散化
将连续符号函数转换为阶梯近似
symbolic_result = stairs(sin(x) + 0.5*cos(2*x))
x_sym, y_sym = symbolic_result
print(f"符号函数离散化点数: {len(x_sym)}")
print(f"输出范围: [{min(y_sym):.3f}, {max(y_sym):.3f}]")
#符号函数离散化点数: 1000
#输出范围: [-0.182, 8.428]
#实际意义: 连续系统的离散化实现
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy.interpolate import interp1d
def stair_wave(input_str):
"""
对标 MATLAB 的 stairs 函数,生成阶梯图数据。
参数:
input_str: 输入的字符串,可以表示:
- 数值矩阵(视为 Y 值,X 自动生成)
- 符号表达式(如 'sin(x)',需配合 x_range 使用)
x_range: 符号表达式时 X 的取值范围,格式为 (start, stop, num_points)
返回:
- 成功时返回 (x_out, y_out) 的 NumPy 数组
- 错误时返回错误消息字符串
示例:
>>> x, y = stair_wave('[[1, 2, 3], [4, 5, 6]]') # 输入二维矩阵
>>> x, y = stair_wave('sin(x)', x_range=(0, 2*np.pi, 100)) # 符号表达式
"""
try:
# 尝试将输入解析为 SymPy 表达式或矩阵
expr = sp.sympify(input_str)
x_out, y_out = None, None
error = False
# Continuous data
NUM = 1000 # modify the number of points you want
if isinstance(expr, list):
# 如果 expr 是一个矩阵,则将其转换为 NumPy 数组并展平
x = np.array(expr, dtype=float).ravel()
# 这里 y 的计算暂时写为 np.sin(x),实际使用时 y 需要根据具体需求输入,例如 0.5*cos(x)
y = np.sin(x)
# 对 y 进行累加操作
y = np.cumsum(y)
# 初始化 x=0 时的 y 值
y0 = np.array([0])
# 通过插值计算 y=0 时对应的 x 值
x0 = np.interp([0], y, x)
# 将 x0 与原 x 数组拼接
x = np.concatenate([x0, x])
# 将 y0 与原 y 数组拼接
y = np.concatenate([y0, y])
# 使用 'next' 方式进行插值,创建插值函数
funct = interp1d(x, y, kind='next')
# 生成连续的 x 值
x_cont = np.linspace(x[0], x[-1], NUM)
# 通过插值函数计算对应的连续 y 值
y_cont = funct(x_cont)
elif expr.free_symbols:
# 如果输入是符号表达式,默认生成 0 到 4π 之间的 50 个 x 值
x_values = np.linspace(0, 4 * np.pi, 50)
# 如果 expr 是一个 SymPy 表达式,则执行相应的操作
if variables := expr.free_symbols:
# 将 SymPy 表达式转换为可以在 NumPy 中计算的函数
expression_func = sp.lambdify(tuple(variables), expr, modules=['numpy'])
# 计算 y
y = expression_func(x_values)
else:
# 如果没有自由变量,直接将 expr 作为 y
y = expr
# 对 y 进行累加操作
y = np.cumsum(y)
# 初始化 x=0 时的 y 值
y0 = np.array([0])
# 通过插值计算 y=0 时对应的 x 值
x0 = np.interp([0], y, x_values)
# 将 x0 与原 x 数组拼接
x_values = np.concatenate([x0, x_values])
# 将 y0 与原 y 数组拼接
y = np.concatenate([y0, y])
# 使用 'next' 方式进行插值,创建插值函数
funct = interp1d(x_values, y, kind='next')
# 生成连续的 x 值
x_cont = np.linspace(x_values[0], x_values[-1], NUM)
# 通过插值函数计算对应的连续 y 值
y_cont = funct(x_cont)
else:
# 如果 expr 不是矩阵也不是 SymPy 表达式,则抛出错误或者执行其他操作
error = True
return x_cont, y_cont if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
# 示例测试
if __name__ == "__main__":
# 示例 : 符号表达式输入
x, y = stair_wave('sin(x)')
print("符号表达式采样:", x[:5], y[:5])
# [0. 0.01257895 0.0251579 0.03773685 0.0503158 ]
# [0. 0.25365458 0.25365458 0.25365458 0.25365458]
插入标准缺失值
B = standardizeMissing(A,indicator) 用 A 中的标准缺失值替换 indicator 中指定的值,并返回一个标准化数组
A — 输入数据,向量,矩阵
indicator — 非标准缺失值指示符,标量
示例1:处理实验中的无效测量值
experiment_data = ([[25.3, -999, 26.1], [24.8, 25.9, -999], [-999, 25.5, 26.2]], -999)
实验数据清理:
print(standardizeMissing(experiment_data))
# [[25.3, nan, 26.1],
[24.8, 25.9, nan],
[nan, 25.5, 26.2]]
# 将实验中的无效测量值-999替换为NaN
示例2:处理股票数据中的缺失交易日
stock_prices = ([[150.2, 152.3, 0, 155.1], [157.8, 0, 159.2, 161.5]], 0)
股票价格数据处理:
print(standardizeMissing(stock_prices))
# [[150.2, 152.3, nan, 155.1],
[157.8, nan, 159.2, 161.5]]
# 将停牌日的价格0标记为缺失值
示例3:处理传感器异常读数
sensor_readings = ([[23.5, 9999, 24.1, 9999], [22.8, 23.9, 9999, 24.3]], 9999)
传感器数据质量控制:
print(standardizeMissing(sensor_readings))
# [[23.5, nan, 24.1, nan],
[22.8, 23.9, nan, 24.3]]
# 将传感器超量程值9999标记为缺失
示例4:处理问卷调查中的未回答题目
survey_data = ([[5, -1, 4, 3], [-1, 2, -1, 5], [3, 4, 2, -1]], -1)
调查问卷数据处理:
print(standardizeMissing(survey_data))
# [[5.0, nan, 4.0, 3.0],
[nan, 2.0, nan, 5.0],
[3.0, 4.0, 2.0, nan]]
# 将未回答的题目(-1)标记为缺失
示例5:处理医疗检测中的多种无效值
medical_tests = ([[36.5, 999, 37.1], [98, 999, 0], [120, 80, 999]], [999, 0])
医疗检测数据处理:
print(standardizeMissing(medical_tests))
# [[36.5, nan, 37.1],
[98.0, nan, nan],
[120.0, 80.0, nan]]
# 将设备错误(999)和无效读数(0)都标记为缺失
示例6:处理环境监测中的多种异常值
environment_data = ([[25.3, -99.9, 26.1, -99.9], [-99.9, 45.2, 46.8, 47.1]], -99.9)
环境监测数据处理:
print(standardizeMissing(environment_data))
# [[25.3, nan, 26.1, nan],
[nan, 45.2, 46.8, 47.1]]
# 输出:将传感器故障值-99.9标记为缺失
示例7:处理经济统计中的占位符数据
economic_data = ([[5.2, -888, 6.1], [7.3, 6.8, -888], [-888, 5.9, 6.4]], -888)
经济统计数据验证:
print(standardizeMissing(economic_data))
# [[5.2, nan, 6.1],
[7.3, 6.8, nan],
[nan, 5.9, 6.4]]
# 将待补充数据-888标记为缺失
示例8:处理图像数据中的无效像素值
image_data = ([[255, 0, 255], [0, -1, 0], [255, 0, -1]], -1)
图像数据处理:
print(standardizeMissing(image_data))
# [[255.0, 0.0, 255.0],
[0.0, nan, 0.0],
[255.0, 0.0, nan]]
# 将损坏的像素值-1标记为缺失
示例9:同时处理多种类型的无效值
comprehensive_data = ([[1, 999, 3, -999], [4, 5, 999, 7], [-999, 8, 9, 10]], [999, -999])
多条件缺失值处理:
print(standardizeMissing(comprehensive_data))
# [[1.0, nan, 3.0, nan],
[4.0, 5.0, nan, 7.0],
[nan, 8.0, 9.0, 10.0]]
# 将999和-999都标记为缺失值
示例10:为时间序列插补准备数据
time_series = ([[10.2, 11.5, 0, 12.8, 13.1], [14.2, 0, 15.7, 16.3, 0]], 0)
时间序列数据插补准备:
print(standardizeMissing(time_series))
# [[10.2, 11.5, nan, 12.8, 13.1],
[14.2, nan, 15.7, 16.3, nan]]
# 将缺失的时间点0标记为NaN,便于后续插补
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from ast import literal_eval # 用于安全解析元组
def standardize_missing(input_str):
"""
对标 MATLAB 的 standardizeMissing 函数,将指定值替换为标准缺失值 NaN
参数:
input_str: 输入的字符串,格式应为 "(matrix, indicator)",其中:
- matrix: 数值矩阵(支持嵌套列表或 SymPy 矩阵)
- indicator: 要替换的值(数值或列表)
返回:
SymPy 矩阵 或 错误信息字符串
示例:
>>> standardize_missing("([[1, 0], [3, -999]], -999)")
Matrix([[1, 0], [3, nan]])
>>> standardize_missing("([5, 2, 888, 4], [2, 888])")
Matrix([[5, nan, nan, 4]])
"""
try:
# 安全解析输入字符串为Python对象
parsed = literal_eval(input_str.strip())
# 验证输入格式是否为 (matrix, indicator)
if not (isinstance(parsed, tuple) and len(parsed) == 2):
return "输入错误: 必须为 (matrix, indicator) 格式的元组"
matrix, indicator = parsed
# 转换输入矩阵为SymPy矩阵
sp_matrix = sp.Matrix(matrix) if isinstance(matrix, list) else None
if sp_matrix is None:
return "输入错误: 无法解析矩阵数据"
# 验证矩阵是否为纯数值型
if sp_matrix.is_symbolic():
return "错误: 矩阵包含符号元素,仅支持数值矩阵"
# 转换指示符为NumPy数组形式
indicators = np.array([indicator]).flatten() if np.isscalar(indicator) else np.array(indicator)
# 转换为NumPy数组进行操作
np_matrix = np.array(sp_matrix.tolist(), dtype=float)
# 创建掩码矩阵(True表示需要替换的位置)
mask = np.isin(np_matrix, indicators)
# 替换目标值为NaN
np_matrix[mask] = np.nan
# 转换回SymPy矩阵
if sp_matrix.shape[1] == 1:
return sp.Matrix(np_matrix).T
else:
return sp.Matrix(np_matrix)
except SyntaxError:
return "语法错误: 输入格式应为有效的Python元组表达式"
except ValueError as ve:
return f"数值转换错误: {ve}"
except Exception as e:
return f"未处理的异常: {str(e)}"
# 示例测试
if __name__ == "__main__":
# 测试用例1:替换单个值
test1 = "([[1, 0], [3, -999]], -999)"
print(f"测试1输入: {test1}")
print("测试1输出:", standardize_missing(test1))
# Matrix([[1.00000000000000, 0],
# [3.00000000000000, nan]])
# 测试用例2:替换多个值
test2 = "([5, 2, 888, 4], [2, 888])"
print(f"\n测试2输入: {test2}")
print("测试2输出:", standardize_missing(test2))
# Matrix([[5.00000000000000, nan, nan, 4.00000000000000]])
标准差
S = std(A) 返回数组元素的标准偏差,即分布范围的度量.默认情况下,标准偏差是为展开的阵列计算的,否则是在指定的轴上计算的.
S = std(A,dim). 计算标准偏差的一个或多个轴.默认情况是计算展平阵列的标准偏差.
dim=0,计算以列为单位的标准差.
dim=1,计算以行为单位的标准差.
A - 输入数组,向量,矩阵
dim - 沿其运算的维度
示例1:分析班级各科目成绩的离散程度
math_scores = [85, 92, 78, 96, 88, 74, 91, 83]
print("数学成绩标准差:", std(math_scores))
# 数学成绩标准差: 7.39570338584699
# 数学成绩相对集中
多科目成绩矩阵(行:学生,列:科目[数学, 语文, 英语])
all_scores = [[85, 78, 82], [92, 85, 88], [78, 92, 75], [96, 88, 94]]
print("\n各科目成绩标准差(按列):", std(all_scores))
#各科目成绩标准差(按列): [7.9320026895272, 5.90903263374528, 8.13941029804985]
#英语成绩离散度最大
print("各学生成绩标准差(按行):", std(all_scores, 2))
#各学生成绩标准差(按行): [3.51188458428425, 3.51188458428425, 9.07377172587747, 4.16333199893227]
#第三个学生各科成绩差异最大
示例2:分析不同股票的价格波动性
每日收益率矩阵(行:日期,列:股票A,B,C)
daily_returns = [[0.02, 0.015, -0.01], [-0.005, 0.02, 0.03], [0.01, -0.008, 0.005], [0.015, 0.012, -0.02]]
print("各股票收益率标准差(风险度量):", std(daily_returns))
#各股票收益率标准差(风险度量): [0.0108012344973464, 0.0122848144742469, 0.0217466472511665]
#股票C风险最高
print("每日市场整体波动:", std(daily_returns, 2))
#每日市场整体波动: [0.0160727512683216, 0.0180277563773199, 0.00929157324317757, 0.019399312702602]
#第二天市场波动最大
示例3:分析生产线上产品尺寸的一致性
不同批次产品尺寸测量(行:批次,列:测量点1,2,3)
product_measurements = [[10.02, 10.01, 10.03], [9.98, 10.02, 9.99], [10.01, 9.97, 10.04], [10.00, 10.01, 10.00]]
print("各测量点尺寸变异:", std(product_measurements))
#各测量点尺寸变异: [0.017078251276599, 0.022173557826083, 0.0238047614284757]
#测量点2和3变异较大
print("各批次生产稳定性:", std(product_measurements, 2))
#各批次生产稳定性: [0.00999999999999979, 0.0208166599946609, 0.0351188458428417, 0.00577350269189613]
#第三批次稳定性最差
示例4:分析不同城市气温变化幅度
月度平均气温(行:月份1-4,列:城市A,B,C,D)
monthly_temps = [[15, 18, 22, 25], [17, 20, 24, 28], [20, 23, 26, 30], [18, 21, 25, 27]]
print("各城市气温变化幅度:", std(monthly_temps))
#各城市气温变化幅度: [2.08166599946613, 2.08166599946613, 1.70782512765993, 2.08166599946613]
#城市C气温变化最小
print("各月份气温差异:", std(monthly_temps, 2))
#各月份气温差异: [4.39696865275764, 4.78713553878169, 4.27200187265877, 4.03112887414927]
#前两个月城市间温差较大
示例5:分析部门预算执行情况的稳定性
季度预算执行率%(行:季度,列:部门A,B,C)
budget_execution = [[95, 102, 98], [88, 105, 96], [92, 98, 102], [96, 101, 99]]
print("各部门预算执行稳定性:", std(budget_execution))
#各部门预算执行稳定性: [3.5939764421413, 2.88675134594813, 2.5]
#部门A执行最不稳定
print("各季度执行一致性:", std(budget_execution}, 2))
#各季度执行一致性: [3.51188458428425, 8.50490054811538, 5.03322295684717, 2.51661147842358]
#第二季度部门间差异最大
示例6:分析实验测量的重复性
重复实验测量值(行:实验次数,列:样品1,2,3)
experiment_data = [[45.2, 67.8, 89.1], [45.5, 67.2, 89.5], [44.9, 68.1, 88.8], [45.3, 67.5, 89.2]]
print("各样品测量重复性:", std(experiment_data))
#各样品测量重复性: [0.25, 0.387298334620738, 0.288675134594815]
#样品2重复性稍差
print("各次实验精度:", std(experiment_data, 2))
#各次实验精度: [21.9532078141973, 22.0006818076168, 21.9618608804749, 21.9504745582717]
#实验精度基本一致
示例7:分析服务器响应时间的稳定性
小时平均响应时间ms(行:小时,列:服务器A,B,C)
response_times = [[120, 115, 125], [118, 112, 128], [122, 118, 130], [119, 114, 126]]
print("各服务器响应稳定性:", std(response_times))
#各服务器响应稳定性: [1.70782512765993, 2.5, 2.21735578260835]
#服务器B响应时间最不稳定
print("各时段系统整体波动:", std(response_times, 2))
#各时段系统整体波动: [5.0, 8.08290376865476, 6.11010092660779, 6.02771377334171]
#第二小时系统波动最大
示例8:分析运动员比赛表现的稳定性
比赛得分(行:比赛场次,列:运动员A,B,C)
player_scores = [[28, 25, 30], [32, 22, 28], [26, 27, 32], [29, 24, 29], [31, 26, 31]]
print("运动员表现稳定性:", std(player_scores))
#运动员表现稳定性: [2.38746727726266, 1.92353840616713, 1.58113883008419]
#运动员A表现最不稳定
print("各场比赛选手差异:", std(player_scores}, 2))
#各场比赛选手差异: [2.51661147842358, 5.03322295684717, 3.21455025366432, 2.88675134594813, 2.88675134594813]
#第二场比赛选手差异最大
示例9:分析销售团队业绩波动
月度销售额(万元)(行:月份,列:销售员A,B,C,D)
sales_data = [[50, 45, 60, 55], [48, 52, 58, 53], [55, 48, 62, 57], [52, 50, 59, 54]]
print("销售员业绩稳定性:", std(sales_data))
#销售员业绩稳定性: [2.98607881119482, 2.98607881119482, 1.70782512765993, 1.70782512765993]
#销售员A和B业绩波动较大
print("各月份销售波动:", std(sales_data}, 2))
#各月份销售波动: [6.45497224367903, 4.11298755975102, 5.8022983951764, 3.86221007541882]
#第一个月销售员间差异最大
示例10:分析医疗检测结果的变异系数
血压测量值(行:测量时间点,列:患者A,B,C)
blood_pressure = [[120, 125, 118], [122, 128, 116], [119, 123, 115], [121, 126, 117]]
print("患者血压波动程度:", std(blood_pressure))
#患者血压波动程度: [1.29099444873581, 2.08166599946613, 1.29099444873581]
#患者B血压波动最大
print("各时间点测量一致性:", std(blood_pressure, 2))
#各时间点测量一致性: [3.60555127546399, 6.0, 4.0, 4.50924975282289]
#第二个时间点患者间差异最大
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
def standard_deviation_array(input_str, ddof=1):
"""
对标 MATLAB 的 std 函数,精确处理向量和矩阵输入
参数:
input_str: 输入字符串,格式支持:
- "matrix" : 直接输入矩阵
- "(matrix, dim)" : 矩阵+维度(1=列方向,2=行方向)
ddof: 自由度调整(默认1对应无偏估计)
返回:
- 标量(向量输入或整体计算)
- 列表(矩阵按列/行计算)
- 错误信息字符串
示例:
>>> standard_deviation_array("[1, 2, 3, 4]") # 向量输入
1.118033988749895
>>> standard_deviation_array("[[1,2],[3,4]]") # 矩阵默认按列
[1.0, 1.0]
>>> standard_deviation_array("([[1,2],[3,4]], 2)") # 按行计算
[0.7071, 0.7071]
"""
try:
# 解析输入
parsed = sp.sympify(input_str)
matrix_data, dim = (parsed if isinstance(parsed, tuple)
else (parsed, None))
# 验证矩阵有效性
sp_matrix = sp.Matrix(matrix_data) if isinstance(matrix_data, list) else None
if not sp_matrix or sp_matrix.is_symbolic():
return "无效矩阵输入" if not sp_matrix else "仅支持数值矩阵"
# 转换为 NumPy 数组
np_matrix = np.array(sp_matrix.tolist(), dtype=float)
original_shape = np_matrix.shape
# 自动识别向量并展平
if np_matrix.ndim == 2 and min(np_matrix.shape) == 1:
np_matrix = np_matrix.ravel()
# 计算维度处理
if dim is None:
# 智能维度判断
if np_matrix.ndim == 1:
axis = None # 向量计算整体
else:
axis = 0 # 矩阵默认按列
else:
axis = int(dim) - 1 # MATLAB 转 NumPy 轴
# 执行标准差计算
result = np.std(np_matrix, axis=axis, ddof=ddof)
# 标准化输出格式
if isinstance(result, np.ndarray):
return np.around(result.tolist(), 4) if result.ndim == 1 else result.tolist()
else:
return float(np.around(result, 4))
except Exception as e:
return f"错误: {str(e)}"
# 验证测试
if __name__ == "__main__":
# 测试1: 行向量输入
print(standard_deviation_array("[[1, 2, 3, 4]]"))
# 1.291
# 测试2: 列向量输入
print(standard_deviation_array("[[1], [2], [3], [4]]"))
# 1.291
# 测试3: 4x3矩阵按列
test_data = "[[1,5,9], [2,6,10], [3,7,11], [4,8,12]]"
print(standard_deviation_array(test_data))
# [1.291 1.291 1.291]
# 测试4: 同上矩阵按行
print(standard_deviation_array(f"({test_data}, 2)"))
# [4. 4. 4. 4.]
阶跃响应图
stepplot(sys) 可视化系统对单位阶跃输入(Unit Step Input)的动态响应.
单位阶跃输入在时间 t = 0时从 0 突然跳变到 1(例如,一个开关的瞬时开启)。
阶跃响应图显示了系统输出随时间的变化,帮助我们分析系统的稳定性、速度、准确性等性能指标。
一阶系统(无振荡):
类似 RC 电路充电过程(如电容器电压响应)
阶跃响应特性:
无超调(单调上升)
上升时间:约 1.15 秒(从 10% 到 90% 稳态值)
调节时间:约 4 秒(±2% 准则)
稳态值:2.5(因为 G(0) = 5/2 = 2.5G(0)=5/2=2.5)
stepplot(5,s+2)
二阶欠阻尼系统(有振荡):
弹簧-质量-阻尼系统的振荡响应(如汽车悬架)
阶跃响应特性:
超调量:约 16.3%(因阻尼比 \zeta = 0.316ζ=0.316)
上升时间:约 0.55 秒
峰值时间:约 1.05 秒
调节时间:约 4 秒(±2% 准则)
稳态值:1(因为 G(0) = 10/10 = 1G(0)=10/10=1)
stepplot(10,s^2+2s+10)
二阶临界阻尼系统(最快无振荡):
门关闭装置的理想响应(快速且无反弹)
阶跃响应特性:
无超调(单调上升)
上升时间:约 1.17 秒
调节时间:约 2.4 秒(±2% 准则)
稳态值:1(因为 G(0) = 9/9 = 1G(0)=9/9=1)
stepplot(9,s^2+6s+9)
高阶系统(含振荡和延迟效应):
带滤波器的电机位置控制系统
阶跃响应特性:
超调量:约 8%
调节时间:约 8 秒
稳态值:0.4(因为 G(0) = 2/5 = 0.4G(0)=2/5=0.4)
stepplot(s+2,s^3+5s^2+9s+5)
质量-弹簧-阻尼系统(机械工程)
汽车减震器设计、建筑抗震分析。
阶跃响应特性:
输入:突加 1 N 的恒定力(阶跃力)
输出:物体位移
超调量 ≈ 15%(轻微振荡)
调节时间 ≈ 4 秒
stepplot(1,0.5s^2+1.2s+8)
水箱液位控制系统(过程控制)
化工生产中的液位调节,需避免溢出。
阶跃响应特性:
输入:进水流量阶跃增加(如 0→2 m³/s)
输出:液位高度(稳态值 = 1 m)
上升时间 ≈ 11 秒(缓慢上升,无超调)
stepplot(2,5s+1)
直流电机位置控制(机电系统)
机器人关节定位,要求精确无振荡。
阶跃响应特性:
输入:目标角度阶跃(如 0→90°)
输出:实际转子角度
稳态值 = 90°(无稳态误差)
上升时间 ≈ 1.2 秒(单调上升)
stepplot(3,s*(s+4))
RLC带通滤波器(电子工程):
通信系统中提取高频信号。
阶跃响应特性:
输入:电压阶跃(0→1 V)
输出:电阻两端电压
初始峰值 ≈ 0.8 V(快速响应)
稳态值 = 0(高通特性)
stepplot(0.6s,s^2+0.7s+1)
疫情传播模型(流行病学)
预测隔离政策对感染峰值的影响。
阶跃响应特性:
输入:突现 1 名感染者(阶跃输入)
输出:累计感染比例
峰值感染率 ≈ 20%(超调)
稳定时间 ≈ 30 天
stepplot(0.05,s^2+0.3s+0.05)
股票市场反应模型(金融)
量化交易中事件驱动策略的回测。
阶跃响应特性:
输入:消息公布(阶跃事件)
输出:股价变动
初始过冲 ≈ +15%(投机泡沫)
稳态值 = +100%(最终合理估值)
stepplot(-0.2s+1,s^2+0.5s+1)
卫星姿态控制(航空航天):
太空望远镜精密指向控制。
阶跃响应特性:
输入:目标角度阶跃(如 0→10°)
输出:实际俯仰角
稳态误差 = 0(积分作用)
超调 ≈ 35%(需优化阻尼)
stepplot(100,s^2*(s+10))
机械减震系统
观察车身振动的超调量、稳定时间,优化舒适性。
汽车悬架系统,输入为路面阶跃冲击(如突然遇到障碍物),输出为车身垂直位移。
分母 s² + 2s + 5 对应质量-弹簧-阻尼系统
s² 项:质量惯性(m)
2s 项:阻尼系数(c)
5:弹簧刚度(k)
stepplot([1],[1,2,5])
温度控制系统
分析水温上升的延迟和稳态时间,避免过热风险。
电热水壶的加热系统,输入为阶跃电压(突然通电),输出为水温。
分母 3s + 1 表示一阶惯性:
3:热容(C)与热阻(R)的乘积(时间常数 τ = RC)
stepplot([1],[3,1])
直流电机调速
检查转速是否快速跟踪指令(上升时间短),且无振荡(超调小)。
电机转速控制,输入为阶跃电压,输出为转速。
分母 s² + 4s + 8 包含: 电感(L)、电阻(R)、反电动势(K)的耦合效应
stepplot([1],[1,4,8])
化学反应釜浓度控制
评估浓度超调是否导致副产物超标,调整进料策略。
反应物输入流量阶跃增加,输出为产物浓度。
三阶系统(s³项)反映多级混合/反应延迟。
stepplot([1],[1,3,3,1])
生态系统种群模型
预测种群是否稳定或震荡,指导生态干预。
突然引入食物资源(阶跃输入),输出为物种数量(如鱼类)。
低阻尼(0.5s项小)易引发振荡(数量暴涨后崩溃)。
stepplot([1],[1,0.5,0.1])
叠加阶跃响应图
stepplot([sys1],[sys2]...[sysN]) 是在同一坐标系中绘制多个系统对单位阶跃输入的响应曲线,用于直观比较不同系统的动态性能。
不同阻尼比的弹簧系统:
质量相同的弹簧系统,阻尼系数递增。
stepplot([1,s^2+0.5s+1], # ζ=0.25 (欠阻尼)
[1,s^2+s+1], # ζ=0.5 (最佳阻尼)
[1,s^2+2s+1]) # ζ=1.0 (临界阻尼)
电路滤波器性能对比
电子滤波器对电压阶跃的响应
stepplot([1,s+1], # 一阶低通
[s,s^2+s+1], # 带通
[1,0.1s^2+0.3s+1]) # 二阶快速响应
温度控制器增益对比
恒温箱加热系统(时间常数5秒)
stepplot([0.5,5s+1], # 低增益
[1,5s+1], # 中增益
[2,5s+1]) # 高增益
无人机高度控制器
stepplot([4,s^2+0.8s+4], # 标准
[6,s^2+1.2s+6], # 高刚度
[3,s^2+0.4s+3]) # 低阻尼
机械臂关节定位精度
stepplot([1,s^2+3s], # PD控制
[s+1,s^3+3s^2+2s], # PID控制
[0.5,s^2+2s+1]) # 简化模型
流线图
StreamPlot(expression)绘制一系列平滑的、永不交叉的曲线(即“流线”)来描绘二维向量场的图像。
1:流体力学 - 一个点源(水龙头滴下一滴水)
想象在原点有一个水龙头,水均匀地向四面八方流出去。
画图范围:x从-2到2,y从-2到2(注意避开原点x=0, y=0,因为那里分母为零)。
它像什么:所有流线都是从原点(源点)直接向外发射的直线。
StreamPlot(x/(x^2+y^2),y/(x^2+y^2),x=[-2,2],y=[-2,2])
2:流体力学 - 一个涡旋(水池排水时形成的漩涡)
想象原点是一个排水口,水在旋转着流下去。
画图范围:x从-2到2,y从-2到2(同样避开原点)。
它像什么:所有流线都是围绕原点旋转的圆圈,形成一个涡旋。
StreamPlot(x/(x^2+y^2),-y/(x^2+y^2),x=[-2,2],y=[-2,2])
3:电磁学 - 一个偶极子(一个正电荷和一个负电荷靠在一起)
就像一根磁铁或一个电荷对的磁场/电场。
画图范围:x从-2到2,y从-1到1。
它像什么:流线从正电荷(源)出发,弯曲地连接并终止于负电荷(汇)。
StreamPlot((x+0.5)/(((x+0.5)^2+y^2 )^1.5)-(x-0.5)/(((x-0.5)^2+y^2)^1.5),y/(((x+0.5)^2+y^2)^1.5)-y/(((x-0.5)^2+y^2)^1.5),x=[-2,2],y=[-1,1])
4:理论模型 - saddle点(鞍点)
这是一个非常基础但又重要的场结构,像一个山口。
画图范围:x从-2到2,y从-2到2。
它像什么:流线沿着x轴向外散开,沿着y轴向内收拢。原点(0,0)这个点就叫做saddle点(鞍点),它既不是源也不是汇,是不稳定点。
StreamPlot(x,-y,x=[-2,2],y=[-2,2])
5:最简单的函数 F(z) = z
表达式:F(z) = z = x + i*y
对应的向量场:( u, v ) = ( x, y )
流线图分析:
这是一个标准的源(Source)。
所有点的向量都从原点指向外。
离原点越远,向量长度(模)越大。
这类似于一个水龙头向平静的水面滴水形成的流场。
StreamPlot(z,z=[-2-2@i,2+2@i])
6:F(z) = i * z (乘以虚数单位 i)
表达式:F(z) = i * (x + i*y) = -y + i*x
对应的向量场:( u, v ) = ( -y, x )
流线图分析:
这是一个纯粹的涡旋(Vortex)。
所有流线都是围绕原点的同心圆。
向量方向永远垂直于该点与原点的连线。
这类似于水池排水时形成的漩涡。
StreamPlot(z*1@i,z=[-2-2@i,2+2@i])
7:F(z) = z^2
表达式:F(z) = (x + i*y)^2 = (x^2 - y^2) + i*(2*x*y)
对应的向量场:( u, v ) = ( x^2 - y^2, 2*x*y )
流线图分析:
这个场看起来会比前两个复杂。
沿着 x 轴 (y=0) 和 y 轴 (x=0) 看,场的方向很好判断。
你会看到两个“源”或“汇”挤压在一起形成的复杂图案,流线是双曲线形状。它在原点是一个鞍点(Saddle Point)。
StreamPlot(z^2,z=[-2-2@i,2+2@i])
8:F(z) = 1 / z
表达式:F(z) = 1 / (x + i*y) = (x - i*y) / (x^2 + y^2)
对应的向量场:( u, v ) = ( x / (x^2+y^2), -y / (x^2+y^2) )
流线图分析:
这是源和涡旋的叠加!
实部 x/(r^2) 代表一个源。
虚部 -y/(r^2) 代表一个涡旋。
最终的流线是从原点出发,同时向外且旋转的螺旋线。
这在物理上对应着一个偶极子(Dipole)的场,但带有旋转效应。原点 z=0 是奇点。
StreamPlot(1/z,z=[-2-2@i,2+2@i])
9:F(z) = exp(z) (指数函数)
表达式:利用欧拉公式 exp(x + i*y) = exp(x) * (cos(y) + i*sin(y))
对应的向量场:( u, v ) = ( exp(x)*cos(y), exp(x)*sin(y) )
流线图分析:
这个场在 y 方向是周期性的(因为包含 cos(y) 和 sin(y))。
沿着任意一条水平线 (y = constant),场的强度 |F| = exp(x) 随着 x 增大而指数增长。
流线图会呈现出周期性重复的、从左向右发散的图案。
StreamPlot(exp(z),z=[-2-2@i,2+2@i])
根据常见的子表达式重写符号表达式
[r,sigma] = subexpr(expr)根据公共子表达式重写符号表达式expr,用符号变量sigma替换该公共子表达式. 输入表达式expr不能包含变量sigma.
expr —— 包含常见子表达式的长表达式,符号表达,符号功能
r —— 用缩写替换普通子表达式的表达式,符号表达,符号功能
示例1:力学系统中的复杂表达式简化
mechanical_system = m*g*sin(theta) + (1/2)*m*v**2 + m*g*h*cos(theta)
力学系统表达式:
result = subexpr(mechanical_system)
print("替换规则:", result[0])
print("简化表达式:", result[1])
#替换规则: [(x0, g*m)]
#简化表达式: [h*x0*cos(theta) + m*v**2/2 + x0*sin(theta)]
示例2:复杂电路方程的简化
circuit_eq = V/(R1 + R2 + R3) + I*(R1*R2 + R2*R3 + R1*R3)/(R1 + R2 + R3)
电路方程:
result = subexpr(circuit_eq)
print("替换规则:", result[0])
print("简化表达式:", result[1])
#替换规则: [(x0, 1/(R1 + R2 + R3))]
#简化表达式: [V*x0 + I*x0*(R1*R2 + R1*R3 + R2*R3)]
示例3:控制系统传递函数的简化
control_system = [[K/(s*(s+a)), K*(s+b)/(s*(s+a))], [K*c/(s*(s+a)), K*d/(s*(s+a))]]
控制系统传递函数矩阵:
result = subexpr(control_system)
print("替换规则:", result[0])
print("简化表达式:", result[1])
#替换规则: [(x0, K/(s*(a + s)))]
#简化表达式:
#[[x0,x0*(b + s)],
[c*x0,d*x0]]
示例4:结构分析中的刚度矩阵
stiffness_matrix = [[E*A/L, -E*A/L, 0], [-E*A/L, 2*E*A/L, -E*A/L], [0, -E*A/L, E*A/L]]
结构刚度矩阵:
result = subexpr(stiffness_matrix)
print("替换规则:", result[0])
print("简化表达式:", result[1])
#替换规则: [(x0, E*A/L), (x1, -x0)]
#简化表达式:
#[[x0,x1,0],
[x1,2*x0,x1],
[0,x1,x0]]
示例5:热传导问题的系数矩阵
heat_transfer = [[k*A/dx, -k*A/dx, 0], [-k*A/dx, 2*k*A/dx, -k*A/dx], [0, -k*A/dx, k*A/dx]]
热传导系数矩阵:
result = subexpr(heat_transfer)
print("替换规则:", result[0])
print("简化表达式:", result[1])
#替换规则: [(x0, A*k/dx), (x1, -x0)]
#简化表达式:
#[[x0,x1,0],
[x1,2*x0,x1],
[0,x1,x0]]
示例6:机器人雅可比矩阵的简化
robot_kinematics = [[-l1*sin(theta1)-l2*sin(theta1+theta2), -l2*sin(theta1+theta2)], [l1*cos(theta1)+l2*cos(theta1+theta2), l2*cos(theta1+theta2)]]
机器人雅可比矩阵:
result = subexpr(robot_kinematics)
print("替换规则:", result[0])
print("简化表达式:", result[1])
#替换规则: [(x0, theta1 + theta2), (x1, l2*sin(x0)), (x2, l2*cos(x0))]
#简化表达式:
#[[-l1*sin(theta1)-x1,-x1],
[l1*cos(theta1)+x2,x2]]
示例7:量子力学中的波函数表达式
wave_function = A*exp(i*k*x - i*omega*t) + B*exp(-i*k*x - i*omega*t)
量子波函数:
result = subexpr(wave_function)
print("替换规则:", result[0])
print("简化表达式:", result[1])
#替换规则: [(x0, i*k*x), (x1, i*omega*t)]
#简化表达式: [A*exp(x0 - x1) + B*exp(-x0 - x1)]
示例8:复杂化学反应速率表达式
reaction_kinetics = k1*A*B/(1 + K_A*A + K_B*B) + k2*A*C/(1 + K_A*A + K_C*C)
化学反应动力学:
result = subexpr(reaction_kinetics)
print("替换规则:", result[0])
print("简化表达式:", result[1])
#替换规则: [(x0, A*K_A + 1)]
#简化表达式: [A*B*k1/(B*K_B + x0) + A*C*k2/(C*K_C + x0)]
示例9:电磁场中的势函数
electromagnetic = [[mu0*I/(4*pi*r), 0, 0], [0, mu0*I/(4*pi*r), 0], [0, 0, mu0*I/(4*pi*r)]]
电磁场势函数矩阵:
result = subexpr(electromagnetic)
print("替换规则:", result[0])
print("简化表达式:", result[1])
#替换规则: [(x0, I*mu0/(4*pi*r))]
#简化表达式:
#[[x0,0,0],
[0,x0,0],
[0,0,x0]]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def subexpression_common_elimination(input_str):
"""
对标 MATLAB 的 subexpr 函数,通过公共子表达式重写符号表达式
Args:
input_str: 可解析为矩阵或符号表达式的字符串
Returns:
成功时返回元组 (替换规则列表, 简化后的表达式)
失败时返回错误描述字符串
Examples:
>>> subexpression_common_elimination("[[x + y, (x + y)**2], [exp(x + y), 1/(x + y)]]")
([(x0, x + y)], Matrix([
[ x0, x0**2],
[exp(x0), 1/x0]]))
>>> subexpression_common_elimination("sin(a) + sqrt(a) + a**2")
([(x0, a)], sin(x0) + sqrt(x0) + x0**2)
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
if expr.free_symbols:
R, sigma = sp.cse(expr)
result = R, sigma
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误:{e}"
# 示例测试
if __name__ == "__main__":
# 矩阵测试用例
test_cases = [
"sin(a) + sqrt(a) + a^2",
# [sqrt(a) + a**2 + sin(a)]
]
for case in test_cases:
print(f"\n输入: {str(case)[:50]}...")
result = subexpression_common_elimination(str(case)) # 统一转换为字符串
if isinstance(result, tuple):
print("替换规则:", result[0])
print("简化表达式:", result[1])
else:
print("错误输出:", result)
两个子空间之间的角度
theta = subspace(A,B) 计算 A 和 B 的列指定的两个子空间之间的角度. 如果 A 和 B 是单位长度的列向量, 则此角度与 acos(abs(A'*B)) 相同
A, B —— 输入矩阵, 向量
示例1:x-y平面 vs z轴
xy_plane = [[1, 0], [0, 1], [0, 0]] # x-y平面
z_axis = [[0], [0], [1]] # z轴
test_case = (xy_plane, z_axis)
angle = subspace(test_case)
print(f"x-y平面与z轴夹角: {angle:.4f} 弧度 ({np.degrees(angle):.1f} 度)")
#x-y平面与z轴夹角: 1.5708 弧度 (90.0 度)
示例2:x轴 vs 对角线(应该45度)
x_axis = [[1], [0]] # x轴
diagonal = [[1], [1]] # 对角线
test_case = (x_axis, diagonal)
angle = subspace(test_case)
print(f"x轴与对角线夹角: {angle:.4f} 弧度 ({np.degrees(angle):.1f} 度)")
#x轴与对角线夹角: 0.7854 弧度 (45.0 度)
示例3:两个不同分布数据集的主成分
数据集1:沿x轴延伸的椭圆分布
pc_set1 = [[0.95, 0.1], [0.9, 0.2], [0.85, 0.15]]
数据集2:旋转45度的椭圆分布
pc_set2 = [[0.7, 0.7], [0.65, 0.75], [0.75, 0.65]]
test_case = (pc_set1, pc_set2)
angle = subspace(test_case)
print(f"不同分布数据集主成分夹角: {angle:.4f} 弧度 ({np.degrees(angle):.1f} 度)")
#不同分布数据集主成分夹角: 1.1799 弧度 (67.6 度)
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy.linalg import svd
def subspace_angle(A, B):
"""
计算两个子空间之间的最大主角度(单位:弧度)
参数:
A, B (np.ndarray): 数值矩阵,每一列代表子空间的基向量
返回:
float: 两个子空间之间的夹角(弧度制)
算法说明:
1. 对两个矩阵进行QR分解获得正交基
2. 计算正交基的乘积矩阵的奇异值
3. 最大主角度由最小奇异值的反余弦确定
"""
# 处理空矩阵情况
if A.size == 0 or B.size == 0:
raise ValueError("输入矩阵不能为空")
# 进行QR分解获得正交基(reduced模式)
Q_A, _ = np.linalg.qr(A, mode='reduced')
Q_B, _ = np.linalg.qr(B, mode='reduced')
# 计算正交基的乘积
C = np.dot(Q_A.T, Q_B)
# 计算奇异值(降序排列)
_, s, _ = svd(C)
# 处理数值误差:将大于1的值截断为1
s = np.clip(s, 0.0, 1.0)
# 最大主角度由最小奇异值确定
return np.arccos(s.min()) if s.size > 0 else np.pi / 2
def subspace_arch_matrix(input_str):
"""
计算两个矩阵列空间之间的最大主角度(对标MATLAB subspace函数)
参数:
input_str (str): 输入字符串,格式应为包含两个矩阵的元组
示例:'([[1,0], [0,1]], [[1,1], [1,1]])'
返回:
float: 子空间夹角(弧度)或错误信息字符串
"""
try:
# 将输入字符串转换为SymPy表达式
expr = sp.sympify(input_str)
# 验证输入格式是否为二元组
if not (isinstance(expr, tuple) and len(expr) == 2):
return f"输入格式错误:需要两个矩阵组成的元组,但收到 {input_str}"
# 转换矩阵
matrix_A = sp.Matrix(expr[0]) if isinstance(expr[0], list) else None
matrix_B = sp.Matrix(expr[1]) if isinstance(expr[1], list) else None
# 验证矩阵有效性
if matrix_A is None or matrix_B is None:
return "输入包含无效矩阵,请检查格式是否正确(例如:[[1,0],[0,1]])"
# 转换为数值矩阵
A = np.array(matrix_A.tolist(), dtype=float)
B = np.array(matrix_B.tolist(), dtype=float)
# 验证矩阵维度
if A.shape[0] != B.shape[0]:
return f"矩阵行数不匹配:矩阵A有{A.shape[0]}行,矩阵B有{B.shape[0]}行"
return subspace_angle(A, B)
except Exception as e:
return f"计算错误:{str(e)}"
# --------------------------
# 示范用例
# --------------------------
if __name__ == "__main__":
# 测试用例1:相同子空间
test_case1 = '([[1,0], [0,1]], [[1,0], [0,1]])'
print(f"测试用例1: {test_case1}")
angle = subspace_arch_matrix(test_case1)
print(f"结果: {angle:.4f} 弧度 ({np.degrees(angle):.1f} 度)\n")
# 0.0000 弧度 (0.0 度)
# 测试用例2:正交子空间
test_case2 = '([[1,0], [0,0]], [[0,0], [0,1]])' # A的列空间是x轴,B的列空间是y轴
print(f"测试用例2: {test_case2}")
angle = subspace_arch_matrix(test_case2)
print(f"结果: {angle:.4f} 弧度 ({np.degrees(angle):.1f} 度)\n")
# .0000 弧度 (0.0 度)
# 测试用例3:45度夹角
test_case3 = '([[1], [0]], [[1], [1]])' # A为x轴,B为y=x线
print(f"测试用例3: {test_case3}")
angle = subspace_arch_matrix(test_case3)
print(f"结果: {angle:.4f} 弧度 ({np.degrees(angle):.1f} 度)\n")
# 0.7854 弧度 (45.0 度)
# 测试用例4:三维空间中的斜交子空间
test_case4 = '([[1,0], [0,1], [0,0]], [[1,1], [1,1], [0,0]])' # 列空间平面与另一平面夹角
print(f"测试用例4: {test_case4}")
angle = subspace_arch_matrix(test_case4)
print(f"结果: {angle:.4f} 弧度 ({np.degrees(angle):.1f} 度)\n")
# 输出: 0.0000 弧度 (0.0 度)
三维曲面法向量
vect1, -vect1 = surfnorm(function,varlist,point) 计算并得到在特定点处的曲面的正负法向量,这些向量表示曲面在该点处的垂直方向,分别朝向曲面内外.
这些向量对于理解曲面的几何性质,绘制曲面的法线图以及进行物理模拟都非常有用.
function -- 曲面函数
varlist -- 曲面函数的变量
point -- 曲面上的特定坐标点
vect1, vect2 -- 向量.
示例1:球面法向量计算
sphere = (x**2 + y**2 + z**2 - 25, (x,y,z), (3,4,0))
result = surfnorm(sphere)
球面 x²+y²+z²=25 在点(3,4,0)的法向量:
print(f"正向: {result[0]}")
print(f"负向: {result[1]}")
#正向: [[0.6],
[0.8],
[0]]
#负向: [[-0.6],
[-0.8],
[0]]
#正向指向球外,负向指向球心
示例2:电势等势面的法向量
electric_potential = (1/sqrt(x**2 + y**2 + z**2), (x,y,z), (1,1,1))
result = surfnorm(electric_potential)
点电荷电势在(1,1,1)处的等势面法向量:
print(f"正向: {result[0]}")
print(f"负向: {result[1]}")
#正向: [[-0.577350269189626],
[-0.577350269189626],
[-0.577350269189626]]
#负向: [[0.577350269189626],
[0.577350269189626],
[0.577350269189626]]
#法向量指向电势变化最快的方向
示例3:机械零件表面法向量
mechanical_surface = (x**2/4 + y**2/9 + z - 5, (x,y,z), (2,3,1))
result = surfnorm(mechanical_surface)
椭圆柱面在(2,3,1)处的法向量:
print(f"正向: {result[0]}")
print(f"负向: {result[1]}")
#正向: [[0.639602149066831],
[0.426401432711221],
[0.639602149066831]]
#负向: [[-0.639602149066831],
[-0.426401432711221],
[-0.639602149066831]]
#用于表面加工或接触力分析
示例4:地形表面法向量(坡度分析)
terrain = (0.1*x**2 + 0.05*y**2 + 0.01*x*y, (x,y,z), (100,50,0))
result = surfnorm(terrain)
地形表面在(100,50)处的法向量:
print(f"正向: {result[0]}")
print(f"负向: {result[1]}")
#正向: [[0.959737407008271],
[0.280898753270713],
[0]]
#负向: [[-0.959737407008271],
[-0.280898753270713],
[0]]
#法向量的z分量反映坡度陡缓
示例5:透镜表面法向量
lens_surface = (sqrt(16 - (x**2 + y**2)/4), (x,y,z), (2,1,0))
result = surfnorm(lens_surface)
球面透镜在(2,1)处的法向量:
print(f"正向: {result[0]}")
print(f"负向: {result[1]}")
#正向: [[-0.894427190999916],
[-0.447213595499958],
[0]]
#负向: [[0.894427190999916],
[0.447213595499958],
[0]]
#用于光线折射计算
示例6:流线表面的法向量
stream_surface = (x*y + y*z + z*x - 10, (x,y,z), (1,2,2))
result = surfnorm(stream_surface)
流线表面在(1,2,2)处的法向量:
print(f"正向: {result[0]}")
print(f"负向: {result[1]}")
#正向: [[0.685994340570035],
[0.514495755427526],
[0.514495755427526]]
#负向: [[-0.685994340570035],
[-0.514495755427526],
[-0.514495755427526]]
#用于计算流体压力方向
示例7:曲面屋顶法向量
roof_surface = (sin(0.1*x) + cos(0.1*y) + 0.01*x*y, (x,y,z), (5,5,0))
result = surfnorm(roof_surface)
曲面屋顶在(5,5)处的法向量:
print(f"正向: {result[0]}")
print(f"负向: {result[1]}")
#正向: [[0.999888488660396],
[0.0149335275279728],
[0]]
#负向: [[-0.999888488660396],
[-0.0149335275279728],
[0]]
#用于雨水流向或雪荷载分析
示例8:器官表面法向量
organ_surface = (sqrt(1 - (x**2/9 + y**2/4)) + 0.1*z, (x,y,z), (1,1,0.5))
result = surfnorm(organ_surface)
椭球器官表面在(1,1,0.5)处的法向量:
print(f"正向: {result[0]}")
print(f"负向: {result[1]}")
#正向: [[-0.389840587792725],
[-0.877141322533632],
[0.280441467000467]]
#负向: [[0.389840587792725],
[0.877141322533632],
[-0.280441467000467]]
#用于手术路径规划或辐射治疗
示例9:晶体生长界面法向量
crystal_interface = (exp(-0.1*(x**2 + y**2)) + 0.5*z, (x,y,z), (1,0,0.5))
result = surfnorm(crystal_interface)
晶体生长界面在(1,0,0.5)处的法向量:
print(f"正向: {result[0]}")
print(f"负向: {result[1]}")
#正向: [[-0.340329685134558],
[0],
[0.940306176421389]]
#负向: [[0.340329685134558],
[0],
[-0.940306176421389]]
#用于分析生长方向或缺陷形成
示例10:障碍物表面法向量
obstacle_surface = (0.2*(x**2 + y**2) - z + 2, (x,y,z), (1,1,0))
result = surfnorm(obstacle_surface)
抛物面障碍物在(1,1,0)处的法向量:
print(f"正向: {result[0]}")
print(f"负向: {result[1]}")
#正向: [[0.348155311911396],
[0.348155311911396],
[-0.870388279778489]]
#负向: [[-0.348155311911396],
[-0.348155311911396],
[0.870388279778489]]
#用于机器人避障或接触检测
示例11:大气等压面法向量
isobaric_surface = (1000 - 0.1*x - 0.05*y**2 - 0.01*z, (x,y,z), (0,0,0))
result = surfnorm(isobaric_surface)
等压面在原点处的法向量:
print(f"正向: {result[0]}")
print(f"负向: {result[1]}")
#正向: [[-0.995037190209989],
[0],
[-0.0995037190209989]]
#负向: [[0.995037190209989],
[0],
[0.0995037190209989]]
#用于分析气压梯度力方向
示例12:船体表面法向量
hull_surface = (0.01*x**2 - 0.005*y**2 + 0.001*z**3, (x,y,z), (10,5,2))
result = surfnorm(hull_surface)
船体表面在(10,5,2)处的法向量:
print(f"正向: {result[0]}")
print(f"负向: {result[1]}")
#正向: [[0.968503129371836],
[-0.242125782342959],
[0.0581101877623102]]
#负向: [[-0.968503129371836],
[0.242125782342959],
[-0.0581101877623102]]
#用于流体阻力计算或结构分析
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def surface_normal_expression(input_str):
"""
计算三维曲面在指定点处的法向量表达式
参数:
input_str (str): 输入字符串,应为格式 ('函数', (变量1,变量2,变量3), (点坐标1,点坐标2,点坐标3)) 的合法 SymPy 表达式
示例: '(x**2 + y**2 + z**2, (x,y,z), (1,0,0))'
返回:
tuple: 包含正负两个法向量的元组,格式为 (正向单位法向量, 负向单位法向量)
或返回错误信息字符串
注意:
1. 法向量通过计算函数梯度后归一化得到
2. 梯度向量指向函数增长最快的方向,即曲面的正向法向量
3. 若输入格式错误或计算过程中出现异常,返回错误描述
"""
try:
# 将输入字符串转换为 SymPy 表达式
expr = sp.sympify(input_str)
error = False
result = None
# 检查是否为三元组结构 (函数, 变量元组, 点坐标元组)
if isinstance(expr, tuple) and len(expr) == 3:
# 解析表达式各部分
func = expr[0] # 曲面函数表达式
variables = expr[1] # 变量元组 (如 (x,y,z))
point_values = expr[2] # 求值点坐标元组 (如 (1,0,0))
# 创建变量到点值的映射字典
substitution_dict = {var: val for var, val in zip(variables, point_values)}
# 计算各变量的偏导数(梯度分量)
gradient_components = [sp.diff(func, var) for var in variables]
# 在指定点代入求值梯度向量
gradient_vector = sp.Matrix([comp.subs(substitution_dict) for comp in gradient_components])
# 计算梯度向量的模长
gradient_magnitude = gradient_vector.norm()
# 处理零梯度异常情况
if gradient_magnitude == 0:
return "错误:梯度为零向量,无法计算法向量"
# 计算单位法向量(正向)
unit_normal_vector = gradient_vector / gradient_magnitude
# 返回正负两个方向的法向量
result = (unit_normal_vector, -unit_normal_vector)
else:
error = True
return result if not error else f"输入格式错误: 需要 (函数, 变量元组, 点坐标元组) 格式,但收到 {input_str}"
except Exception as e:
return f"计算错误: {str(e)}"
# --------------------------
# 示范用例
# --------------------------
if __name__ == "__main__":
# 测试用例1:标准球面函数
test_case1 = '(x**2 + y**2 + z**2, (x,y,z), (1,0,0))'
print("测试用例1:", test_case1)
print("结果:", surface_normal_expression(test_case1))
# (Matrix([[1],
# [0],
# [0]]),
# Matrix([[-1],
# [ 0],
# [ 0]]))
# 测试用例2:平面函数
test_case2 = '(2*x + 3*y + 4*z, (x,y,z), (5,-2,1))'
print("\n测试用例2:", test_case2)
print("结果:", surface_normal_expression(test_case2))
# (Matrix([[2*sqrt(29)/29],
# [3*sqrt(29)/29],
# [4*sqrt(29)/29]]),
# Matrix([[-2*sqrt(29)/29],
# [-3*sqrt(29)/29],
# [-4*sqrt(29)/29]]))
# 测试用例3:变量与点值数量不匹配
test_case3 = '(x**2 + y**2, (x,y,z), (1,2))'
print("\n测试用例4:", test_case3)
print("结果:", surface_normal_expression(test_case3))
# (Matrix([[ sqrt(5)/5],
# [2*sqrt(5)/5],
# [ 0]]),
# Matrix([[ -sqrt(5)/5],
# [-2*sqrt(5)/5],
# [ 0]]))
奇异值分解
U, S, V = svd(A)
U - 左奇异向量组成的矩阵
S - 奇异值组成的对角矩阵
V - 右奇异向量组成的矩阵
A - 输入, 矩阵.
示例1:信号数据去噪
含噪声的信号观测矩阵
signal_data = [[1.02, 2.1, 3.05], [0.98, 2.01, 2.95], [1.05, 1.98, 3.1], [0.95, 2.05, 2.9]]
result = svd(signal_data)
U, S, V = result
print("奇异值分布:", [S[i, i] for i in range(min(S.shape))])
#奇异值分布: [0.00856077629230673, 0, 0, 0, 0.132994518977337, 0, 0, 0, 7.52236925250491]
#小奇异值通常对应噪声,可通过截断去除
示例2:资产收益率相关性分析
不同资产的收益率协方差矩阵
covariance_matrix = [[0.04, 0.02, 0.01], [0.02, 0.09, 0.03], [0.01, 0.03, 0.16]]
result = svd(covariance_matrix)
U, S, V = result
print("风险主成分的方差贡献:", [S[i, i] for i in range(min(S.shape))])
#风险主成分的方差贡献: [0.0329821889430751, 0, 0, 0, 0.0838821332259716, 0, 0, 0, 0.173135677830953]
#奇异值分解揭示风险因子的重要性
示例3:动态系统模型降阶
系统传递函数矩阵(频域数据)
transfer_function = [[1+2@i, 0.5+1@i], [0.3+0.8@i, 1.5+3@i], [0.7+1.5@i, 1.2+2.5@i]]
result = svd(transfer_function)
U, S, V = result
print("系统的Hankel奇异值:", [S[i, i] for i in range(min(S.shape))])
#系统的Hankel奇异值: [1.66910862346536 + 0.e-65*I, 0, 0, 5.08665670190879 - 0.e-66*I]
#小奇异值对应的状态可以截断,实现模型降阶
示例4:矩阵条件数分析
病态矩阵示例
ill_conditioned = [[1, 2], [1, 2.0001]]
result = svd(ill_conditioned)
U, S, V = result
singular_values = [S[i, i] for i in range(min(S.shape))]
condition_number = max(singular_values) / min(singular_values)
print("奇异值:", singular_values)
print("条件数:", condition_number)
#奇异值: [3.16221467673969e-5, 0, 0, 3.16234090651214]
#条件数: zoo
#大条件数表示矩阵接近奇异,数值不稳定
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy.linalg import svd as scipy_svd
def singular_values_matrix(input_str):
"""
执行完整的奇异值分解,对标MATLAB的svd函数
参数:
input_str: 字符串形式的矩阵输入
返回:
当输入为数值矩阵时:
U: 左奇异向量矩阵 (m x m)
S: 奇异值对角矩阵 (m x n)
V: 右奇异向量矩阵 (n x n)
当输入包含符号时返回符号解
错误时返回字符串提示
"""
try:
# 符号解析输入
expr = sp.sympify(input_str)
# 输入有效性验证
if isinstance(expr, tuple):
return "错误:不接受元组输入,请输入单个矩阵"
A = sp.Matrix(expr) if isinstance(expr, list) else None
if A is None:
return "错误:输入不是有效矩阵"
# 符号矩阵的特殊处理
try:
# 尝试符号计算SVD
U, S, V = A.singular_value_decomposition()
return (U.evalf(), sp.diag(*S).evalf(), V.evalf())
except NotImplementedError:
# 符号方法失败时转数值计算
np_A = np.array(A, dtype=float)
U_np, S_np, Vt_np = scipy_svd(np_A, full_matrices=True)
return (sp.Matrix(U_np).evalf(),
sp.Matrix(np.diag(S_np)).evalf(),
sp.Matrix(Vt_np.T).evalf())
except Exception as e:
return f"分解错误: {str(e)}"
# 示范代码
if __name__ == "__main__":
# 示例1:标准数值矩阵
case1 = "[[1, 2], [3, 4], [5, 6]]"
print("案例1 (3x2数值矩阵):")
result1 = singular_values_matrix(case1)
if isinstance(result1, tuple):
print("U:\n", result1[0])
# Matrix([[0.883461017698525, 0.229847696400071],
# [0.240782492132547, 0.524744818760294],
# [-0.401896033433432, 0.819641941120516]])
print("S:\n", result1[1])
# Matrix([[0.514300580658644, 0, 0, 0],
# [0, 0, 0, 0],
# [0, 0, 0, 0],
# [0, 0, 0, 9.52551809156511]])
print("V:\n", result1[2])
# Matrix([[-0.784894453267052, 0.619629483829340],
# [0.619629483829340, 0.784894453267052]])
else:
print(result1)
# 示例2:符号矩阵测试
case2 = "[[x, 0], [0, y]]"
print("\n案例2 (符号矩阵):")
print(singular_values_matrix(case2))
# (Matrix([[x/(x*conjugate(x))**0.5, 0],
# [ 0, y/(y*conjugate(y))**0.5]]),
# Matrix([[(x*conjugate(x))**0.5, 0, 0, 0],
# [ 0, 0, 0, 0],
# [ 0, 0, 0, 0],
# [ 0, 0, 0, (y*conjugate(y))**0.5]]),
# Matrix([[1.0, 0],
# [ 0, 1.0]]))
添加数据后修改SVD
[U1,S1,V1] = svdappend(U,S,V,D),其中A=U*S*V'是一个现有的奇异值分解(SVD),计算[A D]的SVD,而不显式形成A或[A D].结果相等,四舍五入误差
U,S,V —— 现有SVD因素,矩阵
D —— 要追加的新列或行,向量,矩阵
示例1:工业传感器监控
初始传感器读数矩阵的SVD
U_sensor = [[0.9, 0.05], [0.8, 0.1], [0.7, 0.15], [0.6, 0.2]]
S_sensor = [[10.0, 0], [0, 3.0]]
V_sensor = [[0.95, 0.1], [0.2, 0.8]]
新的时间步传感器读数
new_sensor_data = [[12.5], [11.8], [10.9], [9.7]]
result = svdappend(U_sensor, S_sensor, V_sensor, new_sensor_data)
U_new, S_new, V_new = result
传感器模式更新完成
print("新的主成分能量分布:", [S_new[i, i] for i in range(min(S_new.shape))])
#新的主成分能量分布: [46.7065747316725, 6.64793641442384, 2.94787521182036]
#应用:实时检测设备异常或性能变化
示例2:多轮增量更新演示
初始状态
U = [[1, 0], [0, 1]]
S = [[3, 0], [0, 2]]
V = [[0.8, 0.2], [0.6, 0.4]]
print("初始奇异值:", [S[0][0], S[1][1]])
#初始奇异值: [3, 2]
第一轮更新
new_data1 = [[0.5], [0.8]]
result1 = svdappend(U, S, V, new_data1)
U1, S1, V1 = result1
print("第一轮更新后奇异值:", [S1[0, 0], S1[1, 1], S1[2, 2] if S1.shape[0] > 2 else "N/A"])
#第一轮更新后奇异值: [3.04703950115888, 2.14605458420270, 0]
第二轮更新
new_data2 = [[0.3], [0.9]]
result2 = svdappend(U1, S1, V1, new_data2)
U2, S2, V2 = result2
print("第二轮更新后奇异值:", [S2[i, i] for i in range(min(S2.shape))])
#第二轮更新后奇异值: [3.07506272652620, 2.31564103945675, 0.389609810339622, 0]
#演示了连续增量学习的能力
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy.linalg import svd
def singular_values_append(input_str):
"""
在追加新数据列后更新SVD分解,对标MATLAB的svdappend功能。
参数:
input_str: 字符串形式的元组,包含四个元素:(U, S, V, D),其中:
- U: 原左奇异向量矩阵
- S: 原奇异值对角矩阵
- V: 原右奇异向量矩阵
- D: 要追加的新数据列(必须与原矩阵列数相同)
返回:
更新后的U_new, S_new, V_new(SymPy矩阵)或错误信息。
"""
try:
expr = sp.sympify(input_str)
error_msg = None
# 输入格式验证
if not isinstance(expr, tuple) or len(expr) != 4:
error_msg = "输入必须为四元组 (U, S, V, D)"
else:
U, S, V, D = expr
U = sp.Matrix(U) if isinstance(U, list) else None
S = sp.Matrix(S) if isinstance(S, list) else None
V = sp.Matrix(V) if isinstance(V, list) else None
D = sp.Matrix(D) if isinstance(D, list) else None
if None in (U, S, V, D):
error_msg = "无效的矩阵输入"
else:
# 转换为NumPy数组进行数值计算
U_np = np.array(U, dtype=float)
S_np = np.array(S, dtype=float)
D_np = np.array(D, dtype=float)
V_np = np.array(V, dtype=float)
# 验证维度一致性
m, k = U_np.shape
s_dim = S_np.shape
if s_dim[0] != s_dim[1] or s_dim[0] != k:
error_msg = "S必须是方阵且与U的列数一致"
elif D_np.shape[0] != m:
error_msg = "D的行数必须与U的行数一致"
elif V_np.shape[1] != k:
error_msg = "V的列数必须与U的列数一致"
if error_msg:
return error_msg
# 增量SVD核心算法
# 步骤1:计算新列在现有列空间的投影
proj = U_np.T @ D_np
# 步骤2:计算正交补分量
D_ortho = D_np - U_np @ proj
# 步骤3:对正交分量进行QR分解
Q, R = np.linalg.qr(D_ortho, mode='reduced')
# 步骤4:构造中间矩阵
K = np.block([[S_np, proj],
[np.zeros((R.shape[0], S_np.shape[1])), R]])
# 步骤5:计算中间矩阵的SVD
Uk, Sk, Vkt = svd(K, full_matrices=False)
# 步骤6:构造新的U和S
U_new = np.hstack((U_np, Q)) @ Uk
S_new = np.diag(Sk)
# 步骤7:构造新的V
V_ext = np.eye(V_np.shape[0] + 1) # 扩展单位矩阵
V_ext[:V_np.shape[0], :V_np.shape[1]] = V_np
V_new = V_ext @ Vkt.T
# 转换回SymPy矩阵并格式化
return (
sp.Matrix(U_new).evalf(chop=True),
sp.Matrix(S_new).evalf(chop=True),
sp.Matrix(V_new).evalf(chop=True)
)
except Exception as e:
return f"错误: {str(e)}"
# 示范代码
if __name__ == "__main__":
# 示例1:有效输入
U = [[1, 0], [0, 1], [0, 0]]
S = [[5, 0], [0, 3]]
V = [[1, 0], [0, 1]]
D = [[2], [3], [4]]
input_str = f"({U}, {S}, {V}, {D})"
result = singular_values_append(input_str)
print("示例1结果:")
if isinstance(result, tuple):
print("U_new:\n", result[0])
# Matrix([[0.707608901615485, 0.700874167360754, 0.0898055893633361],
# [0.493471643807718, -0.581132003549788, 0.647125436996504],
# [0.505742403909574, -0.413595207874290, -0.757075706195349]])
print("S_new:\n", result[1])
# Matrix([[6.23714970083448, 0, 0],
# [0, 4.39365160364841, 0],
# [0, 0, 2.18947235541766]])
print("V_new:\n", result[2])
# Matrix([[0.567253421479376, 0.797598706709882, 0.205085004021905],
# [0.237354401037559, -0.396798874358104, 0.886686834015394],
# [0.788597770810977, -0.454298312084543, -0.414399082418255]])
else:
print(result)
奇异值和向量的子集
s = svds(A) 返回一个向量,其中包含矩阵A的六个最大的奇异值.当使用svd计算所有奇异值的计算量很大时(例如对于大型稀疏矩阵而言),可以使用此函数
s = svds(A,k) 返回k个最大奇异值
A — 输入, 矩阵
k — 要计算的奇异值个数,标量
示例1:高维数据的主成分提取
模拟高维数据(1000个样本,500个特征),只计算前10个主成分
high_dim_data = (([[1.2, 0.8, 1.5] + [0.0]*497,
[0.9, 1.1, 0.7] + [0.0]*497,
[1.3, 0.6, 1.4] + [0.0]*497,
[0.8, 1.2, 0.9] + [0.0]*497]), 10) # 只计算前10个奇异值
result = svds(high_dim_data)
print(f"前10个奇异值: {[float(result[i]) for i in range(min(10, result.shape[0]))]}")
#前10个奇异值: [3.6170813170748852, 0.7870234814969508, 0.19317552961031642]
#应用:大数据降维,避免计算全部奇异值的高成本
示例2:大型用户-物品矩阵的潜在因子发现
用户-物品评分矩阵,只提取前5个最重要的潜在因子
user_item_matrix = (([[5, 3, 0, 1, 4, 0, 2],
[4, 0, 0, 1, 1, 0, 5],
[1, 1, 0, 5, 4, 0, 3],
[1, 0, 0, 4, 5, 0, 2],
[0, 1, 5, 4, 0, 0, 1]]), 5) # 提取5个主要特征
result = svds(user_item_matrix)
print("主要潜在因子的强度:", [float(result[i]) for i in range(result.shape[0])])
#主要潜在因子的强度: [12.604114694948436, 6.562553934663047, 4.805874566574619, 3.5648787629469787]
#应用:识别用户和物品的主要特征维度
示例3:图像低秩近似的质量评估
图像块矩阵,计算前k个奇异值来评估压缩潜力
image_block = (([[180, 182, 179, 181],
[181, 183, 180, 182],
[179, 181, 178, 180],
[182, 184, 181, 183]]), 2) # 评估使用前2个奇异值的近似质量
result = svds(image_block)
total_energy = sum(float(result[i]) ** 2 for i in range(result.shape[0]))
print(f"前2个奇异值捕获的能量比例: {total_energy:.3f}")
#前2个奇异值捕获的能量比例: 524216.000
#应用:确定图像压缩的最佳秩
示例4:大型网络图的社区检测
图的邻接矩阵,计算前几个奇异值进行谱聚类
adjacency_matrix = (([[0, 1, 1, 0, 0, 0],
[1, 0, 1, 1, 0, 0],
[1, 1, 0, 1, 1, 0],
[0, 1, 1, 0, 1, 1],
[0, 0, 1, 1, 0, 1],
[0, 0, 0, 1, 1, 0]]), 3) # 计算前3个奇异值用于社区发现
result = svds(adjacency_matrix)
print("图的谱特征:", [float(result[i]) for i in range(result.shape[0])])
#图的谱特征: [3.1819433360523934, 1.801937735804838, 1.588363990685104]
#应用:识别网络中的社区结构
示例5:大型文档-词项矩阵的主题分析
文档-词项矩阵(TF-IDF权重),提取主要主题
doc_term_matrix = (([[0.8, 0.2, 0.1, 0.0, 0.3],
[0.1, 0.7, 0.4, 0.2, 0.1],
[0.3, 0.1, 0.6, 0.5, 0.2],
[0.2, 0.3, 0.2, 0.8, 0.1],
[0.4, 0.2, 0.3, 0.1, 0.7]]), 3) # 提取3个主要主题
result = svds(doc_term_matrix)
print("文档主题强度:", [float(result[i]) for i in range(result.shape[0])])
#文档主题强度: [1.589362341845165, 0.8478708222421064, 0.5566151139343753]
#应用:发现文档集合中的潜在主题
示例6:资产收益率协方差矩阵的风险因子分析
资产收益率协方差矩阵,识别主要风险因子
covariance_matrix = (([[0.04, 0.02, 0.01, 0.015, 0.018],
[0.02, 0.09, 0.03, 0.025, 0.022],
[0.01, 0.03, 0.16, 0.012, 0.028],
[0.015, 0.025, 0.012, 0.25, 0.035],
[0.018, 0.022, 0.028, 0.035, 0.36]]), 2) # 识别2个主要风险因子
result = svds(covariance_matrix)
total_variance = sum(float(result[i]) for i in range(result.shape[0]))
print(f"前2个风险因子解释的方差: {total_variance:.3f}")
#前2个风险因子解释的方差: 0.623
#应用:投资组合风险管理和因子投资
示例7:多传感器系统的异常模式检测
多传感器时间序列数据,检测异常模式
sensor_data = (([[12.5, 13.1, 12.8, 12.9, 13.2],
[45.2, 46.1, 45.8, 45.5, 46.3],
[23.1, 23.5, 23.2, 23.8, 23.4],
[78.9, 79.5, 78.7, 79.2, 79.8],
[56.7, 57.2, 56.9, 57.5, 57.1]]), 4) # 计算前4个奇异值
result = svds(sensor_data)
print("传感器数据的主要模式强度:", [float(result[i]) for i in range(result.shape[0])])
#传感器数据的主要模式强度: [248.43529153414653, 0.8053532262125372, 0.5191580844899423, 0.31259601886512767]
#应用:工业设备健康监测和故障预警
示例8:大规模基因表达数据的共表达模块识别
基因在不同条件下的表达矩阵,发现共表达模块
gene_expression = (([[8.2, 7.5, 1.2, 0.8, 8.5, 7.8],
[6.7, 7.1, 1.5, 1.1, 6.9, 7.3],
[1.3, 0.9, 7.8, 8.4, 1.5, 1.0],
[1.1, 1.4, 6.9, 7.3, 1.2, 1.6],
[7.9, 8.3, 0.9, 1.3, 8.1, 8.5],
[0.8, 1.2, 8.1, 8.7, 1.0, 1.4]]), 3)" # 识别3个主要表达模块
result = svds(gene_expression)
print("基因表达模块的显著程度:", [float(result[i]) for i in range(result.shape[0])])
#基因表达模块的显著程度: [28.204719756481577, 18.014677360790117, 1.1368811580512381]
#应用:生物标志物发现和功能基因组学
示例9:自动确定重要奇异值数量
不指定k,让函数自动选择合适数量的奇异值
auto_k_matrix = [[1.0, 0.5, 0.3, 0.2],
[0.5, 1.0, 0.4, 0.1],
[0.3, 0.4, 1.0, 0.6],
[0.2, 0.1, 0.6, 1.0]]
result = svds(auto_k_matrix)
print(f"自动选择的奇异值数量: {result.shape[0]}")
print("奇异值:", [float(result[i]) for i in range(result.shape[0])])
#自动选择的奇异值数量: 3
#奇异值: [2.0635058859675457, 1.0797941357215766, 0.5488088132814815]
#应用:数据探索性分析,无需预先指定维度
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy.sparse import linalg as sparse_linalg
def singular_values_subset(input_str):
"""
计算矩阵的奇异值子集,对标MATLAB的svds函数。
参数:
input_str: 输入的矩阵或元组(矩阵和奇异值数量k)的字符串表示。
返回:
如果输入有效,返回奇异值的SymPy矩阵(按降序排列);否则返回错误信息。
"""
try:
expr = sp.sympify(input_str)
error = False
U, S, Vt = None, None, None
# 处理元组输入(矩阵和k)
if isinstance(expr, tuple) and len(expr) == 2:
A_expr, k_expr = expr[0], expr[1]
A = sp.Matrix(A_expr) if isinstance(A_expr, list) else None
if A is not None and k_expr.is_integer:
k = int(k_expr)
N_A = np.array(A, dtype=float)
m, n = N_A.shape
max_k = min(m, n) - 1
if max_k <= 0:
max_k = 1
k = min(k, max_k)
U, S, Vt = sparse_linalg.svds(N_A, k)
else:
error = True
# 处理单个矩阵输入,自动确定k
else:
A = sp.Matrix(expr) if isinstance(expr, list) else None
if A is not None:
N_A = np.array(A, dtype=float)
m, n = N_A.shape
max_k = min(m, n) - 1
if max_k <= 0:
max_k = 1
k = min(6, max_k)
U, S, Vt = sparse_linalg.svds(N_A, k)
else:
error = True
if error:
return f"输入错误: {input_str}"
else:
# 将奇异值按降序排列
S_sorted = np.sort(S)[::-1]
return sp.Matrix(S_sorted).evalf()
except Exception as e:
return f"错误: {e}"
# 示范代码
if __name__ == "__main__":
# 示例1:输入矩阵和k值
input1 = "(([[1, 2], [3, 4], [5, 6]]), 1)"
result1 = singular_values_subset(input1)
print(f"示例1结果:\n{result1}")
# Matrix([[9.52551809156511]])
# 示例2:输入矩阵,自动确定k
input2 = "[[1, 2], [3, 4]]"
result2 = singular_values_subset(input2)
print(f"示例2结果:\n{result2}")
# Matrix([[5.46498570421904]
计算低秩矩阵草图的SVD
[U,S,V] = svdsketch(A) 返回输入矩阵A的低秩矩阵草图的奇异值分解(SVD).
[U,S,V] = svdsketch(A,tol) 指定矩阵草图的容差。svdsketch 使用 tol 以自适应方式确定矩阵草图逼近的秩。随着容差变大,矩阵草图中使用的 A 的特征越来越少。
矩阵草图是一种低秩逼近,仅反映A的最重要特征(最大容差). 与使用svds相比,它能够更快地计算大型矩阵的部分SVD.
A — 输入, 矩阵, 指定为稀疏矩阵或满矩阵。A 通常为大型稀疏矩阵,但不总是这样。svdsketch 最适合对特征数量相对较少的秩亏矩阵进行操作。
tol — 矩阵草图容差, eps(class(A))^(1/4) (默认) | 实数标量
示例1. 大规模图像数据压缩
模拟大型图像数据矩阵(1000×1000像素,但实际用小型示例演示)
image_data = [[180, 182, 179, 181, 183],
[181, 183, 180, 182, 184],
[179, 181, 178, 180, 182],
[182, 184, 181, 183, 185],
[180, 182, 179, 181, 183]]
使用容差控制压缩质量
result = svdsketch(image_data, 1e-2, 3)
U, S, V, rank = result
原始矩阵大小: 5×5 = 25 元素
print(
f"压缩后表示: U({U.shape}) + S({S.shape}) + V({V.shape}) = {U.shape[0] * U.shape[1] + S.shape[0] * S.shape[1] + V.shape[0] * V.shape[1]} 元素")
print(f"压缩比: {25 / (U.shape[0] * U.shape[1] + S.shape[0] * S.shape[1] + V.shape[0] * V.shape[1]):.2f}x")
print(f"实际使用秩: {rank}")
#压缩后表示: U((5, 1)) + S((1, 1)) + V((5, 1)) = 11 元素
#压缩比: 2.27x
#实际使用秩: 1
示例2. 推荐系统的快速矩阵补全
稀疏的用户-物品评分矩阵(0表示缺失评分)
sparse_ratings = [[5, 3, 0, 0, 4],
[4, 0, 0, 1, 1],
[1, 1, 0, 5, 0],
[0, 0, 4, 0, 0],
[0, 1, 5, 4, 0]]
使用低秩近似填充缺失值
result = svdsketch(sparse_ratings, 0.1, 2)
U, S, V, rank = result
reconstructed = U * S * V.T
print(f"低秩近似秩: {rank}")
#低秩近似秩: 2
重构矩阵(可用于预测缺失评分):
print(reconstructed)
#[[5.47, 2.31, -0.678, 0.773, 3.40],
[2.97, 1.32, 0.0242, 0.802, 1.82],
[1.26, 0.962, 2.36, 2.63, 0.612],
[-0.365, 0.191, 2.07, 1.92, -0.364],
[0.106, 0.823, 4.55, 4.47, -0.246]]
示例3. 高维数据的快速降维
高维特征矩阵(样本×特征)
high_dim_data = [[1.2, 0.8, 1.5, 2.1, 0.9, 1.8],
[0.9, 1.1, 0.7, 1.9, 1.3, 1.6],
[1.3, 0.6, 1.4, 2.2, 1.0, 1.9],
[0.8, 1.2, 0.9, 1.8, 1.1, 1.7],
[1.1, 0.9, 1.3, 2.0, 0.8, 1.5]]
快速降维到2维
result = svdsketch(high_dim_data, 1e-3, 2)
U, S, V, rank = result
low_dim_representation = U * S # 降维后的数据表示
print(f"从 {high_dim_data.count('[') - 1} 维降到 {rank} 维")
#从 5 维降到 2 维
降维后的数据表示:
print(low_dim_representation)
#[[3.56, -0.345],
[3.16, 0.574],
[3.64, -0.386],
[3.16, 0.463],
[3.24, -0.200]]
示例4. 实时传感器数据流处理
多传感器时间序列数据
sensor_stream = [[12.5, 13.1, 12.8, 12.9, 13.2],
[45.2, 46.1, 45.8, 45.5, 46.3],
[23.1, 23.5, 23.2, 23.8, 23.4],
[78.9, 79.5, 78.7, 79.2, 79.8],
[56.7, 57.2, 56.9, 57.5, 57.1]]
快速提取主要模式,用于实时监控
result = svdsketch(sensor_stream, 0.05, 3)
U, S, V, rank = result
print(f"传感器数据的主要模式数量: {rank}")
print("主要模式强度:", [float(S[i, i]) for i in range(min(3, S.shape[0]))])
#传感器数据的主要模式数量: 1
#主要模式强度: [248.43529153414661]
示例5. 社交网络关系分析
用户-用户连接关系矩阵
social_network = [[0, 1, 1, 0, 0, 0],
[1, 0, 1, 1, 0, 0],
[1, 1, 0, 1, 1, 0],
[0, 1, 1, 0, 1, 1],
[0, 0, 1, 1, 0, 1],
[0, 0, 0, 1, 1, 0]]
发现社区结构
result = svdsketch(social_network, 0.1, 2)
U, S, V, rank = result
print(f"网络社区数量估计: {rank}")
#网络社区数量估计: 2
U矩阵可以用于社区检测
社区成员强度:
print(U)
#[[0.286, 0.418],
[0.406, -0.232],
[0.503, -0.521],
[0.503, 0.521],
[0.406, 0.232],
[0.286, -0.418]]
示例6. 文本语义空间构建
文档-词项矩阵(TF-IDF权重)
document_term = [[0.8, 0.2, 0.1, 0.0, 0.3, 0.1],
[0.1, 0.7, 0.4, 0.2, 0.1, 0.2],
[0.3, 0.1, 0.6, 0.5, 0.2, 0.4],
[0.2, 0.3, 0.2, 0.8, 0.1, 0.3],
[0.4, 0.2, 0.3, 0.1, 0.7, 0.2]]
构建低维语义空间
result = svdsketch(document_term, 1e-4, 3)
U, S, V, rank = result
print(f"语义空间维度: {rank}")
#语义空间维度: 3
文档在语义空间中的坐标:
semantic_coords = U * S
print(semantic_coords)
#[[0.630, 0.557, -0.0348],
[0.683, -0.201, 0.492],
[0.872, -0.197, -0.201],
[0.793, -0.437, -0.177],
[0.761, 0.399, 0.00274]]
示例7. 金融风险因子提取
资产收益率协方差矩阵
covariance_matrix = [[0.04, 0.02, 0.01, 0.015, 0.018],
[0.02, 0.09, 0.03, 0.025, 0.022],
[0.01, 0.03, 0.16, 0.012, 0.028],
[0.015, 0.025, 0.012, 0.25, 0.035],
[0.018, 0.022, 0.028, 0.035, 0.36]]
提取主要风险因子
result = svdsketch(covariance_matrix, 1e-3, 2)
U, S, V, rank = result
total_variance = sum(S[i, i] ** 2 for i in range(S.shape[0]))
print(f"主要风险因子数量: {rank}")
print(f"前{rank}个因子解释的方差比例: {total_variance:.3f}")
#主要风险因子数量: 2
#前2个因子解释的方差比例: 0.203
示例8. 基因表达模式发现
基因在不同条件下的表达矩阵
gene_expression = [[8.2, 7.5, 1.2, 0.8, 8.5, 7.8],
[6.7, 7.1, 1.5, 1.1, 6.9, 7.3],
[1.3, 0.9, 7.8, 8.4, 1.5, 1.0],
[1.1, 1.4, 6.9, 7.3, 1.2, 1.6],
[7.9, 8.3, 0.9, 1.3, 8.1, 8.5],
[0.8, 1.2, 8.1, 8.7, 1.0, 1.4]]
发现共表达基因模块
result = svdsketch(gene_expression, 0.01, 3)
U, S, V, rank = result
print(f"发现的表达模式数量: {rank}")
print("各模式的显著程度:", [float(S[i, i]) for i in range(min(3, S.shape[0]))])
#发现的表达模式数量: 3
#各模式的显著程度: [28.204719756481577, 18.014677360790113, 1.136881158051239]
示例9. 视频背景建模
视频帧序列(每列是一帧展平后的像素)
video_frames = [[180, 181, 179, 182, 180, 181],
[182, 183, 181, 184, 182, 183],
[179, 180, 178, 181, 179, 180],
[181, 182, 180, 183, 181, 182],
[183, 184, 182, 185, 183, 184]]
分离背景(低秩)和前景(稀疏)
result = svdsketch(video_frames, 0.05, 1)
U, S, V, rank = result
background = U * S * V.T # 低秩背景模型
print(f"背景模型秩: {rank}")
print("背景成分强度:", float(S[0, 0]))
#背景模型秩: 1
#背景成分强度: 994.1604489872644
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from sklearn.utils.extmath import randomized_svd
def sklearn_randomized_svd(input_str):
"""
对标MATLAB的svdsketch函数,计算低秩矩阵近似SVD
参数:
A: 输入矩阵,支持SymPy矩阵/列表/NumPy数组
tol: 近似容差 (默认1e-10)
max_rank: 最大允许秩 (可选)
random_state: 随机种子 (可选)
返回:
U: 左奇异向量矩阵
S: 奇异值对角矩阵
V: 右奇异向量矩阵
rank: 实际使用的秩
示例:
>>> A = np.random.rand(100, 50)
>>> U, S, V, r = svdsketch(A, tol=1e-5)
"""
try:
# 定义容差,用于后续判断奇异值的截断条件
tol = 1e-10
# 最大秩,初始设为 None,后续会根据矩阵情况确定
max_rank = None
# 随机状态,用于随机化过程的可重复性,初始设为 None
random_state = None
# 错误标志,用于标记是否出现错误情况
error = False
# 将输入字符串转换为 SymPy 表达式
expr = sp.sympify(input_str)
# 检查 expr 是否为元组
if isinstance(expr, tuple):
# 如果元组长度为 4,分别将元素赋值给 A, tol, max_rank, random_state
if len(expr) == 4:
A, tol, max_rank, random_state = expr
# 如果元组长度为 3,分别将元素赋值给 A, tol, max_rank
elif len(expr) == 3:
A, tol, max_rank = expr
# 如果元组长度为 2,分别将元素赋值给 A, tol
elif len(expr) == 2:
A, tol = expr
# 若元组长度不符合上述情况,标记错误
else:
error = True
# 若 expr 不是元组,直接将其赋值给 A
else:
A = expr
# 检查 A 是否为有效的矩阵,如果不是则返回 None
sp_A = sp.Matrix(A) if isinstance(A, list) else None
if sp_A is None:
raise ValueError("无效的矩阵输入")
elif sp_A.is_symbolic():
raise ValueError("需要数值矩阵输入")
else:
np_A = np.array(sp_A, dtype=float)
# 矩阵维度检查
if np_A.ndim != 2:
raise ValueError("输入必须是二维矩阵")
# 自动确定目标秩
m, n = np_A.shape
if max_rank is None:
max_rank = min(m, n) - 1
# 使用自适应随机SVD
rank = min(max_rank, min(m, n))
U, S, Vt = randomized_svd(np_A, n_components=rank,
random_state=random_state)
# 根据容差调整实际秩
sigma_norm = np.linalg.norm(S) # 奇异值的F范数
if sigma_norm > 0:
cumulative = np.cumsum(S[::-1] ** 2)[::-1] # 降序累积平方和
for k in range(len(cumulative)):
if np.sqrt(cumulative[k]) <= tol * sigma_norm:
rank = k
break
rank = max(1, min(rank, max_rank))
# 截断到实际秩
U = U[:, :rank]
S = S[:rank]
Vt = Vt[:rank, :]
if not error:
return U, np.diag(S), Vt.T, rank
except Exception as e:
print(f"计算错误: {e}")
return None, None, None, 0
# 示例代码
if __name__ == "__main__":
# 示例3:数值矩阵测试
try:
C = "[[2, 0], [0, 1]]"
print(sklearn_randomized_svd(C))
# (array([[ 1.00000000e+00],
# [-2.16840434e-19]]),
# array([[2.]]),
# array([[1.],
# [0.]]),
# 1)
except Exception as e:
print(f"示例3 错误捕获: {e}")
求解关于X的西尔维斯特方程AX+XB=C
X=sylvester(A,B,C)将解X返回到sylvester方程.
输入A是一个m乘m矩阵,输入B是一个n乘n矩阵,C和X都是m乘n矩阵.
A,B,C — 输入矩阵
示例1. 控制系统设计 - 李雅普诺夫稳定性分析
连续时间系统的李雅普诺夫方程: A^T X + X A = -Q
这是西尔维斯特方程的特殊形式,其中 B = A^T
系统矩阵 A (稳定系统)
A_lyap = [[-2, 1],
[0, -3]]
正定矩阵 Q (通常取单位矩阵)
Q = [[1, 0],
[0, 1]]
转换为西尔维斯特方程形式: A^T X + X A = -Q
A = A_lyap
B = A_lyap # 注意:这里 B = A,因为原方程是 A^T X + X A = -Q
C = [[-Q[0][0], -Q[0][1]],
[-Q[1][0], -Q[1][1]]]
result = sylvester(A, B, C)
李雅普诺夫方程的解 X:
print(result)
#[[0.25, 0.0833333333333333],
[0, 0.166666666666667]]
验证: 计算 A^T X + X A,应该等于 -Q
X = result
verification = sp.Matrix(A).T * X + X * sp.Matrix(A)
验证 A^T X + X A = -Q:
print(verification)
#[[-1, -0.166666666666667],
[0.25, -0.916666666666667]]
示例2. 图像处理 - 图像配准和变换
在图像配准中,西尔维斯特方程可用于计算变换矩阵
源图像特征点矩阵 A
A_img = [[0.9, 0.1],
[0.2, 0.8]]
目标图像特征点矩阵 B
B_img = [[0.8, 0.3],
[0.1, 0.9]]
对应关系矩阵 C
C_img = [[1.2, 0.5],
[0.3, 1.1]]
求解变换矩阵 X: A X + X B = C
result = sylvester(A_img, B_img, C_img)
图像变换矩阵 X:
print(result)
#[[0.694746275344460, 0.127478436204772],
[0.0618348829393972, 0.621149322280721]]
#这个变换矩阵可以用于将源图像配准到目标图像
示例3. 电路分析 - 多端口网络参数计算
在电路分析中,西尔维斯特方程用于计算多端口网络参数
阻抗矩阵 A
A_circuit = [[5, -2],
[-2, 4]]
导纳矩阵 B
B_circuit = [[0.3, 0.1],
[0.1, 0.4]]
激励矩阵 C
C_circuit = [[10, 0],
[0, 5]]
求解网络响应矩阵 X: A X + X B = C
result = sylvester(A_circuit, B_circuit, C_circuit)
电路网络响应矩阵 X:
print(result)
#[[2.26425822642636, 0.445304477509683],
[1.02254952390534, 1.31553500059746]]
#该矩阵描述了网络在不同端口激励下的响应特性
示例4. 机械振动分析 - 模态耦合
在机械振动中,西尔维斯特方程用于分析耦合模态
质量矩阵相关的系数 A
A_vibration = [[2, -1],
[-1, 3]]
刚度矩阵相关的系数 B
B_vibration = [[5, 1],
[1, 4]]
外力耦合矩阵 C
C_vibration = [[8, 2],
[2, 6]]
求解模态耦合矩阵 X: A X + X B = C
result = sylvester(A_vibration, B_vibration, C_vibration)
机械系统模态耦合矩阵 X:
print(result)
#[[1.14285714285714, 0.285714285714286],
[0.285714285714286, 0.857142857142857]]
#该矩阵描述了不同振动模态之间的耦合关系
示例5. 量子力学 - 密度矩阵演化
在量子力学中,西尔维斯特方程用于描述开放量子系统的演化
哈密顿量矩阵 A (系统能量)
A_quantum = [[0, 1],
[1, 0]]
耗散矩阵 B (环境相互作用)
B_quantum = [[0.1, 0],
[0, 0.2]]
初始条件矩阵 C
C_quantum = [[1, 0],
[0, 0]]
求解密度矩阵演化 X: A X + X B = C
result = sylvester(A_quantum, B_quantum, C_quantum)
量子系统密度矩阵 X:
print(result)
#[[-0.101010101010101, 0],
[1.01010101010101, 0]]
#该矩阵描述了量子态在一定时间后的演化
示例6. 神经网络 - 权重矩阵优化
在神经网络中,西尔维斯特方程可用于权重矩阵的优化
输入相关矩阵 A
A_nn = [[0.8, 0.2],
[0.3, 0.7]]
输出相关矩阵 B
B_nn = [[0.9, 0.1],
[0.2, 0.8]]
目标相关矩阵 C
C_nn = [[0.6, 0.4],
[0.5, 0.5]]
求解最优权重矩阵 X: A X + X B = C
result = sylvester(A_nn, B_nn, C_nn)
神经网络最优权重矩阵 X:
print(result)
#[[0.303921568627451, 0.196078431372549],
[0.220588235294118, 0.279411764705882]]
#该权重矩阵最小化特定损失函数
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy import linalg as dense_linalg
def solve_sylvester_equation(A, B, C):
"""
解西尔维斯特方程 AX + XB = C。
参数:
A: 方程中的矩阵A,支持 SymPy 矩阵、列表或 NumPy 数组。
B: 方程中的矩阵B,支持类型同上。
C: 方程中的矩阵C,支持类型同上。
返回:
SymPy 矩阵: 解矩阵X(若成功)。
str: 错误信息(若输入无效或计算失败)。
示例:
>>> A = [[1, 0], [0, 2]]
>>> B = [[3, 1], [1, 4]]
>>> C = [[5, 6], [7, 8]]
>>> solve_sylvester_equation(A, B, C)
Matrix([
[ 1.0, 1.0],
[-1.5, 2.0]])
"""
try:
# 转换为 SymPy 矩阵
A_mat = sp.Matrix(A) if isinstance(A, list) else None
B_mat = sp.Matrix(B) if isinstance(B, list) else None
C_mat = sp.Matrix(C) if isinstance(C, list) else None
if None in (A_mat, B_mat, C_mat):
return "错误: 输入无法转换为有效矩阵"
# 符号检查
if A_mat.is_symbolic() or B_mat.is_symbolic() or C_mat.is_symbolic():
return "错误: 暂不支持符号运算"
# 维度验证
if not A_mat.is_square or not B_mat.is_square:
return "错误: A 和 B 必须是方阵"
if C_mat.rows != A_mat.rows or C_mat.cols != B_mat.rows:
return f"错误: C的维度应为({A_mat.rows}, {B_mat.rows}),实际为({C_mat.rows}, {C_mat.cols})"
# 转换为 NumPy 数组
A_np = np.array(A_mat, dtype=float)
B_np = np.array(B_mat, dtype=float)
C_np = np.array(C_mat, dtype=float)
# 解方程
X_np = dense_linalg.solve_sylvester(A_np, B_np, C_np)
return sp.Matrix(X_np)
except ValueError as ve:
return f"数值错误: {ve}"
except Exception as e:
return f"未知错误: {e}"
if __name__ == "__main__":
# 示例 1: 标准数值解
A = [[1, 0], [0, 2]]
B = [[3, 1], [1, 4]]
C = [[5, 6], [7, 8]]
print("示例1解:\n", solve_sylvester_equation(A, B, C))
# Matrix([[1.00000000000000, 1.00000000000000],
# [1.17241379310345, 1.13793103448276]])
对称近似最小度置换
对称近似最小度置换,对于对称正定矩阵A,命令p=symamd(S)返回置换向量p,因此S(p,p)倾向于比S具有更稀疏的乔列斯基因子.
示例1. 有限元分析中产生的对称刚度矩阵
stiffness_matrix = [[5, -2, 0, -1, 0],
[-2, 4, -1, 0, 0],
[0, -1, 6, -2, -1],
[-1, 0, -2, 5, -1],
[0, 0, -1, -1, 3]]
permutation = symamd(stiffness_matrix)
print(f"刚度矩阵置换向量: {permutation}")
#刚度矩阵置换向量: [4 2 3 1 0]
#应用:重新排序后的矩阵在LU分解时会产生更少的填充元素
original_matrix = np.array(eval(stiffness_matrix))
reordered_matrix = original_matrix[permutation, :][:, permutation]
重新排序后的矩阵带宽显著减小
示例2. 电路网络导纳矩阵优化
电路分析中的对称导纳矩阵
admittance_matrix = [[10, -2, 0, -3, 0],
[-2, 8, -1, 0, -2],
[0, -1, 12, -4, 0],
[-3, 0, -4, 9, -1],
[0, -2, 0, -1, 7]]
permutation = symamd(admittance_matrix)
print(f"导纳矩阵置换向量: {permutation}")
#导纳矩阵置换向量: [4 2 3 1 0]
#应用:优化后的矩阵在求解电路方程时计算效率更高
示例3. 结构力学质量矩阵优化
结构动力学中的对称质量矩阵
mass_matrix = [[2, 0, 1, 0, 0, 0],
[0, 3, 0, 0, 0, 0],
[1, 0, 2, 0, 1, 0],
[0, 0, 0, 4, 0, 0],
[0, 0, 1, 0, 2, 0],
[0, 0, 0, 0, 0, 3]]
permutation = symamd(mass_matrix)
print(f"质量矩阵置换向量: {permutation}")
#质量矩阵置换向量: [4 2 0 5 3 1]
#应用:在特征值计算和模态分析中提高数值稳定性
示例4. 图像处理拉普拉斯矩阵优化
图像处理中的对称拉普拉斯矩阵(用于图像分割)
laplacian_matrix = [[3, -1, 0, -1, 0, 0],
[-1, 4, -1, 0, -1, 0],
[0, -1, 3, 0, 0, -1],
[-1, 0, 0, 3, -1, 0],
[0, -1, 0, -1, 4, -1],
[0, 0, -1, 0, -1, 3]]
permutation = symamd(laplacian_matrix)
print(f"拉普拉斯矩阵置换向量: {permutation}")
#拉普拉斯矩阵置换向量: [5 2 4 1 3 0]
#应用:在图割算法中提高计算效率
示例5. 社交网络邻接矩阵优化
对称的社交网络邻接矩阵
social_adjacency = [[0, 1, 0, 1, 0, 0],
[1, 0, 1, 0, 1, 0],
[0, 1, 0, 0, 0, 1],
[1, 0, 0, 0, 1, 0],
[0, 1, 0, 1, 0, 1],
[0, 0, 1, 0, 1, 0]]
permutation = symamd(social_adjacency)
print(f"社交网络矩阵置换向量: {permutation}")
#社交网络矩阵置换向量: [5 2 4 1 3 0]
#应用:在社区检测和中心性分析中优化计算
示例6. 分子动力学力常数矩阵优化
分子模拟中的对称力常数矩阵
force_constant_matrix = [[8, -2, 0, -1, 0, 0],
[-2, 6, -1, 0, -1, 0],
[0, -1, 7, -2, 0, -1],
[-1, 0, -2, 9, -3, 0],
[0, -1, 0, -3, 8, -1],
[0, 0, -1, 0, -1, 5]]
permutation = symamd(force_constant_matrix)
print(f"力常数矩阵置换向量: {permutation}")
#力常数矩阵置换向量: [5 4 2 3 1 0]
#应用:在振动频率计算中减少计算复杂度
示例7. 优化问题海森矩阵优化
优化问题中的对称海森矩阵
hessian_matrix = [[6, 2, 1, 0, 0],
[2, 5, 0, 1, 0],
[1, 0, 4, 1, 1],
[0, 1, 1, 5, 0],
[0, 0, 1, 0, 3]]
permutation = symamd(hessian_matrix)
print(f"海森矩阵置换向量: {permutation}")
#海森矩阵置换向量: [1 3 0 2 4]
#应用:在牛顿法优化中提高矩阵分解效率
示例8. 电磁场分析系数矩阵优化
电磁场有限元分析中的对称系数矩阵
em_coefficient_matrix = [[7, -1, 0, -2, 0, 0],
[-1, 8, -1, 0, -1, 0],
[0, -1, 6, 0, 0, -1],
[-2, 0, 0, 9, -2, 0],
[0, -1, 0, -2, 7, -1],
[0, 0, -1, 0, -1, 5]]
permutation = symamd(em_coefficient_matrix)
print(f"电磁场矩阵置换向量: {permutation}")
#电磁场矩阵置换向量: [5 2 4 1 3 0]
#应用:在求解麦克斯韦方程时减少内存使用
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy.sparse import csr_matrix
from scipy.sparse.csgraph import reverse_cuthill_mckee
def symamd_permutation_vector(input_str):
"""
对标 MATLAB 的 symamd 函数(注意:实际使用 RCM 算法实现带宽优化)。
该函数接受矩阵输入,返回行/列置换向量以优化稀疏性模式。
参数:
input_str: 矩阵的字符串表示(如 "[[1, 2], [3, 4]]")或 SymPy 矩阵。
返回:
置换向量 (numpy数组) 或错误信息字符串。
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
if isinstance(expr, list):
matrix = sp.Matrix(expr)
# 检查矩阵是否包含符号
if matrix.is_symbolic():
return "错误: 矩阵包含符号变量,暂不支持符号运算"
# 转换为 numpy 数组并创建稀疏矩阵
try:
np_matrix = np.array(matrix, dtype=float)
graph = csr_matrix(np_matrix)
# 使用反向 Cuthill-McKee 算法获取置换
# 注意:这里实际使用的是 RCM 算法而非精确的 AMD 算法
result = reverse_cuthill_mckee(graph)
except ValueError as ve:
return f"数值转换错误: {ve}"
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
# 示范代码
if __name__ == "__main__":
# 示例 1: 数值矩阵
matrix_str = "[[1, 0, 4], [0, 2, 5], [4, 5, 3]]"
permutation = symamd_permutation_vector(matrix_str)
print(f"示例1置换向量: {permutation}")
# [1 2 0]
# 示例 2: 非对称矩阵
non_sym_matrix = "[[1, 2], [3, 4]]"
print(symamd_permutation_vector(non_sym_matrix))
# [1 0]
级数的乘积
F = symprod(f,k,a,b) 返回表达式 f 指定的级数的乘积, 该级数取决于符号变量 k. k 的值范围从 a 到 b. 如果您未指定 k,symprod 将使用 symvar 确定的变量. 如果f是常量, 则默认变量为x.
F = symprod(f,k) 返回表达式 f 指定的级数的乘积, 该级数取决于符号变量 k. k 的值从 1 开始, 上限未指定. 乘积 F 以 k 的形式返回, 其中 k 表示上限. 此乘积 F 与不定乘积不同. 如果您未指定 k, symprod 将使用 symvar 确定的变量. 如果 f 是常量, 则默认变量为 x.
f — 定义级数项的表达式, 符号表达式, 符号函数, 符号向量, 符号矩阵
k — 乘积指数,符号变量
a — 乘积指数的下限, 数, 符号数, 符号变量, 符号表达式, 符号函数
b — 乘积指数的上限, 数, 符号数, 符号变量, 符号表达式, 符号函数
示例1. 阶乘和组合数学
计算阶乘 n! = ∏(k, k=1..n)
factorial_expr = (k, k, 1, n)
result = symprod(factorial_expr)
print(f"阶乘 n! = {result}")
#阶乘 n! = factorial(n)
计算双阶乘 (2n-1)!! = ∏(2k-1, k=1..n)
double_factorial = (2*k - 1, k, 1, n)
result = symprod(double_factorial)
print(f"双阶乘 (2n-1)!! = {result}")
#双阶乘 (2n-1)!! = 2.0**n*RisingFactorial(1/2, n)
示例2. 概率分布函数
计算泊松分布的概率质量函数部分
poisson_part = (λ**k / factorial(k), k, 0, n)
result = symprod(poisson_part)
print(f"泊松分布求和部分 = {result}")
#泊松分布求和部分 = λ**(0.5*n**2 + 0.5*n)*Product(1/factorial(k), (k, 0, n))
计算几何分布的累积分布函数
geometric_cdf = ((1-p)**(k-1), k, 1, n)
result = symprod(geometric_cdf)
print(f"几何分布CDF部分 = {result}")
#几何分布CDF部分 = (1.0 - p)**(0.5*n**2 - 0.5*n)
示例3. 量子力学应用
计算谐振子的波函数归一化常数部分
harmonic_oscillator = ((2*k), k, 1, n)
result = symprod(harmonic_oscillator)
print(f"谐振子归一化常数部分 = {result}")
#谐振子归一化常数部分 = 2.0**n*factorial(n)
计算角动量算符的矩阵元素
angular_momentum = ((j*(j+1) - m*(m+k)), k, 1, n)
result = symprod(angular_momentum)
print(f"角动量矩阵元素 = {result}")
#角动量矩阵元素 = (-m)**n*RisingFactorial(1 - (j**2 + j - m**2)/m, n)
示例4. 控制系统分析
计算传递函数的增益乘积
transfer_function = ((s + a_k)/(s + b_k), k, 1, n)
result = symprod(transfer_function)
print(f"传递函数乘积 = {result}")
#传递函数乘积 = ((a_k + s)/(b_k + s))**n
计算特征多项式的系数
characteristic_poly = ((λ - λ_k), k, 1, n)
result = symprod(characteristic_poly)
print(f"特征多项式 = {result}")
#特征多项式 = (λ - λ_k)**n
示例5. 金融数学
计算复利终值系数
compound_interest = ((1 + r_k), k, 1, n)
result = symprod(compound_interest)
print(f"复利终值系数 = {result}")
#复利终值系数 = (r_k + 1.0)**n
计算年金现值系数
annuity_pv = ((1/(1 + r)**k), k, 1, n)
result = symprod(annuity_pv)
print(f"年金现值系数 = {result}")
#年金现值系数 = (r + 1.0)**(-0.5*n**2 - 0.5*n)
示例6. 统计推断
计算正态分布的最大似然函数
normal_likelihood = ((1/sqrt(2*pi*σ**2) * exp(-(x_k - μ)**2/(2*σ**2))), k, 1, n)
result = symprod(normal_likelihood)
print(f"正态分布似然函数 = {result}")
#正态分布似然函数 = (0.398942280401433*exp(-(x_k - μ)**2/(2*σ**2))/(σ**2)**0.5)**n
计算伯努利分布的似然函数
bernoulli_likelihood = (p**x_k * (1-p)**(1-x_k), k, 1, n)
result = symprod(bernoulli_likelihood)
print(f"伯努利分布似然函数 = {result}")
#伯努利分布似然函数 = (p**x_k*(1.0 - p)**(1.0 - x_k))**n
示例7. 算法复杂度分析
计算递归算法的时间复杂度
recursive_complexity = (f(k), k, 1, n)
result = symprod(recursive_complexity)
print(f"递归算法复杂度 = {result}")
#递归算法复杂度 = Product(f(k), (k, 1, n))
计算分治算法的乘积项
divide_conquer = ((a * f(n/b_k)), k, 1, log_b(n))
result = symprod(divide_conquer)
print(f"分治算法乘积项 = {result}")
#分治算法乘积项 = (a*f(n/b_k))**log_b(n)
示例8. 矩阵乘积级数
计算矩阵幂的乘积
matrix_powers = ([[a**k, b*k], [c, d]], k, 1, n)
result = symprod(matrix_powers)
print(f"矩阵幂乘积 = {result}")
#矩阵幂乘积 = [[a**(0.5*n**2 + 0.5*n), b**n*factorial(n)],
[c**n, d**n]]
计算转移矩阵的乘积
transition_matrix = ([[p, 1-p], [q, 1-q]], k, 1, n)
result = symprod(transition_matrix)
print(f"转移矩阵乘积 = {result}")
#转移矩阵乘积 = [[p**n, (1.0 - p)**n],
[q**n, (1.0 - q)**n]]
示例9. 数值验证示例
计算具体数值的乘积
numerical_product = (k, k, 1, 5)
result = symprod(numerical_product)
print(f"5! = {result}")
#5! = 120
验证调和数的乘积形式
harmonic_product = ((1 + 1/k), k, 1, n)
result = symprod(harmonic_product)
print(f"调和乘积 = {result}")
#调和乘积 = RisingFactorial(2, n)/factorial(n)
示例10. 数值矩阵乘积
具体数值矩阵的乘积
numeric_matrix = ([[k, 2], [3, 4]], k, 1, 3)
result = symprod(numeric_matrix)
print(f"数值矩阵乘积 = {result}")
#数值矩阵乘积 = [[6, 8],
[27, 64]]
示例11. 符号矩阵高级应用
符号矩阵的乘积级数
symbolic_matrix = ([[a**k, b], [c, d**k]], k, 1, n)
result = symprod(symbolic_matrix)
print(f"符号矩阵乘积 = {result}")
#符号矩阵乘积 = [[a**(0.5*n**2 + 0.5*n), b**n],
[c**n, d**(0.5*n**2 + 0.5*n)]]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def symvar_product_series(input_str):
"""
计算符号乘积级数,类似 MATLAB 的 symprod 函数
参数:
input_str: 输入字符串,支持以下格式:
- 普通符号表达式 (例如 "k")
- 矩阵的嵌套列表 (例如 "[[k, 1], [2, 3]]")
- 元组格式,可包含:
* (表达式, 变量) (例如 "(k, k)")
* (表达式, 变量, 下限) (例如 "(k, k, 1)")
* (表达式, 变量, 下限, 上限) (例如 "(k, k, 1, 5)")
* (矩阵, 变量, 下限, 上限) (例如 "(Matrix([[k]]), k, 1, n)")
返回:
SymPy 表达式/矩阵 或 错误消息
示例:
>>> symvar_product_series("k")
Product(k, (k, 1, n))
>>> symvar_product_series("(k, k, 1, 5)")
120
>>> symvar_product_series("([[k, 1], [2, 3]], k, 1, n)")
Matrix([
[Product(k, (k, 1, n)), 1],
[ 2**n, 3**n]])
"""
try:
# 尝试解析输入字符串为Python对象
expr = sp.sympify(input_str)
error = False
result = None
def evaluation_product_series(f_expr, k=None, a=None, b=None):
"""
内部函数:计算乘积级数
参数:
f_expr: 乘积表达式
k: 乘积变量
a: 下限,默认为1
b: 上限,默认为符号n
"""
# 自动确定乘积变量
if f_expr.free_symbols and (k is None):
k = list(f_expr.free_symbols)[0] # 默认取第一个符号
elif k is None:
k = sp.symbols('x') # 默认变量
# 设置默认上下限
a = 1 if a is None else a
b = sp.symbols('n') if b is None else b
return sp.product(f_expr, (k, a, b)).evalf()
# 处理元组输入的情况
if isinstance(expr, tuple):
# 矩阵处理分支 (格式: (矩阵, 变量, 下限, 上限))
if len(expr) >= 4 and isinstance(expr[0], list):
F = sp.Matrix(expr[0])
k_var = expr[1]
lower = expr[2]
upper = expr[3]
# 对矩阵每个元素计算乘积
result = sp.Matrix(F.shape[0], F.shape[1],
lambda i, j: evaluation_product_series(
F[i, j], k_var, lower, upper))
# 普通表达式处理分支 (格式: (表达式, 变量, 下限, 上限))
elif len(expr) >= 4 and expr[0].free_symbols:
f_expr = expr[0]
k_var = expr[1]
lower = expr[2]
upper = expr[3]
result = evaluation_product_series(f_expr, k_var, lower, upper)
# 简写格式处理 (例如 (矩阵, 变量))
elif isinstance(expr[0], list):
F = sp.Matrix(expr[0])
k_var = expr[1]
result = sp.Matrix(F.shape[0], F.shape[1],
lambda i, j: evaluation_product_series(F[i, j], k_var))
# 简写格式处理 (例如 (表达式, 变量))
elif expr[0].free_symbols:
f_expr = expr[0]
k_var = expr[1]
result = evaluation_product_series(f_expr, k_var)
else:
error = True
# 处理矩阵输入
elif isinstance(expr, list):
F = sp.Matrix(expr)
result = sp.Matrix(F.shape[0], F.shape[1],
lambda i, j: evaluation_product_series(F[i, j]))
# 处理普通符号表达式
elif expr.free_symbols:
result = evaluation_product_series(expr)
# 处理纯数值输入
elif expr.is_number:
result = evaluation_product_series(expr)
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {str(e)}"
# 示例测试
if __name__ == "__main__":
# 普通符号乘积
print(symvar_product_series("k"))
# factorial(n)
# 具体数值范围乘积
print(symvar_product_series("(k, k, 1, 5)"))
# 120.000000000000
# 矩阵乘积
mat_expr = symvar_product_series("([[k, 1], [2, 3]], k, 1, n)")
print(mat_expr)
# Matrix([[factorial(n), 1.00000000000000],
# [2.0**n, 3.0**n]])
符号和(有限或无限)
F = symsum(f,k,a,b)从下界a到上界b,返回级数F相对于求和索引k的符号定和.如果不指定k,symsum将使用symvar确定的变量作为求和索引.如果f是常数,那么默认变量是x.
F = symsum(f,k)返回级数F相对于求和索引k的不定和(反差).f自变量定义级数,使得不定和f满足关系式f(k+1)-f(k)=f(k).如果不指定k,symsum将使用symvar确定的变量作为求和索引.如果f是常数,那么默认变量是x。
f —— 定义级数项的表达式,符号表达式,符号函数,符号向量,符号矩阵,符号数
k —— 求和指数,符号变量
a —— 求和指数的下界,数字,符号数,符号变量,符号表达式,符号函数
b —— 求和指数的上界,数字,符号数,符号变量,符号表达式,符号函数
示例1. 数学分析中的经典级数
算术级数求和
arithmetic = (k, k, 1, n)
result = symsum(arithmetic)
print(f"算术级数 1+2+...+n = {result}")
#算术级数 1+2+...+n = 0.5*n**2 + 0.5*n
几何级数求和
geometric = (a*r**(k-1), k, 1, n)
result = symsum(geometric)
print(f"几何级数 a + ar + ar² + ... = {result}")
#几何级数 a + ar + ar² + ... = a*Piecewise((n/r, Eq(r, 1)), ((r - r**(n + 1.0))/(r*(1.0 - r)), True))
平方和级数
square_sum = (k**2, k, 1, n)
result = symsum(square_sum)
print(f"平方和 1²+2²+...+n² = {result}")
#平方和 1²+2²+...+n² = 0.333333333333333*n**3 + 0.5*n**2 + 0.166666666666667*n
示例2. 物理学中的量子力学应用
角动量量子数求和
angular_momentum = (m, m, -j, j)
result = symsum(angular_momentum)
print(f"角动量投影求和 = {result}")
#角动量投影求和 = 0
示例3. 概率论与统计学
泊松分布归一化验证
poisson_norm = (λ**k / factorial(k), k, 0, oo)
result = symsum(poisson_norm)
print(f"泊松分布归一化常数 = {result}")
#泊松分布归一化常数 = exp(λ)
几何分布期望值
geometric_expectation = (k * p * (1-p)**(k-1), k, 1, oo)
result = symsum(geometric_expectation)
print(f"几何分布期望值 = {result}")
#几何分布期望值 = p*Piecewise((p**(-2), Abs(p - 1) < 1), (Sum(k*(1 - p)**(k - 1), (k, 1, oo)), True))
二项分布概率求和
binomial_sum = (binomial(n, k) * p**k * (1-p)**(n-k), k, 0, n)
result = symsum(binomial_sum)
print(f"二项分布概率和 = {result}")
#二项分布概率和 =
#Piecewise(((1.0 - p)**n*(-p/(p - 1.0) + 1.0)**n,
((re(n) <= -1) & (Abs(p/(p - 1)) < 1)) | ((re(n) > 0) & (Abs(p/(p - 1)) <= 1)) | ((re(n) <= 0) & (re(n) > -1) & (Abs(p/(p - 1)) <= 1))),
(Sum(p**k*(1 - p)**(-k + n)*binomial(n, k), (k, 0, n)), True))
示例4. 工程学中的信号处理
Z变换求和
z_transform = (x_k * z**(-k), k, 0, oo)
result = symsum(z_transform)
print(f"Z变换 = {result}")
#Z变换 = x_k*Piecewise((1/(1.0 - 1/z), 1/Abs(z) < 1), (Sum(z**(-k), (k, 0, oo)), True))
示例5. 金融数学中的现值计算
永续年金现值
perpetuity = (C / (1 + r)**k, k, 1, oo)
result = symsum(perpetuity)
print(f"永续年金现值 = {result}")
#永续年金现值 = C*Piecewise((1/((1.0 - 1/(r + 1.0))*(r + 1.0)), 1/Abs(r + 1) < 1), (Sum((r + 1)**(-k), (k, 1, oo)), True))
增长型年金现值
growing_annuity = (C * (1 + g)**(k-1) / (1 + r)**k, k, 1, n)
result = symsum(growing_annuity)
print(f"增长型年金现值 = {result}")
#增长型年金现值 = C*Piecewise((n/(r + 1.0), Eq(g, r)), (-(g*(g + 1.0)**(n - 1.0) + (g + 1.0)**(n - 1.0) - (r + 1.0)**n)/((-g + r)*(r + 1.0)**n), True))
示例6. 计算机科学中的算法分析
插入排序比较次数
insertion_sort = (k, k, 1, n)
result = symsum(insertion_sort)
print(f"插入排序比较次数 = {result}")
#插入排序比较次数 = 0.5*n**2 + 0.5*n
示例7. 数值分析中的误差估计
泰勒级数余项估计
taylor_remainder = ((M * (x-a)**(k+1) / factorial(k+1)), k, n, oo)
result = symsum(taylor_remainder)
print(f"泰勒级数余项 = {result}")
#泰勒级数余项 = M*(-a + x)**(-n - 1.0)*(-a + x)**(n + 1.0)*(n + 1.0)*exp(-a + x)*lowergamma(n + 1, -a + x)/gamma(n + 2)
示例8. 收敛性测试
收敛级数示例
convergent = (1/k**2, k, 1, oo)
result = symsum(convergent)
print(f"收敛级数 Σ1/k² = {result}")
#收敛级数 Σ1/k² = 1.64493406684823
发散级数示例
divergent = (1/k, k, 1, oo)
result = symsum(divergent)
print(f"调和级数 Σ1/k = {result}")
#调和级数 Σ1/k = oo
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def symsum(input_str):
"""
对标 MATLAB 的 symsum 函数,计算符号级数和
参数:
input_str: 输入字符串,支持以下格式:
- "f" : 自动选择变量,从1到无穷大
- "(f, k)" : 从k=1到无穷大
- "(f, k, a)" : 从k=a到无穷大
- "(f, k, a, b)" : 从k=a到k=b
- "[[f1, f2], [f3, f4]]" : 矩阵输入
返回:
- 符号表达式结果
- SymPy 矩阵(矩阵输入时)
- 错误信息字符串
示例:
>>> symsum("(k, k, 1, 5)") # Σk from 1到5 → 15
>>> symsum("(1/k^2, k, 1, oo)") # π²/6
>>> symsum("[[k, k^2], [k^3, 1]]") # 矩阵各元素求和
"""
try:
# 安全解析输入字符串
expr = sp.sympify(input_str)
def get_summation(f, k=None, a=1, b=sp.oo):
"""
计算符号级数和
:param f: 被求和的表达式
:param k: 求和变量
:param a: 求和下限
:param b: 求和上限
:return: 符号级数和的结果
"""
if k is None:
if f.free_symbols:
k = tuple(f.free_symbols)[0]
else:
k = sp.symbols('x')
return sp.summation(f, (k, a, b))
if isinstance(expr, tuple):
# 处理元组输入
f = expr[0]
k = expr[1] if len(expr) > 1 else None
a = expr[2] if len(expr) > 2 else 1
b = expr[3] if len(expr) > 3 else sp.oo
if isinstance(f, list):
F = sp.Matrix(f)
# 处理矩阵输入
return sp.Matrix(F.shape[0], F.shape[1], lambda i, j: get_summation(F[i, j], k, a, b))
else:
return get_summation(f, k, a, b)
elif isinstance(expr, list):
F = sp.Matrix(expr)
# 处理矩阵输入,默认从1到无穷大
return sp.Matrix(F.shape[0], F.shape[1], lambda i, j: get_summation(F[i, j]))
else:
# 处理普通表达式输入,默认从1到无穷大
return get_summation(expr)
except SyntaxError:
return "语法错误: 输入格式不正确"
except ValueError as ve:
return f"数值错误: {str(ve)}"
except Exception as e:
return f"未处理的错误: {str(e)}"
# 示例测试
if __name__ == "__main__":
# 测试1: 有限求和
print("Σk from 1到5:", symsum("(k, k, 1, 5)"))
# 15
# 测试2: 无限级数
print("Σ1/k² from 1到∞:", symsum("(1/k**2, k, 1, oo)"))
# pi**2/6
# 测试3: 自动变量选择
print("Σm from 1到∞:", symsum("m"))
# oo
# 测试4: 矩阵输入
print("矩阵求和结果:\n", symsum("[[k, k**2], [k**3, 1/k]]"))
# Matrix([[oo, oo],
# [oo, oo]])