对角线缩放以提高特征值准确性
[T,B] = balance(A) 返回相似变换矩阵T以使B = T\A*T 和B具有尽可能接近的,近似相等的行列范数.
T是对角矩阵的置换矩阵,其元素是2的整数次幂,可防止引入舍入误差.如果A是对称的,则B == A和T是单位矩阵.
A -- 输入,矩阵.
1. 控制系统分析 - 状态空间矩阵平衡
控制系统状态矩阵的平衡变换
这对于控制系统的稳定性分析和控制器设计非常重要
T, B = balance([[0, 1, 0], [0, 0, 1], [-1000, -100, -10]])
# 变换矩阵T: [[0.015625, 0, 0],
[0, 0.125, 0],
[0, 0, 2]]
# 平衡后矩阵B: [[0, 8, 0],
[0, 0, 16],
[-7.8125, -6.25, -10]]
2. 结构工程 - 刚度矩阵平衡
结构刚度矩阵的平衡变换
平衡后的矩阵可以提高结构特征值计算的精度
T, B = balance([[1000, 50, 0], [50, 2000, 75], [0, 75, 3000]])
# 变换矩阵T: [[1, 0, 0],
[0, 1, 0],
[0, 0, 1]]
# 平衡后矩阵B: [[1000, 50, 0],
[50, 2000, 75],
[0, 75, 3000]]
3. 电路分析 - 导纳矩阵平衡
电路导纳矩阵的平衡变换
这对于电路频率响应分析和稳定性评估很有帮助
T, B = balance([[0.001, 0.0001], [0.0001, 0.002]])
# 变换矩阵T: [[1, 0],
[0, 1]]
# 平衡后矩阵B: [[0.001, 0.0001],
[0.0001, 0.002]]
4. 量子力学 - 哈密顿矩阵平衡
量子系统哈密顿矩阵的平衡变换
平衡变换可以提高量子能级计算的数值稳定性
T, B = balance([[1, 0.00001], [0.00001, 2]])
# 变换矩阵T: [[1, 0],
[0, 1]]
# 平衡后矩阵B: [[1, 1e-5],
[1e-5, 2]]
5. 经济学 - 投入产出矩阵平衡
经济学投入产出矩阵的平衡变换
这对于经济系统分析和预测模型的数值稳定性很重要
T, B = balance([[0.2, 0.1, 0.3], [0.4, 0.5, 0.2], [0.1, 0.3, 0.4]])
# 变换矩阵T: [[1, 0, 0],
[0, 1, 0],
[0, 0, 1]]
# 平衡后矩阵B: [[0.2, 0.1, 0.3],
[0.4, 0.5, 0.2],
[0.1, 0.3, 0.4]]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
import scipy.linalg as la # 使用SciPy的linalg模块,包含matrix_balance函数
def balance_transformation_matrix(input_str):
"""
计算矩阵的平衡变换矩阵及其平衡后的矩阵。
参数:
input_str: 输入矩阵的字符串表示,可以是SymPy矩阵语法或嵌套列表形式。
返回:
如果成功,返回包含平衡变换矩阵T和平衡后矩阵B的元组 (T, B);
否则返回错误信息字符串。
"""
try:
# 将输入字符串解析为SymPy表达式
expr = sp.sympify(input_str)
error = False
result = None
if isinstance(expr, list):
# 转换为NumPy数组以便使用SciPy的数值计算
N_A = np.array(expr, dtype=float)
# 计算平衡变换矩阵和平衡后的矩阵
B_np, T_np = la.matrix_balance(N_A)
# 验证平衡变换的正确性:B = T^{-1} * A * T
T_inv = np.linalg.inv(T_np)
B_calculated = T_inv @ N_A @ T_np # 矩阵乘法运算
# 检查计算后的B是否与SciPy返回的B一致(考虑浮点误差)
if np.allclose(B_np, B_calculated, atol=1e-10):
# 将NumPy矩阵转换为SymPy矩阵返回
T_sp = sp.Matrix(T_np)
B_sp = sp.Matrix(B_np)
result = (T_sp, B_sp)
else:
error = True
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"运行时错误: {e}"
def main():
"""主入口函数,展示平衡变换矩阵的计算示例"""
# 示例1:嵌套列表输入
input2 = "[[1, 0], [1000, 1]]"
print("\n示例2输入:", input2)
output2 = balance_transformation_matrix(input2)
if isinstance(output2, tuple):
T, B = output2
print("变换矩阵T:\n", T)
print("平衡后矩阵B:\n", B)
else:
print(output2)
# 变换矩阵T: Matrix([[0, 1.00000000000000],
# [1.00000000000000, 0]])
# 平衡后矩阵B: Matrix([[1.00000000000000, 1000.00000000000],
# [0, 1.00000000000000]])
if __name__ == "__main__":
main()
矩阵的上下带宽
B = bandwidth(A,type) 返回 type 指定的矩阵 A 的带宽. 将 type 指定为下带宽 'lower' 或指定为上带宽 'upper'.
[lower,upper] = bandwidth(A) 返回矩阵 A 的下带宽 lower 和上带宽 upper.
A — 输入矩阵,二维数值矩阵.
type — 带宽类型,'lower' | 'upper'
1. 三对角矩阵 - 常见于微分方程数值解
三对角矩阵的带宽计算
bandwidth([[2, -1, 0, 0], [-1, 2, -1, 0], [0, -1, 2, -1], [0, 0, -1, 2]])
#结果: (1, 1)
2. 下三角矩阵 - 常见于Cholesky分解
下三角矩阵的带宽计算
bandwidth([[1, 0, 0, 0], [2, 3, 0, 0], [4, 5, 6, 0], [7, 8, 9, 10]])
#结果: (3, 0)
3. 上三角矩阵 - 常见于QR分解
上三角矩阵的带宽计算
bandwidth([[1, 2, 3, 4], [0, 5, 6, 7], [0, 0, 8, 9], [0, 0, 0, 10]])
#结果: (0, 3)
4. 带状矩阵 - 常见于有限差分法
带状矩阵的带宽计算(带宽为2)
bandwidth([[1, 2, 3, 0, 0], [4, 5, 6, 7, 0], [0, 8, 9, 10, 11], [0, 0, 12, 13, 14], [0, 0, 0, 15, 16]])
#结果: (1, 2)
5. 仅查询下带宽 - 优化存储格式选择
仅查询矩阵的下带宽
bandwidth([[1, 0, 0, 0], [2, 3, 0, 0], [0, 4, 5, 0], [0, 0, 6, 7]], lower)
#结果: 1
6. 仅查询上带宽 - 算法选择依据
bandwidth([[1, 2, 0, 0], [0, 3, 4, 0], [0, 0, 5, 6], [0, 0, 0, 7]], upper)
#结果: 1
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def evaluation_bandwidth(matrix):
"""
计算矩阵的下带宽和上带宽
参数:
matrix: SymPy矩阵对象
返回:
(lower_bandwidth, upper_bandwidth): 包含两个整数的元组
"""
rows, cols = matrix.shape
lower_bandwidth = 0
upper_bandwidth = 0
# 计算下带宽(下三角区域非零元素的最大行差)
for i in range(rows):
for j in range(min(cols, i)): # 仅遍历下三角区域
if matrix[i, j] != 0:
lower_bandwidth = max(lower_bandwidth, i - j)
# 计算上带宽(上三角区域非零元素的最大列差)
for i in range(rows):
for j in range(i + 1, cols): # 仅遍历上三角区域
if matrix[i, j] != 0:
upper_bandwidth = max(upper_bandwidth, j - i)
return lower_bandwidth, upper_bandwidth
def bandwidth_lower_upper_matrix(input_str):
"""
计算矩阵的带宽特征
参数:
input_str: 输入字符串,支持两种格式:
1) 纯矩阵描述(如"Matrix([[1,0],[2,3]]"或"[[1,0],[2,3]]")
2) 矩阵描述后跟带宽类型,用分号分隔(如"[[1,0],[2,3]];lower")
返回:
如果指定类型返回整数,否则返回元组 (lower, upper)
遇到错误时返回描述性错误信息字符串
"""
try:
# 解析矩阵表达式
expr = sp.sympify(input_str)
error = False
if isinstance(expr, tuple) and len(expr) == 2:
matrix_part, mode = expr[0], str(expr[1])
elif isinstance(expr, list):
matrix_part = expr
mode = None
else:
error = True
if isinstance(matrix_part, list):
matrix = sp.Matrix(matrix_part)
else:
return f"错误: 无法解析矩阵 '{matrix_part}'"
# 计算带宽
if not error:
lower, upper = evaluation_bandwidth(matrix)
# 根据模式参数返回结果
if mode == 'lower':
return lower
elif mode == 'upper':
return upper
else:
return (lower, upper)
except Exception as e:
return f"运行时错误: {e}"
def main():
"""主入口函数,展示带宽计算示例"""
# 示例1:完整带宽查询
input1 = "[[1, 0, 0], [2, 3, 0], [4, 5, 6]]"
print(f"示例1输入: {input1}")
print("结果:", bandwidth_lower_upper_matrix(input1))
#结果: (2, 0)
# 示例2:仅查询下带宽
input2 = "[[1, 0, 0], [2, 3, 0],[4, 5, 6]],lower"
print(f"\n示例2输入: {input2}")
print("结果:", bandwidth_lower_upper_matrix(input2))
#结果: 2
# 示例3:仅查询上带宽
input3 = "[[0, 2, 3], [0, 0, 5], [0, 0, 0]],upper"
print(f"\n示例3输入: {input3}")
print("结果:", bandwidth_lower_upper_matrix(input3))
#结果: 2
if __name__ == "__main__":
main()
巴特利窗
w = bartlett(L,sym=1) 返回一个长度为L个点的对称巴特利窗, 默认sym=1
当sym=1, 生成一个对称窗口,用于滤波器设计.
当sym=0, 生成一个周期性窗口,用于光谱分析.
1. 频谱分析 - 减少频谱泄漏
使用Bartlett窗进行频谱分析,减少频谱泄漏
应用:在对信号进行傅里叶变换前加窗,减少频谱泄漏效应
这对于精确分析信号频率成分非常重要
coefficients = bartlett(64)
print(coefficients[:10])
#结果: [0.0, 0.0317, 0.0635, 0.0952, 0.127, 0.1587, 0.1905, 0.2222, 0.254, 0.2857]
2. FIR滤波器设计
使用Bartlett窗设计FIR低通滤波器
应用:将窗函数与理想滤波器响应相乘,得到实际可实现的FIR滤波器
Bartlett窗提供的平滑过渡可以减少吉布斯现象
filter_order = 31 # 滤波器阶数
window_coeff = bartlett(str(filter_order + 1)) # 窗长度 = 阶数 + 1
print(window_coeff[:10])
#结果: [0.0, 0.0645, 0.129, 0.1935, 0.2581, 0.3226, 0.3871, 0.4516, 0.5161, 0.5806]
3. 信号平滑处理
使用Bartlett窗进行信号平滑处理
应用:将窗函数作为卷积核,对信号进行滑动平均平滑处理
三角形权重使得中心点权重最大,边缘权重较小
smoothing_window = bartlett(15)
print(smoothing_window[:10])
#结果: [0.0, 0.1429, 0.2857, 0.4286, 0.5714, 0.7143, 0.8571, 1.0, 0.8571, 0.7143]
4. 非对称窗口应用
使用非对称Bartlett窗进行特殊应用
应用:在某些特定信号处理场景中,可能需要非对称窗口
例如,处理因果系统或需要特定相位响应的应用
asymmetric_window = bartlett(10,0)
print(asymmetric_window[:10])
#结果: [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 0.8, 0.6, 0.4, 0.2]
5. 语音信号处理
在语音处理中使用Bartlett窗进行分帧
应用:在语音信号处理中,对语音信号进行分帧加窗
Bartlett窗可以减少帧边缘的不连续性
frame_size = 256 # 帧大小
bartlett_win = bartlett(frame_size)
print(bartlett_win[:10])
#结果: [0.0, 0.0078, 0.0157, 0.0235, 0.0314, 0.0392, 0.0471, 0.0549, 0.0627, 0.0706]
6. 图像处理 - 二维窗函数
创建二维Bartlett窗用于图像处理
通过外积创建二维窗函数
应用:在图像处理中作为平滑核或特征提取的权重矩阵
bartlett_1d = bartlett(5)
通过外积创建二维窗函数
bartlett_2d = np.outer(bartlett_1d, bartlett_1d)
#结果: [[0. 0. 0. 0. 0. ]
[0. 0.25 0.5 0.25 0. ]
[0. 0.5 1. 0.5 0. ]
[0. 0.25 0.5 0.25 0. ]
[0. 0. 0. 0. 0. ]]
7. 雷达信号处理
在雷达系统中使用Bartlett窗进行脉冲压缩
应用:在雷达信号处理中,使用窗函数改善距离分辨率和旁瓣抑制
compression_window = bartlett(32)
print(compression_window[:10])
#结果: [0.0, 0.0645, 0.129, 0.1935, 0.2581, 0.3226, 0.3871, 0.4516, 0.5161, 0.5806]
8. 生物医学信号处理
在EEG/ECG信号分析中使用Bartlett窗
应用:在生物医学信号分析中,使用窗函数减少频谱泄漏,提高频率分辨率
eeg_window = bartlett(128)
print(eeg_window[:10])
#结果: [0.0, 0.0157, 0.0315, 0.0472, 0.063, 0.0787, 0.0945, 0.1102, 0.126, 0.1417]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy import signal
def bartlett_window(input_str):
"""
生成Bartlett(三角形)窗口的滤波器系数
参数:
input_str: 输入字符串,支持两种格式:
1) 单个整数表示窗口长度(如"7")
2) 元组格式 "(m, sym_flag)",其中:
- m: 窗口长度(正整数)
- sym_flag: 对称标志(0表示False,非0表示True)
返回:
成功时返回浮点数列表形式的窗口系数,失败返回错误信息字符串
"""
try:
# 将输入字符串解析为SymPy表达式
expr = sp.sympify(input_str)
# 参数初始化
m = None
sym = True # 默认使用对称窗口
# 处理元组输入 (m, sym_flag)
if isinstance(expr, tuple):
if len(expr) != 2:
raise ValueError("元组参数需要包含两个元素")
m_expr, sym_expr = expr
if not (m_expr.is_integer and sym_expr.is_integer):
raise TypeError("参数必须为整数")
m = int(m_expr)
sym = bool(int(sym_expr)) # 将0转换为False,非0转换为True
# 处理单个整数输入
elif expr.is_integer:
m = int(expr)
else:
raise TypeError("输入格式不正确")
# 验证窗口长度有效性
if m < 1:
raise ValueError("窗口长度必须为大于0的整数")
# 生成Bartlett窗口
window = signal.windows.bartlett(m, sym)
# 转换为Python列表并保留4位小数
return [round(float(x), 4) for x in window]
except Exception as e:
return f"错误: {str(e)}"
def main():
"""主入口函数,展示Bartlett窗口生成示例"""
# 示例1:基本对称窗口
print("示例1: 对称窗口 m=7")
print(bartlett_window("7")) # 预期输出7个元素的对称窗口
#[0.0, 0.3333, 0.6667, 1.0, 0.6667, 0.3333, 0.0]
# 示例2:非对称窗口
print("\n示例2: 非对称窗口 m=5")
print(bartlett_window("(5, 0)")) # 第二个参数为0表示非对称
#[0.0, 0.4, 0.8, 0.8, 0.4]
if __name__ == "__main__":
main()
布莱克曼窗
Blackman窗函数在信号处理中有多种实际应用,特别是在频谱分析和滤波器设计中。
w = blackman(L,sym=1) 返回一个长度为L个点的对称布莱克曼窗, 默认sym=1
当sym=1, 生成一个对称窗口,用于滤波器设计.
当sym=0, 生成一个周期性窗口,用于光谱分析.
1. 音频频谱分析
在音频处理中,Blackman窗常用于短时傅里叶变换(STFT)分析。
1024点的窗口长度适合分析44.1kHz采样率音频的频谱特性,能够提供良好的频率分辨率同时减少频谱泄漏,特别适合音乐信号分析和语音处理。
blackman(1024)[:10]
#输出: [-0.0, 3e-06, 1.4e-05, 3.1e-05, 5.4e-05, 8.5e-05, 0.000122, 0.000166, 0.000217, 0.000275]
2. 振动信号分析
在机械故障诊断中,Blackman窗用于分析旋转机械的振动信号。
512点的非对称窗口(sym=0)适合捕捉瞬态振动特征,其低旁瓣特性有助于准确识别微弱的故障频率成分,减少噪声干扰。
blackman(512, 0)[:10]
#输出: [-0.0, 1.4e-05, 5.4e-05, 0.000122, 0.000217, 0.000339, 0.000489, 0.000666, 0.00087, 0.001103]
3. 雷达信号处理
在脉冲多普勒雷达中,Blackman窗用于处理回波信号。
256点的窗口长度适合中等距离分辨率的应用,能够有效抑制距离旁瓣,提高目标检测性能,同时保持足够的主瓣宽度。
blackman(256)[:10]
#输出: [-0.0, 5.5e-05, 0.000219, 0.000493, 0.000877, 0.001374, 0.001983, 0.002706, 0.003546, 0.004504]
4. 医学心电图(ECG)分析
在心电图信号分析中,Blackman窗用于提取心电特征。
128点的对称窗口适合分析心搏周期,其平滑的窗函数特性有助于准确识别P波、QRS复合波和T波,减少基线漂移的影响。
blackman(128,1)[:10]
#输出: [-0.0, 0.00022, 0.000884, 0.001998, 0.003574, 0.005627, 0.008178, 0.011251, 0.014872, 0.019072]
5. 通信系统中的滤波器设计
在数字通信系统中,Blackman窗用于设计FIR滤波器。
64点的窗口长度适合实现中等复杂度的滤波器,其优异的频率响应特性能够提供陡峭的过渡带和低通带纹波,适合用于符号同步和信道均衡。
blackman(64)[:10]
#输出: [-0.0, 0.000898, 0.003632, 0.008313, 0.015121, 0.024293, 0.036108, 0.05087, 0.068887, 0.090453]
6. 地震信号处理
在地震勘探中,Blackman窗用于处理地震波形数据。
2048点的大窗口适合分析低频地震波,其卓越的频谱特性有助于准确识别不同地层界面的反射信号,提高地层分辨率。
blackman(2048,1)[:10]
#输出: [-0.0, 1e-06, 3e-06, 8e-06, 1.4e-05, 2.1e-05, 3.1e-05, 4.2e-05, 5.4e-05, 6.9e-05]
7. 图像处理中的频域滤波
在图像处理中,Blackman窗可用于设计2D滤波器或在频域滤波中作为窗函数。
32点的小窗口适合局部特征分析,能够有效抑制吉布斯现象,在边缘检测和纹理分析中表现良好。
blackman(32)[:10]
#输出: [-0.0, 0.003752, 0.015638, 0.037403, 0.071465, 0.120286, 0.185647, 0.267955, 0.365735, 0.475379]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy import signal
def blackman_window(input_str):
"""
根据输入字符串生成Blackman窗口函数
参数:
input_str (str): 输入表达式,支持两种格式:
1. 单个整数M表示窗口长度(生成对称窗口)
2. 元组(M, sym)表示窗口长度和对称性
- M:窗口长度(必须为正整数)
- sym:窗口对称性(True/False或0/1)
返回:
list | str: 成功时返回窗口数组,失败返回错误描述字符串
"""
try:
expr = sp.sympify(input_str)
error_flag = False
result = None
# 情况1:输入为元组 (M, sym)
if isinstance(expr, tuple) and len(expr) == 2:
# 验证窗口长度参数
if expr[0].is_number and expr[0].is_integer and int(expr[0]) > 0:
m = int(expr[0])
else:
error_flag = True
raise ValueError("窗口长度必须为正整数")
# 解析对称性参数
if not error_flag:
if expr[1].is_Boolean: # 处理布尔类型参数
sym = bool(expr[1])
elif expr[1].is_number: # 处理数值类型参数
sym = expr[1] != 0
else:
error_flag = True
raise ValueError("对称参数应为布尔值或0/1")
# 生成窗口
if not error_flag:
try:
window = signal.windows.blackman(m, sym)
result = [round(x, 6) for x in window] # 保留6位小数
except ValueError as ve:
return f"参数错误:{str(ve)}"
# 情况2:输入为单个整数
elif expr.is_integer and int(expr) > 0:
m = int(expr)
try:
window = signal.windows.blackman(m)
result = [round(x, 6) for x in window]
except ValueError as ve:
return f"参数错误:{str(ve)}"
else:
error_flag = True
if error_flag:
return f"输入格式错误:{input_str}"
return result
except sp.SympifyError:
return f"语法错误:无法解析输入 '{input_str}'"
except ValueError as ve:
return f"数值错误:{str(ve)}"
except Exception as e:
return f"意外错误:{str(e)}"
def main():
"""测试函数"""
test_cases = [
"64",
# 输出: [-0.0, 0.000898, 0.003632, 0.008313, 0.015121, 0.024293, 0.036108, 0.05087, 0.068887, 0.090453]
"(64, 0)",
# 输出: [-0.0, 0.00087, 0.003518, 0.008047, 0.014629, 0.023485, 0.03488, 0.049102, 0.066447, 0.087196]
"(64, 2)",
# 输出: [-0.0, 0.000898, 0.003632, 0.008313, 0.015121, 0.024293, 0.036108, 0.05087, 0.068887, 0.090453]
]
for case in test_cases:
print(f"输入:{case}")
print("输出:", blackman_window(case)[:10])
print("-" * 60)
if __name__ == "__main__":
main()
最小四项布莱克曼-哈里斯窗
Blackman-Harris窗是Blackman窗的一种改进版本,具有更低的旁瓣电平,适用于需要极高动态范围的应用场景。
w = blackmanharris(L,sym) 返回一个长度为L个点的对称四项布莱克曼-哈里斯窗, 默认sym=1
当sym=1, 生成一个对称窗口,用于滤波器设计.
当sym=0, 生成一个周期性窗口,用于光谱分析.
1. 高精度频谱分析
在天文学和物理学研究中,Blackman-Harris窗用于分析极微弱信号的频谱特性。
其极低的旁瓣电平(-92dB)使其特别适合检测被强信号掩盖的微弱频率成分,如恒星光谱分析或粒子物理实验中的数据解析。
blackmanharris(2048)[:10]
#输出:[6e-05, 6e-05, 6.1e-05, 6.1e-05, 6.2e-05, 6.3e-05, 6.5e-05, 6.7e-05, 6.9e-05, 7.1e-05]
2. 声学测量与噪声分析
在专业声学测量中,Blackman-Harris窗用于精确分析噪声频谱。
其优异的动态范围使其能够同时捕捉高声压级和极低声压级的频率成分,适合用于环境噪声评估、建筑声学测量和音频设备测试。
blackmanharris(4096,0)[:10]
#输出:[6e-05, 6e-05, 6e-05, 6e-05, 6.1e-05, 6.1e-05, 6.1e-05, 6.2e-05, 6.2e-05, 6.3e-05]
3. 雷达与声纳信号处理
在高分辨率雷达和声纳系统中,Blackman-Harris窗用于脉冲压缩和 Doppler 处理。
其极低的旁瓣特性有助于减少距离和速度模糊,提高弱小目标检测能力,特别适合军事和海洋勘探应用。
blackmanharris(512)[:10]
#输出:[6e-05, 6.2e-05, 6.9e-05, 7.9e-05, 9.4e-05, 0.000114, 0.000138, 0.000167, 0.0002, 0.000238]
4. 振动与结构健康监测
在大型结构(如桥梁、风力涡轮机)的健康监测中,Blackman-Harris窗用于分析结构振动响应。
其高动态范围能够同时捕捉强振动模态和微弱损伤特征,有助于早期故障检测和预测性维护。
blackmanharris(1024,1)[:10]
#输出:[6e-05, 6.1e-05, 6.2e-05, 6.5e-05, 6.9e-05, 7.3e-05, 7.9e-05, 8.6e-05, 9.4e-05, 0.000104]
5. 医学成像与信号处理
在医学超声成像中,Blackman-Harris窗用于波束形成和频谱分析。
其优异的旁瓣抑制特性能够提高图像对比度和分辨率,减少伪影,特别适合细微组织结构成像和多普勒血流测量。
blackmanharris(256,0)[:10]
#输出:[6e-05, 6.9e-05, 9.4e-05, 0.000138, 0.0002, 0.000281, 0.000383, 0.000508, 0.000656, 0.000832]
6. 地震勘探与地质分析
在地震数据处理中,Blackman-Harris窗用于提高地震剖面的分辨率。
其极低的旁瓣电平有助于区分紧密间隔的地层反射,提高油气勘探的准确性和地层解释的可靠性。
blackmanharris(4096,1)[:10]
#输出:[6e-05, 6e-05, 6e-05, 6e-05, 6.1e-05, 6.1e-05, 6.1e-05, 6.2e-05, 6.2e-05, 6.3e-05]
7. 通信系统测试与校准
在通信设备测试中,Blackman-Harris窗用于频谱纯度测量和互调失真分析。
其卓越的动态范围特性能够准确测量极低水平的杂散信号和失真产物,适合5G设备、卫星通信系统等高要求应用。
blackmanharris(128)[:10]
#输出:[6e-05, 9.5e-05, 0.000202, 0.000388, 0.000667, 0.001054, 0.001574, 0.002251, 0.00312, 0.004215]
8. 音频恢复与修复
在历史音频修复和文化遗产保护中,Blackman-Harris窗用于分析老旧录音的频谱特性。
其高动态范围能够同时保留强信号和提取微弱信号,有助于去除噪声和恢复原始音频质量。
blackmanharris(512,0)[:10]
#输出:[6e-05, 6.2e-05, 6.9e-05, 7.9e-05, 9.4e-05, 0.000114, 0.000138, 0.000166, 0.0002, 0.000238]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy import signal
def blackmanharris_window(input_str):
"""
根据输入的字符串生成Blackman-Harris窗口。
参数:
input_str (str): 输入字符串,可以是单个整数M或元组(M, sym)。
M为窗口长度,sym为是否对称(True/False或0/1)。
返回:
list or str: 生成的窗口列表,或错误信息字符串。
"""
try:
# 解析输入字符串为SymPy表达式
expr = sp.sympify(input_str)
error = False
result = None
# 情况1:输入为元组 (M, sym)
if isinstance(expr, tuple) and len(expr) == 2:
# 检查窗口长度M是否为整数
if expr[0].is_integer:
m = int(expr[0])
else:
error = True
# 解析sym参数
if expr[1].is_number: # 处理数值型参数
sym = expr[1] != 0
else:
error = True
# 生成窗口
if not error:
try:
window = signal.windows.blackmanharris(m, sym)
except ValueError as e:
return f"参数错误:{e}"
# 情况2:输入为单个整数M
elif expr.is_integer:
m = int(expr)
try:
window = signal.windows.blackmanharris(m)
except ValueError as e:
return f"参数错误:{e}"
# 无效输入格式
else:
error = True
result = [round(x, 6) for x in window] # 保留6位小数
return result if not error else f"输入错误: {input_str}"
except sp.SympifyError:
return f"语法错误:无法解析输入 '{input_str}'"
except Exception as e:
return f"运行时错误:{str(e)}"
def main():
"""主函数,演示函数用法及测试用例"""
test_cases = [
"64", # 有效输入:生成默认对称窗口
"(64, 0)", # 有效输入:非对称窗口
"(64, 1)", # 有效输入:对称窗口
"(64, 2.5)", # 有效输入:sym=2.5视为True
]
for case in test_cases:
print(f"输入:{case}")
output = blackmanharris_window(case)
print(f"输出:{output}\n{'-' * 40}")
if __name__ == "__main__":
main()
修正的Bartlett-Hann窗
修正的Bartlett-Hann窗(Barthann窗)结合了Bartlett窗和Hann窗的特性,提供了良好的频率分辨率和适中的旁瓣抑制。
w = barthannwin(L,sym=1) 返回一个长度为L个点的修正的Bartlett-Hann窗, 默认sym=1
当sym=1, 生成一个对称窗口,用于滤波器设计.
当sym=0, 生成一个周期性窗口,用于光谱分析.
1. 语音信号处理
在语音识别和分析中,Barthann窗用于短时傅里叶变换(STFT)。
256点的窗口长度适合分析语音信号的频谱特性,其平滑的窗函数形状有助于准确提取共振峰特征,同时减少频谱泄漏,提高语音识别精度。
barthannwin(256)[:10]
#输出: [0.0, 0.001998, 0.004226, 0.006685, 0.009374, 0.012292, 0.015439, 0.018815, 0.022418, 0.026247]
2. 振动信号分析
在机械故障诊断中,Barthann窗用于分析旋转设备的振动信号。
512点的非对称窗口适合捕捉瞬态振动特征,其平衡的频率分辨率和旁瓣抑制特性有助于检测早期故障信号,同时减少噪声干扰。
barthannwin(512,0)[:10]
#输出: [0.0, 0.000966, 0.001989, 0.00307, 0.004208, 0.005403, 0.006655, 0.007964, 0.00933, 0.010753]
3. 生物医学信号处理
在心电图(ECG)和脑电图(EEG)分析中,Barthann窗用于提取生物电信号的频谱特征。
128点的窗口长度适合分析生理信号的节律特性,其适中的主瓣宽度和旁瓣抑制能够准确识别心搏周期或脑电节律。
barthannwin(128)[:10]
#输出: [0.0, 0.004244, 0.009418, 0.015516, 0.022535, 0.030465, 0.039297, 0.049018, 0.059613, 0.071067]
4. 音频均衡与滤波
在音频处理中,Barthann窗用于设计数字均衡器和滤波器。
64点的对称窗口适合实现中等复杂度的音频处理算法,其平滑的频率响应特性能够减少音频处理中的预回声和振铃效应。
barthannwin(64,1)[:10]
#输出: [0.0, 0.009507, 0.022773, 0.039739, 0.060315, 0.084371, 0.111744, 0.142236, 0.175622, 0.211645]
5. 通信系统同步
在数字通信系统中,Barthann窗用于符号定时同步和载波频率估计。
32点的小窗口适合快速变化的通信环境,其良好的主瓣特性有助于准确估计定时偏移和频率偏差。
barthannwin(32)[:10]
#输出: [0.0, 0.023262, 0.061764, 0.114562, 0.180128, 0.256413, 0.340927, 0.430845, 0.523118, 0.614603]
6. 地震数据分析
在地震勘探中,Barthann窗用于处理地震波形数据。
1024点的大窗口适合分析低频地震波,其平衡的频率特性有助于准确识别不同地层界面的反射信号,同时保持合理的计算效率。
barthannwin(1024,1)[:10]
#输出: [0.0, 0.000476, 0.000967, 0.001472, 0.001992, 0.002525, 0.003073, 0.003636, 0.004212, 0.004803]
7. 图像处理中的频域滤波
在图像处理中,Barthann窗可用于设计2D滤波器或在频域滤波中作为窗函数。
16点的小窗口适合局部特征分析,能够有效平衡频率分辨率和旁瓣抑制,在图像增强和特征提取中表现良好。
barthannwin(16)[:10]
#输出: [0.0, 0.064853, 0.18973, 0.358574, 0.547721, 0.73, 0.879426, 0.975696, 0.975696, 0.879426]
8. 雷达信号处理
在脉冲雷达系统中,Barthann窗用于距离处理和 Doppler 分析。
256点的非对称窗口适合中等距离分辨率的应用,能够提供良好的主瓣特性同时抑制距离旁瓣,提高目标检测性能。
barthannwin(256,0)[:10]
#输出: [0.0, 0.001989, 0.004208, 0.006655, 0.00933, 0.012233, 0.015363, 0.018719, 0.022302, 0.026108]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy import signal
def barthannwin_window(input_str):
"""
生成Barthann窗函数系数
参数:
input_str (str): 输入字符串,可以是单个整数M,或两个数值的元组(M, sym_flag)
- M: 窗口长度(正整数)
- sym_flag: 对称标志,0表示非对称(periodic),非0表示对称(symmetric)
返回:
list or str: 成功返回窗系数列表,失败返回错误信息字符串
"""
try:
# 将输入字符串转换为SymPy表达式
expr = sp.sympify(input_str)
error = False
result = None
# 情况1:输入为元组 (M, sym_flag)
if isinstance(expr, tuple) and len(expr) == 2:
# 检查两个元素是否为数字
if all(e.is_number for e in expr):
m = int(expr[0]) # 转换为整数
sym_flag = int(expr[1])
# 参数校验
if m <= 0:
return f"错误: 窗口长度M必须为正整数"
# 生成窗函数(sym_flag=0时sym=False,否则True)
window = signal.windows.barthann(m, sym=(sym_flag != 0))
result = list(window.round(6)) # 保留6位小数
else:
error = True
# 情况2:输入为单个整数M
elif expr.is_number:
m = int(expr)
if m <= 0:
return f"错误: 窗口长度M必须为正整数"
window = signal.windows.barthann(m)
result = list(window.round(6))
# 情况3:无效输入
else:
error = True
if error:
return f"输入错误: 无效格式或参数 '{input_str}'"
return result
except Exception as e:
return f"错误: {e}"
if __name__ == "__main__":
# --------------------------
# 示例测试
# --------------------------
test_cases = [
"10", # 输出: 前3个系数 [0.0, 0.142236, 0.42068] ... 后3个系数 [0.42068, 0.142236, 0.0]
"(5, 0)", # 输出: 前3个系数 [0.0, 0.358574, 0.879426] ... 后3个系数 [0.879426, 0.879426, 0.358574]
"(7, 1)", # 输出: 前3个系数 [0.0, 0.27, 0.73] ... 后3个系数 [0.73, 0.27, 0.0]
]
for case in test_cases:
print(f"输入: {case}")
output = barthannwin_window(case)
if isinstance(output, list):
print(f"输出: 前3个系数 {output[:3]} ... 后3个系数 {output[-3:]}\n")
else:
print(f"输出: {output}\n")
伯努利数与多项式
bernoulli(n)返回第n个伯努利数.
bernoulli(n,x)返回第n个伯努利多项式.
n - 伯努利数或多项式的索引.
非负整数|符号非负整数|symbol变量|符号表达式|符号函数|符号向量|符号矩阵
x - 是多项式变量.
实数|符号变量|符号表达式|符号函数|符号向量|符号矩阵
多项式变量,指定为符号变量、表达式、函数、向量或矩阵。如果x是向量或矩阵,则伯努利为x的每个元素返回伯努利数或多项式。
当使用伯努利函数查找伯努利多项式时,至少一个参数必须是标量,或者两个参数都必须是相同大小的向量或矩阵。
如果一个输入自变量是标量,而另一个是向量或矩阵,则伯努利(n,x)将标量扩展为与另一个自变量大小相同的向量或矩阵(所有元素都等于该标量)。
如果x是一个数字,则伯努利在该数字上计算多项式,这里的结果是一个浮点数.
1. 数值分析与求和公式
在欧拉-麦克劳林求和公式中,伯努利数用于将求和与积分联系起来。
例如,计算前n个自然数的p次幂和时,伯努利数出现在公式的系数中。这在数值积分和离散求和近似中非常有用,特别是在计算大数求和时可以提高效率。
bernoulli(10)
#结果: 0.0757575757575756
bernoulli(5,0.5)
#结果: 1.435240815084171e-13
2. 热力学与统计物理
在理想玻色气体和费米气体的统计力学中,伯努利多项式出现在配分函数的展开式中。
特别是在低温极限下,伯努利多项式用于描述量子气体的热力学性质,如比热容和压缩率。
bernoulli(4,x)
#结果: x^4 - 2*x^3 + x^2 - 1/30
3. 数论与特殊函数
在解析数论中,伯努利数与黎曼ζ函数有密切关系:ζ(1-n) = -B_n/n。
这使得伯努利数在质数分布理论和L函数的研究中非常重要。伯努利多项式也出现在某些类型的模形式的傅里叶展开中。
bernoulli(12)
#结果: -0.253113553113553
bernoulli(3,y)
#结果: y^3 - 3*y^2/2 + y/2
4. 近似理论与插值
在数值分析中,伯努利多项式用于构造某些类型的插值公式和近似方法。
特别是在周期函数的逼近中,伯努利多项式提供了一种有效的基函数系统,用于最小二乘拟合和谱方法。
bernoulli(6,t)
#结果: t^6 - 3*t^5 + 5*t^4/2 - t^2/2 + 1/42
5. 概率论与组合数学
在概率论中,伯努利数与某些随机变量的矩有关,特别是在泊松过程和相关分布中。
在组合数学中,伯努利数计数了某些类型的排列和分区,如带有特定限制的排列数。
bernoulli(8)
#结果: -0.0333333333333330
bernoulli(4,0.25)
#结果: 0.0018229166667240865
6. 流体动力学
在势流理论中,伯努利多项式出现在某些边界值问题的解中。
特别是在计算绕圆柱或椭圆柱的势流时,伯努利多项式可以帮助描述流函数和速度势。
bernoulli(2,z)
#结果: z^2 - z + 1/6
7. 信号处理与滤波器设计
在某些特殊类型的数字滤波器设计中,伯努利多项式用于构造具有特定频率响应的滤波器。
这些滤波器在需要精确控制相位和幅度特性的应用中很有用。
bernoulli(16)
#结果: -7.09215686274510
bernoulli(5,0.75)
#结果: 0.024414062500215203
8. 金融数学
在期权定价和利率模型等金融数学问题中,伯努利多项式有时出现在某些近似公式和展开式中,特别是在处理连续复利和年金计算时。
bernoulli(10,x)
#结果: x^10 - 5*x^9 + 15*x^8/2 - 7*x^6 + 5*x^4 - 3*x^2/2 + 5/66
9. 量子力学
在量子力学中,伯努利多项式出现在某些势阱问题的波函数展开中,特别是在计算能级和跃迁概率时。
bernoulli(4,phi)
#结果: phi^4 - 2*phi^3 + phi^2 - 1/30
10. 计算机科学中的算法分析
在分析算法复杂度时,伯努利数有时出现在求和公式的精确解中,特别是在分析分治算法和递归算法的运行时间时。
bernoulli(20)
#结果: -529.124242424243
bernoulli(6,0.5)
#结果: -0.02306547619026231
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.special import comb, bernoulli
def bernoulli_number_polynomials(input_str):
"""
计算伯努利数或伯努利多项式,支持矩阵输入
参数:
input_str (str): 输入表达式,支持以下形式:
- 单个整数 n(返回伯努利数 B_n)
- 元组 (n, x)(返回伯努利多项式 B_n(x))
- 矩阵形式(元素级计算)
返回:
Union[sp.Expr, sp.Matrix, str]: 计算结果或错误信息
"""
try:
expr = sp.sympify(input_str)
result = None
error = False
def bernoulli_poly(n, x):
# 获取前n+1个伯努利数(索引0到n)
B = bernoulli(n)
# 计算多项式展开式
total = 0.0
for k in range(n + 1):
total += comb(n, k) * B[k] * x ** (n - k)
return total
# 情况1:输入为元组 (n, x) 形式
if isinstance(expr, tuple) and len(expr) == 2:
# 检查所有元素是否有符号类型
if any(e.free_symbols for e in expr):
result = sp.bernoulli(*expr)
# 检查所有元素是否为数值类型
elif all(e.is_number for e in expr):
n = int(expr[0])
x = float(expr[1])
result = bernoulli_poly(n, x)
else:
error = True
# 情况2:标量输入
elif expr.is_integer:
n = int(expr)
result = bernoulli(n)[-1]
# 情况3:
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
if __name__ == "__main__":
# ======================
# 测试用例
# ======================
test_cases = [
# 有效标量输入
("5", "伯努利数 B_5"), #结果: 0.0
("(3, 0.5)", "多项式 B_3(0.5)"), #结果: 0.0
# 边界测试
("0", "B_0 = 1"), #结果: 1.0
]
for case, desc in test_cases:
print(f"测试案例: {desc}")
print(f"输入: {case}")
output = bernoulli_number_polynomials(case)
print(f"结果: {output}")
print("-" * 50)
第一类修正贝塞尔函数
第一类修正贝塞尔函数(Iv(x))在物理学、工程学和数学中有广泛的应用。
I = besseli(nu,Z) 为数组 Z 中的每个元素计算第一类修正贝塞尔函数.
nu是方程的阶,可以是标量,向量,矩阵,多维数组
Z是函数的域,可以是标量,向量,矩阵,多维数组
1. 热传导与扩散问题
在圆柱坐标系中的热传导问题中,修正贝塞尔函数出现在稳态解中。
例如,计算半径为2.5个单位的圆柱体在特定边界条件下的温度分布。
besseli(0,2.5)
#结果: 3.28983914405012
besseli(1,3.2)
#结果: 4.73425389470962
2. 电磁波在波导中的传播
在圆柱形波导中,计算特定模式(n=2)在距离轴心1.8个单位处的场强,或者计算基模(n=0)在2.4个单位处的场强。
besseli(2,1.8)
#结果: 0.526040211738163
besseli(0,2.4)
#结果: 3.04925665798941
3. 概率论与统计学
在冯·米塞斯分布(圆形正态分布)中,计算浓度参数κ=1.5时的归一化常数I₀(1.5),用于处理周期性数据如风向分析。
besseli(0,1.5)
#结果: 1.64672318977289
4. 信号处理与滤波
在贝塞尔滤波器设计中,计算三阶滤波器在归一化频率2.1处的响应特性,用于保持信号形状的应用。
besseli(3,2.1)
#结果: 0.252352458138809
5. 声学与振动分析
在柱对称声学问题中,计算距离声源1.2个单位处的声压分布,用于扬声器设计或管道声学分析。
besseli(0,1.2)
#结果: 1.39372558413406
6. 量子力学
在量子力学中,计算角量子数l=2的粒子在径向距离0.8处的波函数幅度,或基态(l=0)在距离1.5处的概率幅分布。
besseli(2,0.8)
#结果: 0.0843529163182032
besseli(0,1.5)
#结果: 1.64672318977289
7. 流体动力学
在振荡流通过圆柱的问题中,计算距离轴心2.0个单位处的流体速度,用于分析血液在动脉中的流动或工业流体系统。
besseli(1,2)
#结果: 1.59063685463733
8. 无线通信
在瑞利衰落信道中,计算信噪比参数为3.0时的接收信号幅度分布,用于无线通信系统性能分析。
besseli(0,3)
#结果: 4.88079258586502
9. 图像处理
在图像处理中,计算一阶或二阶修正贝塞尔函数在特定距离(1.5或2.0)处的值,用于构造径向对称滤波器核。
besseli(1,1.5)
#结果: 0.981666428577907
besseli(2,2)
#结果: 0.688948447698738
10. 金融数学
在随机过程模型中,计算特定参数(ν=1, λ和σ的组合使得√(2λx)/σ=1.2)下的转移概率密度,用于利率建模和期权定价。
besseli(1,1.2)
#结果: 0.714677941552643
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.special import iv
def bessel_i_calculate(input_str):
"""
计算修正的第一类贝塞尔函数,支持标量和矩阵输入
参数:
input_str (str): 输入表达式,支持格式:
- "(v, x)":计算Iv(x),v和x可以是标量或矩阵
- 单个数值或矩阵:元素级计算Iv(n)
返回:
Union[sp.Expr, sp.Matrix, str]: 计算结果或错误信息
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
# 情况1:输入为元组 (v, x)
if isinstance(expr, tuple) and len(expr) == 2:
# 检查所有元素是否有符号类型
if any(e.free_symbols for e in expr):
result = sp.expand_func(sp.besseli(*expr))
# 检查所有元素是否为数值类型
elif all(e.is_number for e in expr):
v = float(expr[0])
x = complex(expr[1])
result = iv(v, x)
else:
error = True
# 无效输入类型
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
if __name__ == "__main__":
# ======================
# 测试用例
# ======================
test_cases = [
# 有效标量输入
("(0, 5)", "Iv(0,5)"), #结果: (27.239871823604446+0j)
("(2, 3.5)", "Iv(2,3.5)"), #结果: (3.832012048077842+0j)
# 特殊值测试
("(1, 0)", "Iv(1,0)=0"), #结果: 0j
("(0.5, 1)", "半整数阶"), #结果: (0.9376748882454888+0j)
]
for case, desc in test_cases:
print(f"测试案例: {desc}")
print(f"输入: {case}")
output = bessel_i_calculate(case)
print("结果:", output)
print("-" * 50)
第一类贝塞尔函数
第一类贝塞尔函数(Jₙ(x))在物理学、工程学和数学中有极其广泛的应用。
I = besselj(nu,Z) 为数组 Z 中的每个元素计算第一类贝塞尔函数.
nu是方程的阶,可以是标量,向量,矩阵,多维数组
Z是函数的域,可以是标量,向量,矩阵,多维数组
1. 圆柱形膜振动
计算半径为3.8317个单位的圆形膜在二阶振动模式(n=2)下的贝塞尔函数值。
这个特定的值(3.8317)接近J₂(x)的第一个零点,对于确定鼓膜或扬声器膜的振动模式非常重要。
besselj(2,3.8317)
#结果: 0.402760650782696 - 2.33014321788975e-16ⅈ
2. 电磁波在圆柱波导中的传播
计算圆柱形波导中TM₀₁模式的截止频率相关参数。
2.4048是J₀(x)的第一个零点,决定了波导中最低阶横磁模式的截止条件。
besselj(1, 2.4048)
#结果: 0.519153014507553 - 6.16297582203915e-33ⅈ
3. 热传导问题
在圆柱坐标系中的热传导问题中,计算半径1.5个单位处的温度分布。
J₀(1.5)出现在无限长圆柱的稳态热传导解中。
besselj(0, 1.5)
#结果: 0.511827671735918
4. 声学中的衍射模式
计算圆形孔径声学衍射的三阶模式在4.2个波长距离处的幅度。
这对于扬声器设计和声学成像系统非常重要。
besselj(3, 4.2)
#结果: 0.434394276387201 + 5.10396122978925e-17ⅈ
5. 信号处理中的调频分析
在频率调制(FM)信号分析中,计算调制指数为2.5时的载波幅度。
J₀(2.5)给出了FM信号中载波分量的相对幅度。
besselj(0, 2.5)
#结果: -0.0483837764681979 + 4.43511160492778e-18ⅈ
6. 量子力学中的势阱问题
计算无限深圆柱形势阱中粒子波函数的相关参数。
5.1356接近J₂(x)的第一个零点,用于确定量子化能级。
besselj(2, 5.1356)
#结果: 7.575254633593e-6 + 2.25718798642556e-21ⅈ
7. 流体力学中的粘性流动
在圆柱管中的振荡流问题中,计算距离轴心3.0个单位处的流速分布。
这对于血液流动分析和工业管道设计很重要。
besselj(1,3)
#结果: 0.339058958525936 - 7.78706977665213e-18ⅈ
8. 天线理论中的辐射模式
计算圆形孔径天线的辐射模式参数。1.8412是J₁(x)的第一个零点,决定了天线主瓣的宽度和旁瓣电平。
besselj(0,1.8412)
#结果: 0.316018343628141
9. 图像处理中的滤波器设计
在图像处理中,计算四阶贝塞尔滤波器在归一化频率2.0处的响应。
贝塞尔滤波器具有线性相位特性,适合需要保持信号形状的应用。
besselj(4,2)
#结果: 0.0339957198075684 + 8.32654988940979e-18ⅈ
10. 地球物理学中的波动传播
在地震波或声波在分层介质中传播的问题中,计算特定参数下的波场分布。
J₀(2.0)出现在柱对称波动方程的解中。
besselj(0,2)
#结果: 0.223890779141236
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.special import jv
def bessel_j_calculate(input_str):
"""
计算贝塞尔函数J_n(x),支持标量、向量和矩阵输入
参数:
input_str: 数学表达式字符串,支持格式:
- 参数元组 "(n, x)",其中n和x可以是:
* 标量(整数/浮点数)
* 一维列表(自动转为列向量)
* 二维列表或SymPy矩阵
返回:
SymPy矩阵/数值 或 错误信息字符串
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
# 情况1:输入为元组 (v, x)
if isinstance(expr, tuple) and len(expr) == 2:
# 检查所有元素是否为数值类型
if any(e.free_symbols for e in expr):
result = sp.expand_func(sp.besselj(*expr))
elif all(e.is_number for e in expr):
v = float(expr[0])
x = complex(expr[1])
result = jv(v, x)
else:
error = True
# 无效输入类型
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
if __name__ == "__main__":
# 示例测试用例
test_cases = [
("(2.2, 5+2j)", "标量参数"), #输出: (0.23703505374382045-1.0739195381970457j)
]
for input_str, desc in test_cases:
print(f"测试用例:{desc}")
print(f"输入:{input_str}")
result = bessel_j_calculate(input_str)
print("输出:")
sp.pprint(result) # 使用SymPy的美化打印
print("\n" + "=" * 50 + "\n")
第一类贝塞尔函数的第k个零点
第一类贝塞尔函数的零点在物理学和工程学中有广泛的应用,特别是在涉及圆形或柱对称系统的问题中。
I = besseljZero(n,k) 返回第k个零点的值
n - 整数,贝塞尔函数的阶数
k - 整数,要返回的零数
1. 圆形膜振动频率计算
计算圆形鼓膜或扬声器膜的振动频率。Jₙ(x)的第k个零点决定了特定振动模式的频率。
例如,J₀(x)的第一个零点(约2.4048)对应基频,J₂(x)的第三个零点对应更高阶的振动模式。
J₀(x)的第一个零点 → 圆形膜的基频振动模式
besseljZero(0,1)
#结果: 2.404825557695773
J₂(x)的第三个零点 → 具有2个径向节线和3个角向节线的复杂振动模式
besseljZero(2,3)
#结果: 11.61984117214906
J₅(x)的第二个零点 → 高频振动模式,适合分析精密传感器的共振特性
besseljZero(5,2)
#结果: 12.338604197466944
2. 圆柱形波导的截止频率
确定圆柱形波导中电磁波的截止频率。对于TM模式,截止频率与J₀(x)的零点相关;对于TE模式,与J₁(x)的零点相关。
例如,J₀(x)的第二个零点决定了TM₀₂模式的截止频率。
J₁(x)的第一个零点 → TE₁₁模式(最常见的圆波导工作模式)
besseljZero(1,1)
#结果: 3.8317059702075125
J₀(x)的第二个零点 → TM₀₂模式(用于特殊应用的更高阶模式)
besseljZero(0,2)
#结果: 5.520078110286311
J₃(x)的第一个零点 → 高次模,用于多模通信系统
besseljZero(3,1)
#结果: 6.380161895923984
3. 声学共振腔设计
设计圆柱形声学共振腔的尺寸。Jₙ(x)的零点决定了共振频率,这对于音乐乐器设计、建筑声学和噪声控制应用非常重要。
主共振频率(用于乐器设计)
besseljZero(0,1)
#结果: 2.404825557695773
第一次谐波(影响音色特性)
besseljZero(1,1)
#结果: 3.8317059702075125
第五次谐波(用于高精度声学测量)
besseljZero(0,5)
#结果: 14.930917708487787
4. 光纤模式分析
计算光纤中光波的传播模式。贝塞尔函数零点决定了光纤中可以支持的模式数量及其特性,这对于光纤通信系统的设计至关重要。
基模(LP₀₁)的截止条件
besseljZero(0,1)
#结果: 2.404825557695773
LP₁₂模式的传播特性
besseljZero(1,2)
#结果: 7.015586669815619
高阶模式LP₄₁,用于特殊传感应用
besseljZero(4,1)
#结果: 7.5883424345038035
5. 量子力学中的无限深圆柱形势阱
确定粒子在无限深圆柱形势阱中的能级。能级与Jₙ(x)的零点平方成正比,这对于理解量子限制系统中的能级结构非常重要。
s轨道基态能级
besseljZero(0,1)
#结果: 2.404825557695773
p轨道第一激发态
besseljZero(1,1)
#结果: 3.8317059702075125
d轨道高激发态,用于量子计算研究
besseljZero(2,3)
#结果: 11.61984117214906
6. 热传导问题中的特征值
求解圆柱坐标系中的热传导方程时,Jₙ(x)的零点出现在特征值问题中,决定了温度分布的时空演化。
besseljZero(0,1)
#结果: 2.404825557695773
besseljZero(1,1)
#结果: 3.8317059702075125
7. 天线设计中的辐射模式
计算圆形孔径天线的辐射模式。J₁(x)的第一个零点决定了主瓣的宽度,而高阶零点影响旁瓣结构。
确定主瓣宽度
besseljZero(1,1)
#结果: 3.8317059702075125
控制第一个旁瓣位置
besseljZero(2,1)
#结果: 5.135622301840683
优化远场辐射模式
besseljZero(1,3)
#结果: 10.173468135062722
8. 流体力学中的振荡流
分析圆柱管中振荡流的速度分布。贝塞尔函数零点出现在解中,决定了流动的相位和幅度分布。
besseljZero(0,1)
#结果: 2.404825557695773
besseljZero(1,1)
#结果: 3.8317059702075125
9. 地震学中的面波分析
研究地球表面波的传播特性。贝塞尔函数零点出现在柱对称波动方程的解中,对于理解地震波的传播模式很重要。
besseljZero(0,1)
#结果: 2.404825557695773
besseljZero(1,1)
#结果: 3.8317059702075125
10. 图像处理中的滤波器设计
设计基于贝塞尔函数的图像处理滤波器。这些滤波器的截止频率通常与贝塞尔函数的零点相关,用于实现特定的频率响应特性。
besseljZero(0,1)
#结果: 2.404825557695773
besseljZero(1,1)
#结果: 3.8317059702075125
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.special import jn_zeros
def bessel_j_zero(input_str):
"""
计算贝塞尔函数J_n的第k个零点,支持标量、向量和矩阵输入
参数:
input_str: 数学表达式字符串,支持格式:
- 参数元组 "(n, k)",其中n和k可以是:
* 标量(整数)
* 一维列表(自动转为列向量)
* 二维列表或SymPy矩阵
返回:
SymPy矩阵/数值 或 错误信息字符串
"""
try:
# 将输入字符串解析为SymPy表达式
expr = sp.sympify(input_str)
error = False
result = None
# 检查是否为参数元组(SymPy Tuple类型)
if isinstance(expr, tuple) and len(expr) == 2:
# 检查所有元素是否为数值类型
if all(e.is_integer for e in expr):
# 转换为整数的元组
params = tuple(int(e.evalf()) for e in expr)
result = jn_zeros(*params)[-1]
elif any(e.free_symbols for e in expr):
result = sp.jn(expr[0] + 0.5, expr[1])
else:
error = True
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"计算错误: {str(e)}"
# 实现besseljZero, 请检查代码。
if __name__ == "__main__":
# 示例测试用例
test_cases = [
("(0, 1)", "标量参数:J0的第一个零点"), #结果: 2.404825557695773
]
for input_str, desc in test_cases:
print(f"测试用例:{desc}")
print(f"输入:{input_str}")
result = bessel_j_zero(input_str)
print("输出:")
sp.pprint(result) # 使用SymPy的美化打印
print("\n" + "=" * 50 + "\n")
第二类修正贝塞尔函数
第二类修正贝塞尔函数 K_n(x) 在物理学和工程学中有广泛的应用,特别是在描述指数衰减行为的问题中。
I = besselk(nu,Z) 为数组 Z 中的每个元素计算第二类修正贝塞尔函数.
nu是方程的阶,可以是标量,向量,矩阵,多维数组
Z是函数的域,可以是标量,向量,矩阵,多维数组
1. 热传导问题中的温度分布
在圆柱坐标系中的热传导问题中,K_n(x) 描述了温度随距离的指数衰减。
例如,计算距离热源1.5个单位处的温度分布(使用K₀),或计算具有角向变化的温度场(使用K₁)。
besselk(0,1.5)
#结果: 0.213805562647526
besselk(1,2)
#结果: 0.139865881816522
2. 电磁场中的衰减波
在波导或传输线中,K_n(x) 描述了截止频率以下的电磁场衰减。
例如,计算距离波导轴心2.5个单位处的场强衰减(使用K₀),或分析角向变化的衰减模式(使用K₁)。
besselk(0,2.5)
#结果: 0.0623475532003662
besselk(1,3)
#结果: 0.0401564311281942
3. 量子力学中的势垒穿透
在量子力学中,K_n(x) 描述了粒子在势垒区域的波函数衰减。
例如,计算粒子在势垒内1.2个单位距离处的穿透概率(使用K₀),或分析角动量不为零的粒子的衰减行为(使用K₁)。
besselk(0,1.2)
#结果: 0.318508220286594
besselk(1,1.8)
#结果: 0.182623099801747
4. 声学中的衰减场
在声学中,K_n(x) 描述了声波在耗散介质中的衰减。
例如,计算距离声源0.8个单位处的声压衰减(使用K₀),或分析高阶衰减模式(使用K₂)。
besselk(0,0.8)
#结果: 0.565347105265896
besselk(2,1.5)
#结果: 0.583655963256651
5. 流体力学中的粘性效应
在流体力学中,K_n(x) 描述了粘性流体中的速度分布衰减。
例如,计算距离边界层2.0个单位处的流速衰减(使用K₀),或分析旋转流体的衰减行为(使用K₁)。
besselk(0,2)
#结果: 0.113893872749533
besselk(1,2.5)
#结果: 0.0738908163477471
6. 核物理中的中子扩散
在核反应堆物理中,K_n(x) 描述了中子在介质中的扩散和吸收。
例如,计算距离中子源3.0个单位处的中子通量衰减(使用K₀),或分析角向不对称的扩散模式(使用K₁)。
besselk(0,3)
#结果: 0.0347395043862793
besselk(1,2.2)
#结果: 0.107896810119087
7. 地球物理学中的热流
在地球物理学中,K_n(x) 描述了地壳中的热流分布。
例如,计算距离热源1.5个单位深处的地温梯度(使用K₀),或分析非均匀地热场的分布(使用K₁)。
besselk(0,1.5)
#结果: 0.213805562647526
besselk(1,2)
#结果: 0.139865881816522
8. 电磁兼容性中的屏蔽效应
在电磁兼容性设计中,K_n(x) 描述了电磁波在屏蔽材料中的衰减。
例如,计算电磁波穿透2.5个单位厚度屏蔽材料后的场强(使用K₀),或分析特定极化模式的衰减(使用K₁)。
besselk(0,2.5)
#结果: 0.0623475532003662
besselk(1,3)
#结果: 0.0401564311281942
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.special import kv
def bessel_k_calculate(input_str):
"""
计算第二类修正贝塞尔函数K_n(x),支持标量、向量和矩阵输入
参数:
input_str: 数学表达式字符串,支持格式:
- 参数元组 "(n, x)",其中n和x可以是:
* 标量(整数/浮点数)
* 一维列表(自动转为列向量)
* 二维列表或SymPy矩阵
返回:
SymPy矩阵/数值 或 错误信息字符串
"""
try:
# 将输入字符串解析为SymPy表达式
expr = sp.sympify(input_str)
error = False
result = None
# 检查是否为参数元组(SymPy Tuple类型)
if isinstance(expr, tuple) and len(expr) == 2:
# 数值标量计算模式
if all(e.is_number for e in expr):
nu = float(expr[0])
Z = complex(expr[1])
result = kv(nu, Z)
elif any(e.free_symbols for e in expr):
# 符号标量计算模式
result = sp.expand_func(sp.besselk(*expr))
else:
error = True
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"计算错误: {str(e)}"
if __name__ == "__main__":
# 示例测试用例
test_cases = [
("(0, 1)", "标量参数:K0(1)"), #结果: (0.42102443824070834+0j)
]
for input_str, desc in test_cases:
print(f"测试用例:{desc}")
print(f"输入:{input_str}")
result = bessel_k_calculate(input_str)
print("输出:")
sp.pprint(result) # 使用SymPy的美化打印
print("\n" + "=" * 50 + "\n")
第二类贝塞尔函数
第二类贝塞尔函数 Y_n(x),也称为Neumann函数或Weber函数,在物理学和工程学中有广泛的应用,特别是在涉及柱对称问题和边界条件的场景中。
I = bessely(nu,Z) 为数组 Z 中的每个元素计算第二类贝塞尔函数.
nu是方程的阶,可以是标量,向量,矩阵,多维数组
Z是函数的域,可以是标量,向量,矩阵,多维数组
1. 柱对称波动方程的通解
在柱坐标系中的波动方程(如声波或电磁波)求解中,通解通常包含第一类和第二类贝塞尔函数的组合。
Y_n(x) 提供了在原点处奇异但满足特定边界条件的解分量。例如,计算距离轴心2.5个单位处的波动场强。
bessely(0,2.5)
#结果: 0.498070359615232
bessely(1,3)
#结果: 0.324674424791800
2. 圆柱形腔体的声学共振
在圆柱形空腔的声学共振问题中,Y_n(x) 与 J_n(x) 组合形成满足刚性边界条件的解。
例如,计算具有特定角向模式(n=1)的声场在距离轴心2.0个单位处的压力分布。
bessely(1,2)
#结果: -0.107032431540938
bessely(2,3.5)
#结果: 0.0453714377291803
3. 电磁波在圆柱体周围的散射
在电磁波散射问题中,Y_n(x) 描述了散射场的特性。
例如,计算平面波照射无限长圆柱体时,距离圆柱体表面4.0个单位处的散射场幅度。
bessely(0,4)
#结果: -0.0169407393250650
bessely(1,5)
#结果: 0.147863143391227
4. 量子力学中的势散射
在量子力学中,Y_n(x) 出现在柱对称势散射问题的径向波函数中。
例如,计算角动量为零的粒子在距离散射中心1.5个单位处的波函数幅度。
bessely(0,1.5)
#结果: 0.382448923797759
bessely(1,2)
#结果: -0.107032431540938
5. 热传导问题的外部解
在柱坐标系中的热传导问题中,当考虑外部区域(如圆柱体周围的介质)时,Y_n(x) 提供了满足无穷远处边界条件的解。
例如,计算距离热圆柱体2.5个单位处的温度分布。
bessely(0,2.5)
#结果: 0.498070359615232
bessely(1,3)
#结果: 0.324674424791800
6. 流体力学中的势流问题
在理想流体绕圆柱体的流动中,Y_n(x) 出现在流函数或速度势的表达式中。
例如,计算距离圆柱体表面2.5个单位处的流速势。
bessely(1,2.5)
#结果: 0.145918137966786
bessely(2,3)
#结果: -0.160400393484924
7. 地震学中的面波分析
在地震面波(如Love波或Rayleigh波)的传播分析中,Y_n(x) 描述了地壳分层结构中的波场特性。
例如,计算距离震源1.5个单位深度处的面波幅度。
bessely(0,1.5)
#结果: 0.382448923797759
bessely(1,2)
#结果: -0.107032431540938
8. 天线理论中的辐射场计算
在柱对称天线的辐射场分析中,Y_n(x) 与 J_n(x) 组合形成满足辐射边界条件的解。
例如,计算距离天线3.0个单位处的辐射场幅度。
bessely(0,3)
#结果: 0.376850010012790
bessely(1,4)
#结果: 0.397925710557100
9. 弹性力学中的振动分析
在圆柱壳或杆的振动分析中,Y_n(x) 提供了满足特定边界条件的振动模式。
例如,计算距离固定端2.0个单位处的振动幅度。
bessely(0,2)
#结果: 0.510375672649745
bessely(1,2.5)
#结果: 0.145918137966786
10. 地球物理学中的地幔对流
在地幔对流的柱对称模型中,Y_n(x) 描述了温度或速度场的空间分布。
例如,计算距离地心3.0个单位半径处的对流速度。
bessely(2,3)
#结果: -0.160400393484924
bessely(3,4)
#结果: -0.182022115953485
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.special import yv
def bessel_y_calculate(input_str):
"""
计算第二类贝塞尔函数(Bessel Y函数)
参数:
input_str: 输入字符串,可以是元组 (n, x) 或单个表达式
返回:
计算结果(SymPy矩阵或数值)或错误信息
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
if isinstance(expr, tuple) and len(expr) == 2:
if all(e.is_number for e in expr):
nu = float(expr[0])
Z = complex(expr[1])
result = yv(nu, Z)
elif any(e.free_symbols for e in expr):
result = sp.expand_func(sp.bessely(*expr))
else:
error = True
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
def main():
"""
主函数,用于测试 bessel_y_calculate 函数
"""
# 示例 1: 单个数值输入
input_str1 = "(2, 3.5)"
result1 = bessel_y_calculate(input_str1)
print(f"输入: {input_str1}\n结果: {result1}\n") #结果: (0.04537143772918033+0j)
if __name__ == "__main__":
main()
第二类贝塞尔函数的第k个零点
I = besselyZero(n,k) 返回第k个零点的值
n - 整数,贝塞尔函数的阶数
k - 整数,要返回的零数
1. 标量输入
计算 Y₀(x) 的第 1 个零点
besselyZero(0,1)
#结果: 0.8935769662791676
计算 Y₂(x) 的第 3 个零点
besselyZero(2,3)
#结果: 10.023477979360038
2. 向量/矩阵输入
同时计算多个阶数的零点, 各阶的第一个零点
besselyZero([0,1,2],[1,1,1])
#结果: [0.89357697 2.19714133 3.38424177]
计算同阶多个零点,Y₂(x) 的前 3 个零点
besselyZero(2,[1,2,3])
#结果: [3.38424177 6.79380751 10.02347798]
完整矩阵运算
besselyZero([[0,1],[2,3]],[[1,2],[3,4]])
#结果: [[0.89357697,5.42968104]
[10.02347798,14.62307774]]
3. 符号计算(理论研究)
符号计算
besselyZero(n,k)
#结果: yn(n, k)
混合符号数值计算,第3个零点的符号表达式
besselyZero(n,3)
#结果: yn(n, 3)
4. 声学工程 - 多模式共振分析
分析前3阶的前3个零点
n_values = [0, 1, 2] # 0-3 阶
k_values = [1, 2, 3] # 前3个零点
besselyZero(n_values,k_values)
#结果: [0.89357697 5.42968104 10.02347798]
5. 微波工程 - 波导模式计算
计算重要电磁模式的零点
important_modes = [
(0, 1), # TM₀₁ 模式
(1, 1), # TE₁₁ 模式
(2, 1), # TM₂₁ 模式
(3, 1) # TE₃₁ 模式
]
besselyZero([0,1,2,3],1)
#结果: [0.89357697 2.19714133 3.38424177 4.52702466]
6. 机械振动 - 频率响应分析
分析结构的多阶振动特性
n_range = [[0],[1],[2],[3],[4],[5],[6],[7],[8],[9]] # 0-9 阶
k_range = [1,2,3,4,5] # 前 5 个零点
besselyZero(n_range,k_range)
#结果: [[ 0.89357697 3.95767842 7.08605106 10.22234504 13.36109747]
[ 2.19714133 5.42968104 8.59600587 11.74915483 14.89744213]
[ 3.38424177 6.79380751 10.02347798 13.20998671 16.37896656]
[ 4.52702466 8.09755376 11.39646674 14.62307774 17.81845523]
[ 5.64514789 9.36162062 12.73014447 15.99962709 19.22442896]
[ 6.74718382 10.59717673 14.0338041 17.34708639 20.60289902]
[ 7.83773782 11.81103711 15.31361512 18.67070497 21.9582909 ]
[ 8.91960573 13.00771144 16.57391513 19.97434231 23.29397259]
[ 9.99462838 14.1903613 17.81788784 21.26093227 24.61257638]
[11.06409026 15.36130134 19.04794965 22.53276542 25.91620496]]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.special import yn_zeros # 导入贝塞尔Y函数零点计算函数
def bessel_y_zero(input_str):
"""
计算第二类贝塞尔函数(Bessel Y函数)的第n阶前k个零点
参数:
input_str: 输入字符串,格式为元组 (n, k) 或单个表达式
返回:
计算结果(SymPy矩阵、数值数组或列表)或错误信息
说明:
- 输入应为元组 (n, k),其中n为阶数,k为需要计算的零点数量
- n和k可为单个数值或矩阵,当为矩阵时需形状一致
- 返回值根据输入形状自动调整为矩阵或列表
"""
try:
# 假设此处需要表达式预处理(根据实际情况调整或移除)
expr = sp.sympify(input_str)
error = False
result = None
if isinstance(expr, tuple) and len(expr) == 2:
# 检查所有元素是否为整数值类型
if all(e.is_integer for e in expr):
params = tuple(int(e.evalf()) for e in expr)
if params[0] < 0 or params[1] <= 0:
raise ValueError("阶数n需非负,零点数量k需为正整数")
result = yn_zeros(*params)[-1] # 返回NumPy数组
elif any(e.free_symbols for e in expr):
# 因为sp.yn是计算贝塞尔函数在某个点的值,而不是零点
result = sp.yn(*expr)
else:
error = True
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
def main():
"""
主函数,用于测试贝塞尔Y函数零点计算功能
"""
# 示例1:标量输入
input1 = "(2, 3)" # 计算2阶贝塞尔Y函数前3个零点
print(f"输入: {input1}")
print("结果:", bessel_y_zero(input1), "\n") #结果: 10.023477979360038
if __name__ == "__main__":
main()
Beta 函数
B = beta(Z,W) 返回在Z和W的元素处计算的beta函数.
Z是标量,向量,矩阵
W是标量或符号变量,向量,矩阵.
如果Z或W等于0,则beta函数返回Inf.
1, 概率论中的先验分布(标量符号)
beta(a,b)
#结果: gamma(a)*gamma(b)/gamma(a + b)
2, 概率论中的先验分布(具体数值)
beta(2,5)
#结果: 0.03333333333333333
3, 统计学中的相关性分析(向量输入)
beta([1,2,3],[0.5,1.5,2.5])
#结果: [2,0.26666667,0.05079365]
4, 贝叶斯统计中的共轭先验(矩阵输入)
beta([[1,2],[3,4]],[[0.5,1.5],[2.5,3.5]])
#结果: [[2,0.26666667]
[0.05079365,0.01065601]]
5, 数值稳定性测试(极大值)
beta(100,100)
#结果: 2.2087606931994364e-61
6, 特殊函数关系验证
beta(1/2,1/2)
#结果: 3.1415926535897927
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.special import beta
def beta_function(input_str):
"""
计算Beta函数 B(x,y) = Γ(x)Γ(y)/Γ(x+y),支持矩阵输入
参数:
input_str: 输入字符串,格式为元组 (x, y) 或单个表达式
返回:
计算结果(SymPy矩阵或符号表达式)或错误信息
说明:
- 输入应为元组 (x, y),其中x和y可为数值或矩阵
- 当输入为矩阵时,要求x和y的矩阵形状一致
- 自动对结果进行伽马函数化简
"""
try:
# 如果存在表达式预处理需求(此处假设util模块已定义)
expr = sp.sympify(input_str)
error = False
result = None
if isinstance(expr, tuple) and len(expr) == 2:
# 检查所有元素是否为数值类型
if all(e.is_number for e in expr):
# 转换为浮点数的元组
params = tuple(float(e.evalf()) for e in expr)
result = beta(*params)
elif any(e.free_symbols for e in expr):
result = sp.gammasimp(sp.beta(*expr))
else:
error = True
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
def main():
"""
主函数,用于测试Beta函数计算功能
"""
# 示例1:符号输入
input1 = "(3, x)"
print(f"输入: {input1}")
print("结果:", beta_function(input1), "\n") # 结果: 2/(x*(x + 1)*(x + 2))
# 示例2:标量输入
input1 = "(3, 5)"
print(f"输入: {input1}")
print("结果:", beta_function(input1), "\n") # 结果: 0.009523809523809525
if __name__ == "__main__":
main()
贝塔函数的累积分布函数
p = betacdf(x,a,b) 使用a和b中的对应参数返回x中每个值处的beta cdf.
x,a和b可以是大小都相同的向量,矩阵.标量输入扩展为常量数组,其维度与其他输入相同.a和b中的参数必须均为正数,并且x中的值必须位于区间[0,1]上.
a是标量, 向量,矩阵.
b是标量, 向量,矩阵
a和b中的参数必须均为正数,并且x中的值必须位于区间[0,1]上.
1:A/B测试中的置信度计算
假设A版本有50次成功,100次失败;B版本有60次成功,90次失败
计算A版本优于B版本的概率
alpha_A, beta_A = 50, 100
alpha_B, beta_B = 60, 90
# 创建一系列x值来比较两个分布
x_values = np.linspace(0, 1, 100)
cdf_A = betacdf(x_values.tolist(), alpha_A, beta_A)
cdf_B = betacdf(x_values.tolist(), alpha_B, beta_B)
print(f"A版本转化率CDF值示例: {cdf_A[0]:.4f}, {cdf_A[50]:.4f}, {cdf_A[-1]:.4f}")
print(f"B版本转化率CDF值示例: {cdf_B[0]:.4f}, {cdf_B[50]:.4f}, {cdf_B[-1]:.4f}")
#A版本转化率CDF值示例: 0.0000, 1.0000, 1.0000
#B版本转化率CDF值示例: 0.0000, 0.9952, 1.0000
2:项目完成时间预测
使用Beta分布建模任务完成时间(归一化到0-1范围)
乐观时间(a=2, b=8), 悲观时间(a=8, b=2)
optimistic = betacdf(0.5, 2, 8) # 50%可能性能在乐观估计内完成
pessimistic = betacdf(0.5, 8, 2) # 50%可能性能在悲观估计内完成
print(f"乐观估计下50%完成概率: {optimistic:.4f}")
print(f"悲观估计下50%完成概率: {pessimistic:.4f}")
#乐观估计下50%完成概率: 0.9805
#悲观估计下50%完成概率: 0.0195
3:产品质量控制
假设产品合格率服从Beta(5, 1)分布
计算合格率低于90%的概率
defect_prob = betacdf(0.9, 5, 1)
print(f"产品合格率低于90%的概率: {defect_prob:.4f}")
#产品合格率低于90%的概率: 0.5905
4:医学研究中的治疗效果评估
新药在临床试验中:成功20例,失败5例
计算药物有效率超过80%的概率 = 1 - CDF(0.8)
efficacy = 1 - betacdf(0.8, 20, 5)
print(f"药物有效率超过80%的概率: {efficacy:.4f}")
#药物有效率超过80%的概率: 0.5401
5:符号计算 - 理论分析
使用符号变量分析Beta分布性质
symbolic_result = betacdf(x, a, b)
print(f"Beta分布的符号CDF表达式: {symbolic_result}")
#Beta分布的符号CDF表达式:
#Piecewise((-0**a*gamma(a)*hyper((a, 1 - b), (a + 1,), 0)/(beta(a, b)*gamma(a + 1)) + x**a*gamma(a)*hyper((a, 1 - b), (a + 1,), x*exp_polar(2*I*pi))/(beta(a, b)*gamma(a + 1)), x >= 0), (0, True))
6:多参数组合分析
同时计算多个Alpha和Beta参数组合下的CDF值
alphas = [[2, 3], [4, 5]]
betas = [[1, 2], [3, 4]]
x_value = 0.7
matrix_result = betacdf(x_value, alphas, betas)
print(f"在x={x_value}时,不同(α,β)组合的CDF值:")
#在x=0.7时,不同(α,β)组合的CDF值:
#[[0.49,0.6517]
[0.74431,0.80589565]]
7:风险评估
计算不同风险阈值下的累积概率
risk_levels = [0.1, 0.3, 0.5, 0.7, 0.9]
# 假设风险分布为Beta(2, 5)
risk_probs = betacdf(risk_levels, 2, 5)
print("不同风险阈值下的累积概率:")
for i, level in enumerate(risk_levels):
print(f"风险水平 ≤ {level}: {risk_probs[i]:.4f}")
#不同风险阈值下的累积概率:
#风险水平 ≤ 0.1: 0.1143
#风险水平 ≤ 0.3: 0.5798
#风险水平 ≤ 0.5: 0.8906
#风险水平 ≤ 0.7: 0.9891
#风险水平 ≤ 0.9: 0.9999
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
from sympy.stats import Beta, cdf
import sympy as sp
from scipy.stats import beta as sc_beta
def beta_function_cdf(input_str):
"""
计算Beta分布的累积分布函数(CDF)
参数:
input_str: 输入字符串,格式为元组 (x, alpha, beta)
- x: 取值点(需在[0,1]区间)
- alpha: 形状参数α
- beta: 形状参数β
返回:
SymPy表达式/数值/矩阵 或 错误信息
特性:
1. 支持标量、矩阵混合输入
2. 自动形状一致性检查
3. 支持符号计算
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
if isinstance(expr, tuple) and len(expr) == 3:
# 检查所有元素是否为数值类型
if all(e.is_number for e in expr):
params = tuple(float(e.evalf()) for e in expr)
# 输入验证
if not (0 <= params[0] <= 1):
raise ValueError("x必须在[0,1]区间")
if params[1] <= 0:
raise ValueError("alpha必须为正数")
if params[2] <= 0:
raise ValueError("beta必须为正数")
# 直接调用scipy的beta.cdf函数
result = sc_beta.cdf(*params)
elif any(e.free_symbols for e in expr):
x, alpha, beta = expr
if x.is_number and (x < 0 or x > 1):
raise ValueError("x必须在[0,1]区间")
if alpha.is_number and alpha <= 0:
raise ValueError("alpha必须为正数")
if beta.is_number and beta <= 0:
raise ValueError("beta必须为正数")
# 创建Beta分布
beta_dist = Beta('beta', alpha, beta)
return cdf(beta_dist)(x)
else:
error = True
else:
error = True
if error:
return f"输入错误: {input_str}"
return result
except Exception as e:
return f"计算错误: {str(e)}"
def main():
"""测试函数"""
# 示例1:标量计算
print("测试1: (0.5, 2, 3)")
sp.pprint(beta_function_cdf("(0.5, 2, 3)"))
# 结果: 0.6875
# 示例2:符号参数
print("测试2: (x, 2, 3)")
print(beta_function_cdf("(x, 2, 3)"))
# 结果: Piecewise((3*x**4 - 8*x**3 + 6*x**2, x >= 0), (0, True))
if __name__ == "__main__":
main()
贝塔参数估计
a,b,loc,scale = betafit(data)从数据中返回形状(如果适用),位置和比例参数的估计值.
1. A/B测试转化率数据
假设我们有一个月的每日转化率数据(0-1之间)
conversion_rates = [0.12, 0.15, 0.11, 0.14, 0.13, 0.16, 0.12,
0.17, 0.15, 0.14, 0.13, 0.16, 0.15, 0.14,
0.16, 0.15, 0.13, 0.14, 0.15, 0.16, 0.14,
0.15, 0.13, 0.14, 0.15, 0.16, 0.14, 0.15, 0.16]
a, b, loc, scale = betafit(conversion_rates)
print(f"转化率数据拟合参数: α={a:.3f}, β={b:.3f}")
print(f"转化率范围: [{loc:.3f}, {loc + scale:.3f}]")
#转化率数据拟合参数: α=4.611, β=2.533
#转化率范围: [0.090, 0.174]
2. 产品质量合格率数据
假设我们有30批产品的合格率数据
pass_rates = [0.85, 0.88, 0.92, 0.87, 0.90, 0.91, 0.89, 0.86,
0.93, 0.88, 0.90, 0.91, 0.89, 0.87, 0.92, 0.90,
0.88, 0.91, 0.89, 0.90, 0.92, 0.87, 0.89, 0.91,
0.88, 0.90, 0.92, 0.89, 0.91, 0.90]
a, b, loc, scale = betafit(pass_rates)
print(f"合格率数据拟合参数: α={a:.3f}, β={b:.3f}")
print(f"合格率范围: [{loc:.3f}, {loc+scale:.3f}]")
#合格率数据拟合参数: α=2.660, β=1.805
#合格率范围: [0.840, 0.933]
3. 用户满意度评分数据
假设我们有50个用户的满意度评分(已归一化到0-1)
satisfaction_scores = [0.7, 0.8, 0.6, 0.9, 0.75, 0.85, 0.7, 0.8, 0.65,
0.9, 0.75, 0.8, 0.7, 0.85, 0.8, 0.75, 0.9, 0.7,
0.8, 0.75, 0.85, 0.8, 0.7, 0.9, 0.75, 0.8, 0.7,
0.85, 0.8, 0.75, 0.9, 0.7, 0.8, 0.75, 0.85, 0.8,
0.7, 0.9, 0.75, 0.8, 0.7, 0.85, 0.8, 0.75, 0.9,
0.7, 0.8, 0.75, 0.85, 0.8]
a, b, loc, scale = betafit(satisfaction_scores)
print(f"满意度数据拟合参数: α={a:.3f}, β={b:.3f}")
print(f"满意度范围: [{loc:.3f}, {loc+scale:.3f}]")
#满意度数据拟合参数: α=1.362, β=0.677
#满意度范围: [0.589, 0.900]
4. 任务完成时间比例数据
假设我们有项目完成时间与预计时间的比例数据
time_ratios = [0.8, 1.2, 0.9, 1.1, 1.0, 0.95, 1.05, 0.85, 1.15,
0.9, 1.1, 0.95, 1.05, 0.88, 1.12, 0.92, 1.08, 0.96,
1.04, 0.98, 1.02, 0.94, 1.06, 0.97, 1.03, 0.99, 1.01]
a, b, loc, scale = betafit(time_ratios)
print(f"时间比例数据拟合参数: α={a:.3f}, β={b:.3f}")
print(f"时间比例范围: [{loc:.3f}, {loc+scale:.3f}]")
#时间比例数据拟合参数: α=4.000, β=4.000
#时间比例范围: [0.722, 1.278]
5. 广告点击率数据
假设我们有不同广告的点击率数据
ctr_data = [0.02, 0.015, 0.025, 0.018, 0.022, 0.016, 0.024, 0.019,
0.021, 0.017, 0.023, 0.02, 0.015, 0.025, 0.018, 0.022,
0.016, 0.024, 0.019, 0.021, 0.017, 0.023, 0.02, 0.015]
a, b, loc, scale = betafit(ctr_data)
print(f"点击率数据拟合参数: α={a:.3f}, β={b:.3f}")
print(f"点击率范围: [{loc:.3f}, {loc+scale:.3f}]")
#点击率数据拟合参数: α=0.490, β=1.126
#点击率范围: [0.015, 0.026]
6. 医学研究中的治疗效果数据
假设我们有不同患者对药物的反应率数据
response_rates = [0.3, 0.4, 0.35, 0.45, 0.38, 0.42, 0.36, 0.44,
0.37, 0.43, 0.39, 0.41, 0.34, 0.46, 0.38, 0.42,
0.36, 0.44, 0.37, 0.43, 0.39, 0.41, 0.35, 0.45]
a, b, loc, scale = betafit(response_rates)
print(f"药物反应率数据拟合参数: α={a:.3f}, β={b:.3f}")
print(f"反应率范围: [{loc:.3f}, {loc+scale:.3f}]")
#药物反应率数据拟合参数: α=1.381, β=0.902
#反应率范围: [0.296, 0.460]
7. 异常值检测
假设我们有一些包含异常值的数据
data_with_outliers = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 2.5]
a, b, loc, scale = betafit(data_with_outliers)
print(f"含异常值数据拟合参数: α={a:.3f}, β={b:.3f}")
print(f"数据范围: [{loc:.3f}, {loc+scale:.3f}]")
print("注意: 异常值2.5导致范围扩大,这可能不是真正的Beta分布")
#含异常值数据拟合参数: α=0.416, β=0.684
#数据范围: [0.098, 2.500]
#注意: 异常值2.5导致范围扩大,这可能不是真正的Beta分布
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import numpy as np
import sympy as sp
from scipy.stats import beta
def beta_parameter_estimates(input_str):
"""
根据输入字符串估计 Beta 分布的参数 (a, b, loc, scale)
参数:
input_str (str): 输入字符串,应能解析为数值列表(例如 "[1, 2, 3]")
返回:
tuple: 若成功则返回 (a, b, loc, scale) 参数元组
str: 若失败则返回错误信息字符串
"""
try:
# 尝试将输入字符串解析为 SymPy 表达式
expr = sp.sympify(input_str)
# 初始化错误标志
error = False
data = None
# 检查解析后的表达式类型
if isinstance(expr, tuple):
# 如果是 SymPy 的 Tuple 类型,标记错误(仅支持列表)
error = True
elif isinstance(expr, list):
# 如果是 SymPy 的 List 类型,提取元素并转换为浮点数列表
try:
rvs_data = [float(item) for item in expr]
data = np.ravel(rvs_data)
except TypeError:
# 若元素无法转为浮点数,标记错误
error = True
else:
# 其他类型(如符号表达式)标记错误
error = True
if error:
return f"输入格式错误: 无法解析 '{input_str}' 为数值列表"
else:
# 使用 scipy.stats.beta.fit 拟合 Beta 分布参数
a, b, loc, scale = beta.fit(data) # 固定 loc=0, scale=1
return (a, b, loc, scale)
except sp.SympifyError:
return f"语法错误: 无法解析输入字符串 '{input_str}'"
except Exception as e:
return f"运行时错误: {str(e)}"
def main():
"""主函数,包含测试用例"""
test_cases = [
"[0.1, 0.5, 0.9]",
# 拟合参数: a=0.534, b=0.513, loc=0.03855715490410458, scale=0.8614428450958955
"[2.3, 4.5, 6.7, 8.9]"
# 拟合参数: a=0.750, b=0.682, loc=1.941944998834866, scale=6.958055001165135
]
for case in test_cases:
print(f"输入: {case}")
result = beta_parameter_estimates(case)
if isinstance(result, tuple):
print(f"拟合参数: a={result[0]:.3f}, b={result[1]:.3f}, loc={result[2]}, scale={result[3]}")
else:
print(f"结果: {result}")
print("-" * 50)
if __name__ == "__main__":
main()
不完全的贝塔函数
I = betainc(X,Z,W) 为数组X,Z和W的相应元素计算不完全beta函数.
X的元素必须位于闭区间 [0,1] 中.数组Z和W必须是非负实数.所有数组的大小必须相同,或者任一数组可以为标量.
1:二项分布的累积分布函数(CDF)
二项分布的CDF可以用不完全Beta函数表示
betainc(4,7,0.5)
2:置信区间计算
使用不完全Beta函数计算二项比例的置信区间
successes, trials = 8, 20
confidence = 0.95
alpha = (1 - confidence) / 2
# 计算置信区间的下限和上限
lower_bound = betainc(trials - successes + 1, successes, alpha)
upper_bound = betainc(trials - successes, successes + 1, 1-alpha)
print(f"{successes}次成功/{trials}次试验的{confidence * 100}%置信区间:")
print(f"下限: {lower_bound:.4f}, 上限: {upper_bound:.4f}")
#8次成功/20次试验的95.0%置信区间:
#下限: 0.0000, 上限: 1.0000
3:贝叶斯A/B测试
计算A版本优于B版本的概率
A版本: 50次成功,100次失败
B版本: 60次成功,90次失败
prob_A_better = betainc(100, 50, 0.5)
prob_B_better = betainc(90, 60, 0.5)
print(f"A版本优于B版本的概率: {prob_A_better:.4f}")
print(f"B版本优于A版本的概率: {prob_B_better:.4f}")
#A版本优于B版本的概率: 0.0000
#B版本优于A版本的概率: 0.0069
4:项目风险评估
使用Beta分布建模项目完成概率
基于历史数据,乐观估计参数为(2, 8),悲观估计参数为(8, 2)
optimistic = betainc(2, 8, 0.7) # 70%置信度的乐观估计
pessimistic = betainc(8, 2, 0.7) # 70%置信度的悲观估计
print(f"乐观估计下项目有70%概率至少完成: {optimistic:.4f}")
print(f"悲观估计下项目有70%概率至少完成: {pessimistic:.4f}")
#乐观估计下项目有70%概率至少完成: 0.9996
#悲观估计下项目有70%概率至少完成: 0.1960
5:质量控制
计算产品合格率超过某个阈值的概率
假设合格率服从Beta(5, 1)分布
threshold = 0.9
prob_above_threshold = 1 - float(betainc(5,1,0.9))
print(f"产品合格率超过{threshold*100}%的概率: {prob_above_threshold:.4f}")
#产品合格率超过90.0%的概率: 0.4095
6:医学研究
计算药物有效率超过某个阈值的概率
临床试验结果: 20次成功,5次失败
efficacy_threshold = 0.8
prob_effective = 1 - betainc(20, 5, efficacy_threshold)
print(f"药物有效率超过{efficacy_threshold * 100}%的概率: {prob_effective:.4f}")
#药物有效率超过80.0%的概率: 0.5401
7:多参数矩阵计算
# 同时计算多个参数组合下的不完全Beta函数值
x_values = [[0.2, 0.4], [0.6, 0.8]]
a_values = [[2, 3], [4, 5]]
b_values = [[1, 2], [3, 4]]
matrix_result = betainc(a_values, b_values, x_values)
print("不同(x, a, b)组合的不完全Beta函数值:")
print(matrix_result)
#不同(x, a, b)组合的不完全Beta函数值:
#[[0.04,0.1792]
[0.54432,0.9437184]]
8:符号计算
# 使用符号变量进行理论分析
symbolic_result = betainc(a, b, x)
print(f"不完全Beta函数的符号表达式: {symbolic_result}")
#结果: Piecewise((nan, Eq(x, -2) | Eq(x, -1) | Eq(x, 0)), (-2.0*(-1.0)**x*x**2 - 4.0*(-1.0)**x*x - (-1.0)**x + 1.0, True))
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy import special as sp_special
def beta_incomplete_function(input_str):
"""
计算不完全Beta函数 I_x(a, b),支持标量、向量和矩阵输入
参数:
input_str (str): 输入字符串,格式为 "(n, a, x)",
n, a, x 可以是标量、向量或矩阵
返回:
Matrix 或 float: 计算结果矩阵或标量值
str: 错误信息(若输入非法或计算失败)
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
# 检查输入是否为三元组 (n, a, x)
if isinstance(expr, tuple) and len(expr) == 3:
x, a, b = expr
if all(e.is_number for e in expr):
params = tuple(float(e.evalf()) for e in expr)
new_params = params[1:] + (params[0],)
result = sp_special.betainc(*new_params)
elif x.is_number and a.is_number and b.free_symbols:
t = sp.symbols('t', positive=True)
# 计算不完全贝塔函数的分子(积分部分)
integral = sp.integrate(t ** (a - 1) * (1 - t) ** (b - 1), (t, 0, x))
# 计算贝塔函数B(a, b)
beta_function = sp.gamma(a) * sp.gamma(b) / sp.gamma(a + b)
# 得到归一化的不完全贝塔函数结果
incomplete_beta = integral / beta_function
# 简化表达式(可选)
result = sp.simplify(incomplete_beta).evalf()
else:
error = True
else:
error = True
if error or result is None:
return f"输入错误: {input_str}(可能原因:非三元组/矩阵形状不匹配/符号参数)"
else:
return result
except sp.SympifyError:
return f"语法错误: 无法解析输入字符串 '{input_str}'"
except Exception as e:
return f"运行时错误: {str(e)}"
def main():
"""主函数,包含测试用例"""
test_cases = [
# 标量测试
"(1, 3, 0.5)",
# 结果: 1.0000
"(1, 1, 0.5)",
# 结果: 1.0000
"(2, 3, x)",
# 结果: Piecewise((nan, Eq(x, -2) | Eq(x, -1) | Eq(x, 0)),
# (-2.0*(-1.0)**x*x**2 - 4.0*(-1.0)**x*x - (-1.0)**x + 1.0, True))
]
for case in test_cases:
print(f"输入: {case}")
result = beta_incomplete_function(case)
if isinstance(result, sp.Matrix):
print("结果矩阵:")
sp.pprint(result, use_unicode=True)
elif isinstance(result, float):
print(f"结果标量: {result:.4f}")
else:
print(f"结果: {result}")
print("-" * 50)
if __name__ == "__main__":
main()
贝塔逆累积分布函数
不完全 Beta 函数的逆函数(也称为逆不完全 Beta 函数)在统计学和工程中有多种实际应用。
x = betaincinv(y,z,w) 针对y,z和w的对应元素计算逆不完全beta函数,以使y = betainc(x,z,w).
y 的元素必须位于闭区间 [0,1] 中, z和w的元素必须为非负值. y,z和w必须均为实数,并且其大小必须相同(或者任一元素可以为标量).
1. 置信区间计算(二项分布比例)
计算二项分布成功比例的95%置信区间
n = 100 # 试验次数
k = 65 # 成功次数
alpha = 0.05 # 显著性水平
# 使用不完全Beta函数的逆函数计算置信区间
lower = betaincinv(k, n-k+1, alpha/2)
upper = betaincinv(k+1, n-k, 1-alpha/2)
print(f"成功比例的95%置信区间: [{lower:.4f}, {upper:.4f}]")
#成功比例的95%置信区间: [0.5482, 0.7427]
2. 贝叶斯统计中的后验分布分位数
在贝叶斯分析中,当先验分布是Beta分布时,后验分布也是Beta分布,可以使用逆函数计算后验分布的分位数。
# 计算Beta后验分布的中位数和90%置信区间
alpha_post = 15 # 后验分布的α参数
beta_post = 10 # 后验分布的β参数
median = betaincinv(alpha_post, beta_post, 0.5)
lower_90 = betaincinv(alpha_post, beta_post, 0.05)")
upper_90 = betaincinv(alpha_post, beta_post, 0.95)")
print(f"后验分布的中位数: {median:.4f}")
print(f"90%置信区间: [{lower_90:.4f}, {upper_90:.4f}]")
#后验分布的中位数: 0.6027
#90%置信区间: [0.4371, 0.7536]
3. 假设检验中的临界值计算
在二项比例检验中,可以使用逆函数计算拒绝域的临界值。
# 计算单侧二项检验的临界值
n = 50 # 试验次数
p0 = 0.5 # 原假设下的成功概率
alpha = 0.05 # 显著性水平
# 计算临界值(使用连续型校正)
critical_value = betaincinv(n*p0, n*(1-p0)+1, 1-alpha)
print(f在{p0}的原假设下,{n}次试验中拒绝域的临界值为: {critical_value:.4f}")
#在0.5的原假设下,50次试验中拒绝域的临界值为: 0.6046
4. 可靠性工程中的故障时间分析
在可靠性工程中,Beta分布常用于建模系统故障时间的分布。
# 计算系统在给定时间内的可靠度置信界限
operating_hours = 1000
failures = 2
total_units = 10
confidence = 0.90
# 计算可靠度的单侧置信下限
reliability_lower = 1 - betaincinv(failures+1, total_units-failures, confidence)
print(f"系统运行{operating_hours}小时后的可靠度{confidence*100}%置信下限: {reliability_lower:.4f}")
#系统运行1000小时后的可靠度90.0%置信下限: 0.5504
5. A/B测试中的效果评估
在A/B测试中,可以使用逆函数计算转换率差异的置信区间。
# A/B测试结果分析
conversions_A = 120
visitors_A = 1000
conversions_B = 150
visitors_B = 1000
# 计算A组的95%置信区间
alpha_A, beta_A = conversions_A + 1, visitors_A - conversions_A + 1
lower_A = betaincinv(alpha_A, beta_A, 0.025)
upper_A = betaincinv(alpha_A, beta_A, 0.975)
print(f"A组转换率的95%置信区间: [{lower_A:.4f}, {upper_A:.4f}]")
#A组转换率的95%置信区间: [0.1013, 0.1416]
6. 处理向量输入
# 同时计算多个分位数
alphas = [1, 2, 3, 4, 5]
betas = [5, 4, 3, 2, 1]
quantiles = [0.1, 0.5, 0.9]
results = []
for q in quantiles:
result = betaincinv(alphas, betas, q)
results.append(result)
print("多个分位数计算结果:")
for i, q in enumerate(quantiles):
print(f"{q*100}%分位数: {results[i]}")
#多个分位数计算结果:
#10.0%分位数: [0.02085164 0.11223496 0.24663645 0.41610963 0.63095734]
#50.0%分位数: [0.12944944 0.31381017 0.5 0.68618983 0.87055056]
#90.0%分位数: [0.36904266 0.58389037 0.75336355 0.88776504 0.97914836]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy import special as sp_special
def beta_incomplete_inverse(input_str):
"""
计算不完全Beta函数的逆函数 I_x^{-1}(a, b),支持标量、向量和矩阵输入
参数:
input_str (str): 输入字符串,格式为 "(a, b, y)",
a, b, y 可以是标量、向量或矩阵
返回:
Matrix 或 float: 计算结果矩阵或标量值
str: 错误信息(若输入非法或计算失败)
注意:
SciPy 的 betaincinv 参数顺序为 (a, b, y),对应 I_y^{-1}(a, b) = x
"""
try:
expr = sp.sympify(input_str)
result = None
# 检查输入是否为三元组 (a, b, y)
if isinstance(expr, tuple) and len(expr) == 3:
# 检查所有元素是否为数值类型
if all(e.is_number for e in expr):
# 转换为浮点数的元组
params = tuple(float(e.evalf()) for e in expr)
result = sp_special.betaincinv(*params)
else:
return f"不支持符号变量,输入错误:{input_str}"
return result
except sp.SympifyError:
return f"语法错误: 无法解析输入字符串 '{input_str}'"
except Exception as e:
return f"运行时错误: {str(e)}"
def main():
"""主函数,包含测试用例"""
test_cases = [
# 标量测试
"(2, 3, 0.8125)",
# 结果标量: 0.5928793866966796
"(1, 1, 0.5)",
# 结果标量: 0.5
]
for case in test_cases:
print(f"输入: {case}")
result = beta_incomplete_inverse(case)
if isinstance(result, float):
print(f"结果标量: {result}")
else:
print(f"结果: {result}")
print("-" * 50)
if __name__ == "__main__":
main()
贝塔的逆累积分布函数(目前只支持数值计算)
X = betinv(P,A,B)使用由A和B指定的参数为P中的相应概率计算beta-cdf的倒数. P、A和B可以是大小都相同的向量,矩阵.
标量输入被扩展为与其他输入具有相同维度的常量数组.A和B中的参数必须都是正的,而P中的值必须位于区间[0,1]上.
A是标量, 向量,矩阵.
B是标量, 向量,矩阵
A和B中的参数必须均为正数,并且P中的值必须位于区间[0,1]上。
1:A/B测试中的置信区间计算
在A/B测试中,我们经常需要计算转化率的置信区间。
假设A组有100次转化和900次未转化,B组有120次转化和880次未转化,我们可以计算95%置信区间的下限和上限:
A组转化率95%置信区间:
print("下限:", betinv(0.025, 101, 901))
print("上限:", betinv(0.975, 101, 901))
#下限: 0.08293639849581784
#上限: 0.12016912987586062
B组转化率95%置信区间:
print("下限:", betinv(0.025, 121, 881))
print("上限:", betinv(0.975, 121, 881))
#下限: 0.10132341964422845
#上限: 0.14162699974885076
2:质量控制的接受概率
在质量控制中,Beta分布可用于计算接受一批产品的概率。
假设我们有一个验收抽样计划,要求在不合格品率不超过0.02时接受概率为95%:
# 定义参数
alpha_val = 5 # 历史数据中的不合格品数+1
beta_val = 495 # 历史数据中的合格品数+1
# 计算不同不合格品率下的接受概率
defect_rates = [0.01, 0.02, 0.03, 0.05]
accept_prob = 1 - float(betinv([0.01, 0.02, 0.03, 0.05],5,495))
print(f"不合格品率为{rate * 100}%时的接受概率: {accept_prob * 100:.2f}%")
#不合格品率为1.0%时的接受概率: 99.74%
#不合格品率为2.0%时的接受概率: 99.69%
#不合格品率为3.0%时的接受概率: 99.66%
#不合格品率为5.0%时的接受概率: 99.60%
3:医学测试的可靠性分析
在医学研究中,Beta分布可用于估计诊断测试的敏感性和特异性
假设一个测试在100个已知患病者中检测出85个阳性, 在200个已知健康者中检测出190个阴性
# 计算敏感性(真阳性率)的95%置信区间
sens_alpha = 85 + 1
sens_beta = 15 + 1 # 100-85个假阴性
print("敏感性95%置信区间:")
print("下限:", betinv(0.025, 86, 16))
print("上限:", betinv(0.975, 86, 16))
#敏感性95%置信区间:
#下限: 0.7669030961466508
#上限: 0.9066533805315818
# 计算特异性(真阴性率)的95%置信区间
spec_alpha = 190 + 1
spec_beta = 10 + 1 # 200-190个假阳性
print("\n特异性95%置信区间:")
print("下限:", betinv(0.025, 191, 11))
print("上限:", betinv(0.975, 191, 11))
#特异性95%置信区间:
#下限: 0.9104108558267539
#上限: 0.972367517775229
4:处理矩阵输入
当需要同时计算多个不同参数的Beta分位数时:
# 创建概率矩阵和参数矩阵
P_matrix = [[0.05, 0.5, 0.95], [0.1, 0.9, 0.99]]
A_matrix = [[2, 2, 2], [5, 5, 5]]
B_matrix = [[5, 5, 5], [2, 2, 2]]
betinv(P_matrix,A_matrix,B_matrix)
#[[0.06284989,0.26444998,0.58180341]
[0.48968369,0.90740474,0.97323681]]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import scipy.stats as stats
def beta_function_cdf_inverse(input_str):
"""
计算Beta分布逆累积分布函数(对应MATLAB的betainv函数)
参数:
input_str: 字符串形式的输入元组,格式为"(P, A, B)"
P: 概率值(单个数值或矩阵)
A: Alpha参数(单个数值或矩阵)
B: Beta参数(单个数值或矩阵)
返回:
SymPy矩阵/数值 或 错误信息字符串
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
# 检查输入是否为三元组 (P, A, B)
if isinstance(expr, tuple) and len(expr) == 3:
# 检查每个元素是否为数值类型
if all(e.is_number for e in expr):
# 转换为浮点数并返回列表
params = [float(e.evalf()) for e in expr]
result = stats.beta.ppf(*params)
else:
error = True
else:
error = True
return result if not error else f"输入格式错误: {input_str}"
except Exception as e:
return f"处理过程中发生错误: {e}"
def main():
"""主函数用于测试功能"""
# 示例1:标量参数计算
print("示例1: 标量参数计算")
input_scalar = "(0.01, 10, 5)"
print(f"输入: {input_scalar}")
print("结果:", beta_function_cdf_inverse(input_scalar), "\n")
#结果: 0.37256530511457264
if __name__ == "__main__":
main()
贝塔近似负对数函数
负对数似然函数(negative log-likelihood)的值越小,表示模型对数据的拟合越好。因为负对数似然是似然函数的负对数,所以当似然函数越大时,负对数似然越小。
nlogL = betalike(a,b)返回β参数a和b以及列向量数据中指定的观测值的β对数似然函数的负值.
A和B可以是大小都相同的向量,矩阵.
A是标量,向量,矩阵,多维数组
B是标量,向量,矩阵,多维数组
1:A/B测试分析
在网站A/B测试中,我们可以使用Beta分布来建模点击率(CTR)的不确定性。
测试两种不同设计的点击率
设计A: 100次展示,20次点击 → Beta(20+1, 80+1)
设计B: 120次展示,30次点击 → Beta(30+1, 90+1)
print("设计A:", betalike(21, 81))
print("设计B:", betalike(31, 91))
A/B测试负对数似然比较:
#设计A: [-186.3454596]
#设计B: [-178.77204643]
#设计A的负对数似然值(-186.35)比设计B的负对数似然值(-178.77)更小(即更负)。
#这意味着设计A的似然值更大,因此设计A的参数(α=21, β=81)比设计B的参数(α=31, β=91)更符合模拟数据。
2:产品质量控制
在制造业中,Beta分布可用于建模产品合格率。
三个生产批次的合格率估计
批次1: 95个合格,5个不合格 → Beta(95, 5)
批次2: 85个合格,15个不合格 → Beta(85, 15)
批次3: 98个合格,2个不合格 → Beta(98, 2)
print("批次1:", betalike(95, 5))
print("批次2:", betalike(85, 15))
print("批次3:", betalike(98, 2))
产品质量控制负对数似然:
#批次1: [-246.03971091]
#批次2: [-191.10832591]
#批次3: [-289.45217742]
3:医学试验分析
在医学研究中,Beta分布可用于描述治疗成功率。
两种不同药物的治疗效果比较
药物A: 45人中有40人有效 → Beta(40, 5)
药物B: 50人中有42人有效 → Beta(42, 8)
print("药物A:", betalike(40, 5))
print("药物B:", betalike(42, 8))
药物治疗效果负对数似然:
#药物A: [-168.66496082]
#药物B: [-150.25472351]
4:矩阵参数计算
当我们需要同时评估多个参数组合时,可以使用矩阵形式输入。
alpha_matrix = [[1, 2, 3], [4, 5, 6]]
beta_matrix = [[10, 10, 10], [20, 20, 20]]
betalike(alpha_matrix, beta_matrix)
#[[-129.96636416,-87.67594223,-89.73813295]
[-131.60436356,-99.46809879,-115.97322783]]
5:参数敏感性分析
通过计算不同参数下的负对数似然,可以进行敏感性分析。
# 测试α参数固定时,β变化对似然的影响
beta_values = [1, 5, 10, 20, 50]
alpha_fixed = 5
betalike(alpha_fixed, beta_values)
#[-64.01049599,-53.09338383,-78.34318945,-99.46809879,-193.69795679]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from scipy.stats import beta
def beta_negative_log_likelihood(input_str):
"""
计算Beta分布负对数似然函数(基于模拟数据)
参数:
input_str: 字符串形式的输入元组,格式为"(alpha, beta)"
alpha: Beta分布参数α(单个数值或矩阵)
beta: Beta分布参数β(单个数值或矩阵)
返回:
SymPy矩阵/数值 或 错误信息字符串
说明:
1. 使用固定随机种子生成100个模拟数据点
2. 计算负对数似然值:-Σ log(beta.pdf(data, alpha, beta))
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
def calculate_nll(alpha_val, beta_val):
"""计算单个参数的负对数似然"""
# 参数有效性检查
if alpha_val <= 0 or beta_val <= 0:
return sp.nan
try:
# 固定随机种子保证可重复性
seed = hash((alpha_val, beta_val)) % 2 ** 32
np.random.seed(seed)
# 生成模拟数据
data = beta.rvs(alpha_val, beta_val, size=100)
# 计算负对数似然
return -np.sum(beta.logpdf(data, alpha_val, beta_val))
except Exception as e:
print(f"计算错误: {e}")
return sp.nan
# 检查输入是否为二元组 (alpha, beta)
if isinstance(expr, tuple) and len(expr) == 2:
if any(e.is_number for e in expr):
params = tuple(float(e.evalf()) for e in expr)
result = calculate_nll(*params)
else:
error = True
else:
error = True
return result if not error else f"输入格式错误: {input_str}"
except Exception as e:
return f"处理过程中发生错误: {e}"
def main():
"""主函数用于测试功能"""
# 示例1:标量参数计算
print("示例1: 标量参数计算")
input_scalar = "(2, 5)"
print(f"输入: {input_scalar}")
print("结果:", beta_negative_log_likelihood(input_scalar), "\n")
#结果: -57.470963328888395
if __name__ == "__main__":
main()
贝塔函数的对数
L = betaln(Z,W)为数组Z和W的对应元素计算beta函数的自然对数log(beta(Z,W)),而不会计算 beta(Z,W).
由于beta函数的范围可以涵盖极大或极小的值,因此其对数有时会更有用.
Z和W必须是实数和非负数组.它们的大小必须相同,或者任一数组可以为标量.
示例1:贝叶斯A/B测试中的先验分布计算
在A/B测试中,Beta分布常用于表示点击率的先验分布。假设我们有两个广告版本:
版本A:100次展示,20次点击
版本B:120次展示,25次点击
# 版本A的Beta对数似然
betaln(20,80) # 成功20次,失败80次
#结果: -50.503223531356085
# 版本B的Beta对数似然
betaln(25, 95)
#结果: -61.97898486118534
示例2:概率密度函数的归一化常数计算
在贝叶斯统计中,Beta分布常作为二项分布的共轭先验。计算Beta分布的归一化常数:
不同先验参数的Beta函数对数
betaln(1,1) # 均匀先验
#结果: 0
betaln(0.5,0.5) # Jeffreys先验
#结果: 1.1447298858494
betaln(2,5) # 信息性先验
#结果: -3.4011973816621555
示例3:处理矩阵输入
当需要同时计算多个Beta对数时,可以使用矩阵输入:
# 定义成功和失败的矩阵
successes = [[10, 20], [30, 40]]
failures = [[90, 80], [70, 60]]
# 计算每个元素的Beta对数
betaln(successes,failures)
#结果: [[-32.67954794,-50.50322353]
[-61.68661808,-67.96861625]]
#位置(0,0): Beta(10, 90)的对数 = -32.67954794
#表示在10次成功和90次失败的情况下,Beta分布归一化常数的对数, 相对较小的绝对值表示相对较高的不确定性
#位置(1,1): Beta(40, 60)的对数 = -67.96861625
#表示在40次成功和60次失败的情况下,Beta分布归一化常数的对数, 较大的绝对值表示相对较低的不确定性(更多数据点)
示例4:符号计算
使用符号变量进行理论推导:
betaln(a,b)
#结果: loggamma(a) + loggamma(b) - loggamma(a + b)
示例5:比较数值稳定性
对于大参数值,直接计算Beta函数可能导致数值下溢,使用对数形式更稳定:
# 大参数值示例
betaln(1000,1000)
#结果: -1388.482601635902
# 对比直接计算Beta函数再取对数可能遇到的问题
# 直接计算B(1000,1000)可能会下溢,但对数形式是稳定的
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.special import betaln
def beta_log_function(input_str):
"""
计算Beta函数的对数:log(B(z,w)) = logΓ(z) + logΓ(w) - logΓ(z+w)
参数:
input_str: 字符串形式的输入元组,格式为"(z, w)"
z: Beta函数参数z(数值或矩阵)
w: Beta函数参数w(数值或矩阵)
返回:
SymPy矩阵/数值 或 错误信息字符串
特性:
- 支持矩阵运算(逐元素计算)
- 自动处理标量与矩阵的混合输入
- 参数有效性检查(z,w > 0)
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
# 检查输入是否为二元组 (z, w)
if isinstance(expr, tuple) and len(expr) == 2:
# 处理数值标量
if all(e.is_number for e in expr):
# 转换为浮点数的元组
params = tuple(float(e.evalf()) for e in expr)
result = betaln(*params)
elif any(e.free_symbols for e in expr):
z, w = expr
result = sp.loggamma(z) + sp.loggamma(w) - sp.loggamma(z + w)
else:
error = True
else:
error = True
return result if not error else f"输入格式错误: {input_str}"
except Exception as e:
return f"处理过程中发生错误: {e}"
def main():
"""主函数用于测试功能"""
print("示例1: 标量参数计算")
input_scalar = "(510, 510)"
print(f"输入: {input_scalar}")
print("结果:", beta_log_function(input_scalar), "\n")
#结果: -708.8615723125185
print("测试非正数参数:")
input_invalid1 = "(0, 5)"
print(f"输入: {input_invalid1}")
print("结果:", beta_log_function(input_invalid1))
#inf
print("\n测试非数值参数:")
input_invalid2 = "(a, 5)" # 符号参数
print(f"输入: {input_invalid2}")
print("结果:", beta_log_function(input_invalid2), "\n")
#结果: loggamma(a) - loggamma(a + 5) + log(24)
if __name__ == "__main__":
main()
贝塔概率密度函数
p = betapdf(x,a,b) 使用a和b中的对应参数返回x中每个值处的beta pdf.
x,a和b可以是大小都相同的向量,矩阵.标量输入扩展为常量数组,其维度与其他输入相同.a和b中的参数必须均为正数,并且x中的值必须位于区间[0,1]上.
a是标量, 向量,矩阵.
b是标量, 向量,矩阵
a和b中的参数必须均为正数,并且x中的值必须位于区间[0,1]上。
示例1:A/B测试中的概率密度计算
假设我们正在运行A/B测试,比较两个网页设计的转化率。我们可以使用Beta分布来表示每个设计的转化率的不确定性:
# 设计A: 100次访问,20次转化
# 设计B: 120次访问,25次转化
# 计算不同转化率下的概率密度
conversion_rates = [0.15, 0.18, 0.20, 0.22, 0.25]
# 设计A的Beta分布参数 (α = 转化数+1, β = 未转化数+1)
alpha_A, beta_A = 21, 81 # 20+1, 80+1
# 设计B的Beta分布参数
alpha_B, beta_B = 26, 96 # 25+1, 95+1
# 计算概率密度
pdf_A = betapdf(conversion_rates, alpha_A, beta_A)
pdf_B = betapdf(conversion_rates, alpha_B, beta_B)
#不同转化率下的概率密度:
#转化率 设计A 设计B
#0.15 4.0627 2.5149
#0.18 8.7909 7.8988
#0.20 10.0293 10.5374
#0.22 8.9021 10.3036
#0.25 4.9794 6.0639
示例2:产品质量控制
在制造业中,Beta分布可用于模拟产品合格率的不确定性:
# 假设我们测试了3批产品,每批的测试结果不同
# 批次1: 测试50个,合格45个
# 批次2: 测试100个,合格92个
# 批次3: 测试80个,合格76个
# 计算合格率的概率密度分布
# 生成10个合格率点
quality_rates = [0.85,0.86444444,0.87888889,0.89333333,0.90777778,0.92222222,
0.93666667,0.95111111,0.96555556,0.98]
# 每批产品的Beta分布参数
batch_params = [
(46, 6), # α=合格数+1, β=不合格数+1
(93, 9),
(77, 5)
]
pdf = betapdf(quality_rates}, 46, 6)
#批次1的合格率概率密度:
#0.850: 5.469654
#0.864: 7.037323
#0.879: 8.445021
#0.893: 9.319762
#0.908: 9.266367
#0.922: 8.045089
#0.937: 5.796177
#0.951: 3.163073
#0.966: 1.081994
#0.980: 0.139308
pdf = betapdf(quality_rates}, 93, 9)
#批次2的合格率概率密度:
#0.850: 1.546360
#0.864: 3.241829
#0.879: 6.045567
#0.893: 9.806520
#0.908: 13.391909
#0.922: 14.647293
#0.937: 11.828353
#0.951: 6.095317
#0.966: 1.480817
#0.980: 0.075003
pdf = betapdf(quality_rates}, 77, 5)
#批次3的合格率概率密度:
#0.850: 0.280401
#0.864: 0.673076
#0.879: 1.511103
#0.893: 3.138485
#0.908: 5.934226
#0.922: 9.965581
#0.937: 14.274816
#0.951: 16.217812
#0.966: 12.563921
#0.980: 4.414463
示例3:矩阵输入处理多个场景
当需要同时分析多个场景时,可以使用矩阵输入:
# 定义多个场景的参数矩阵
x_values = [[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]] # 2x3矩阵
alpha_values = [[2, 3, 4], [5, 6, 7]] # 2x3矩阵
beta_values = [[3, 4, 5], [6, 7, 8]] # 2x3矩阵
# 计算每个场景的概率密度
betapdf(x_values,alpha_values,beta_values)
#[0.85,0.86444444,0.87888889,0.89333333,0.90777778,0.92222222,0.93666667,0.95111111,0.96555556,0.98]
示例4:符号计算与理论分析
使用符号变量进行理论推导和分析
# 计算符号形式的Beta PDF
betapdf(x,a,b)
#x^(a - 1.0)*(1.0 - x)^(b - 1.0)/beta(a, b)
# 计算特定参数下的PDF
betapdf(x,2,3)
#12*x*(1.0 - x)^2
# 计算在x=0.5处的值
betapdf(0.5,2,3)
#1.5000000000000004
示例5:贝叶斯更新过程
演示如何使用Beta分布进行贝叶斯更新
# 先验分布: Beta(2, 2)
prior_alpha, prior_beta = 2, 2
# 观察数据: 10次试验,7次成功
successes, failures = 7, 3
# 后验分布: Beta(2+7, 2+3) = Beta(9, 5)
posterior_alpha = prior_alpha + successes
posterior_beta = prior_beta + failures
# 计算先验和后验分布的概率密度
x = np.linspace(0.01, 0.99, 100)
prior_pdf = betapdf(x, prior_alpha, prior_beta)
posterior_pdf = betapdf(x, posterior_alpha, posterior_beta)
print(prior_pdf[:5])
#[0.0594,0.11701812,0.17346036,0.22872672,0.2828172]
print(posterior_pdf[:5])
#[6.18143532e-13,1.45975560e-10,3.54398456e-09,3.37474214e-08,1.92199400e-07]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from sympy.stats import Beta, density
from scipy.stats import beta as scipy_beta
def beta_function_pdf(input_str):
"""
计算贝塔分布的概率密度函数值,支持标量、向量、矩阵输入
参数:
input_str: 输入参数元组 (x, a, b),其中:
- x: 输入值(0-1之间)
- a: alpha参数(正数)
- b: beta参数(正数)
每个参数可以是标量、列表或SymPy矩阵
返回:
SymPy矩阵/标量 或 错误信息字符串
"""
try:
# 解析输入表达式
expr = sp.sympify(input_str)
error = False
result = None
# 输入必须为包含三个元素的元组
if isinstance(expr, tuple) and len(expr) == 3:
if all(e.is_number for e in expr):
# 转换为浮点数的元组
params = tuple(float(e.evalf()) for e in expr)
result = scipy_beta.pdf(*params)
elif any(e.free_symbols for e in expr):
x, a, b = expr
"""计算单点贝塔分布PDF值"""
if x.is_number and (x < 0 or x > 1):
return None # x超出定义域
B = Beta('beta', a, b)
result = density(B)(x)
else:
error = True
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
def main():
"""测试案例"""
# 标量测试
print("--- 标量测试 ---")
scalar_input = "0.5, 2, 3" # x=0.5, a=2, b=3
print(beta_function_pdf(scalar_input))
# 输出 1.5000000000000004
if __name__ == "__main__":
main()
贝塔随机数
R = betarnd(A,B,size=1) 使用A和B指定的参数从beta分布中生成随机数.A和B可以是具有相同大小的向量、矩阵.A或B的一个标量输入扩展为其维数与另一个输入的维数相同的常量数组.
A是标量, 向量,矩阵.
B是标量, 向量,矩阵.
size是标量, 生成多少个贝塔随机数.
示例1:模拟A/B测试结果
假设我们正在进行A/B测试,比较两个网页设计的转化率。我们可以使用Beta分布来模拟可能的转化率:
# 设计A: 基于历史数据,我们估计转化率遵循Beta(20, 80)分布
# 设计B: 基于历史数据,我们估计转化率遵循Beta(25, 75)分布
# 生成1000次模拟的转化率
design_A_rates = betarnd(20, 80, 1000)
design_B_rates = betarnd(25, 75, 1000)
#A/B测试转化率模拟结果:
print(f"设计A的平均转化率: {np.mean(design_A_rates):.4f}")
print(f"设计B的平均转化率: {np.mean(design_B_rates):.4f}")
print(f"设计A的转化率标准差: {np.std(design_A_rates):.4f}")
print(f"设计B的转化率标准差: {np.std(design_B_rates):.4f}")
#设计A的平均转化率: 0.1985
#设计B的平均转化率: 0.2466
#设计A的转化率标准差: 0.0391
#设计B的转化率标准差: 0.0431
# 计算设计B优于设计A的比例
b_better_than_a = np.mean(design_B_rates > design_A_rates)
print(f"设计B优于设计A的概率: {b_better_than_a:.4f}")
#设计B优于设计A的概率: 0.7950
示例2:产品质量控制模拟
在制造业中,可以使用Beta分布模拟产品的合格率:
# 三个生产批次的合格率历史数据:
# 批次1: 基于50次测试,45次合格 → Beta(46, 6)
# 批次2: 基于100次测试,92次合格 → Beta(93, 9)
# 批次3: 基于80次测试,76次合格 → Beta(77, 5)
# 为每个批次生成1000次模拟合格率
batch_1_rates = betarnd(46, 6, 1000)
batch_2_rates = betarnd(93, 9, 1000)
batch_3_rates = betarnd(77, 5, 1000)
print("产品质量合格率模拟:")
print(f"批次1平均合格率: {np.mean(batch_1_rates):.4f}")
print(f"批次2平均合格率: {np.mean(batch_2_rates):.4f}")
print(f"批次3平均合格率: {np.mean(batch_3_rates):.4f}")
#批次1平均合格率: 0.8829
#批次2平均合格率: 0.9113
#批次3平均合格率: 0.9389
# 计算合格率超过95%的概率
threshold = 0.95
p1_above = np.mean(batch_1_rates > threshold)
p2_above = np.mean(batch_2_rates > threshold)
p3_above = np.mean(batch_3_rates > threshold)
print(f"批次1合格率超过{threshold:.2f}的概率: {p1_above:.4f}")
print(f"批次2合格率超过{threshold:.2f}的概率: {p2_above:.4f}")
print(f"批次3合格率超过{threshold:.2f}的概率: {p3_above:.4f}")
#批次1合格率超过0.95的概率: 0.0430
#批次2合格率超过0.95的概率: 0.0710
#批次3合格率超过0.95的概率: 0.4020
示例3:矩阵输入处理多个场景
当需要同时模拟多个场景的参数时,可以使用矩阵输入:
# 定义多个产品的Beta分布参数矩阵
alpha_matrix = [[2, 5, 10], [3, 7, 15]] # 2x3矩阵
beta_matrix = [[8, 5, 20], [7, 13, 35]] # 2x3矩阵
# 为每个产品生成随机合格率
random_rates = betarnd(alpha_matrix, beta_matrix)
#多产品合格率随机矩阵:
print(random_rates)
#[[0.25566271 0.53045006 0.24686348]
[0.17210655 0.46058921 0.30724223]]
示例4:蒙特卡洛模拟
使用Beta分布进行蒙特卡洛模拟,评估项目成功率:
# 假设一个项目有3个关键阶段,每个阶段的成功率遵循Beta分布
# 阶段1: Beta(8, 2) - 高成功率
# 阶段2: Beta(5, 5) - 中等成功率
# 阶段3: Beta(3, 7) - 较低成功率
# 进行10000次蒙特卡洛模拟
n_simulations = 10000
phase1_success = betarnd(8, 2, 10000)
phase2_success = betarnd(5, 5, 10000)
phase3_success = betarnd(3, 7, 10000)
# 项目整体成功率是各阶段成功率的乘积
project_success = phase1_success * phase2_success * phase3_success
#项目成功率蒙特卡洛模拟结果:
print(f"平均项目成功率: {np.mean(project_success):.4f}")
print(f"项目成功率中位数: {np.median(project_success):.4f}")
print(f"项目成功率90%分位数: {np.percentile(project_success, 90):.4f}")
print(f"项目成功率超过0.5的概率: {np.mean(project_success > 0.5):.4f}")
#平均项目成功率: 0.1195
#项目成功率中位数: 0.1059
#项目成功率90%分位数: 0.2163
#项目成功率超过0.5的概率: 0.0001
示例5:用户行为建模
在推荐系统中,可以使用Beta分布模拟用户的点击率:
# 假设我们有3个推荐算法,每个算法的历史表现如下:
# 算法A: 1000次展示,150次点击 → Beta(151, 851)
# 算法B: 800次展示,120次点击 → Beta(121, 681)
# 算法C: 1200次展示,180次点击 → Beta(181, 1021)
# 生成未来100次展示的点击率预测
algo_A_ctr = betarnd(151, 851, 100)
algo_B_ctr = betarnd(121, 681, 100)
algo_C_ctr = betarnd(181, 1021, 100)
#推荐算法点击率预测:
print(f"算法A预测平均CTR: {np.mean(algo_A_ctr):.4f}")
print(f"算法B预测平均CTR: {np.mean(algo_B_ctr):.4f}")
print(f"算法C预测平均CTR: {np.mean(algo_C_ctr):.4f}")
#算法A预测平均CTR: 0.1516
#算法B预测平均CTR: 0.1506
#算法C预测平均CTR: 0.1500
# 计算每个算法成为最佳的概率
best_algo = np.argmax([algo_A_ctr, algo_B_ctr, algo_C_ctr], axis=0)
algo_A_best = np.mean(best_algo == 0)
algo_B_best = np.mean(best_algo == 1)
algo_C_best = np.mean(best_algo == 2)
print(f"算法A成为最佳的概率: {algo_A_best:.4f}")
print(f"算法B成为最佳的概率: {algo_B_best:.4f}")
print(f"算法C成为最佳的概率: {algo_C_best:.4f}")
#算法A成为最佳的概率: 0.3200
#算法B成为最佳的概率: 0.3700
#算法C成为最佳的概率: 0.3100
示例6:金融风险评估
在金融领域,Beta分布可用于模拟投资组合的收益率:
# 假设我们有三支股票,每支股票的收益率遵循Beta分布
# 股票A: Beta(3, 2) - 较高风险较高收益
# 股票B: Beta(2, 3) - 中等风险中等收益
# 股票C: Beta(1, 4) - 较低风险较低收益
# 生成1000次模拟收益率
stock_A_returns = betarnd(3, 2, 1000)
stock_B_returns = betarnd(2, 3, 1000)
stock_C_returns = betarnd(1, 4, 1000)
# 计算投资组合收益率(假设等权重)
portfolio_returns = (stock_A_returns + stock_B_returns + stock_C_returns) / 3
print("投资组合收益率模拟:")
print(f"股票A平均收益率: {np.mean(stock_A_returns):.4f}")
print(f"股票B平均收益率: {np.mean(stock_B_returns):.4f}")
print(f"股票C平均收益率: {np.mean(stock_C_returns):.4f}")
print(f"投资组合平均收益率: {np.mean(portfolio_returns):.4f}")
#股票A平均收益率: 0.5974
#股票B平均收益率: 0.3973
#股票C平均收益率: 0.1979
#投资组合平均收益率: 0.3975
# 计算风险指标
print(f"投资组合收益率标准差: {np.std(portfolio_returns):.4f}")
print(f"投资组合负收益率概率: {np.mean(portfolio_returns < 0):.4f}")
#投资组合收益率标准差: 0.1030
#投资组合负收益率概率: 0.0000
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.stats import beta
def beta_random_number(input_str):
"""
根据输入生成Beta分布随机数或矩阵。
参数:
input_str: 输入字符串,支持以下形式:
- "(a, b)":生成单个随机数
- "(MatrixA, MatrixB)":同维矩阵逐元素生成随机数
- "(MatrixA, b)" 或 "(a, MatrixB)":标量与矩阵组合
- "(a, b, size)":生成指定大小的数组(返回numpy数组)
返回:
SymPy矩阵、数值、numpy数组,错误时返回字符串描述。
"""
try:
expr = sp.sympify(input_str)
# 计算 Beta Random函数
error = False
result = None
def evaluation_beta_random(x, y, size=None):
"""生成Beta分布随机数,支持标量和矩阵"""
return beta.rvs(float(x), float(y), size=size)
if isinstance(expr, tuple):
if len(expr) in (2, 3) and all(e.is_number for e in expr):
result = evaluation_beta_random(*expr)
else:
error = True
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误:{e}"
def main():
"""示例用法"""
# 示例1:标量输入
print("示例1:", beta_random_number("(2, 3)"), end="\n\n")
#结果: 0.3371839997481763
# 示例2:带size参数
print("示例2:", beta_random_number("(2, 3, 5)"), end="\n\n") # 返回5x1矩阵
#结果: [0.48052799 0.18822748 0.51598961 0.23080004 0.36741535]
if __name__ == "__main__":
main()
贝塔平均值和方差
(M,V) = betastat(A,B),当A>0和B>0时,返回具有由A和B指定的参数的贝塔分布的均值和方差. A和B可以是具有相同大小的向量,矩阵,这也是M和V的大小.A或B的标量输入被扩展为与其他输入具有相同维度的常量数组.
A是标量, 向量,矩阵.
B是标量, 向量,矩阵.
M, V的大小与A, B相同.
示例1:A/B测试结果分析
假设我们正在进行A/B测试,比较两个网页设计的转化率。我们可以计算每个设计的转化率的期望值和不确定性:
# 设计A: 基于100次展示,20次转化 → Beta(21, 81)
# 设计B: 基于120次展示,25次转化 → Beta(26, 96)
# 计算每个设计的转化率均值和方差
mean_A, var_A = betastat(21, 81)
mean_B, var_B = betastat(26, 96)
#A/B测试转化率分析
print(f"设计A - 期望转化率: {mean_A:.4f}, 方差: {var_A:.6f}")
print(f"设计B - 期望转化率: {mean_B:.4f}, 方差: {var_B:.6f}")
#设计A - 期望转化率: 0.2059, 方差: 0.001587
#设计B - 期望转化率: 0.2131, 方差: 0.001363
# 计算转化率的95%置信区间(近似正态假设)
from scipy.stats import norm
z_score = norm.ppf(0.975) # 1.96 for 95% CI
ci_A_low = mean_A - z_score * np.sqrt(var_A)
ci_A_high = mean_A + z_score * np.sqrt(var_A)
ci_B_low = mean_B - z_score * np.sqrt(var_B)
ci_B_high = mean_B + z_score * np.sqrt(var_B)
print(f"设计A转化率95%置信区间: [{ci_A_low:.4f}, {ci_A_high:.4f}]")
print(f"设计B转化率95%置信区间: [{ci_B_low:.4f}, {ci_B_high:.4f}]")
#设计A转化率95%置信区间: [0.1278, 0.2840]
#设计B转化率95%置信区间: [0.1407, 0.2855]
示例2:产品质量控制分析
在制造业中,可以使用Beta分布分析产品合格率的期望值和变异性:
# 三个生产批次的合格率数据:
# 批次1: 测试50个,合格45个 → Beta(46, 6)
# 批次2: 测试100个,合格92个 → Beta(93, 9)
# 批次3: 测试80个,合格76个 → Beta(77, 5)
# 计算每个批次的合格率均值和方差
batch_params = [(46, 6), (93, 9), (77, 5)]
#产品质量合格率分析:
for i, (alpha, beta_val) in enumerate(batch_params):
mean, var = betastat(alpha, beta_val)
std_dev = np.sqrt(var)
print(f"批次{i+1}: 期望合格率={mean:.4f}, 标准差={std_dev:.4f}")
# 计算合格率超过95%的概率(使用正态近似)
if std_dev > 0:
z_score = (0.95 - mean) / std_dev
prob_above_95 = 1 - norm.cdf(z_score)
print(f" 合格率超过95%的概率: {prob_above_95:.4f}")
#批次1: 期望合格率=0.8846, 标准差=0.0439, 合格率超过95%的概率: 0.0681
#批次2: 期望合格率=0.9118, 标准差=0.0279, 合格率超过95%的概率: 0.0856
#批次3: 期望合格率=0.9390, 标准差=0.0263, 合格率超过95%的概率: 0.3380
示例3:矩阵输入处理多个场景
当需要同时分析多个产品的质量特性时,可以使用矩阵输入:
示例3:贝叶斯先验与后验分布比较
在贝叶斯分析中,可以使用Beta分布作为二项分布的共轭先验,并比较先验和后验分布的均值和方差:
# 先验分布: Beta(2, 2)
prior_alpha, prior_beta = 2, 2
# 观察数据: 10次试验,7次成功
successes, failures = 7, 3
# 后验分布: Beta(2+7, 2+3) = Beta(9, 5)
posterior_alpha = prior_alpha + successes
posterior_beta = prior_beta + failures
# 计算先验和后验分布的均值和方差
prior_mean, prior_var = betastat(prior_alpha, prior_beta)
posterior_mean, posterior_var = betastat(posterior_alpha, posterior_beta)
#贝叶斯更新分析:
print(f"先验分布: Beta({prior_alpha}, {prior_beta})")
print(f" 均值: {prior_mean:.4f}, 方差: {prior_var:.6f}")
#先验分布: Beta(2, 2)
#均值: 0.5000, 方差: 0.050000
print(f"后验分布: Beta({posterior_alpha}, {posterior_beta})")
print(f" 均值: {posterior_mean:.4f}, 方差: {posterior_var:.6f}")
#后验分布: Beta(9, 5)
#均值: 0.6429, 方差: 0.015306
# 计算信息增益(方差减少)
variance_reduction = (prior_var - posterior_var) / prior_var
print(f"方差减少(信息增益): {variance_reduction:.2%}")
#方差减少(信息增益): 69.39%
示例4:项目风险评估
在项目管理中,可以使用Beta分布评估任务完成概率的不确定性:
# 假设一个项目有3个关键任务,每个任务的完成概率遵循Beta分布
# 任务1: Beta(8, 2) - 高完成概率
# 任务2: Beta(5, 5) - 中等完成概率
# 任务3: Beta(3, 7) - 较低完成概率
# 计算每个任务的完成概率均值和方差
task_params = [(8, 2), (5, 5), (3, 7)]
#项目任务完成概率分析:
for i, (alpha, beta_val) in enumerate(task_params):
mean, var = betastat(alpha, beta_val)
std_dev = np.sqrt(var)
print(f"任务{i + 1}: 期望完成概率={mean:.4f}, 标准差={std_dev:.4f}")
# 计算完成概率超过80%的概率
if std_dev > 0:
z_score = (0.8 - mean) / std_dev
prob_above_80 = 1 - norm.cdf(z_score)
print(f" 完成概率超过80%的概率: {prob_above_80:.4f}")
#任务1: 期望完成概率=0.8000, 标准差=0.1206, 完成概率超过80%的概率: 0.5000
#任务2: 期望完成概率=0.5000, 标准差=0.1508, 完成概率超过80%的概率: 0.0233
#任务3: 期望完成概率=0.3000, 标准差=0.1382, 完成概率超过80%的概率: 0.0001
示例5:投资组合风险评估
在金融领域,可以使用Beta分布分析投资收益率的不确定性:
# 假设我们有三支股票,每支股票的收益率遵循Beta分布
# 股票A: Beta(3, 2) - 较高风险较高收益
# 股票B: Beta(2, 3) - 中等风险中等收益
# 股票C: Beta(1, 4) - 较低风险较低收益
# 计算每支股票的收益率均值和方差
stock_params = [(3, 2), (2, 3), (1, 4)]
#股票收益率分析:
for i, (alpha, beta_val) in enumerate(stock_params):
mean, var = betastat(alpha, beta_val)
std_dev = np.sqrt(var)
print(f"股票{chr(65+i)}: 期望收益率={mean:.4f}, 标准差={std_dev:.4f}")
# 计算夏普比率(假设无风险收益率为0)
sharpe_ratio = mean / std_dev if std_dev > 0 else 0
print(f" 夏普比率: {sharpe_ratio:.4f}")
#股票A: 期望收益率=0.6000, 标准差=0.2000, 夏普比率: 3.0000
#股票B: 期望收益率=0.4000, 标准差=0.2000, 夏普比率: 2.0000
#股票C: 期望收益率=0.2000, 标准差=0.1633, 夏普比率: 1.2247
# 计算等权重投资组合的期望收益率和方差
# 注意:这是一个简化计算,实际中需要考虑股票间的相关性
portfolio_mean = np.mean([mean for mean, _ in [betastat(a, b) for a, b in stock_params]])
portfolio_var = np.mean([var for _, var in [betastat(a, b) for a, b in stock_params]]) / len(stock_params)
print(f"\n等权重投资组合: 期望收益率={portfolio_mean:.4f}, 方差={portfolio_var:.6f}")
#等权重投资组合: 期望收益率=0.4000, 方差=0.011852
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
def beta_mean_variance(input_str):
"""
计算Beta分布的均值和方差,支持矩阵和标量输入
参数:
input_str: 输入字符串,支持格式:
- "(a, b)":计算标量的均值和方差
- "(MatrixA, MatrixB)":同型矩阵逐元素计算
- "(MatrixA, b)" 或 "(a, MatrixB)":标量与矩阵组合
返回:
若成功:返回包含均值矩阵/值和方差矩阵/值的元组 (M, V)
若失败:返回错误描述字符串
"""
try:
expr = sp.sympify(input_str)
result = None # 初始化均值和方差结果
error = False
def betastat(A, B):
"""
计算贝塔分布的均值和方差
参数:
A, B : array_like
贝塔分布的形状参数。可以是标量、向量、矩阵或多维数组。
支持NumPy广播规则,维度必须兼容。
返回:
M : ndarray
贝塔分布的均值,形状与广播后的输入相同
V : ndarray
贝塔分布的方差,形状与广播后的输入相同
公式:
均值 M = A / (A + B)
方差 V = (A * B) / ((A + B)**2 * (A + B + 1))
当分母为零时返回NaN
"""
# 确保输入为NumPy数组以支持广播
A = np.asarray(A)
B = np.asarray(B)
# 计算总和 S = A + B(使用广播机制)
S = A + B
# 计算均值
M = np.divide(A, S, out=np.full_like(S, np.nan, dtype=float), where=(S != 0))
# 计算方差
denominator = S ** 2 * (S + 1)
V = np.divide(
A * B,
denominator,
out=np.full_like(S, np.nan, dtype=float),
where=(denominator != 0)
)
return M, V
# 仅处理包含两个元素的元组
if isinstance(expr, tuple) and len(expr) == 2:
# 处理数值标量
if all(e.is_number for e in expr):
# 转换为浮点数的元组
params = tuple(float(e.evalf()) for e in expr)
if any(param <= 0 for param in params):
raise ValueError(f"参数错误")
mean, var = betastat(*params)
result = mean, var
else:
error = True
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"计算失败: {str(e)}"
def main():
"""示例用法"""
# 示例1:标量计算
print("标量计算:", beta_mean_variance("(2, 5)"), end="\n\n")
#结果: (array(0.28571429), array(0.0255102))
if __name__ == "__main__":
main()
国债贴现收益率
Yield = beytbill(Settle,Maturity,Discount) 返回国库券的债券等价收益率。
Settle - 国库券结算日期
Maturity - 国库券到期日
Discount - 国库券贴现率
Yield - 国债贴现收益率
示例1:国债投资回报分析
假设投资者正在考虑购买一张短期国债,可以使用BEY来比较不同国债的投资回报
# 不同国债的比较
treasury_bills = [
{
"name": "13周国债",
"settle": "2023-01-15",
"maturity": "2023-04-15",
"discount": 0.045 # 4.5%贴现率
},
{
"name": "26周国债",
"settle": "2023-01-15",
"maturity": "2023-07-15",
"discount": 0.048 # 4.8%贴现率
},
{
"name": "52周国债",
"settle": "2023-01-15",
"maturity": "2024-01-15",
"discount": 0.052 # 5.2%贴现率
}
]
#不同期限国债的等效收益率比较:
for bill in treasury_bills:
bey = beytbill(
bill["settle"],
bill["maturity"],
bill["discount"]
)
print(f"{bill['name']}: 贴现率={bill['discount']*100:.2f}%, BEY={bey*100:.2f}%")
#13周国债: 贴现率=4.50%, BEY=4.61%
#26周国债: 贴现率=4.80%, BEY=4.99%
#52周国债: 贴现率=5.20%, BEY=5.57%
示例2:投资决策支持
财务分析师可以使用BEY来比较不同投资工具的收益率:
# 比较国债与其他短期投资工具
investments = [
{
"name": "3个月国债",
"settle": "2023-03-01",
"maturity": "2023-06-01",
"discount": 0.0475,
"type": "国债"
},
{
"name": "6个月大额存单",
"rate": 0.051, # 5.1%年化利率
"type": "存单"
},
{
"name": "货币市场基金",
"rate": 0.048, # 4.8%七日年化
"type": "基金"
}
]
#不同短期投资工具收益率比较:
for investment in investments:
if investment["type"] == "国债":
bey = beytbill(
investment["settle"],
investment["maturity"],
investment["discount"]
)
print(f"{investment['name']}: BEY={bey*100:.2f}%")
else:
print(f"{investment['name']}: 年化收益率={investment['rate']*100:.2f}%")
#3个月国债: BEY=4.88%
#6个月大额存单: 年化收益率=5.10%
#货币市场基金: 年化收益率=4.80%
示例3:市场利率变化分析
跟踪国债收益率随时间的变化,分析市场利率趋势:
# 模拟市场利率变化对BEY的影响
base_date = "2023-01-01"
maturity_date = "2023-07-01"
# 不同贴现率下的BEY
discount_rates = [0.03, 0.035, 0.04, 0.045, 0.05, 0.055]
#贴现率变化对BEY的影响:
print("贴现率\tBEY\t变化幅度")
prev_bey = None
for rate in discount_rates:
bey = beytbill(base_date, maturity_date, rate)
change = (bey - prev_bey)*100 if prev_bey is not None else 0
print(f"{rate*100:.1f}%\t{bey*100:.2f}%\t{change:+.2f}%" if prev_bey is not None else f"{rate*100:.1f}%\t{bey*100:.2f}%\t-")
prev_bey = bey
#贴现率 BEY 变化幅度
3.0% 3.09% -
3.5% 3.61% +0.52%
4.0% 4.14% +0.53%
4.5% 4.67% +0.53%
5.0% 5.20% +0.53%
5.5% 5.73% +0.53%
示例4:投资组合优化
财务顾问可以使用BEY来帮助客户优化短期投资组合:
# 客户短期投资组合分析
client_portfolio = [
{"name": "国债A", "settle": "2023-02-01", "maturity": "2023-05-01", "discount": 0.046, "amount": 50000},
{"name": "国债B", "settle": "2023-02-01", "maturity": "2023-08-01", "discount": 0.049, "amount": 75000},
{"name": "国债C", "settle": "2023-02-01", "maturity": "2023-11-01", "discount": 0.051, "amount": 100000}
]
#客户国债投资组合分析:
total_investment = 0
weighted_bey = 0
for investment in client_portfolio:
bey = beytbill(
investment["settle"],
investment["maturity"],
investment["discount"]
)
investment_value = investment["amount"]
total_investment += investment_value
weighted_bey += bey * investment_value
print(f"{investment['name']}: 投资额=${investment_value:,.0f}, BEY={bey*100:.2f}%")
#国债A: 投资额=$50,000, BEY=4.72%
#国债B: 投资额=$75,000, BEY=5.09%
#国债C: 投资额=$100,000, BEY=5.38%
portfolio_bey = weighted_bey / total_investment
print(f"\n投资组合总体BEY: {portfolio_bey*100:.2f}%")
print(f"总投资额: ${total_investment:,.0f}")
#投资组合总体BEY: 5.14%
#总投资额: $225,000
示例5:风险管理与期限匹配
企业财务部门可以使用BEY来管理现金流和期限匹配:
# 企业现金流期限匹配分析
cash_flow_needs = [
{"date": "2023-04-15", "amount": 100000},
{"date": "2023-07-15", "amount": 150000},
{"date": "2023-10-15", "amount": 200000}
]
available_tbills = [
{"settle": "2023-01-15", "maturity": "2023-04-10", "discount": 0.045, "face_value": 50000},
{"settle": "2023-01-15", "maturity": "2023-07-10", "discount": 0.048, "face_value": 100000},
{"settle": "2023-01-15", "maturity": "2023-10-10", "discount": 0.051, "face_value": 150000}
]
#企业现金流期限匹配与收益率分析:
for i, need in enumerate(cash_flow_needs):
# 找到最接近到期日的国债
best_match = None
min_days_diff = float('inf')
for tbill in available_tbills:
maturity_date = datetime.strptime(tbill["maturity"], "%Y-%m-%d").date()
need_date = datetime.strptime(need["date"], "%Y-%m-%d").date()
days_diff = abs((maturity_date - need_date).days)
if days_diff < min_days_diff:
min_days_diff = days_diff
best_match = tbill
if best_match:
bey = beytbill(
best_match["settle"],
best_match["maturity"],
best_match["discount"]
)
print(f"现金流{need['date']}: 最佳匹配国债BEY={bey*100:.2f}%, 期限差异={min_days_diff}天")
#现金流2023-04-15: 最佳匹配国债BEY=4.61%, 期限差异=5天
#现金流2023-07-15: 最佳匹配国债BEY=4.98%, 期限差异=5天
#现金流2023-10-15: 最佳匹配国债BEY=5.37%, 期限差异=5天
示例6:学术研究与教学示例
在金融教育中,BEY计算是理解债券收益率计算的重要案例:
#金融数学教学示例
#债券等效收益率(BEY)教学示例:
#公式: BEY = (365 × Discount) / (360 - Discount × Days)
# 展示不同参数对BEY的影响
examples = [
{"days": 90, "discount": 0.05, "description": "短期低贴现率"},
{"days": 90, "discount": 0.10, "description": "短期高贴现率"},
{"days": 180, "discount": 0.05, "description": "中期低贴现率"},
{"days": 180, "discount": 0.10, "description": "中期高贴现率"},
{"days": 360, "discount": 0.05, "description": "长期低贴现率"},
{"days": 360, "discount": 0.10, "description": "长期高贴现率"},
]
for example in examples:
# 使用固定结算日,计算到期日
settle_date = "2023-01-01"
maturity_date = (datetime.strptime(settle_date, "%Y-%m-%d") + timedelta(days=example["days"])).strftime("%Y-%m-%d")
bey = beytbill(settle_date, maturity_date, example["discount"])
print(f"{example['description']}: {example['days']}天, {example['discount']*100}%贴现率 → BEY={bey*100:.2f}%")
#短期低贴现率: 90天, 5.0%贴现率 → BEY=5.13%
#短期高贴现率: 90天, 10.0%贴现率 → BEY=10.40%
#中期低贴现率: 180天, 5.0%贴现率 → BEY=5.20%
#中期高贴现率: 180天, 10.0%贴现率 → BEY=10.67%
#长期低贴现率: 360天, 5.0%贴现率 → BEY=5.34%
#长期高贴现率: 360天, 10.0%贴现率 → BEY=11.27%
二项累积分布函数
y = binocdf(x,n,p) 使用 n 中对应的试验次数和 p 中每次试验的成功概率,计算在 x 中每个值处的二项累积分布函数.
x,n和p可以是具有相同大小的向量,矩阵.或者,一个或多个参量可以是标量.binocdf函数将标量输入扩展为常量数组,其维数与其他输入的维数相同.
x — 计算二项cdf所基于的值
n — 试验次数,正整数,正整数数组
p — 每次试验的成功概率, 来自区间[0 1]的标量值,来自区间[0 1]的标量值组成的数组
示例1:基本的数值计算(标量输入)
10次试验,成功概率0.5,最多3次成功的概率
binocdf(3,10,0.5)
#结果: 0.171875
示例2:质量控制场景(向量输入)
假设有3条生产线,每条生产100个产品,不良率分别为0.01, 0.02, 0.03
计算每条生产线最多出现2个不良品的概率
n_vals = [100, 100, 100]
p_vals = [0.01, 0.02, 0.03]
x_vals = [2, 2, 2]
三条生产线最多出现2个不良品的概率:
binocdf(x_vals,n_vals,p_vals)
#结果: [0.9206268,0.67668562,0.41977508]
示例3:医学试验场景(矩阵输入)
两种药物在三个不同剂量下的试验结果
矩阵行表示不同药物,列表示不同剂量
n_matrix = [[50, 50, 50], [50, 50, 50]] # 每组50名患者
p_matrix = [[0.7, 0.75, 0.8], [0.65, 0.7, 0.75]] # 不同情况下的有效率
x_matrix = [[40, 38, 35], [35, 35, 35]] # 计算至少达到这些有效人数的概率
不同药物和剂量组合的有效率累积概率:
binocdf(x_matrix,n_matrix,p_matrix)
#结果: [[0.95976837,0.61838144,0.06072208]
[0.81222301,0.55316843,0.25191886]]
示例4:符号计算
binocdf(n,p,k)
#结果: Sum(k**x*(1 - k)**(k - x)*binomial(k, x), (x, 0, floor(n)))
示例5:混合符号和数值计算
固定试验次数和成功次数,变化概率
20次试验中最多15次成功的概率(关于p的函数):
binocdf(15,20,p)
#结果: Sum(p**x*(1 - p)**(20 - x)*binomial(20, x), (x, 0, 15))
示例6:教育评估场景(多维数组)
三个班级,每个班级有4次测验,每次测验有30道题
计算每个学生至少答对20题的概率
n_3d = np.full((3, 4, 5), 30) # 3个班级×4次测验×5个学生
p_3d = np.random.uniform(0.6, 0.9, (3, 4, 5)) # 每个学生的正确率
x_3d = np.full((3, 4, 5), 20) # 阈值是20题
result6 = binocdf(x_3d, n_3d, p_3d)
print(f"每个学生至少答对20题的概率矩阵形状: {np.array(result6).shape}")
#每个学生至少答对20题的概率矩阵形状: (3, 4, 5)
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
from scipy.stats import binom
import numpy as np
import sympy as sp
def binomial_distribution_cdf(input_str):
"""
计算二项分布的累积分布函数(CDF)
输入格式支持:
- 元组 (n, p, x) :标量参数
- 元组 (n, p, x, [数值代入点]) :带数值代入的符号计算
- 各参数可以是标量或矩阵(需形状一致)
返回:
数值结果、符号表达式或错误信息
"""
# 解析输入表达式
try:
# 解析输入表达式
expr = sp.sympify(input_str)
error = False
result = None
# 定义二项分布的CDF表达式
def binocdf_sym(x_val, n_val, p_val):
"""用SymPy计算二项分布的CDF(数值标量参数)"""
k = sp.symbols('k') # 定义求和符号变量k
K = int(sp.floor(x_val)) # 将x向下取整为整数
expr = sp.Sum(
sp.binomial(n_val, k) * (p_val ** k) * ((1 - p_val) ** (n_val - k)),
(k, 0, K) # 求和范围:k从0到K(含K)
)
return expr.doit() # 执行求和并转为浮点数
if isinstance(expr, tuple) and len(expr) == 3:
if all(e.is_number for e in expr):
params = tuple(float(e.evalf()) for e in expr)
"""二项分布CDF(数值标量参数)"""
k = np.floor(params[0]) # 将x向下取整为整数k(二项分布的定义域)
result = binom.cdf(int(k), params[1], params[2])
elif expr[0].is_integer and any(e.free_symbols for e in expr[1:]):
result = binocdf_sym(*expr)
else:
error = True
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {str(e)}"
def main():
"""主函数演示用法"""
print("=== 标量计算示例 ===")
# 示例1:符号计算
print("符号表达式:")
print(binomial_distribution_cdf("(1, p, x)")) # 输出符号表达式
#结果: p*x*(1 - x)**(p - 1) + (1 - x)**p
# 示例2:数值计算
print("\n数值计算 (n=55, p=100, x=0.5):")
print(binomial_distribution_cdf("(55, 100, 0.5)")) # 输出 0.8643
#结果: 0.8643734879630823
if __name__ == "__main__":
main()
二项式比例的置信区间
c_low, c_high = binofit(x,n) 返回95%置信区间pci.
x — 成功次数,正整数,,正整数数组
n — 试验次数,正整数,正整数数组
c_low, c_high - 覆盖范围(大约)为1
示例1:基本标量输入
成功10次,总试验100次,95%置信区间:
binofit(10,100)
##结果: (array(0.05522914), array(0.17436566))
示例2:医学试验场景
一种药物在三个不同剂量组的效果
success_counts = [15, 20, 25] # 每个剂量组的成功治疗人数
total_patients = [30, 30, 30] # 每个剂量组的总患者数
lower, upper = binofit(success_counts, total_patients)
for i in range(len(success_counts)):
print(f"剂量组{i + 1}: 成功率={success_counts[i] / total_patients[i]:.3f}, "
f"95%CI=({lower[i]:.3f}, {upper[i]:.3f})")
#剂量组1: 成功率=0.500, 95%CI=(0.332, 0.668)
#剂量组2: 成功率=0.667, 95%CI=(0.488, 0.808)
#剂量组3: 成功率=0.833, 95%CI=(0.664, 0.927)
示例3:质量控制场景
三条生产线在一周内生产的产品质量
defect_counts = [[5, 3, 7], [2, 4, 6], [1, 0, 2]] # 每天的不良品数量
daily_production = [[100, 100, 100], [100, 100, 100], [100, 100, 100]] # 每天的产量
lower, upper = binofit(defect_counts, daily_production)
三条生产线的不良率置信区间:
for i in range(len(defect_counts)):
for j in range(len(defect_counts[0])):
defect_rate = defect_counts[i][j] / daily_production[i][j]
print(f"生产线{i+1} 第{j+1}天: 不良率={defect_rate:.3f}, "
f"95%CI=({lower[i][j]:.3f}, {upper[i][j]:.3f})")
#生产线1 第1天: 不良率=0.050, 95%CI=(0.022, 0.112)
#生产线1 第2天: 不良率=0.030, 95%CI=(0.010, 0.085)
#生产线1 第3天: 不良率=0.070, 95%CI=(0.034, 0.137)
#生产线2 第1天: 不良率=0.020, 95%CI=(0.006, 0.070)
#生产线2 第2天: 不良率=0.040, 95%CI=(0.016, 0.098)
#生产线2 第3天: 不良率=0.060, 95%CI=(0.028, 0.125)
#生产线3 第1天: 不良率=0.010, 95%CI=(0.002, 0.054)
#生产线3 第2天: 不良率=0.000, 95%CI=(0.000, 0.037)
#生产线3 第3天: 不良率=0.020, 95%CI=(0.006, 0.070)
示例4:教育评估场景
三个班级在四次测验中的表现
correct_answers = np.random.randint(15, 25, (3, 4, 5)) # 3个班级×4次测验×5个学生
total_questions = np.full((3, 4, 5), 30) # 每次测验30道题
lower, upper = binofit(correct_answers, total_questions)
print(f"置信区间数组形状: {np.array(lower).shape}")
print(f"第一个班级第一次测验第一个学生的正确率置信区间: "
f"({lower[0][0][0]:.3f}, {upper[0][0][0]:.3f})")
#置信区间数组形状: (3, 4, 5)
#第一个班级第一次测验第一个学生的正确率置信区间: (0.455, 0.781)
示例5:A/B测试场景
比较两个版本的转化率
version_a_conversions = 120
version_a_visitors = 1000
version_b_conversions = 150
version_b_visitors = 1000
分别计算两个版本的置信区间
lower_a, upper_a = binofit(version_a_conversions, version_a_visitors)
lower_b, upper_b = binofit(version_b_conversions, version_b_visitors)
print(f"版本A转化率: {version_a_conversions/version_a_visitors:.3f}, "
f"95%CI=({lower_a:.3f}, {upper_a:.3f})")
print(f"版本B转化率: {version_b_conversions/version_b_visitors:.3f}, "
f"95%CI=({lower_b:.3f}, {upper_b:.3f})")
#版本A转化率: 0.120, 95%CI=(0.101, 0.142)
#版本B转化率: 0.150, 95%CI=(0.129, 0.173)
检查置信区间是否重叠
if upper_a < lower_b:
print("版本B显著优于版本A")
elif upper_b < lower_a:
print("版本A显著优于版本B")
else:
print("两个版本差异不显著")
#两个版本差异不显著
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from statsmodels.stats.proportion import proportion_confint # 新增关键依赖
def binomial_parameter_estimates(input_str):
"""
二项分布参数估计(置信区间计算)
输入格式支持:
- 元组 (success_count, total_trials)
- 参数可以是:
- 标量数字
- 矩阵(需形状一致)
- 矩阵与标量组合
返回:
tuple: (lower_bounds, upper_bounds) 或错误信息
"""
try:
# 输入预处理(假设util模块存在)
expr = sp.sympify(input_str)
def calculate_ci(count, nobs):
"""计算单个置信区间"""
if count < 0 or nobs <= 0 or count > nobs:
raise ValueError("无效参数: count需满足 0 ≤ count ≤ nobs")
return proportion_confint(
count=int(count),
nobs=int(nobs),
alpha=0.05,
method='wilson'
)
if isinstance(expr, tuple) and len(expr) == 2:
if all(e.is_number for e in expr):
# 转换为整数的元组
params = tuple(float(e.evalf()) for e in expr)
ci_lower, ci_upper = calculate_ci(*params)
else:
error = True
return ci_lower, ci_upper
else:
return f"错误:输入格式应为 (success_count, total_trials)"
except Exception as e:
return f"错误: {str(e)}"
def main():
"""主函数演示用法"""
print("=== 标量计算示例 ===")
# 示例1:有效输入
print("正常输入 (10, 100):")
print(binomial_parameter_estimates("(10, 100)"))
#结果: (0.05522913706067509, 0.17436566150491348)
# 示例2:边界条件
print("\n边界条件 (0, 50):")
print(binomial_parameter_estimates("(0, 50)"))
#结果: (0.0, 0.07134759913335874)
if __name__ == "__main__":
main()
二项逆累积分布函数
二项逆累积分布函数(binoinv)用于计算给定概率值、试验次数和成功概率时,使得二项分布的累积分布函数(CDF)大于等于该概率值的最小整数k(即分位数)。
X = binoinv(Y,N,P)返回最小整数X,使得在X处评估的二项式cdf等于或超过Y.您可以将Y视为在N个独立试验中观察到X成功的概率,其中P是每个试验中成功的概率.每个X是小于或等于N的正整数.
Y,N和P可以是具有相同大小的向量,矩阵.标量输入被扩展为与其他输入具有相同维度的常量数组.N中的参数必须是正整数,P和Y中的值必须位于区间[01]上.
N — 试验次数,正整数,正整数数组.
P — 每次试验的成功概率,来自区间[0 1]的标量值,来自区间[0 1]的标量值组成的数组
示例1:基本标量输入
在100次试验中,成功概率0.6,95%置信水平下的阈值:
binoinv(0.95, 100, 0.6)
#结果: 68.0
示例2:质量控制场景
确定三条生产线的质量验收标准
confidence_levels = [0.95, 0.99, 0.90] # 不同的置信水平
sample_sizes = [100, 100, 100] # 每批抽样数量
expected_defect_rates = [0.05, 0.03, 0.08] # 预期的缺陷率
thresholds = binoinv(confidence_levels,sample_sizes,expected_defect_rates)
for i in range(len(confidence_levels)):
print(f"生产线{i+1}: {confidence_levels[i]*100}%置信水平下,"
f"预期缺陷率{expected_defect_rates[i]},"
f"最大允许缺陷数: {thresholds[i]}")
#生产线1: 95.0%置信水平下,预期缺陷率0.05,最大允许缺陷数: 9.0
#生产线2: 99.0%置信水平下,预期缺陷率0.03,最大允许缺陷数: 8.0
#生产线3: 90.0%置信水平下,预期缺陷率0.08,最大允许缺陷数: 12.0
示例3:医学研究场景
确定临床试验中需要观察到的有效病例数
confidence = 0.95 # 置信水平
patient_groups = [50, 100, 150] # 不同组的患者数量
expected_efficacy = [0.7, 0.8, 0.75] # 预期的有效率
使用广播机制,将标量与数组组合
required_successes = binoinv(confidence,patient_groups,expected_efficacy)
for i in range(len(patient_groups)):
print(f"患者组大小{patient_groups[i]}, 预期有效率{expected_efficacy[i]}, "
f"95%置信水平下需要至少{required_successes[i]}例成功")
#患者组大小50, 预期有效率0.7, 95%置信水平下需要至少40.0例成功
#患者组大小100, 预期有效率0.8, 95%置信水平下需要至少86.0例成功
#患者组大小150, 预期有效率0.75, 95%置信水平下需要至少121.0例成功
示例4:金融风险管理
计算在给定置信水平下的最大损失次数
confidence_matrix = [[0.95, 0.99], [0.90, 0.95]] # 不同资产和置信水平的矩阵
trial_counts = [[100, 100], [200, 200]] # 交易次数
loss_probabilities = [[0.1, 0.05], [0.15, 0.1]] # 损失概率
max_losses = binoinv(confidence_matrix,trial_counts,loss_probabilities)
不同资产和置信水平下的最大损失次数:
for i in range(len(confidence_matrix)):
for j in range(len(confidence_matrix[0])):
print(f"资产{i + 1}, 置信水平{confidence_matrix[i][j] * 100}%: "
f"最多{max_losses[i][j]}次损失")
#资产1, 置信水平95.0%: 最多15.0次损失
#资产1, 置信水平99.0%: 最多11.0次损失
#资产2, 置信水平90.0%: 最多37.0次损失
#资产2, 置信水平95.0%: 最多27.0次损失
示例5:教育评估中的及格标准设定
确定不同难度测验的及格分数线
confidence_level = 0.90 # 置信水平
question_counts = [20, 30, 40] # 不同测验的题目数量
expected_pass_rates = [0.6, 0.7, 0.65] # 预期的通过率
pass_thresholds = binoinv(confidence_level,question_counts,expected_pass_rates)
for i in range(len(question_counts)):
print(f"{question_counts[i]}题测验,预期通过率{expected_pass_rates[i]}, "
f"90%置信水平下的及格题数: {pass_thresholds[i]}")
#20题测验,预期通过率0.6, 90%置信水平下的及格题数: 15.0
#30题测验,预期通过率0.7, 90%置信水平下的及格题数: 24.0
#40题测验,预期通过率0.65, 90%置信水平下的及格题数: 30.0
示例6:A/B测试中的样本量确定
确定需要多少成功转化才能确信版本B优于版本A
confidence = 0.95
visitors = 1000 # 每组访问者数量
baseline_rate = 0.1 # 版本A的转化率
expected_improvement = [0.12, 0.15, 0.2] # 版本B预期的转化率
required_conversions = binoinv(confidence,visitors,expected_improvement)
for i, rate in enumerate(expected_improvement):
improvement = (rate - baseline_rate) / baseline_rate * 100
print(f"预期转化率提升{improvement:.1f}% (从{baseline_rate}到{rate}), "
f"需要至少{required_conversions[i]}次转化才能有95%置信度")
#预期转化率提升20.0% (从0.1到0.12), 需要至少137.0次转化才能有95%置信度
#预期转化率提升50.0% (从0.1到0.15), 需要至少169.0次转化才能有95%置信度
#预期转化率提升100.0% (从0.1到0.2), 需要至少221.0次转化才能有95%置信度
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
from scipy.stats import binom
import sympy as sp
def binomial_function_cdf_inverse(input_str):
"""
二项分布逆累积分布函数计算
输入格式: (q, n, p) 元组
- q: 概率值 (0 ≤ q ≤ 1)
- n: 试验次数(正整数)
- p: 成功概率 (0 ≤ p ≤ 1)
支持标量、矩阵及混合输入
返回: 满足 P(X ≤ k) ≥ q 的最小整数k
"""
try:
# 解析输入表达式
expr = sp.sympify(input_str)
error = False
result = None
def binoinv_scipy(q, n, p):
"""
二项分布分位函数(数值标量版本)
:param q: 累积概率值(0 ≤ q ≤ 1)
:param n: 试验次数(正整数)
:param p: 成功概率(0 ≤ p ≤ 1)
:return: 最小整数k,使得CDF(k) ≥ q
"""
# 参数校验
if not (0 <= q <= 1):
raise ValueError("q必须在[0,1]范围内")
if not (isinstance(n, int) or (isinstance(n, float) and n.is_integer())):
raise ValueError("n必须为整数")
n = int(n)
if n <= 0:
raise ValueError("n必须为正整数")
if not (0 <= p <= 1):
raise ValueError("p必须在[0,1]范围内")
# 计算分位数(结果转为整数)
return int(binom.ppf(q, n, p))
# 检查输入格式
if isinstance(expr, tuple) and len(expr) == 3:
if all(e.is_number for e in expr):
params = tuple(float(e.evalf()) for e in expr)
result = binoinv_scipy(*params)
else:
error = True
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {str(e)}"
def main():
"""主函数演示用法"""
print("=== 标量计算示例 ===")
# 示例1:标准数值计算
print("正常输入 (0.025, 100, 0.6):")
print(binomial_function_cdf_inverse("(0.025, 100, 0.6)")) # 输出 50
#结果: 50
# 示例2:边界条件测试
print("\n边界条件 (1.0, 5, 0.6):")
print(binomial_function_cdf_inverse("(1.0, 5, 0.6)")) # 输出 5.0
#结果: 5
if __name__ == "__main__":
main()
二项矩阵
它是对合矩阵的倍数
A = binomial(n) 返回一个 n×n 矩阵, 其中包含整数项, 满足 A^2 = 2^(n-1)*eye(n).
矩阵 B = A*2^((1-n)/2) 是对合矩阵(矩阵与其逆矩阵相同).
n — 输入,标量.
示例1:小阶数矩阵
binomial(3)
#结果: [[1, 1, 1],
[1, 1, 2],
[1, 2, 1]]
binomial(5)
#结果: [[1, 1, 1, 1, 1],
[1, 1, 2, 3, 4],
[1, 2, 1, 3, 6],
[1, 3, 3, 1, 4],
[1, 4, 6, 4, 1]]
示例2:组合数学应用
计算组合数的和
n = 6
binom_mat = binomial(n)
#[[1, 1, 1, 1, 1, 1],
[1, 1, 2, 3, 4, 5],
[1, 2, 1, 3, 6, 10],
[1, 3, 3, 1, 4, 10],
[1, 4, 6, 4, 1, 5],
[1, 5, 10, 10, 5, 1]]
计算矩阵的迹(对角线元素之和)
trace = sum(binom_mat[i, i] for i in range(n))
print(f"矩阵的迹(对角线元素之和): {trace}")
#矩阵的迹(对角线元素之和): 6
示例3:图论应用 - 邻接矩阵的幂
二项式矩阵可以用于计算图中路径的数量
n = 4
binom_mat = binomial(n)
#[[1, 1, 1, 1],
[1, 1, 2, 3],
[1, 2, 1, 3],
[1, 3, 3, 1]]
计算矩阵的平方,表示长度为2的路径数量
binom_squared = binom_mat ** 2
print(f"\n矩阵的平方(表示长度为2的路径数量):")
print(binom_squared)
#矩阵的平方(表示长度为2的路径数量):
#[[4, 7, 7, 8],
[7, 15, 14, 13],
[7, 14, 15, 13],
[8, 13, 13, 20]]
示例4:数值分析应用
二项式矩阵的条件数分析
sizes = [3, 5, 7, 10]
for size in sizes:
binom_mat = binomial(size)
# 转换为浮点数矩阵以计算条件数
binom_float = np.array(binom_mat.tolist()).astype(float)
cond_number = np.linalg.cond(binom_float)
print(f"{size}阶二项式矩阵的条件数: {cond_number:.4f}")
#3阶二项式矩阵的条件数: 13.9282
#5阶二项式矩阵的条件数: 18.2750
#7阶二项式矩阵的条件数: 93.0719
#10阶二项式矩阵的条件数: 704.1159
示例5:线性代数教学示例
展示矩阵的秩、行列式等性质
n = 4
binom_mat = binomial(n)
print(binom_mat)
#[[1, 1, 1, 1],
[1, 1, 2, 3],
[1, 2, 1, 3],
[1, 3, 3, 1]]
print(f"\n矩阵的秩: {binom_mat.rank()}")
print(f"矩阵的行列式: {binom_mat.det()}")
#矩阵的秩: 4
#矩阵的行列式: 8
计算特征值和特征向量
eigenvalues = binom_mat.eigenvals()
print(f"\n矩阵的特征值: {eigenvalues}")
#矩阵的特征值: {-1: 1,
5/3 + 67/(9*(332/27 + sqrt(21171)*I/9)**(1/3)) + (332/27 + sqrt(21171)*I/9)**(1/3): 1,
5/3 + 67/(9*(-1/2 + sqrt(3)*I/2)*(332/27 + sqrt(21171)*I/9)**(1/3)) + (-1/2 + sqrt(3)*I/2)*(332/27 + sqrt(21171)*I/9)**(1/3): 1,
5/3 + (-1/2 - sqrt(3)*I/2)*(332/27 + sqrt(21171)*I/9)**(1/3) + 67/(9*(-1/2 - sqrt(3)*I/2)*(332/27 + sqrt(21171)*I/9)**(1/3)): 1}
示例6:密码学应用
二项式矩阵可用于某些加密算法中的扩散层
n = 8
binom_mat = binomial(n)
对矩阵取模,用于有限域运算
mod_value = 251 # 常用质数,适合8位表示
binom_mod = binom_mat.applyfunc(lambda x: x % mod_value)
print(f"{n}阶二项式矩阵模{mod_value}:")
print(binom_mod)
#[[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 2, 3, 4, 5, 6, 7],
[1, 2, 1, 3, 6, 10, 15, 21],
[1, 3, 3, 1, 4, 10, 20, 35],
[1, 4, 6, 4, 1, 5, 15, 35],
[1, 5, 10, 10, 5, 1, 6, 21],
[1, 6, 15, 20, 15, 6, 1, 7],
[1, 7, 21, 35, 35, 21, 7, 1]]
检查矩阵是否可逆(在模运算下)
try:
inv_mod = binom_mod.inv_mod(mod_value)
print("\n矩阵在模运算下可逆,其逆矩阵为:")
print(inv_mod)
except:
print("\n矩阵在模运算下不可逆")
#矩阵在模运算下可逆,其逆矩阵为:
#[[138, 106, 106, 204, 84, 1, 206, 160],
[106, 234, 215, 66, 147, 118, 210, 159],
[106, 215, 84, 48, 163, 61, 114, 213],
[204, 66, 48, 60, 24, 224, 141, 237],
[84, 147, 163, 24, 57, 236, 72, 221],
[1, 118, 61, 224, 236, 85, 219, 60],
[206, 210, 114, 141, 72, 219, 234, 59],
[160, 159, 213, 237, 221, 60, 59, 146]]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
import numpy as np
from sympy import Matrix
def binomial_matrix(input_str):
"""
生成n阶二项式系数矩阵
参数:
input_str (str): 输入字符串,应为一个表示矩阵阶数的正整数
返回:
SymPy矩阵: n阶二项式矩阵,满足A[i,j] = C(max(i,j), min(i,j))
错误信息: 当输入不合法时返回错误描述
矩阵特性:
- 矩阵是对称矩阵
- 主对角线元素为组合数C(n,0), C(n,1), ..., C(n,n)
- 例如n=3时矩阵为:
[1 1 1]
[1 2 2]
[1 2 3]
"""
try:
# 解析输入表达式
expr = sp.sympify(input_str)
def generate_binomial_matrix(n):
"""生成n阶二项式系数矩阵"""
# 验证矩阵阶数合法性
if not isinstance(n, int) or n <= 0:
raise ValueError("矩阵阶数必须是正整数")
# 初始化矩阵
mat = np.zeros((n, n), dtype=int)
# 填充矩阵元素
for i in range(n):
for j in range(n):
# 计算组合数C(max(i,j), min(i,j))
mat[i][j] = np.math.comb(max(i, j), min(i, j))
return mat
# 输入验证
if isinstance(expr, tuple):
# 不接受元组输入
raise TypeError("输入应为单个正整数")
elif expr.is_number:
# 转换为整数并验证
n = int(expr)
if n != expr or n <= 0: # 检查是否为合法正整数
raise ValueError("矩阵阶数必须是正整数")
# 生成并返回矩阵
np_matrix = generate_binomial_matrix(n)
return Matrix(np_matrix)
else:
# 其他类型输入不合法
raise TypeError("输入类型不合法")
except Exception as e:
return f"错误: {str(e)}"
def main():
"""主函数演示用法"""
print("=== 正常输入示例 ===")
# 示例1:3阶矩阵
print("n=3:")
print(binomial_matrix("3"))
#结果: Matrix([[1, 1, 1], [1, 1, 2], [1, 2, 1]])
# 示例2:5阶矩阵
print("\nn=5:")
print(binomial_matrix("5"))
#结果: Matrix([[1, 1, 1, 1, 1], [1, 1, 2, 3, 4], [1, 2, 1, 3, 6], [1, 3, 3, 1, 4], [1, 4, 6, 4, 1]])
if __name__ == "__main__":
main()
二项概率密度函数
y = binopdf(x,n,p) 使用n中对应的试验次数和p中每次试验的成功概率,计算x中每个值处的二项概率密度函数.
x,n和p可以是具有相同大小的向量,矩阵或多维数组.或者,一个或多个参量可以是标量.binopdf函数将标量输入扩展为常量数组,其维数与其他输入的维数相同.
x — 用于计算二项pdf的值, 来自区间[0 n]的整数, 来自区间[0 n]的整数组成的数组.
n — 试验次数,正整数,正整数数组.
p — 每次试验的成功概率,来自区间[0 1]的标量值,来自区间[0 1]的标量值组成的数组
y — 二项pdf值,标量值,标量值组成的数组.
示例1:基本标量输入
binopdf(3,10,0.5)
#结果: 0.1171875
示例2:质量控制场景
计算三条生产线在100个产品中出现特定数量不良品的概率
defect_counts = [2, 5, 8] # 不良品数量
total_products = [100, 100, 100] # 总产品数
defect_rates = [0.03, 0.05, 0.08] # 预期不良率
probabilities = binopdf(defect_counts,total_products,defect_rates)
for i in range(len(defect_counts)):
print(f"生产线{i+1}: 不良率{defect_rates[i]}, "
f"恰好{defect_counts[i]}个不良品的概率: {probabilities[i]:.6f}")
#生产线1: 不良率0.03, 恰好2个不良品的概率: 0.225153
#生产线2: 不良率0.05, 恰好5个不良品的概率: 0.180018
#生产线3: 不良率0.08, 恰好8个不良品的概率: 0.145518
示例3:医学研究场景
计算药物试验中不同响应人数的概率
response_counts = np.arange(0, 11) # 响应人数从0到10
patient_count = 10 # 患者总数
response_rate = 0.7 # 预期响应率
response_probs = binopdf(response_counts,patient_count,response_rate)
for i, count in enumerate(response_counts):
print(f" 恰好{count}人响应的概率: {response_probs[i]:.6f}")
#恰好0人响应的概率: 0.000006
#恰好1人响应的概率: 0.000138
#恰好2人响应的概率: 0.001447
#恰好3人响应的概率: 0.009002
#恰好4人响应的概率: 0.036757
#恰好5人响应的概率: 0.102919
#恰好6人响应的概率: 0.200121
#恰好7人响应的概率: 0.266828
#恰好8人响应的概率: 0.233474
#恰好9人响应的概率: 0.121061
#恰好10人响应的概率: 0.028248
示例4:教育评估场景
计算学生在多项选择题测验中猜对特定数量题目的概率
question_count = 20 # 题目数量
correct_guesses = np.arange(0, 21) # 可能猜对的题目数
guess_probability = 0.25 # 每道题猜对的概率(4选1)
guess_probs = binopdf(correct_guesses,question_count,guess_probability)
找出最可能的结果
20道4选1选择题,纯粹猜测时:
most_likely = np.argmax(guess_probs)
print(f" 最可能猜对的题目数: {most_likely} (概率: {guess_probs[most_likely]:.6f})")
print(f" 猜对至少{int(question_count*0.6)}题的概率: {np.sum(guess_probs[int(question_count*0.6):]):.6f}")
#最可能猜对的题目数: 5 (概率: 0.202331)
#猜对至少12题的概率: 0.000935
示例5:金融风险管理
计算投资组合中特定数量资产违约的概率
asset_count = 50 # 资产数量
default_counts = [0, 1, 2, 3, 4, 5] # 违约资产数量
default_probability = 0.02 # 单个资产违约概率
default_probs = binopdf(default_counts,asset_count,default_probability)
50个资产的投资组合,单个违约概率0.02:
for i, count in enumerate(default_counts):
print(f" 恰好{count}个资产违约的概率: {default_probs[i]:.6f}")
#恰好0个资产违约的概率: 0.364170
#恰好1个资产违约的概率: 0.371602
#恰好2个资产违约的概率: 0.185801
#恰好3个资产违约的概率: 0.060670
#恰好4个资产违约的概率: 0.014548
#恰好5个资产违约的概率: 0.002732
示例6:符号计算
获取一般的二项分布PMF表达式
binopdf(k,n,p)
#结果: p**k*(1 - p)**(-k + n)*binomial(n, k)
示例7:矩阵输入
计算不同试验条件下的概率
k_matrix = [[2, 3], [4, 5]] # 成功次数矩阵
n_matrix = [[10, 10], [10, 10]] # 试验次数矩阵
p_matrix = [[0.3, 0.4], [0.5, 0.6]] # 成功概率矩阵
matrix_result = binopdf(k_matrix,n_matrix,p_matrix)
不同试验条件下的概率矩阵:
print(matrix_result)
#[[0.23347444 0.21499085]
[0.20507812 0.20065812]]
示例8:A/B测试场景
计算两个版本在特定转化次数下的概率
conversions = 150 # 转化次数
visitors = 1000 # 访问者数量
conversion_rates = [0.12, 0.15, 0.18] # 不同版本的转化率
conversion_probs = binopdf(conversions,visitors,conversion_rates)
1000次访问中恰好150次转化的概率:
for i, rate in enumerate(conversion_rates):
print(f" 转化率{rate}: {conversion_probs[i]:.10f}")
#转化率0.12: 0.0006540182
#转化率0.15: 0.0353107801
#转化率0.18: 0.0014480444
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.stats import binom
def binomial_distribution_pdf(input_str):
"""
二项分布概率质量函数计算
输入格式: (k, n, p) 元组,支持:
- 标量输入:k(成功次数),n(总试验次数),p(成功概率)
- 矩阵输入:任意参数可为矩阵,矩阵形状需一致
- 混合输入:矩阵与标量组合
返回:
SymPy表达式 或 Matrix:概率计算结果
错误信息:当输入不合法时返回错误描述
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
n, p, x = sp.symbols('n p x')
binomial_pdf = sp.binomial(n, x) * p ** x * (1 - p) ** (n - x)
def binopdf_sym(n_parm, p_parm, x_parm):
# 数值有效性检查
if all(val.is_number for val in [n_parm, p_parm, x_parm]):
if not (0 <= float(p_parm) <= 1):
raise ValueError("成功概率p必须在[0,1]范围内")
if float(n_parm) < 0 or float(x_parm) < 0:
raise ValueError("参数n和k必须非负")
# 执行符号替换
return binomial_pdf.subs({
n: n_parm,
p: p_parm,
x: x_parm
})
def binopdf_sci(x, n, p):
"""
计算二项分布的概率质量函数(仅处理标量参数)
参数:
x (int/float): 成功次数,必须为整数且在[0, n]范围内
n (int/float): 总试验次数,必须为非负整数
p (float): 每次试验的成功概率,范围[0, 1]
返回:
float: 二项分布概率值
异常:
ValueError: 参数无效时抛出
"""
# 检查并转换n为非负整数
if isinstance(n, float):
if not n.is_integer():
raise ValueError("n必须是整数")
n = int(n)
elif not isinstance(n, int):
raise ValueError("n必须是整数或可转换为整数的浮点数")
if n < 0:
raise ValueError("n必须为非负整数")
# 检查p范围
if not (0 <= p <= 1):
raise ValueError("p必须在[0, 1]范围内")
# 检查并转换x为整数
if isinstance(x, float):
if not x.is_integer():
raise ValueError("x必须是整数")
x = int(x)
elif not isinstance(x, int):
raise ValueError("x必须是整数或可转换为整数的浮点数")
if x < 0 or x > n:
raise ValueError(f"x必须在[0, {n}]范围内")
return binom.pmf(x, n, p)
if isinstance(expr, tuple) and len(expr) == 3:
if all(e.is_number for e in expr):
params = tuple(float(e.evalf()) for e in expr)
result = binopdf_sci(*params)
elif any(e.free_symbols for e in expr):
result = binopdf_sym(*expr)
else:
error = True
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误:{e}"
def main():
"""主函数演示用法"""
print("=== 标量计算示例 ===")
# 示例1:数值计算
print("正常输入 (0, 200, 0.02):")
print(binomial_distribution_pdf("(0, 200, 0.02)")) # 0.3125
#结果: 0.0175879466057215
# 示例2:符号计算
print("\n符号表达式:")
print(binomial_distribution_pdf("(k, n, p)")) # 返回符号表达式
#结果: n**p*(1 - n)**(k - p)*binomial(k, p)
if __name__ == "__main__":
main()
二项式随机数
R = binornd(A,B,size=1) 使用A和B指定的参数从beta分布中生成随机数.A和B可以是具有相同大小的向量、矩阵.A或B的一个标量输入扩展为其维数与另一个输入的维数相同的常量数组.
A是标量, 向量,矩阵.
B是标量, 向量,矩阵.
size是标量, 生成多少个贝塔随机数.
示例1:基本标量输入
10次试验,成功概率0.5的随机结果:
binornd(10,0.5)
#结果: 1
示例2:质量控制场景
模拟三条生产线的不良品数量
sample_sizes = [100, 100, 100] # 每批抽样数量
defect_rates = [0.03, 0.05, 0.08] # 预期不良率
defect_counts = binornd(sample_sizes,defect_rates)
for i in range(len(sample_sizes)):
print(f"生产线{i + 1}: 抽样{sample_sizes[i]}个产品,预期不良率{defect_rates[i]}, "
f"模拟不良品数量: {defect_counts[i]}")
#生产线1: 抽样100个产品,预期不良率0.03, 模拟不良品数量: 1
#生产线2: 抽样100个产品,预期不良率0.05, 模拟不良品数量: 7
#生产线3: 抽样100个产品,预期不良率0.08, 模拟不良品数量: 7
示例3:医学研究场景
模拟药物试验中的响应人数
patient_count = 50 # 患者总数
response_rate = 0.7 # 预期响应率
num_simulations = 5 # 模拟次数
response_counts = binornd(patient_count,response_rate,num_simulations)
50名患者,预期响应率0.7:
for i, count in enumerate(response_counts):
print(f" 第{i+1}次模拟响应人数: {count}")
#第1次模拟响应人数: 37
#第2次模拟响应人数: 34
#第3次模拟响应人数: 35
#第4次模拟响应人数: 34
#第5次模拟响应人数: 34
示例4:金融风险管理
模拟投资组合中违约资产数量
asset_count = 100 # 资产数量
default_probability = 0.02 # 单个资产违约概率
simulation_count = 10 # 模拟次数
default_counts = binornd(asset_count,default_probability,simulation_count)
100个资产的投资组合,单个违约概率0.02:
for i, count in enumerate(default_counts):
print(f" 第{i+1}次模拟违约资产数量: {count}")
#第1次模拟违约资产数量: 4
#第2次模拟违约资产数量: 2
#第3次模拟违约资产数量: 3
#第4次模拟违约资产数量: 1
#第5次模拟违约资产数量: 2
#第6次模拟违约资产数量: 2
#第7次模拟违约资产数量: 2
#第8次模拟违约资产数量: 1
#第9次模拟违约资产数量: 6
#第10次模拟违约资产数量: 2
示例5:教育评估场景
模拟学生在多项选择题测验中猜对的题目数
question_count = 20 # 题目数量
guess_probability = 0.25 # 每道题猜对的概率(4选1)
student_count = 5 # 学生数量
correct_guesses = binornd(question_count,guess_probability,student_count)
5名学生,20道4选1选择题,纯粹猜测:
for i, count in enumerate(correct_guesses):
print(f" 学生{i+1}猜对的题目数: {count}")
#学生1猜对的题目数: 6
#学生2猜对的题目数: 5
#学生3猜对的题目数: 5
#学生4猜对的题目数: 5
#学生5猜对的题目数: 4
示例6:A/B测试场景
模拟两个版本的转化次数
visitors = 1000 # 访问者数量
conversion_rates = [0.12, 0.15] # 两个版本的转化率
test_runs = 3 # 测试次数
conversions = binornd(visitors,conversion_rates,test_runs)
1000次访问,两个版本的转化率比较:
for i, rate in enumerate(conversion_rates):
print(f" 版本{i+1}转化率{rate}: {conversions[i]}次转化")
#版本1转化率0.12: 错次转化
#版本2转化率0.15: 误次转化
示例7:矩阵输入
模拟不同试验条件下的结果
n_matrix = [[10, 15], [20, 25]] # 试验次数矩阵
p_matrix = [[0.3, 0.4], [0.5, 0.6]] # 成功概率矩阵
results = binornd(n_matrix,p_matrix)
不同试验条件下的随机结果矩阵:
print(results)
#[[ 4 5]
[10 16]]
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy.stats import binom
def binomial_random_number(input_str):
"""
生成二项分布随机数,支持标量、矩阵和不同形状的参数组合
参数:
input_str: 输入字符串表达式,支持格式:
- (n, p) # 标量参数
- (n_matrix, p) # 矩阵n和标量p
- (n, p_matrix) # 标量n和矩阵p
- (n_matrix, p_matrix) # 同形矩阵
- (n, p, size) # 指定输出形状
返回:
SymPy矩阵、数值或错误信息字符串
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
def evaluation_binomial_random(n, p, size=None):
"""生成单个二项分布随机数或数组"""
if size is not None:
return binom.rvs(int(n), float(p), size=int(size))
else:
return binom.rvs(int(n), float(p))
# 处理二元参数 (n, p) 或矩阵参数
if isinstance(expr, tuple):
if len(expr) in (2, 3) and all(e.is_number for e in expr):
result = evaluation_binomial_random(*expr)
else:
error = True
else:
error = True
return result if not error else f"输入错误: {input_str}"
except Exception as e:
return f"错误: {e}"
def main():
"""主函数用于测试不同用例"""
import numpy as np
test_cases = [
# 标量测试
("(5, 0.3)", "标量参数"),
# 结果: 3
("(10, 0.5)", "大样本测试"),
# 结果: 6
# 指定size测试
("(5, 0.5, 3)", "一维size测试"),
# 结果: [2 1 2]
]
for input_str, desc in test_cases:
print(f"\n测试用例: {desc}")
print(f"输入: {input_str}")
output = binomial_random_number(input_str)
print("输出:")
if isinstance(output, sp.Matrix):
sp.pprint(output)
else:
print(output)
if __name__ == "__main__":
main()
二项式平均值和方差
[M,V]=binostat(N,P)返回二项式分布的均值和方差,参数由试验次数N和每次试验的成功概率P指定.
N和P可以是大小相同的向量,矩阵,这也是M和V的大小.N或P的标量输入被扩展为与其他输入具有相同维度的常数组.
N是标量, 向量,矩阵.
P是标量, 向量,矩阵.
示例1:基本标量输入
10次试验,成功概率0.5:
mean, variance = binostat(10, 0.5)
print(f" 均值={mean}, 方差={variance}")
#均值=5.0, 方差=2.5
示例2:质量控制场景
计算三条生产线的次品数均值和方差
sample_sizes = [100, 100, 100] # 每批抽样数量
defect_rates = [0.03, 0.05, 0.08] # 预期次品率
means, variances = binostat(sample_sizes,defect_rates)
for i in range(len(sample_sizes)):
print(f"生产线{i+1}: 抽样{sample_sizes[i]}个产品,次品率{defect_rates[i]}")
print(f" 预期次品数: {means[i]:.2f}, 方差: {variances[i]:.2f}")
#生产线1: 抽样100个产品,次品率0.03, 预期次品数: 3.00, 方差: 2.91
#生产线2: 抽样100个产品,次品率0.05, 预期次品数: 5.00, 方差: 4.75
#生产线3: 抽样100个产品,次品率0.08, 预期次品数: 8.00, 方差: 7.36
示例3:医学研究场景
计算不同药物试验组的响应人数均值和方差
patient_counts = [50, 100, 150] # 不同组的患者数量
response_rates = [0.7, 0.75, 0.8] # 不同组的预期响应率
means, variances = binostat(patient_counts,response_rates)
for i in range(len(patient_counts)):
print(f"患者组{i+1}: {patient_counts[i]}名患者,预期响应率{response_rates[i]}")
print(f" 预期响应人数: {means[i]:.2f}, 方差: {variances[i]:.2f}")
#患者组1: 50名患者,预期响应率0.7, 预期响应人数: 35.00, 方差: 10.50
#患者组2: 100名患者,预期响应率0.75, 预期响应人数: 75.00, 方差: 18.75
#患者组3: 150名患者,预期响应率0.8, 预期响应人数: 120.00, 方差: 24.00
示例4:金融风险管理
计算投资组合中违约资产数量的均值和方差
asset_counts = [100, 200, 300] # 不同投资组合的资产数量
default_rates = [0.02, 0.03, 0.04] # 不同投资组合的违约概率
means, variances = binostat(asset_counts,default_rates)
for i in range(len(asset_counts)):
print(f"投资组合{i + 1}: {asset_counts[i]}个资产,违约概率{default_rates[i]}")
print(f" 预期违约资产数: {means[i]:.2f}, 方差: {variances[i]:.2f}")
print(f" 标准差: {np.sqrt(variances[i]):.2f} (风险度量)")
#投资组合1: 100个资产,违约概率0.02
#预期违约资产数: 2.00, 方差: 1.96
#标准差: 1.40 (风险度量)
#投资组合2: 200个资产,违约概率0.03
#预期违约资产数: 6.00, 方差: 5.82
#标准差: 2.41 (风险度量)
#投资组合3: 300个资产,违约概率0.04
#预期违约资产数: 12.00, 方差: 11.52
#标准差: 3.39 (风险度量)
示例5:教育评估场景
计算学生在多项选择题测验中猜对题数的均值和方差
question_counts = [20, 30, 40] # 不同测验的题目数量
guess_probabilities = [0.25, 0.25, 0.25] # 猜对概率(4选1)
means, variances = binostat(question_counts,guess_probabilities)
for i in range(len(question_counts)):
print(f"测验{i+1}: {question_counts[i]}道4选1选择题,纯粹猜测")
print(f" 预期猜对题数: {means[i]:.2f}, 方差: {variances[i]:.2f}")
print(f" 标准差: {np.sqrt(variances[i]):.2f} (成绩波动程度)")
#测验1: 20道4选1选择题,纯粹猜测
#预期猜对题数: 5.00, 方差: 3.75
#标准差: 1.94 (成绩波动程度)
#测验2: 30道4选1选择题,纯粹猜测
#预期猜对题数: 7.50, 方差: 5.62
#标准差: 2.37 (成绩波动程度)
#测验3: 40道4选1选择题,纯粹猜测
#预期猜对题数: 10.00, 方差: 7.50
#标准差: 2.74 (成绩波动程度)
示例6:A/B测试场景
计算两个版本的转化次数的均值和方差
visitors = 1000 # 访问者数量
conversion_rates = [0.12, 0.15, 0.18] # 不同版本的转化率
means, variances = binostat(visitors,conversion_rates)
for i, rate in enumerate(conversion_rates):
print(f"版本{i+1}: {visitors}次访问,转化率{rate}")
print(f" 预期转化次数: {means[i]:.2f}, 方差: {variances[i]:.2f}")
print(f" 标准差: {np.sqrt(variances[i]):.2f} (转化稳定性)")
#版本1: 1000次访问,转化率0.12
#预期转化次数: 120.00, 方差: 105.60
#标准差: 10.28 (转化稳定性)
#版本2: 1000次访问,转化率0.15
#预期转化次数: 150.00, 方差: 127.50
#标准差: 11.29 (转化稳定性)
#版本3: 1000次访问,转化率0.18
#预期转化次数: 180.00, 方差: 147.60
#标准差: 12.15 (转化稳定性)
示例7:矩阵输入
计算不同试验条件下的均值和方差
n_matrix = [[10, 15], [20, 25]] # 试验次数矩阵
p_matrix = [[0.3, 0.4], [0.5, 0.6]] # 成功概率矩阵
means, variances = binostat(n_matrix,p_matrix)
print("不同试验条件下的均值矩阵:")
print(means)
#不同试验条件下的均值矩阵:
#[[ 3. 6.]
[10. 15.]]
print("\n不同试验条件下的方差矩阵:")
print(variances)
#不同试验条件下的方差矩阵:
#[[2.1 3.6]
[5. 6. ]]
示例8:大规模数据分析
计算大规模临床试验的均值和方差
patient_groups = np.array([100, 200, 300, 400, 500]) # 不同组的患者数量
efficacy_rates = np.array([0.7, 0.72, 0.75, 0.78, 0.8]) # 不同组的有效率
means, variances = binostat(patient_groups,efficacy_rates)
大规模临床试验分析:
for i in range(len(patient_groups)):
print(f" 组{i+1}: {patient_groups[i]}名患者,有效率{efficacy_rates[i]}")
print(f" 预期有效人数: {means[i]:.2f} ± {np.sqrt(variances[i]):.2f}")
# 组1: 100名患者,有效率0.7, 预期有效人数: 70.00 ± 4.58
# 组2: 200名患者,有效率0.72, 预期有效人数: 144.00 ± 6.35
# 组3: 300名患者,有效率0.75, 预期有效人数: 225.00 ± 7.50
# 组4: 400名患者,有效率0.78, 预期有效人数: 312.00 ± 8.28
# 组5: 500名患者,有效率0.8, 预期有效人数: 400.00 ± 8.94
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
def binomial_mean_variance(input_str):
"""
计算二项分布的均值和方差,支持标量和矩阵参数
参数:
input_str: 输入字符串表达式,支持格式:
- (n, p) # 标量参数
- (n_matrix, p) # 矩阵n和标量p
- (n, p_matrix) # 标量n和矩阵p
- (n_matrix, p_matrix) # 同形矩阵参数
返回:
(均值矩阵, 方差矩阵) 或 错误信息字符串
"""
try:
expr = sp.sympify(input_str)
error = False
M, V = None, None
def eval_binomial_sci(n, p):
"""计算单个二项分布的均值和方差"""
# 参数有效性检查
if n <= 0 or p < 0 or p > 1:
return None, None
# 计算均值和方差
mean = n * p
var = n * p * (1 - p)
return mean, var
# 仅处理二元组输入
if isinstance(expr, tuple) and len(expr) == 2:
if all(e.is_number for e in expr):
params = tuple(float(e.evalf()) for e in expr)
M, V = eval_binomial_sci(*params)
else:
error = True
else:
error = True
if error or M is None:
return f"输入错误: {input_str}"
else:
return M, V
except Exception as e:
return f"系统错误: {str(e)}"
def main():
"""主函数用于测试不同用例"""
test_cases = [
# 有效测试用例
("(5, 0.5)", "标量参数"),
#结果: (2.5, 1.5)
]
for input_str, desc in test_cases:
print(f"\n=== 测试用例: {desc} ===")
print(f"输入: {input_str}")
result = binomial_mean_variance(input_str)
if isinstance(result, tuple):
print("均值矩阵:")
sp.pprint(result[0])
print("方差矩阵:")
sp.pprint(result[1])
else:
print("输出:", result)
if __name__ == "__main__":
main()
使用考克斯-罗斯-鲁宾斯坦模型计算美式看涨和看跌二项式期权定价
[AssetPrice,OptionValue] = binprice(Price,Strike,Rate,Time,Increment,Volatility,Flag) 使用考克斯-罗斯-鲁宾斯坦二项式定价模型对美式期权定价。美式期权可以在到期日之前的任何时间行权。
[AssetPrice,OptionValue] = binprice(___,DividendRate,Dividend,ExDiv) 添加了可选参量 DividendRate、Dividend 和 ExDiv。
Price — 标的资产的当前价格,数值
Strike — 期权的行权价格,数值
Rate — 无风险利率,小数
Time — 期权到期时间,数值
Increment — 时间增量,数值
Volatility — 资产波动率,数值
Flag — 指示期权是看涨还是看跌的标志,值为 0 或 1 的整数
DividendRate — 股息率,0 (默认) | 小数
Dividend — 股息支付,0 (默认) | 数值
ExDiv — 除息日,0 (默认) | 数值
AssetPrice — 资产价格,向量
OptionValue — 期权价值,向量
示例1:基本美式看跌期权
asset_tree, option_tree = bin_price(
Price=50, Strike=52, Rate=0.05, Time=1.0,
Increment=0.25, Volatility=0.3, Flag=0
)
资产价格树:
print(asset_tree)
#[[50. 43.0354 37.0409 31.8814 27.4406]
[ 0. 58.0917 50. 43.0354 37.0409]
[ 0. 0. 67.4929 58.0917 50. ]
[ 0. 0. 0. 78.4156 67.4929]
[ 0. 0. 0. 0. 91.1059]]
期权价格树:
print(option_tree)
#[[ 6.0808 9.751 14.9591 20.1186 24.5594]
[ 0. 2.6254 4.8758 8.9646 14.9591]
[ 0. 0. 0.4792 0.979 2. ]
[ 0. 0. 0. 0. 0. ]
[ 0. 0. 0. 0. 0. ]]
print(f"\n美式看跌期权价格: {option_tree[0, 0]:.4f}")
#美式看跌期权价格: 6.0808
示例2:美式看涨期权
asset_tree, option_tree = bin_price(
Price=100, Strike=105, Rate=0.04, Time=0.5,
Increment=0.1, Volatility=0.25, Flag=1
)
print(f"美式看涨期权价格: {option_tree[0, 0]:.4f}")
#美式看涨期权价格: 5.8526
示例3:带离散股息的美式看跌期权
asset_tree, option_tree = bin_price(
Price=52, Strike=50, Rate=0.1, Time=0.4167,
Increment=0.0833, Volatility=0.4, Flag=0,
Dividend=2.06, ExDiv=0.25
)
print(f"带离散股息的美式看跌期权价格: {option_tree[0, 0]:.4f}")
#带离散股息的美式看跌期权价格: 4.7036
示例4:带连续股息率的美式看涨期权
asset_tree, option_tree = bin_price(
Price=100, Strike=95, Rate=0.05, Time=1.0,
Increment=0.2, Volatility=0.2, Flag=1,
DividendRate=0.03
)
print(f"带连续股息率的美式看涨期权价格: {option_tree[0, 0]:.4f}")
#带连续股息率的美式看涨期权价格: 11.4120
示例5:高波动率环境下的期权定价
asset_tree, option_tree = bin_price(
Price=50, Strike=50, Rate=0.03, Time=0.5,
Increment=0.1, Volatility=0.6, Flag=1
)
print(f"高波动率平值看涨期权价格: {option_tree[0, 0]:.4f}")
#高波动率平值看涨期权价格: 9.1255
示例6:不同时间步长的比较
increments = [0.5, 0.25, 0.1, 0.05]
for inc in increments:
asset_tree, option_tree = bin_price(
Price=100, Strike=100, Rate=0.05, Time=1.0,
Increment=inc, Volatility=0.3, Flag=1
)
print(f"时间步长 {inc}: 期权价格 = {option_tree[0, 0]:.4f}")
#时间步长 0.5: 期权价格 = 12.8905
#时间步长 0.25: 期权价格 = 13.5240
#时间步长 0.1: 期权价格 = 13.9408
#时间步长 0.05: 期权价格 = 14.0849
示例7:不同执行价格的比较
strikes = [90, 100, 110]
for strike in strikes:
asset_tree, option_tree = bin_price(
Price=100, Strike=strike, Rate=0.05, Time=1.0,
Increment=0.1, Volatility=0.3, Flag=1
)
moneyness = "价内" if strike < 100 else ("平价" if strike == 100 else "价外")
print(f"执行价 {strike} ({moneyness}): 期权价格 = {option_tree[0, 0]:.4f}")
#执行价 90 (价内): 期权价格 = 19.9299
#执行价 100 (平价): 期权价格 = 13.9408
#执行价 110 (价外): 期权价格 = 10.2922
示例8:风险管理应用 - 计算希腊值
通过微小价格变化计算Delta
price_change = 0.01
price1 = 100
price2 = price1 + price_change
_, option_tree1 = bin_price(
Price=price1, Strike=100, Rate=0.05, Time=0.5,
Increment=0.1, Volatility=0.3, Flag=1
)
_, option_tree2 = bin_price(
Price=price2, Strike=100, Rate=0.05, Time=0.5,
Increment=0.1, Volatility=0.3, Flag=1
)
delta = (option_tree2[0, 0] - option_tree1[0, 0]) / price_change
print(f"期权Delta值: {delta:.4f}")
#期权Delta值: 0.5900
基于布莱克模型建立期货期权隐含波动率
Volatility = blkimpv(Price,Strike,Rate,Time,Value) 使用布莱克模型根据欧式期货期权的市场价值计算期货价格的隐含波动率。
如果 Class 名称-值参量为空或未指定,默认为看涨期权。
Price — 标的资产的当前价格,数值
Strike — 期货期权的行权价格,数值
Rate — 期权有效期内的年化连续复合无风险收益率,正小数
Time — 期权到期日,数值
Limit - 隐含波动率搜索区间的上界
Tolerance - 隐含波动率终止容差
Class — 期权类别
Volatility — 从欧式期货期权价格计算得出的标的资产隐含波动率,以小数形式返回
示例1:平值看涨期权
iv = blkimpv(
Price=20, Strike=20, Rate=0.09, Time=4/12,
Value=1.1166, Class=1
)
print(f"平值看涨期权隐含波动率: {iv}")
#平值看涨期权隐含波动率: 0.25
示例2:平值看跌期权
iv = blkimpv(
Price=20, Strike=20, Rate=0.09, Time=4/12,
Value=0.9754, Class=0
)
print(f"平值看跌期权隐含波动率: {iv}")
#平值看跌期权隐含波动率: 0.2183
示例3:价内期权
iv = blkimpv(
Price=22, Strike=20, Rate=0.05, Time=0.5,
Value=3.25, Class=1
)
print(f"价内看涨期权隐含波动率: {iv}")
#价内看涨期权隐含波动率: 0.3708
示例4:价外期权
iv = blkimpv(
Price=18, Strike=20, Rate=0.05, Time=0.5,
Value=0.85, Class=1
)
print(f"价外看涨期权隐含波动率: {iv}")
#价外看涨期权隐含波动率: 0.3155
示例5:不同期限的期权
time_periods = [1/12, 3/12, 6/12, 1.0] # 1个月, 3个月, 6个月, 1年
for t in time_periods:
iv = blkimpv(
Price=100, Strike=100, Rate=0.03, Time=t,
Value=5.0, Class=1
)
print(f"{t*12:.0f}个月期限平值期权隐含波动率: {iv}")
#1个月期限平值期权隐含波动率: 0.4355
#3个月期限平值期权隐含波动率: 0.2527
#6个月期限平值期权隐含波动率: 0.18
#12个月期限平值期权隐含波动率: 0.1292
示例6:波动率微笑分析
strikes = [90, 95, 100, 105, 110] # 不同行权价
market_prices = [12.5, 8.2, 5.0, 2.8, 1.5] # 对应市场价
波动率微笑曲线:
for i, strike in enumerate(strikes):
iv = blkimpv(
Price=100, Strike=strike, Rate=0.03, Time=0.5,
Value=market_prices[i], Class=1
)
moneyness = strike/100 # 行权价/标的价
print(f"行权价{strike} (相对价{moneyness:.2f}): 隐含波动率 = {iv}")
#行权价90 (相对价0.90): 隐含波动率 = 0.2431
#行权价95 (相对价0.95): 隐含波动率 = 0.1989
#行权价100 (相对价1.00): 隐含波动率 = 0.18
#行权价105 (相对价1.05): 隐含波动率 = 0.1712
#行权价110 (相对价1.10): 隐含波动率 = 0.1695
示例7:风险管理应用 - 计算不同置信水平的VaR
使用隐含波动率计算风险价值(VaR)
portfolio_value = 1000000 # 投资组合价值
confidence_level = 0.95 # 95%置信水平
从期权市场获取隐含波动率
iv = blkimpv(
Price=100, Strike=100, Rate=0.03, Time=0.5,
Value=5.0, Class=1
)
计算VaR (简化计算)
var = portfolio_value * iv * math.sqrt(0.5) * 1.645 # 1.645是95%置信水平的Z值
print(f"基于隐含波动率{iv}的95%置信水平VaR: ${var:,.2f}")
#基于隐含波动率0.18的95%置信水平VaR: $209,374.32
示例8:市场情绪分析
比较看涨和看跌期权的隐含波动率
call_iv = blkimpv(
Price=100, Strike=100, Rate=0.03, Time=0.5,
Value=5.5, Class=1
)
put_iv = blkimpv(
Price=100, Strike=100, Rate=0.03, Time=0.5,
Value=4.8, Class=0
)
print(f"看涨期权隐含波动率: {call_iv}")
print(f"看跌期权隐含波动率: {put_iv}")
#看涨期权隐含波动率: 0.1981
#看跌期权隐含波动率: 0.1728
计算波动率偏斜(Volatility Skew)
volatility_skew = put_iv - call_iv
print(f"波动率偏斜: {volatility_skew}")
#波动率偏斜: -0.02529999999999999
if volatility_skew > 0:
print("市场情绪: 偏谨慎(投资者更担心下跌风险)")
else:
print("市场情绪: 偏乐观(投资者更看好上涨潜力)")
#市场情绪: 偏乐观(投资者更看好上涨潜力)
布莱克期货期权定价模型
[Call,Put] = blkprice(Price,Strike,Rate,Time,Volatility) 使用布莱克模型计算欧式看跌和看涨期货期权价格。
Price — 标的资产的当前价格,数值
Strike — 期货期权的行权价格,数值
Rate — 期权有效期内的年化连续复合无风险收益率,正小数
Time — 期权到期日,数值
Volatility — 年化资产价格波动率,正小数
Call — 欧式看涨期货期权价格,矩阵
Put — 欧式看跌期货期权价格,矩阵
示例1:农产品期货期权定价
假设一个农产品交易商希望对大豆期货期权进行定价:
当前大豆期货价格:$1,200/吨
执行价格:$1,250/吨
无风险利率:3.5%
到期时间:6个月(0.5年)
波动率:25%
call_price, put_price = blkprice(
Price=1200,
Strike=1250,
Rate=0.035,
Time=0.5,
Volatility=0.25
)
print(f"看涨期权价格: ${call_price:.2f}, 看跌期权价格: ${put_price:.2f}")
#看涨期权价格: $62.46, 看跌期权价格: $111.59
示例2:能源期货期权定价
能源公司希望对原油期货期权进行定价:
当前原油期货价格:$85/桶
执行价格:$80/桶
无风险利率:4.2%
到期时间:3个月(0.25年)
波动率:35%
call_price, put_price = blkprice(
Price=85,
Strike=80,
Rate=0.042,
Time=0.25,
Volatility=0.35
)
print(f"看涨期权价格: ${call_price:.2f}, 看跌期权价格: ${put_price:.2f}")
#看涨期权价格: $8.50, 看跌期权价格: $3.56
示例3:贵金属期货期权批量定价
贵金属交易公司需要同时计算多个黄金期货期权的价格:
多个执行价格的期权定价
prices = [1850, 1850, 1850] # 当前期货价格
strikes = [1800, 1850, 1900] # 不同执行价
rates = [0.03, 0.03, 0.03] # 无风险利率
times = [0.5, 0.5, 0.5] # 到期时间(年)
volatilities = [0.22, 0.22, 0.22] # 波动率
call_prices, put_prices = blkprice(
Price=prices,
Strike=strikes,
Rate=rates,
Time=times,
Volatility=volatilities
)
print("不同执行价的看涨期权价格:", call_prices)
#不同执行价的看涨期权价格: [[137.8110],
[112.9893],
[91.5635]]
print("不同执行价的看跌期权价格:", put_prices)
#不同执行价的看跌期权价格: [[88.5554],
[112.9893],
[140.8191]]
示例4:利率期货期权定价
金融机构希望对利率期货期权进行定价:
当前利率期货价格:98.50
执行价格:99.00
无风险利率:2.5%
到期时间:9个月(0.75年)
波动率:18%
call_price, put_price = blkprice(
Price=98.50,
Strike=99.00,
Rate=0.025,
Time=0.75,
Volatility=0.18
)
print(f"看涨期权价格: {call_price:.4f}, 看跌期权价格: {put_price:.4f}")
#看涨期权价格: 5.7788, 看跌期权价格: 6.2695
示例5:外汇期货期权定价
跨国公司希望对欧元/美元外汇期货期权进行定价:
当前欧元期货价格:1.1200(USD/EUR)
执行价格:1.1500
无风险利率:1.5%(美元利率)
到期时间:1年
波动率:12%
call_price, put_price = blkprice(
Price=1.1200,
Strike=1.1500,
Rate=0.015,
Time=1.0,
Volatility=0.12
)
print(f"看涨期权价格: {call_price:.4f}, 看跌期权价格: {put_price:.4f}")
#看涨期权价格: 0.0400, 看跌期权价格: 0.0696
布莱克-斯科尔斯模型期权价值对标的价格变化的敏感度
[CallDelta,PutDelta] = blsdelta(Price,Strike,Rate,Time,Volatility) 返回 delta,即期权价值对标的资产价格变化的敏感度。
delta 也称为套期保值比率。blsdelta 使用 normcdf,即 Statistics and Machine Learning Toolbox™ 中的正态累积分布函数。
[CallDelta,PutDelta] = blsdelta(___,Yield) 添加了一个可选参量 Yield。
Price — 标的资产的当前价格,数值
Strike — 期权的行权价格,数值
Rate — 期权有效期内的年化连续复合无风险收益率,正小数
Time — 期权到期日(以年为单位), 数值
Volatility — 年化资产价格波动率, 正小数
Yield — 标的资产在期权有效期内的年化连续复合收益率, 0 (默认) | 小数
CallDelta — 看涨期权 delta, 数值
PutDelta — 看跌期权 delta, 数值
示例1:股票期权Delta计算
假设投资者考虑购买苹果公司(AAPL)的期权:
当前股价:$150
执行价格:$155
无风险利率:2.5%
到期时间:3个月(0.25年)
波动率:30%
call_delta, put_delta = blsdelta(
Price=150,
Strike=155,
Rate=0.025,
Time=0.25,
Volatility=0.30
)
print(f"看涨期权Delta: {call_delta:.4f}")
print(f"看跌期权Delta: {put_delta:.4f}")
#看涨期权Delta: 0.4594
#看跌期权Delta: -0.5406
实际意义:Delta值约0.45意味着如果苹果股价上涨$1,该看涨期权价格将上涨约$0.45。这帮助投资者评估期权对股价变动的敏感度。
示例2:深度实值期权Delta分析
考虑一个深度实值的看涨期权:
当前股价:$100
执行价格:$70
无风险利率:3%
到期时间:6个月(0.5年)
波动率:25%
call_delta, put_delta = blsdelta(
Price=100,
Strike=70,
Rate=0.03,
Time=0.5,
Volatility=0.25
)
print(f"深度实值看涨期权Delta: {call_delta:.4f}")
#深度实值看涨期权Delta: 0.9858
实际意义:深度实值期权的Delta接近1,表明其价格几乎与标的资产同幅度变动,类似于持有标的资产本身。
示例3:平价期权Delta中性策略
交易者构建Delta中性策略:
当前股价:$50
执行价格:$50
无风险利率:4%
到期时间:1个月(1/12年)
波动率:20%
call_delta, put_delta = blsdelta(
Price=50,
Strike=50,
Rate=0.04,
Time=1/12,
Volatility=0.20
)
print(f"平价看涨期权Delta: {call_delta:.4f}")
print(f"平价看跌期权Delta: {put_delta:.4f}")
#平价看涨期权Delta: 0.5345
#平价看跌期权Delta: -0.4655
实际意义:平价期权的Delta约为0.5,意味着每份看涨期权需要卖出0.5股标的资产来实现Delta中性对冲。
示例4:考虑股息的Delta计算
某公司股票支付股息,影响期权Delta:
当前股价:$80
执行价格:$85
无风险利率:2%
到期时间:4个月(4/12年)
波动率:22%
股息率:3%
call_delta, put_delta = blsdelta(
Price=80,
Strike=85,
Rate=0.02,
Time=4/12,
Volatility=0.22,
Yield=0.03
)
print(f"考虑股息的看涨Delta: {call_delta:.4f}")
print(f"考虑股息的看跌Delta: {put_delta:.4f}")
#考虑股息的看涨Delta: 0.3267
#考虑股息的看跌Delta: -0.6634
实际意义:股息会降低看涨期权的Delta值,因为预期股价在除息日会下降。
示例5:不同到期时间的Delta比较
比较短期和长期期权的Delta差异:
当前股价:$200
执行价格:$210
无风险利率:3%
波动率:35%
# 短期期权(1个月)
short_call_delta, short_put_delta = blsdelta(
Price=200, Strike=210, Rate=0.03, Time=1/12, Volatility=0.35
)
# 长期期权(1年)
long_call_delta, long_put_delta = blsdelta(
Price=200, Strike=210, Rate=0.03, Time=1.0, Volatility=0.35
)
print(f"短期看涨Delta: {short_call_delta:.4f}")
print(f"长期看涨Delta: {long_call_delta:.4f}")
#短期看涨Delta: 0.3418
#长期看涨Delta: 0.5483
实际意义:长期期权的Delta通常高于短期期权,因为有更多时间让期权变为实值状态。
示例6:Delta随时间衰减的分析
观察Delta如何随时间变化:
当前股价:$60
执行价格:$65
无风险利率:2.5%
波动率:28%
不同到期时间的Delta值
time_periods = [1.0, 0.75, 0.5, 0.25, 0.1] # 年
for T in time_periods:
call_delta, put_delta = black_scholes_delta(
Price=60, Strike=65, Rate=0.025, Time=T, Volatility=0.28
)
print(f"到期时间 {T:.2f} 年: 看涨Delta = {call_delta:.4f}")
#到期时间 1.00 年: 看涨Delta = 0.4774
#到期时间 0.75 年: 看涨Delta = 0.4477
#到期时间 0.50 年: 看涨Delta = 0.4043
#到期时间 0.25 年: 看涨Delta = 0.3238
#到期时间 0.10 年: 看涨Delta = 0.2029
实际意义:随着到期日临近,虚值期权的Delta趋近于0,实值期权的Delta趋近于1,平价期权的Delta保持在0.5左右。
布莱克-斯科尔斯模型 delta 对标的资产价格变化的敏感度
Gamma = blsgamma(Price,Strike,Rate,Time,Volatility) 返回 gamma,即 delta 对标的资产价格变化的敏感度。
blsgamma 使用 normpdf,即 Statistics and Machine Learning Toolbox™ 中的概率密度函数。
Gamma = blsgamma(___,Yield) 添加了一个可选参量 Yield。
Price — 标的资产的当前价格,数值
Strike — 期权的行权价格,数值
Rate — 期权有效期内的年化连续复合无风险收益率,正小数
Time — 期权到期日(以年为单位), 数值
Volatility — 年化资产价格波动率, 正小数
Yield — 标的资产在期权有效期内的年化连续复合收益率, 0 (默认) | 小数
Gamma — delta 对标的证券价格变化的敏感度, 数值
Gamma衡量的是期权Delta值对标的资产价格变化的敏感度,即标的资产价格变动1单位时期权Delta值的变化量。
通过几个实际示例来说明Gamma值的意义:
示例1:平价期权(At-the-Money Option)
平价期权,当前价格等于行权价
gamma = blsgamma(Price=100, Strike=100, Rate=0.05, Time=0.25, Volatility=0.2)
print(f"平价期权的Gamma值: {gamma}")
#平价期权的Gamma值: 0.0393
实际意义:平价期权的Gamma通常最高,意味着当标的资产价格在行权价附近波动时,Delta值变化最快。这对期权交易者的对冲策略非常重要,需要更频繁地调整头寸。
示例2:虚值期权(Out-of-the-Money Option)
虚值看涨期权,当前价格远低于行权价
gamma = blsgamma(Price=90, Strike=100, Rate=0.05, Time=0.25, Volatility=0.2)
print(f"虚值期权的Gamma值: {gamma}")
#虚值期权的Gamma值: 0.0301
实际意义:深度虚值期权的Gamma较低,意味着即使标的资产价格发生变化,Delta值变化也很小。这类期权变成实值期权的概率较低。
示例3:实值期权(In-the-Money Option)
实值看涨期权,当前价格远高于行权价
gamma = blsgamma(Price=110, Strike=100, Rate=0.05, Time=0.25, Volatility=0.2)
print(f"实值期权的Gamma值: {gamma}")
#实值期权的Gamma值: 0.0192
实际意义:深度实值期权的Gamma较低,其Delta接近1,即使标的资产价格变化,Delta值也几乎不变,表现得更像标的资产本身。
示例4:临近到期日的期权
临近到期日的平价期权
gamma = blsgamma(Price=100, Strike=100, Rate=0.05, Time=0.01, Volatility=0.2)
print(f"临近到期平价期权的Gamma值: {gamma}")
#临近到期平价期权的Gamma值: 0.1993
对比:还有较长时间到期的平价期权
gamma_long = blsgamma(Price=100, Strike=100, Rate=0.05, Time=1.0, Volatility=0.2)
print(f"长期平价期权的Gamma值: {gamma_long}")
#长期平价期权的Gamma值: 0.0188
实际意义:临近到期日的平价期权Gamma值会急剧上升,因为期权价值对价格变化极为敏感,很小的价格变动就可能导致期权在实值和虚值之间转换。
示例5:高波动率环境下的期权
高波动率环境
gamma_high_vol = blsgamma(Price=100, Strike=100, Rate=0.05, Time=0.25, Volatility=0.4)
print(f"高波动率期权的Gamma值: {gamma_high_vol}")
#高波动率期权的Gamma值: 0.0197
对比:低波动率环境
gamma_low_vol = blsgamma(Price=100, Strike=100, Rate=0.05, Time=0.25, Volatility=0.1)
print(f"低波动率期权的Gamma值: {gamma_low_vol}")
#低波动率期权的Gamma值: 0.0768
实际意义:高波动率会降低平价期权附近的Gamma值,因为价格更可能分布在更广的范围内,减少了在特定价格点附近的敏感性。
示例6:有股息支付的期权
有股息支付的股票期权
gamma_with_dividend = blsgamma(Price=100, Strike=100, Rate=0.05, Time=0.25, Volatility=0.2, Yield=0.03)
print(f"有股息期权的Gamma值: {gamma_with_dividend}")
#有股息期权的Gamma值: 0.0394
对比:无股息支付
gamma_no_dividend = blsgamma(Price=100, Strike=100, Rate=0.05, Time=0.25, Volatility=0.2)
print(f"无股息期权的Gamma值: {gamma_no_dividend}")
#无股息期权的Gamma值: 0.0393
实际意义:股息支付会降低股票价格,从而影响期权的Gamma值。对于看涨期权,股息支付会降低Gamma,因为预期股价下降会使期权更可能变为虚值。
布莱克-斯科尔斯隐含波动率
Volatility = blsimpv(Price,Strike,Rate,Time,Value) 使用布莱克-斯科尔斯模型根据欧式期权的市场价值计算标的资产的隐含波动率。如果 Class 名称-值参量为空或未指定,默认为看涨期权
Volatility = blsimpv(___,Name,Value) 支持上述语法中的输入参量,且可使用一个或多个名称-值对组参量来指定选项。
Price — 标的资产的当前价格,标量数值
Strike — 期权的行权价格,标量数值
Rate — 期权有效期内的年化连续复合无风险收益率,标量正小数
Time — 期权到期日,标量数值
Value — 计算标的资产隐含波动率时所基于的欧式期权价格,标量数值
Limit — 隐含波动率搜索区间的上界,10(每年 1000%) (默认) | 正标量数值
Yield — 标的资产在期权有效期内的年化连续复合收益率,0 (默认) | 小数
Tolerance — 隐含波动率终止容差,1e6 (默认) | 正标量数值
Class — 计算隐含波动率时所基于的期权类别,1(看涨期权) (默认)
隐含波动率是期权定价中的关键参数,它反映了市场对未来资产价格波动的预期。以下是几个实际应用示例:
示例1:平价期权的隐含波动率计算
平价期权(当前价格接近行权价)
iv = blsimpv(
Price=100, # 标的资产当前价格
Strike=100, # 行权价格
Rate=0.05, # 无风险利率
Time=0.25, # 到期时间(3个月)
Value=5.0, # 期权市场价格
Class=1 # 看涨期权
)
print(f"平价看涨期权的隐含波动率: {iv:.4f} (或 {iv*100:.2f}%)")
#平价看涨期权的隐含波动率: 0.2196 (或 21.96%)
实际意义:平价期权的隐含波动率通常被视为市场对未来波动率的共识预期,常用于衡量市场恐慌指数(如VIX)。
示例2:虚值期权的隐含波动率微笑
不同行权价的虚值看涨期权
strikes = [90, 95, 100, 105, 110]
market_prices = [2.5, 3.8, 5.0, 3.5, 2.2] # 市场价格
implied_vols = []
for K, price in zip(strikes, market_prices):
iv = blsimpv(
Price=100, Strike=K, Rate=0.05, Time=0.25,
Value=price, Class=1
)
implied_vols.append(iv)
print(f"行权价 {K} 的隐含波动率: {iv}")
#行权价 95 的隐含波动率: None
#行权价 100 的隐含波动率: 0.2196
#行权价 105 的隐含波动率: 0.2531
#行权价 110 的隐含波动率: 0.263
绘制波动率微笑曲线
import matplotlib.pyplot as plt
plt.plot(strikes, implied_vols, 'o-')
plt.xlabel('行权价')
plt.ylabel('隐含波动率')
plt.title('波动率微笑')
plt.grid(True)
plt.show()
实际意义:波动率微笑反映了市场对极端价格变动的预期,通常虚值期权(无论是看涨还是看跌)的隐含波动率较高,表明市场预期尾部风险较大。
示例3:期限结构对隐含波动率的影响
不同到期时间的期权
times = [0.08, 0.25, 0.5, 1.0] # 1个月, 3个月, 6个月, 1年
market_prices = [3.0, 5.0, 7.0, 10.0] # 市场价格
implied_vols = []
for T, price in zip(times, market_prices):
iv = blsimpv(
Price=100, Strike=100, Rate=0.05, Time=T,
Value=price, Class=1
)
implied_vols.append(iv)
print(f"期限 {T:.2f} 年的隐含波动率: {iv:.4f}")
#期限 0.08 年的隐含波动率: 0.2483
#期限 0.25 年的隐含波动率: 0.2196
#期限 0.50 年的隐含波动率: 0.2041
#期限 1.00 年的隐含波动率: 0.1880
绘制波动率期限结构
import matplotlib.pyplot as plt
plt.plot(times, implied_vols, 'o-')
plt.xlabel('到期时间(年)')
plt.ylabel('隐含波动率')
plt.title('波动率期限结构')
plt.grid(True)
plt.show()
实际意义:波动率期限结构反映了市场对不同时间范围内波动率的预期。通常情况下,长期期权的隐含波动率高于短期期权,这被称为"波动率溢价"。
示例4:比较看涨和看跌期权的隐含波动率
同一行权价的看涨和看跌期权
call_price = 5.0
put_price = 4.5
call_iv = blsimpv(
Price=100, Strike=100, Rate=0.05, Time=0.25,
Value=call_price, Class=1
)
put_iv = blsimpv(
Price=100, Strike=100, Rate=0.05, Time=0.25,
Value=put_price, Class=0
)
print(f"看涨期权隐含波动率: {call_iv:.4f}")
print(f"看跌期权隐含波动率: {put_iv:.4f}")
print(f"看涨看跌波动率差: {abs(call_iv - put_iv):.4f}")
#看涨期权隐含波动率: 0.2196
#看跌期权隐含波动率: 0.2573
#看涨看跌波动率差: 0.0377
# 检查看跌看涨平价关系
# 理论上,相同行权价和到期日的看涨和看跌期权应有相同的隐含波动率
# 差异可能反映市场情绪或套利机会
实际意义:看涨和看跌期权的隐含波动率差异可以反映市场情绪。当看跌期权的隐含波动率高于看涨期权时,可能表明市场预期下跌风险较大("恐惧"情绪)。
示例5:高股息股票期权的隐含波动率
高股息股票的期权
iv_with_dividend = blsimpv(
Price=100, Strike=100, Rate=0.05, Time=0.25,
Value=4.5, Yield=0.04, Class=1 # 4%股息率
)
iv_no_dividend = blsimpv(
Price=100, Strike=100, Rate=0.05, Time=0.25,
Value=4.5, Yield=0, Class=1 # 无股息
)
print(f"有股息期权的隐含波动率: {iv_with_dividend:.4f}")
print(f"无股息期权的隐含波动率: {iv_no_dividend:.4f}")
print(f"股息对隐含波动率的影响: {iv_with_dividend - iv_no_dividend:.4f}")
#有股息期权的隐含波动率: 0.2219
#无股息期权的隐含波动率: 0.1941
#股息对隐含波动率的影响: 0.0278
实际意义:股息支付会降低股票价格,从而影响期权价格和隐含波动率。对于看涨期权,股息支付会降低其价值,因此需要更高的隐含波动率来匹配市场价格。
示例6:极端市场条件下的隐含波动率
市场恐慌时期的高波动率期权
iv_high_vol = blsimpv(
Price=100, Strike=100, Rate=0.05, Time=0.25,
Value=15.0, # 极高的期权价格
Limit=2.0, # 提高搜索上限
Class=1
)
print(f"高波动率环境下的隐含波动率: {iv_high_vol:.4f} (或 {iv_high_vol*100:.2f}%)")
#高波动率环境下的隐含波动率: 0.7289 (或 72.89%)
# 对比正常市场条件
iv_normal = blsimpv(
Price=100, Strike=100, Rate=0.05, Time=0.25,
Value=5.0, Class=1
)
print(f"正常市场下的隐含波动率: {iv_normal:.4f} (或 {iv_normal*100:.2f}%)")
print(f"波动率飙升: {(iv_high_vol/iv_normal - 1)*100:.2f}%")
#正常市场下的隐含波动率: 0.2196 (或 21.96%)
#波动率飙升: 231.92%
实际意义:在市场恐慌时期(如金融危机),隐含波动率会急剧上升,反映市场对未来不确定性的增加。这种现象被称为"波动率聚集"。
示例7:隐含波动率曲面构建
构建隐含波动率曲面(行权价×到期时间)
strikes = np.arange(90, 111, 5) # 行权价从90到110
times = np.array([0.08, 0.25, 0.5, 1.0]) # 不同到期时间
假设的市场价格矩阵(行:行权价, 列:到期时间)
market_prices = np.array([
[12.5, 13.8, 15.0, 17.5], # K=90
[7.5, 8.8, 10.0, 12.5], # K=95
[3.0, 5.0, 7.0, 10.0], # K=100
[1.0, 2.5, 4.5, 7.5], # K=105
[0.5, 1.2, 2.5, 5.0] # K=110
])
iv_surface = np.zeros_like(market_prices)
for i, K in enumerate(strikes):
for j, T in enumerate(times):
iv_surface[i, j] = blsimpv(
Price=100, Strike=K, Rate=0.05, Time=T,
Value=market_prices[i, j], Class=1
)
# 可视化隐含波动率曲面
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
X, Y = np.meshgrid(strikes, times)
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X, Y, iv_surface.T, cmap='viridis')
ax.set_xlabel('行权价')
ax.set_ylabel('到期时间')
ax.set_zlabel('隐含波动率')
ax.set_title('隐含波动率曲面')
plt.show()
布莱克-斯科尔斯期权弹性
[CallEl,PutEl]=blslambda(Price,Strike,Rate,Time,Volatility)返回期权的弹性。CallEl是看涨期权弹性或杠杆因子,PutEl是看跌期权弹性或负债因子。
弹性(期权头寸的杠杆)衡量标的资产价格每变化1%,期权价格的百分比变化。blslambda使用normcdf,统计和机器学习工具箱™中的正态累积分布函数。
blslambda(___,Yield) 添加了一个可选参量 Yield。
Price — 标的资产的当前价格,数值
Strike — 期权的行权价格,数值
Rate — 期权有效期内的年化连续复合无风险收益率,正小数
Time — 期权到期日(以年为单位), 数值
Volatility — 年化资产价格波动率, 正小数
Yield — 标的资产在期权有效期内的年化连续复合收益率, 0 (默认) | 小数
期权弹性(Lambda)是期权希腊字母之一,衡量期权价格对标的资产价格变化的敏感度,具体表示为标的资产价格变动1%时期权价格变动的百分比。
示例1:平价期权(无股息)
标的资产价格=100,行权价=100,无风险利率=5%,期限=1年,波动率=20%,无股息
lambda_call, lambda_put = blslambda(100, 100, 0.05, 1.0, 0.20)
print(f"平价期权弹性 - 看涨: {lambda_call}, 看跌: {lambda_put}")
#平价期权弹性 - 看涨: 6.0937, 看跌: -6.516
实际意义:平价期权的弹性通常较高,因为期权价值对标的资产价格变化非常敏感。看涨期权弹性约为5-6,意味着标的资产价格上涨1%时期权价格约上涨5-6%。
示例2:虚值期权(高波动市场)
标的资产价格=90,行权价=100,无风险利率=5%,期限=0.5年,波动率=40%,无股息
lambda_call, lambda_put = blslambda(90, 100, 0.05, 0.5, 0.40)
print(f"虚值期权弹性 - 看涨: {lambda_call}, 看跌: {lambda_put}")
#虚值期权弹性 - 看涨: 5.5413, 看跌: -3.4016
实际意义:虚值期权的弹性通常非常高(可能超过10),因为期权价格较低但对价格变动敏感。高波动率进一步增加了这种敏感性。
示例3:实值期权(有股息)
标的资产价格=110,行权价=100,无风险利率=3%,期限=0.25年,波动率=15%,股息率=2%
lambda_call, lambda_put = blslambda(110, 100, 0.03, 0.25, 0.15, 0.02)
print(f"实值期权弹性 - 看涨: {lambda_call}, 看跌: {lambda_put}")
#实值期权弹性 - 看涨: 9.4413, 看跌: -27.8923
实际意义:实值期权的弹性接近1但大于1,因为期权价值主要由内在价值构成,但仍有一定杠杆效应。股息率会降低看涨期权的弹性。
示例4:短期到期期权
标的资产价格=105,行权价=100,无风险利率=4%,期限=0.1年(约36天),波动率=25%,无股息
lambda_call, lambda_put = blslambda(105, 100, 0.04, 0.1, 0.25)
print(f"短期期权弹性 - 看涨: {lambda_call}, 看跌: {lambda_put}")
#短期期权弹性 - 看涨: 12.0624, 看跌: -20.6462
实际意义:短期期权的弹性通常较高,特别是对于接近平价的期权,因为时间价值衰减速度快,价格对标的资产变动更为敏感。
示例5:高利率环境下的期权
标的资产价格=95,行权价=100,无风险利率=8%,期限=1年,波动率=30%,无股息
lambda_call, lambda_put = blslambda(95, 100, 0.08, 1.0, 0.30)
print(f"高利率环境期权弹性 - 看涨: {lambda_call}, 看跌: {lambda_put}")
#高利率环境期权弹性 - 看涨: 4.5151, 看跌: -3.8771
实际意义:高利率会增加看涨期权的价值(因为持有成本增加),从而影响其弹性。对于看跌期权,高利率会降低其价值。
布莱克-斯科尔斯看跌和看涨期权定价
[Call,Put] = blsprice(Price,Strike,Rate,Time,Volatility) 使用布莱克-斯科尔斯模型计算欧式看跌和看涨期权价格。
[Call,Put] = blsprice(___,Yield) 添加了一个可选参量 Yield。
Price — 标的资产的当前价格,数值
Strike — 期权的行权价格,数值
Rate — 期权有效期内的年化连续复合无风险收益率,正小数
Time — 期权到期日,数值
Volatility — 年化资产价格波动率,正小数
Yield — 标的资产在期权有效期内的年化连续复合收益率,0 (默认) | 小数
Call — 欧式看涨期权价格,矩阵
Put — 欧式看跌期权价格,矩阵
Black-Scholes模型是金融工程中最著名的期权定价模型,广泛应用于欧式期权的定价和风险管理。以下是几个具有实际意义的应用示例:
示例1:标准欧式期权定价
标的股票价格=100,行权价=100,无风险利率=5%,期限=1年,波动率=20%
call_price, put_price = blsprice(100, 100, 0.05, 1.0, 0.20)
print(f"平价期权价格 - 看涨: {call_price}, 看跌: {put_price}")
#平价期权价格 - 看涨: 10.4506, 看跌: 5.5735
实际意义:这是最基本的期权定价场景,用于确定平价期权的公允价格。投资者可以用这个价格判断市场上的期权是否被高估或低估。
示例2:高波动率市场中的期权定价(如科技股或市场危机时期)
标的股票价格=50,行权价=55,无风险利率=3%,期限=0.5年,波动率=60%
call_price, put_price = blsprice(50, 55, 0.03, 0.5, 0.60)
print(f"高波动率期权价格 - 看涨: {call_price}, 看跌: {put_price}")
#高波动率期权价格 - 看涨: 6.8143, 看跌: 10.9955
实际意义:在高波动率环境中,期权价格会显著上升,因为价格大幅波动的可能性增加。这对于风险管理特别重要,因为高波动率意味着更高的期权费。
示例3:股息支付对期权价格的影响
标的股票价格=80,行权价=75,无风险利率=4%,期限=0.75年,波动率=25%,股息率=3%
call_price, put_price = blsprice(80, 75, 0.04, 0.75, 0.25, 0.03)
print(f"含股息期权价格 - 看涨: {call_price}, 看跌: {put_price}")
#含股息期权价格 - 看涨: 9.5824, 看跌: 4.1457
对比无股息情况
call_no_div, put_no_div = blsprice(80, 75, 0.04, 0.75, 0.25)
print(f"无股息期权价格 - 看涨: {call_no_div}, 看跌: {put_no_div}")
#无股息期权价格 - 看涨: 10.8087, 看跌: 3.5921
实际意义:股息支付会降低看涨期权价格(因为股息支付后股价会下跌),但会提高看跌期权价格。这对股息股票期权定价至关重要。
示例4:短期期权定价(临近到期)
短期期权(如季度财报前)
标的股票价格=120,行权价=125,无风险利率=2%,期限=0.1年(约36天),波动率=35%
call_price, put_price = blsprice(120, 125, 0.02, 0.1, 0.35)
print(f"短期期权价格 - 看涨: {call_price}, 看跌: {put_price}")
#短期期权价格 - 看涨: 3.354, 看跌: 8.1043
实际意义:短期期权的时间价值衰减非常快,特别是对于虚值期权。这对期权卖方有利,但对买方风险较高。
示例5:低利率环境下的期权定价
低利率环境(如近年来的市场情况)
标的股票价格=150,行权价=145,无风险利率=0.5%,期限=1年,波动率=15%
call_price, put_price = blsprice(150, 145, 0.005, 1.0, 0.15)
print(f"低利率期权价格 - 看涨: {call_price}, 看跌: {put_price}")
#低利率期权价格 - 看涨: 11.9519, 看跌: 6.2287
实际意义:低利率环境下,看涨期权价格相对较高(因为融资成本低),而看跌期权价格相对较低。
示例6:批量计算不同行权价的期权价格
计算同一标的资产不同行权价的期权价格(波动率微笑曲线)
S = 100 # 标的资产价格
r = 0.03 # 无风险利率
T = 0.5 # 到期时间
sigma = 0.25 # 波动率
strikes = [80, 90, 100, 110, 120] # 不同行权价
print("行权价 | 看涨期权价格 | 看跌期权价格")
print("----------------------------------")
for K in strikes:
call_price, put_price = blsprice(S, K, r, T, sigma)
print(f"{K} | {call_price} | {put_price}")
#行权价 | 看涨期权价格 | 看跌期权价格
#----------------------------------
#80 | 21.8351 | 0.644
#90 | 13.7908 | 2.4509
#100 | 7.7603 | 6.2715
#110 | 3.8986 | 12.2609
#120 | 1.7669 | 19.9803
实际意义:这种计算可用于构建波动率微笑曲线,帮助交易员识别市场对极端价格变动的预期,并发现可能的套利机会。
示例7:不同到期时间的期权价格比较
比较不同到期时间的期权价格
S = 100
K = 100
r = 0.04
sigma = 0.30
time_periods = [0.25, 0.5, 1.0, 2.0] # 3个月, 6个月, 1年, 2年
print("到期时间(年) | 看涨期权价格 | 看跌期权价格")
print("---------------------------------------")
for T in time_periods:
call_price, put_price = blsprice(S, K, r, T, sigma)
print(f"{T} | {call_price} | {put_price}")
#到期时间(年) | 看涨期权价格 | 看跌期权价格
#---------------------------------------
#0.25 | 6.4595 | 5.4645
#0.5 | 9.3904 | 7.4103
#1.0 | 13.7533 | 9.8322
#2.0 | 20.2798 | 12.5915
实际意义:时间价值是期权价格的重要组成部分。这个示例展示了时间价值如何随到期时间增加而增加,帮助投资者理解时间衰减(theta)对期权价格的影响。
布莱克-斯科尔斯模型期权价值对利率变化的敏感度
[CallRho,PutRho] = blsrho(Price,Strike,Rate,Time,Volatility) 返回看涨期权 rho CallRho 和看跌期权 rho PutRho。
rho 是衍生证券价值相对于利率的变化率。
[CallRho,PutRho] = blsrho(___,Yield) 添加了一个可选参量 Yield。
Price — 标的资产的当前价格,数值
Strike — 期权的行权价格,数值
Rate — 期权有效期内的年化连续复合无风险收益率,正小数
Time — 期权到期日,数值
Volatility — 年化资产价格波动率,正小数
Yield — 标的资产在期权有效期内的年化连续复合收益率,0 (默认) | 小数
CallRho — 看涨期权 rho, 数值
PutRho — 看跌期权 rho, 数值
rho 敏感度 rho 衡量期权价格预计随无风险利率变化而变化的速率。 rho 表示无风险利率每变化一个百分点 (1%),期权价格随之增加或减少的金额。
例如,如果看涨期权的 rho 值为 0.05,则意味着利率每上升一个百分点,看涨期权的价格预计会增加 0.05 美元。
Rho是期权希腊字母之一,衡量期权价格对无风险利率变化的敏感度。它表示无风险利率每变化1个百分点(100个基点)时期权价格的变化量。以下是几个具有实际意义的Rho值计算示例:
示例1:标准欧式期权的Rho值
标的资产价格=100,行权价=100,无风险利率=5%,期限=1年,波动率=20%
call_rho, put_rho = blsrho(100, 100, 0.05, 1.0, 0.20)
print(f"平价期权Rho值 - 看涨: {call_rho}, 看跌: {put_rho}")
#平价期权Rho值 - 看涨: 53.2325, 看跌: -41.8905
实际意义:对于平价期权,看涨期权的Rho值为正(利率上升时期权价值增加),看跌期权的Rho值为负(利率上升时期权价值减少)。这反映了利率变化对期权时间价值的影响。
示例2:长期期权的Rho值
长期期权(如LEAPS)
标的资产价格=150,行权价=160,无风险利率=4%,期限=2年,波动率=25%
call_rho, put_rho = blsrho(150, 160, 0.04, 2.0, 0.25)
print(f"长期期权Rho值 - 看涨: {call_rho}, 看跌: {put_rho}")
#长期期权Rho值 - 看涨: 132.0659, 看跌: -163.3314
对比短期期权
call_rho_short, put_rho_short = black_scholes_rho(150, 160, 0.04, 0.5, 0.25)
print(f"短期期权Rho值 - 看涨: {call_rho_short}, 看跌: {put_rho_short}")
#短期期权Rho值 - 看涨: 28.7631, 看跌: -49.6528
实际意义:长期期权的Rho值通常比短期期权大,因为利率变化对远期现金流贴现的影响更大。这对于长期投资者特别重要,尤其是在利率环境变化较大的时期。
示例3:不同利率环境下的Rho值
高利率环境
call_rho_high, put_rho_high = blsrho(100, 100, 0.08, 1.0, 0.20)
print(f"高利率环境Rho值 - 看涨: {call_rho_high}, 看跌: {put_rho_high}")
#高利率环境Rho值 - 看涨: 57.0404, 看跌: -35.2712
低利率环境
call_rho_low, put_rho_low = blsrho(100, 100, 0.01, 1.0, 0.20)
print(f"低利率环境Rho值 - 看涨: {call_rho_low}, 看跌: {put_rho_low}")
#低利率环境Rho值 - 看涨: 47.5285, 看跌: -51.4765
实际意义:在高利率环境下,Rho值通常更大,因为利率变化对期权定价的影响更显著。在低利率环境下,Rho值较小,因为利率变化空间有限。
示例4:实值、平值和虚值期权的Rho值比较
S = 100 # 标的资产价格
r = 0.05 # 无风险利率
T = 1.0 # 到期时间
sigma = 0.20 # 波动率
不同行权价的期权
strikes = [80, 100, 120] # 实值、平值、虚值
print("行权价 | 看涨期权Rho | 看跌期权Rho")
print("----------------------------------")
for K in strikes:
call_rho, put_rho = blsrho(S, K, r, T, sigma)
print(f"{K} | {call_rho} | {put_rho}")
#行权价 | 看涨期权Rho | 看跌期权Rho
#----------------------------------
#80 | 68.2749 | -7.8234
#100 | 53.2325 | -41.8905
#120 | 25.4717 | -88.6758
实际意义:实值看涨期权的Rho值最大,因为其实值部分较大,对利率变化更敏感。虚值期权的Rho值较小,因为其主要由时间价值组成,对利率变化不那么敏感。
示例5:利率变化对期权组合的影响
计算跨式期权组合的Rho值
S = 100
K = 100
r = 0.05
T = 0.5
sigma = 0.25
跨式期权:同时买入看涨和看跌期权
call_rho, put_rho = blsrho(S, K, r, T, sigma)
straddle_rho = call_rho + put_rho
print(f"跨式期权组合Rho值: {straddle_rho}")
print(f"看涨期权Rho: {call_rho}, 看跌期权Rho: {put_rho}")
#跨式期权组合Rho值: 2.0625
#看涨期权Rho: 25.414, 看跌期权Rho: -23.3515
实际意义:跨式期权组合的Rho值接近零,因为看涨和看跌期权的Rho值相互抵消。这表明跨式期权策略对利率变化相对不敏感,更适合在利率不确定的环境中使用。
示例6:利率政策变化时期的Rho值分析
假设央行即将宣布利率决策
当前利率=2%,预期可能升至3%或降至1%
current_rate = 0.02
possible_rates = [0.01, 0.03] # 可能的利率变化
S = 100
K = 105
T = 0.25
sigma = 0.30
利率变化对期权价格的影响分析:
当前利率: 2%
call_rho, put_rho = blsrho(S, K, current_rate, T, sigma)
print(f"当前Rho值 - 看涨: {call_rho}, 看跌: {put_rho}")
#当前Rho值 - 看涨: 9.3202, 看跌: -16.7989
for new_rate in possible_rates:
# 计算利率变化后的期权价格变化
call_price_change = call_rho * (new_rate - current_rate) * 100 # 乘以100因为Rho是每1%变化
put_price_change = put_rho * (new_rate - current_rate) * 100
print(f"\n如果利率变化到 {new_rate*100}%:")
print(f"看涨期权价格变化: {call_price_change:.4f}")
print(f"看跌期权价格变化: {put_price_change:.4f}")
#如果利率变化到 1.0%:
#看涨期权价格变化: -9.3202
#看跌期权价格变化: 16.7989
#如果利率变化到 3.0%:
#看涨期权价格变化: 9.3202
#看跌期权价格变化: -16.7989
实际意义:在央行利率决策前后,交易员可以使用Rho值来评估利率变化对期权头寸的潜在影响,并相应调整对冲策略。
布莱克-斯科尔斯模型期权价值对到期时间变化的敏感度度
[CallTheta,PutTheta] = blstheta(Price,Strike,Rate,Time,Volatility) 返回看涨期权 theta CallTheta 和看跌期权 theta PutTheta。
theta 是期权价值相对于时间的敏感度,以年为单位衡量。CallTheta 或 PutTheta 可以除以 365 来得到每个日历日的 theta,或除以 252 来得到每个交易日的 theta。
[CallTheta,PutTheta] = blstheta(___,Yield) 添加了一个可选参量 Yield。
Price — 标的资产的当前价格,数值
Strike — 期权的行权价格,数值
Rate — 期权有效期内的年化连续复合无风险收益率,正小数
Time — 期权到期日,数值
Volatility — 年化资产价格波动率,正小数
Yield — 标的资产在期权有效期内的年化连续复合收益率,0 (默认) | 小数
CallTheta — 看涨期权 theta, 数值
PutTheta — 看跌期权 theta, 数值
敏感度 theta 衡量在所有其他条件相同的情况下,期权价格随时间的推移而下降的速率。
theta 本质上是对时间衰减的量化,而时间衰减是期权定价中的一个关键概念。theta 是在假设标的资产价格不变动、波动率不变化的情况下,对期权价格每天下降的美元数额的估计。
例如,如果看涨期权的 theta 值为 -0.05,则意味着在所有其他因素保持不变的情况下,该期权的价格预计每天下降 0.05 美元。
示例1:平值期权(At-the-Money)
平值期权,到期时间较短
result = blstheta(Price=100, Strike=100, Rate=0.05, Time=0.1, Volatility=0.2)
print(f"看涨Theta: {result[0]}, 看跌Theta: {result[1]}")
#看涨Theta: -15.1203, 看跌Theta: -10.1452
平值期权,到期时间较长
result = blstheta(Price=100, Strike=100, Rate=0.05, Time=1.0, Volatility=0.2)
print(f"看涨Theta: {result[0]}, 看跌Theta: {result[1]}")
#看涨Theta: -6.414, 看跌Theta: -1.6579
示例2:虚值期权(Out-of-the-Money)
虚值看涨期权
result = blstheta(Price=90, Strike=100, Rate=0.05, Time=0.25, Volatility=0.3)
print(f"看涨Theta: {result[0]}, 看跌Theta: {result[1]}")
#看涨Theta: -10.4935, 看跌Theta: -5.5556
虚值看跌期权
result = blstheta(Price=110, Strike=100, Rate=0.05, Time=0.25, Volatility=0.3)
print(f"看涨Theta: {result[0]}, 看跌Theta: {result[1]}")
#看涨Theta: -13.2623, 看跌Theta: -8.3244
示例3:实值期权(In-the-Money)
实值看涨期权
result = blstheta(Price=110, Strike=100, Rate=0.05, Time=0.25, Volatility=0.3)
print(f"看涨Theta: {result[0]}, 看跌Theta: {result[1]}")
#看涨Theta: -13.2623, 看跌Theta: -8.3244
实值看跌期权
result = blstheta(Price=90, Strike=100, Rate=0.05, Time=0.25, Volatility=0.3)
print(f"看涨Theta: {result[0]}, 看跌Theta: {result[1]}")
#看涨Theta: -10.4935, 看跌Theta: -5.5556
示例4:高波动率环境
高波动率股票期权
result = blstheta(Price=50, Strike=55, Rate=0.03, Time=0.5, Volatility=0.6)
print(f"看涨Theta: {result[0]}, 看跌Theta: {result[1]}")
#看涨Theta: -9.0199, 看跌Theta: -7.3944
示例5:含股息股票期权
支付股息的股票期权
result = blstheta(Price=100, Strike=100, Rate=0.05, Time=0.5, Volatility=0.25, Yield=0.03)
print(f"看涨Theta: {result[0]}, 看跌Theta: {result[1]}")
#看涨Theta: -10.8991, 看跌Theta: -3.0672
示例6:不同利率环境
高利率环境
result = blstheta(Price=100, Strike=100, Rate=0.08, Time=0.5, Volatility=0.2)
print(f"看涨Theta: {result[0]}, 看跌Theta: {result[1]}")
#看涨Theta: -9.7889, 看跌Theta: -2.1025
低利率环境
result = blstheta(Price=100, Strike=100, Rate=0.01, Time=0.5, Volatility=0.2)
print(f"看涨Theta: {result[0]}, 看跌Theta: {result[1]}")
#看涨Theta: -6.0937, 看跌Theta: -5.0987
实际意义解释
Theta值表示期权价格随时间流逝而减少的速率,通常为负值(表示时间衰减):
平值期权:Theta值通常最大,因为时间价值衰减最快
临近到期:Theta绝对值增大,时间衰减加速("Gamma挤压")
虚值期权:Theta绝对值较小,因为本身时间价值较低
实值期权:看跌期权Theta可能接近零甚至为正值(由于利率因素)
高波动率:Theta绝对值通常较大,因为期权包含更多时间价值
股息影响:股息会增加看跌期权的Theta(更负),减少看涨期权的Theta
这些示例可以帮助期权交易者理解时间衰减对其头寸的影响,特别是在制定Theta中性策略或日历价差策略时。
布莱克-斯科尔斯模型期权价值对标的价格波动率的敏感度
Vega = blsvega(Price,Strike,Rate,Time,Volatility) 返回期权价值相对于标的资产波动率的变化率。
Vega = blsvega(___,Yield) 添加了一个可选参量 Yield。
Price — 标的资产的当前价格,数值
Strike — 期权的行权价格,数值
Rate — 期权有效期内的年化连续复合无风险收益率,正小数
Time — 期权到期日,数值
Volatility — 年化资产价格波动率,正小数
Yield — 标的资产在期权有效期内的年化连续复合收益率,0 (默认) | 小数
Vega — 期权价值相对于标的资产波动率的变化率,数值
敏感度 vega 衡量期权价格对标的资产波动率变化的敏感度。 vega 表示当标的资产的隐含波动率变化 1% 时,期权价格的预期变化量。vega 表示为随着波动率的上升或下降,每股标的股票期权价值的增减金额。
例如,如果一个期权的 vega 值为 0.10,则意味着当标的资产的隐含波动率每变化 1% 时,该期权的价格预计会变化 0.10 美元。
示例1:平值期权(At-the-Money)
平值期权,到期时间较短
vega = blsvega(Price=100, Strike=100, Rate=0.05, Time=0.1, Volatility=0.2)
print(f"Vega值: {vega} (表示波动率每增加1%,期权价格增加约${vega/100})")
#Vega值: 12.5386 (表示波动率每增加1%,期权价格增加约$0.125386)
平值期权,到期时间较长
vega = blsvega(Price=100, Strike=100, Rate=0.05, Time=1.0, Volatility=0.2)
print(f"Vega值: {vega} (表示波动率每增加1%,期权价格增加约${vega/100})")
#Vega值: 37.524 (表示波动率每增加1%,期权价格增加约$0.37524)
示例2:虚值期权(Out-of-the-Money)
虚值看涨期权
vega = blsvega(Price=90, Strike=100, Rate=0.05, Time=0.25, Volatility=0.3)
print(f"Vega值: {vega}")
#Vega值: 15.4826
虚值看跌期权
vega = blsvega(Price=110, Strike=100, Rate=0.05, Time=0.25, Volatility=0.3)
print(f"Vega值: {vega} (与看涨期权相同)")
#Vega值: 16.0128 (与看涨期权相同)
示例3:实值期权(In-the-Money)
实值看涨期权
vega = blsvega(Price=110, Strike=100, Rate=0.05, Time=0.25, Volatility=0.3)
print(f"Vega值: {vega}")
#Vega值: 16.0128
实值看跌期权
vega = blsvega(Price=90, Strike=100, Rate=0.05, Time=0.25, Volatility=0.3)
print(f"Vega值: {vega} (与看涨期权相同)")
#Vega值: 15.4826 (与看涨期权相同)
示例4:不同波动率环境
低波动率股票期权
vega = blsvega(Price=100, Strike=100, Rate=0.05, Time=0.5, Volatility=0.15)
print(f"Vega值: {vega}")
#Vega值: 27.0578
高波动率股票期权
vega = blsvega(Price=100, Strike=100, Rate=0.05, Time=0.5, Volatility=0.4)
print(f"Vega值: {vega}")
#Vega值: 27.4743
示例5:含股息股票期权
支付股息的股票期权
vega = blsvega(Price=100, Strike=100, Rate=0.05, Time=0.5, Volatility=0.25, Yield=0.03)
print(f"Vega值: {vega}")
#Vega值: 27.4991
不含股息的相同期权
vega = blsvega(Price=100, Strike=100, Rate=0.05, Time=0.5, Volatility=0.25, Yield=0)
print(f"Vega值: {vega}")
#Vega值: 27.4743
示例6:不同到期时间
短期期权(30天)
vega = blsvega(Price=100, Strike=100, Rate=0.05, Time=30/365, Volatility=0.25)
print(f"Vega值: {vega}")
#Vega值: 11.3878
中期期权(90天)
vega = blsvega(Price=100, Strike=100, Rate=0.05, Time=90/365, Volatility=0.25)
print(f"Vega值: {vega}")
#Vega值: 19.5537
长期期权(1年)
vega = blsvega(Price=100, Strike=100, Rate=0.05, Time=1.0, Volatility=0.25)
print(f"Vega值: {vega}")
#Vega值: 37.842
实际意义解释
Vega值表示期权价格对标的资产波动率变化的敏感度:
Vega总是正值:波动率增加总是增加期权价值(无论看涨还是看跌)
平值期权:Vega值通常最大,因为波动率变化对平值期权影响最大
到期时间:长期期权的Vega更大,因为有更多时间让波动率变化影响价格
波动率水平:在高波动率环境中,Vega值通常更大
股息影响:股息会略微降低Vega值,因为股息降低了标的资产的预期价格变动
实际交易中的应用
波动率交易:交易者可以通过Vega来评估波动率变化对期权头寸的影响
Vega中性策略:通过组合不同期权,创建对波动率变化不敏感的头寸
事件交易:在财报季或其他可能引起波动率变化的事件前,评估Vega风险
跨式组合:跨式组合的盈利依赖于波动率增加,其价值与Vega直接相关
债券凸性
[YearConvexity,PerConvexity] = bndconvp(Price,CouponRate,Settle,Maturity) 在给定每种债券的净价的情况下,计算固定收益证券的凸性。
Price —— 债券净价(标量)
CouponRate —— 息票率, 用于确定债券应付息票的年百分比率, 小数
Settle —— 债券结算日期, 日期时间数组|字符串数组|日期字符向量
Maturity——债券到期日, 日期时间数组|字符串数组|日期字符向量
Period —— 年付息次数, 2(默认)|值为0、1、2、3、4、6或12的数字
Basis —— 日计数基准, 0(默认)|数值:0、1、2、3、4、6、7、8、9、10、11、12、13
示例1:不同价格水平的债券凸性
print("不同价格水平的债券凸性:")
year_conv, period_conv = bndconvp(
Settle='2023-07-15',
Maturity='2033-07-15',
CouponRate=0.05,
Price=[90, 95, 100, 105, 110] # 折价、平价和溢价债券
)
for i, price in enumerate([90, 95, 100, 105, 110]):
print(f"价格 {price}: 年凸性={year_conv[i]}, 周期凸性={period_conv[i]}")
#不同价格水平的债券凸性:
#价格 90: 年凸性=71.2384, 周期凸性=284.9534
#价格 95: 年凸性=72.5396, 周期凸性=290.1586
#价格 100: 年凸性=73.7606, 周期凸性=295.0422
#价格 105: 年凸性=74.9098, 周期凸性=299.6391
#价格 110: 年凸性=75.9948, 周期凸性=303.979
示例2:不同到期期限的债券凸性
print("不同到期期限的债券凸性:")
maturities = ['2025-07-15', '2030-07-15', '2040-07-15', '2050-07-15']
for maturity in maturities:
year_conv, period_conv = bndconvp(
Settle='2023-07-15',
Maturity=maturity,
CouponRate=0.04,
Price=[100]
)
print(f"到期日 {maturity}: 年凸性={year_conv[0]}, 周期凸性={period_conv[0]}")
#不同到期期限的债券凸性:
#到期日 2025-07-15: 年凸性=4.6323, 周期凸性=18.5291
#到期日 2030-07-15: 年凸性=42.6722, 周期凸性=170.6886
#到期日 2040-07-15: 年凸性=187.7642, 周期凸性=751.0567
#到期日 2050-07-15: 年凸性=367.2657, 周期凸性=1469.0627
示例3:不同票面利率的债券凸性
print("不同票面利率的债券凸性:")
coupon_rates = [0.02, 0.04, 0.06, 0.08]
for rate in coupon_rates:
year_conv, period_conv = bndconvp(
Settle='2023-07-15',
Maturity='2033-07-15',
CouponRate=rate,
Price=[100]
)
print(f"票面利率 {rate * 100}%: 年凸性={year_conv[0]}, 周期凸性={period_conv[0]}")
#不同票面利率的债券凸性:
#票面利率 2.0%: 年凸性=90.9991, 周期凸性=363.9965
#票面利率 4.0%: 年凸性=79.0357, 周期凸性=316.1429
#票面利率 6.0%: 年凸性=68.9012, 周期凸性=275.6047
#票面利率 8.0%: 年凸性=60.2874, 周期凸性=241.1497
示例4:零息债券与附息债券凸性比较
零息债券
year_conv_zero, period_conv_zero = bndconvp(
Settle='2023-07-15',
Maturity='2033-07-15',
CouponRate=0.00,
Price=[50] # 零息债券通常折价交易
)
print(f"零息债券: 年凸性={year_conv_zero[0]}, 周期凸性={period_conv_zero[0]}")
#零息债券: 年凸性=98.1313, 周期凸性=392.5253
附息债券
year_conv_coupon, period_conv_coupon = bndconvp(
Settle='2023-07-15',
Maturity='2033-07-15',
CouponRate=0.05,
Price=[100]
)
print(f"附息债券: 年凸性={year_conv_coupon[0]}, 周期凸性={period_conv_coupon[0]}")
#附息债券: 年凸性=73.7606, 周期凸性=295.0422
示例5:不同付息频率的债券凸性
frequencies = [1, 2, 4, 12] # 年付、半年付、季付、月付
for freq in frequencies:
year_conv, period_conv = bndconvp(
Settle='2023-07-15',
Maturity='2033-07-15',
CouponRate=0.05,
Price=[100],
Period=freq
)
print(f"付息频率 {freq}: 年凸性={year_conv[0]}, 周期凸性={period_conv[0]}")
#付息频率 1: 年凸性=75.1228, 周期凸性=75.1228
#付息频率 2: 年凸性=73.7606, 周期凸性=295.0422
#付息频率 4: 年凸性=73.0377, 周期凸性=1168.6037
#付息频率 12: 年凸性=72.5439, 周期凸性=10446.3182
示例6:不同天数计算基础的债券凸性
bases = [0, 1, 2, 3] # 实际/实际, 30/360, 实际/360, 实际/365
for basis in bases:
year_conv, period_conv = bndconvp(
Settle='2023-07-15',
Maturity='2033-07-15',
CouponRate=0.05,
Price=[100],
Basis=basis
)
print(f"天数计算基础 {basis}: 年凸性={year_conv[0]}, 周期凸性={period_conv[0]}")
#天数计算基础 0: 年凸性=73.7606, 周期凸性=295.0422
#天数计算基础 1: 年凸性=73.7606, 周期凸性=295.0422
#天数计算基础 2: 年凸性=73.7606, 周期凸性=295.0422
#天数计算基础 3: 年凸性=73.7606, 周期凸性=295.0422
实际意义解释
债券凸性衡量债券价格对利率变化的二阶敏感度,是久期的补充指标:
1, 凸性总是正值:对于不含期权的普通债券,凸性总是正的
2, 凸性与价格关系:通常,价格越低(收益率越高),凸性越大
3, 凸性与期限关系:长期债券的凸性通常大于短期债券
4, 凸性与票息关系:低票息债券的凸性通常大于高票息债券
5, 零息债券:零息债券的凸性通常最大,因为所有现金流都在到期日
实际交易中的应用
1, 利率风险管理:凸性帮助投资者更精确地估计利率变化对债券价格的影响
2, 债券组合优化:通过组合不同凸性的债券,可以创建对利率变化有特定敏感度的投资组合
3, 相对价值分析:比较不同债券的凸性可以帮助识别被低估或高估的债券
4, 免疫策略:在构建免疫组合时,考虑凸性可以提高免疫效果
这些示例可以帮助债券投资者理解凸性的重要性,特别是在利率环境变化较大时,凸性成为债券投资决策中的重要考量因素。
给定收益率的债券凸性
[YearConvexity,PerConvexity] = bndconvy(Yield,CouponRate,Settle,Maturity)计算固定收益证券的凸性,给定每种债券的净价。
Yield —— 每半年到期收益率
CouponRate —— 息票率, 用于确定债券应付息票的年百分比率, 小数
Settle —— 债券结算日期, 日期时间数组|字符串数组|日期字符向量
Maturity——债券到期日, 日期时间数组|字符串数组|日期字符向量
Period —— 年付息次数, 2(默认)|值为0、1、2、3、4、6或12的数字
Basis —— 日计数基准, 0(默认)|数值:0、1、2、3、4、6、7、8、9、10、11、12、13
示例1:不同收益率水平的债券凸性
yields = [0.02, 0.04, 0.06, 0.08] # 2%, 4%, 6%, 8%
year_conv, per_conv = bndconvy(
Settle='2023-07-15',
Maturity='2033-07-15',
CouponRate=0.05,
Yield=yields
)
for i, yld in enumerate(yields):
print(f"收益率 {yld*100}%: 年凸性={year_conv[i]}, 周期凸性={per_conv[i]}")
#收益率 2.0%: 年凸性=79.177, 周期凸性=316.708
#收益率 4.0%: 年凸性=75.4925, 周期凸性=301.9701
#收益率 6.0%: 年凸性=71.8058, 周期凸性=287.2231
#收益率 8.0%: 年凸性=68.1253, 周期凸性=272.5014
示例2:不同到期期限的债券凸性
maturities = ['2025-07-15', '2030-07-15', '2040-07-15', '2050-07-15']
for maturity in maturities:
year_conv, per_conv = bndconvy(
Settle='2023-07-15',
Maturity=maturity,
CouponRate=0.04,
Yield=0.05
)
print(f"到期日 {maturity}: 年凸性={year_conv[0]}, 周期凸性={per_conv[0]}")
#到期日 2025-07-15: 年凸性=4.5774, 周期凸性=18.3098
#到期日 2030-07-15: 年凸性=41.9259, 周期凸性=167.7034
#到期日 2040-07-15: 年凸性=179.2088, 周期凸性=716.8352
#到期日 2050-07-15: 年凸性=335.9129, 周期凸性=1343.6515
示例3:不同票面利率的债券凸性
coupon_rates = [0.02, 0.04, 0.06, 0.08]
for rate in coupon_rates:
year_conv, per_conv = bndconvy(
Settle='2023-07-15',
Maturity='2033-07-15',
CouponRate=rate,
Yield=0.05
)
print(f"票面利率 {rate*100}%: 年凸性={year_conv[0]}, 周期凸性={per_conv[0]}")
#票面利率 2.0%: 年凸性=86.2214, 周期凸性=344.8854
#票面利率 4.0%: 年凸性=77.1313, 周期凸性=308.525
#票面利率 6.0%: 年凸性=70.6702, 周期凸性=282.6809
#票面利率 8.0%: 年凸性=65.8418, 周期凸性=263.3671
示例4:零息债券与附息债券凸性比较
零息债券
year_conv_zero, per_conv_zero = bndconvy(
Settle='2023-07-15',
Maturity='2033-07-15',
CouponRate=0.00,
Yield=0.05
)
print(f"零息债券: 年凸性={year_conv_zero[0]}, 周期凸性={per_conv_zero[0]}")
#零息债券: 年凸性=99.9551, 周期凸性=399.8203
附息债券
year_conv_coupon, per_conv_coupon = bond_convexity_yield(
Settle='2023-07-15',
Maturity='2033-07-15',
CouponRate=0.05,
Yield=0.05
)
print(f"附息债券: 年凸性={year_conv_coupon[0]}, 周期凸性={per_conv_coupon[0]}")
#附息债券: 年凸性=73.6489, 周期凸性=294.5958
示例5:不同付息频率的债券凸性
frequencies = [1, 2, 4, 12] # 年付、半年付、季付、月付
for freq in frequencies:
year_conv, per_conv = bndconvy(
Settle='2023-07-15',
Maturity='2033-07-15',
CouponRate=0.05,
Yield=0.05,
Period=freq
)
print(f"付息频率 {freq}: 年凸性={year_conv[0]}, 周期凸性={per_conv[0]}")
#付息频率 1: 年凸性=75.0095, 周期凸性=75.0095
#付息频率 2: 年凸性=73.6489, 周期凸性=294.5958
#付息频率 4: 年凸性=72.9276, 周期凸性=1166.8409
#付息频率 12: 年凸性=72.4345, 周期凸性=10430.5658
示例6:不同天数计算基础的债券凸性
bases = [0, 1, 2, 3] # 实际/实际, 30/360, 实际/360, 实际/365
for basis in bases:
year_conv, per_conv = bndconvy(
Settle='2023-07-15',
Maturity='2033-07-15',
CouponRate=0.05,
Yield=0.05,
Basis=basis
)
print(f"天数计算基础 {basis}: 年凸性={year_conv[0]}, 周期凸性={per_conv[0]}")
#天数计算基础 0: 年凸性=73.6489, 周期凸性=294.5958
#天数计算基础 1: 年凸性=73.6287, 周期凸性=294.5149
#天数计算基础 2: 年凸性=75.6796, 周期凸性=302.7182
#天数计算基础 3: 年凸性=73.7518, 周期凸性=295.0072
示例7:收益率曲线变动对凸性的影响
平行移动
yield_changes = [-0.02, -0.01, 0.00, 0.01, 0.02] # -2%, -1%, 0%, +1%, +2%
base_yield = 0.05
for change in yield_changes:
year_conv, per_conv = bndconvy(
Settle='2023-07-15',
Maturity='2033-07-15',
CouponRate=0.05,
Yield=base_yield + change
)
print(f"收益率 {base_yield+change:.3f}: 年凸性={year_conv[0]}, 周期凸性={per_conv[0]}")
#收益率 0.030: 年凸性=77.3355, 周期凸性=309.342
#收益率 0.040: 年凸性=75.4925, 周期凸性=301.9701
#收益率 0.050: 年凸性=73.6489, 周期凸性=294.5958
#收益率 0.060: 年凸性=71.8058, 周期凸性=287.2231
#收益率 0.070: 年凸性=69.9642, 周期凸性=279.8566
实际意义解释
债券凸性衡量债券价格对利率变化的二阶敏感度,是久期的补充指标:
凸性总是正值:对于不含期权的普通债券,凸性总是正的
凸性与收益率关系:通常,收益率越高,凸性越大
凸性与期限关系:长期债券的凸性通常大于短期债券
凸性与票息关系:低票息债券的凸性通常大于高票息债券
零息债券:零息债券的凸性通常最大,因为所有现金流都在到期日
实际交易中的应用
利率风险管理:凸性帮助投资者更精确地估计利率变化对债券价格的影响
债券组合优化:通过组合不同凸性的债券,可以创建对利率变化有特定敏感度的投资组合
相对价值分析:比较不同债券的凸性可以帮助识别被低估或高估的债券
免疫策略:在构建免疫组合时,考虑凸性可以提高免疫效果
收益率曲线策略:分析不同收益率水平下的凸性变化,可以帮助制定收益率曲线策略
这些示例可以帮助债券投资者理解凸性的重要性,特别是在利率环境变化较大时,凸性成为债券投资决策中的重要考量因素。
债券价格久期计算
[ModDuration,YearDuration,PerDuration] = bnddurp(Price,CouponRate,Settle,Maturity) 给定债券净价,计算固定收益证券的麦考利久期和修正久期。
Price —— 债券净价(标量)
CouponRate —— 息票率, 用于确定债券应付息票的年百分比率, 小数
Settle —— 债券结算日期, 日期时间数组|字符串数组|日期字符向量
Maturity——债券到期日, 日期时间数组|字符串数组|日期字符向量
Period —— 年付息次数, 2(默认)|值为0、1、2、3、4、6或12的数字
Basis —— 日计数基准, 0(默认)|数值:0、1、2、3、4、6、7、8、9、10、11、12、13
示例1:不同价格水平的债券久期
不同价格水平的债券久期
prices = [90, 95, 100, 105, 110] # 折价、平价和溢价债券
mod_durs, year_durs, period_durs = bnddurp(
Settle='2023-07-15',
Maturity='2033-07-15',
CouponRate=0.05,
Price=prices
)
for i, price in enumerate(prices):
print(f"价格 {price}: 修正久期={mod_durs[i]}, 麦考利久期={year_durs[i]}, 周期久期={period_durs[i]}")
#价格 90: 修正久期=7.7388, 麦考利久期=7.8619, 周期久期=15.7238
#价格 95: 修正久期=7.8189, 麦考利久期=7.9296, 周期久期=15.8591
#价格 100: 修正久期=7.893, 麦考利久期=7.9917, 周期久期=15.9834
#价格 105: 修正久期=7.9619, 麦考利久期=8.049, 周期久期=16.0979
#价格 110: 修正久期=8.026, 麦考利久期=8.102, 周期久期=16.204
示例2:不同到期期限的债券久期
不同到期期限的债券久期比较
maturities = ['2025-07-15', '2030-07-15', '2040-07-15', '2050-07-15']
for maturity in maturities:
mod_durs, year_durs, period_durs = bnddurp(
Settle='2023-07-15',
Maturity=maturity,
CouponRate=0.04,
Price=100
)
print(f"到期日 {maturity}: 修正久期={mod_durs[0]}, 麦考利久期={year_durs[0]}, 周期久期={period_durs[0]}")
#到期日 2025-07-15: 修正久期=1.9242, 麦考利久期=1.9435, 周期久期=3.8869
#到期日 2030-07-15: 修正久期=6.1144, 麦考利久期=6.1755, 周期久期=12.3511
#到期日 2040-07-15: 修正久期=12.3734, 麦考利久期=12.4971, 周期久期=24.9942
#到期日 2050-07-15: 修正久期=16.5847, 麦考利久期=16.7505, 周期久期=33.501
示例3:不同票面利率的债券久期
不同票面利率的债券久期比较
coupon_rates = [0.02, 0.04, 0.06, 0.08]
for rate in coupon_rates:
mod_durs, year_durs, period_durs = bnddurp(
Settle='2023-07-15',
Maturity='2033-07-15',
CouponRate=rate,
Price=100
)
print(f"票面利率 {rate*100}%: 修正久期={mod_durs[0]}, 麦考利久期={year_durs[0]}, 周期久期={period_durs[0]}")
#票面利率 2.0%: 修正久期=9.0694, 麦考利久期=9.1147, 周期久期=18.2294
#票面利率 4.0%: 修正久期=8.2587, 麦考利久期=8.3413, 周期久期=16.6826
#票面利率 6.0%: 修正久期=7.5511, 麦考利久期=7.6643, 周期久期=15.3286
#票面利率 8.0%: 修正久期=6.9311, 麦考利久期=7.0697, 周期久期=14.1394
示例4:零息债券与附息债券久期比较
零息债券
mod_durs_zero, year_durs_zero, period_durs_zero = bnddurp(
Settle='2023-07-15',
Maturity='2033-07-15',
CouponRate=0.00,
Price=50 # 零息债券通常折价交易
)
print(f"零息债券: 修正久期={mod_durs_zero[0]}, 麦考利久期={year_durs_zero[0]}, 周期久期={period_durs_zero[0]}")
#零息债券: 修正久期=9.8281, 麦考利久期=10.0014, 周期久期=20.0027
附息债券
mod_durs_coupon, year_durs_coupon, period_durs_coupon = bnddurp(
Settle='2023-07-15',
Maturity='2033-07-15',
CouponRate=0.05,
Price=100
)
print(f"附息债券: 修正久期={mod_durs_coupon[0]}, 麦考利久期={year_durs_coupon[0]}, 周期久期={period_durs_coupon[0]}")
#附息债券: 修正久期=7.893, 麦考利久期=7.9917, 周期久期=15.9834
示例5:不同付息频率的债券久期
frequencies = [1, 2, 4, 12] # 年付、半年付、季付、月付
for freq in frequencies:
mod_durs, year_durs, period_durs = bnddurp(
Settle='2023-07-15',
Maturity='2033-07-15',
CouponRate=0.05,
Price=100,
Period=freq
)
print(f"付息频率 {freq}: 修正久期={mod_durs[0]}, 麦考利久期={year_durs[0]}, 周期久期={period_durs[0]}")
#付息频率 1: 修正久期=7.7231, 麦考利久期=8.1092, 周期久期=8.1092
#付息频率 2: 修正久期=7.893, 麦考利久期=7.9917, 周期久期=15.9834
#付息频率 4: 修正久期=7.907, 麦考利久期=7.9317, 周期久期=31.727
#付息频率 12: 修正久期=7.889, 麦考利久期=7.8917, 周期久期=94.7008
示例6:不同天数计算基础的债券久期
bases = [0, 1, 2, 3] # 实际/实际, 30/360, 实际/360, 实际/365
for basis in bases:
mod_durs, year_durs, period_durs = bnddurp(
Settle='2023-07-15',
Maturity='2033-07-15',
CouponRate=0.05,
Price=100,
Basis=basis
)
print(f"天数计算基础 {basis}: 修正久期={mod_durs[0]}, 麦考利久期={year_durs[0]}, 周期久期={period_durs[0]}")
#天数计算基础 0: 修正久期=7.893, 麦考利久期=7.9917, 周期久期=15.9834
#天数计算基础 1: 修正久期=7.8908, 麦考利久期=7.9894, 周期久期=15.9789
#天数计算基础 2: 修正久期=8.0096, 麦考利久期=8.1082, 周期久期=16.2164
#天数计算基础 3: 修正久期=7.8985, 麦考利久期=7.9971, 周期久期=15.9943
示例7:实际债券市场数据
美国10年期国债
mod_durs, year_durs, period_durs = bnddurp(
Settle='2023-07-15',
Maturity='2033-07-15',
CouponRate=0.0375, # 当前10年期国债利率
Price=98.5 # 当前市场价格
)
print(f"美国10年期国债: 修正久期={mod_durs[0]}, 麦考利久期={year_durs[0]}, 周期久期={period_durs[0]}")
#美国10年期国债: 修正久期=8.336, 麦考利久期=8.4179, 周期久期=16.8358
公司债券(较高票息)
mod_durs, year_durs, period_durs = bnddurp(
Settle='2023-07-15',
Maturity='2033-07-15',
CouponRate=0.055, # 较高票息
Price=102.5 # 溢价交易
)
print(f"公司债券(5.5%票息): 修正久期={mod_durs[0]}, 麦考利久期={year_durs[0]}, 周期久期={period_durs[0]}")
#公司债券(5.5%票息): 修正久期=7.7563, 麦考利久期=7.8566, 周期久期=15.7133
实际意义解释
债券久期衡量债券价格对利率变化的敏感度:
修正久期:表示利率变化1%时,债券价格变化的百分比
麦考利久期:表示债券现金流的加权平均到期时间
周期久期:以付息周期为单位的麦考利久期
关键特性:
久期与到期期限:通常,到期期限越长,久期越大
久期与票息:票息越高,久期越小(因为前期现金流更多)
久期与收益率:收益率越高,久期越小
零息债券:零息债券的久期等于其到期期限
实际交易中的应用
利率风险管理:久期帮助投资者估计利率变化对债券价格的影响
免疫策略:通过匹配资产和负债的久期,可以创建对利率变化免疫的投资组合
债券组合管理:通过调整组合久期,可以表达对利率走势的看法
相对价值分析:比较不同债券的久期可以帮助识别被低估或高估的债券
风险度量:久期是债券风险度量的重要指标,常用于风险管理和监管报告
这些示例可以帮助债券投资者理解久期的重要性,特别是在利率环境变化较大时,久期成为债券投资决策中的重要考量因素。
债券久期计算(给定收益率)
[ModDuration,YearDuration,PerDuration] = bnddury(Yield,CouponRate,Settle,Maturity) 给定债券的收益率,计算固定收益证券的麦考利久期和修正久期。
Yield —— 每半年到期收益率
CouponRate —— 息票率, 用于确定债券应付息票的年百分比率, 小数
Settle —— 债券结算日期, 日期时间数组|字符串数组|日期字符向量
Maturity——债券到期日, 日期时间数组|字符串数组|日期字符向量
Period —— 年付息次数, 2(默认)|值为0、1、2、3、4、6或12的数字
Basis —— 日计数基准, 0(默认)|数值:0、1、2、3、4、6、7、8、9、10、11、12、13
示例1:零息债券(无票息支付)
mod_durations, year_durations, per_durations = bnddury(
Settle='2023-01-01',
Maturity='2033-01-01',
CouponRate=0.0, # 零票息
Yield=[0.03, 0.04, 0.05] # 不同收益率
)
print(f"修正久期: {[round(d, 4) for d in mod_durations]}")
print(f"麦考利久期: {[round(d, 4) for d in year_durations]}")
#修正久期: [9.8522, 9.8039, 9.7561]
#麦考利久期: [10.0, 10.0, 10.0]
#理论上零息债券的麦考利久期应等于其剩余期限
示例2:高票息债券(票息率高于市场利率)
mod_durations, year_durations, per_durations = bnddury(
Settle='2023-06-15',
Maturity='2030-06-15',
CouponRate=0.08, # 高票息
Yield=[0.03, 0.04, 0.05], # 较低的市场收益率
Period=2 # 半年付息
)
print(f"修正久期: {[round(d, 4) for d in mod_durations]}")
print(f"麦考利久期: {[round(d, 4) for d in year_durations]}")
#修正久期: [5.628, 5.5591, 5.49]
#麦考利久期: [5.7125, 5.6703, 5.6273]
#高票息债券通常有较短的久期
示例3:贴水债券(票息率低于市场利率)
mod_durations, year_durations, per_durations = bnddury(
Settle='2023-06-15',
Maturity='2035-06-15',
CouponRate=0.02, # 低票息
Yield=[0.05, 0.06, 0.07], # 较高的市场收益率
Period=2 # 半年付息
)
print(f"修正久期: {[round(d, 4) for d in mod_durations]}")
print(f"麦考利久期: {[round(d, 4) for d in year_durations]}")
#修正久期: [10.1959, 10.0462, 9.8924]
#麦考利久期: [10.4508, 10.3476, 10.2387]
# 贴水债券通常有较长的久期
示例4:不同付息频率的影响
# 年付息
mod_dur_annual, year_dur_annual, per_dur_annual = bnddury(
Settle='2023-01-01',
Maturity='2033-01-01',
CouponRate=0.05,
Yield=[0.04],
Period=1 # 年付息
)
# 半年付息
mod_dur_semi, year_dur_semi, per_dur_semi = bnddury(
Settle='2023-01-01',
Maturity='2033-01-01',
CouponRate=0.05,
Yield=[0.04],
Period=2 # 半年付息
)
# 季付息
mod_dur_quarterly, year_dur_quarterly, per_dur_quarterly = bnddury(
Settle='2023-01-01',
Maturity='2033-01-01',
CouponRate=0.05,
Yield=[0.04],
Period=4 # 季付息
)
不同付息频率对久期的影响:
print(f"年付息 - 修正久期: {round(mod_dur_annual[0], 4)}, 麦考利久期: {round(year_dur_annual[0], 4)}")
print(f"半年付息 - 修正久期: {round(mod_dur_semi[0], 4)}, 麦考利久期: {round(year_dur_semi[0], 4)}")
print(f"季付息 - 修正久期: {round(mod_dur_quarterly[0], 4)}, 麦考利久期: {round(year_dur_quarterly[0], 4)}")
#年付息 - 修正久期: 7.8759, 麦考利久期: 8.1909
#半年付息 - 修正久期: 7.9225, 麦考利久期: 8.0809
#季付息 - 修正久期: 7.9461, 麦考利久期: 8.0255
示例5:不同日计数基准的影响
# 30/360基准
mod_dur_30360, year_dur_30360, per_dur_30360 = bnddury(
Settle='2023-01-15',
Maturity='2028-01-15',
CouponRate=0.04,
Yield=[0.035],
Basis=0 # 30/360
)
# ACT/ACT基准
mod_dur_actact, year_dur_actact, per_dur_actact = bnddury(
Settle='2023-01-15',
Maturity='2028-01-15',
CouponRate=0.04,
Yield=[0.035],
Basis=1 # ACT/ACT
)
不同日计数基准对久期的影响:
print(f"30/360基准 - 修正久期: {round(mod_dur_30360[0], 6)}, 麦考利久期: {round(year_dur_30360[0], 6)}")
print(f"ACT/ACT基准 - 修正久期: {round(mod_dur_actact[0], 6)}, 麦考利久期: {round(year_dur_actact[0], 6)}")
#30/360基准 - 修正久期: 4.507937, 麦考利久期: 4.586826
#ACT/ACT基准 - 修正久期: 4.510124, 麦考利久期: 4.589051
示例6:实际市场数据测试
假设的美国国债数据
mod_durations, year_durations, per_durations = bnddury(
Settle='2023-09-20',
Maturity='2043-08-15', # 30年期国债
CouponRate=0.0425, # 4.25%票息
Yield=[0.045, 0.046, 0.047], # 不同收益率水平
Period=2, # 半年付息
Basis=1 # ACT/ACT日计数基准
)
30年期美国国债久期计算:
print(f"修正久期: {[round(d, 4) for d in mod_durations]}")
print(f"麦考利久期: {[round(d, 4) for d in year_durations]}")
#修正久期: [13.1624, 13.1088, 13.0552]
#麦考利久期: [13.4585, 13.4103, 13.362]
# 长期债券对利率变化更为敏感,久期应较长
从收益到到期的固定收益证券价格
[Price,AccruedInt]=bndprice(Yield,CouponRate,Settle,Maturity),给定具有SIA日期参数和到期收益率的债券,返回清洁价格和应计利息。
[Price,AccruedInt]=bndprice(___,Name,Value)添加可选的名称-值对参数。
Yield —— 债券到期收益率, 数字
CouponRate —— 息票率, 用于确定债券应付息票的年百分比率, 小数
Settle —— 债券结算日期, 日期时间数组|字符串数组|日期字符向量
Maturity——债券到期日, 日期时间数组|字符串数组|日期字符向量
Period —— 年付息次数, 2(默认)|值为0、1、2、3、4、6或12的数字
Basis —— 日计数基准, 0(默认)|数值:0、1、2、3、4、6、7、8、9、10、11、12、13
示例1:美国国债定价
10年期美国国债,票面利率2.5%,半年付息,30/360日计数基准
prices, accrued = bndprice(
Yield=[0.03, 0.035, 0.04], # 不同收益率水平
Settle='15-Jul-2023',
Maturity='15-Jul-2033',
CouponRate=0.025,
Period=2,
Basis=1 # 30/360基准
)
10年期美国国债价格:
print(f"收益率3.0%: {prices[0]:.4f} (应计利息: {accrued[0]:.4f})")
print(f"收益率3.5%: {prices[1]:.4f} (应计利息: {accrued[1]:.4f})")
print(f"收益率4.0%: {prices[2]:.4f} (应计利息: {accrued[2]:.4f})")
#收益率3.0%: 95.7078 (应计利息: 1.2500)
#收益率3.5%: 91.6236 (应计利息: 1.2500)
#收益率4.0%: 87.7364 (应计利息: 1.2500)
#随着收益率上升,债券价格下降
示例2:公司债券定价
5年期公司债券,票面利率6%,季度付息,实际/365日计数基准
prices, accrued = bndprice(
Yield=[0.05, 0.055, 0.06],
Settle='01-Sep-2023',
Maturity='01-Sep-2028',
CouponRate=0.06,
Period=4, # 季度付息
Basis=3 # 实际/365基准
)
5年期公司债券价格:
print(f"收益率5.0%: {prices[0]:.4f} (应计利息: {accrued[0]:.4f})")
print(f"收益率5.5%: {prices[1]:.4f} (应计利息: {accrued[1]:.4f})")
print(f"收益率6.0%: {prices[2]:.4f} (应计利息: {accrued[2]:.4f})")
#收益率5.0%: 104.0621 (应计利息: 1.5000)
#收益率5.5%: 101.8102 (应计利息: 1.5000)
#收益率6.0%: 99.6140 (应计利息: 1.5000)
#当收益率等于票面利率时,价格接近面值
示例3:零息债券定价
3年期零息债券,实际/360日计数基准
prices, accrued = bndprice(
Yield=[0.03, 0.035, 0.04],
Settle='15-Aug-2023',
Maturity='15-Aug-2026',
CouponRate=0.00, # 零票息
Period=1, # 年付息(尽管无票息)
Basis=2 # 实际/360基准
)
3年期零息债券价格:
print(f"收益率3.0%: {prices[0]:.4f}")
print(f"收益率3.5%: {prices[1]:.4f}")
print(f"收益率4.0%: {prices[2]:.4f}")
#收益率3.0%: 91.3940
#收益率3.5%: 90.0565
#收益率4.0%: 88.7448
#价格低于面值,且随着收益率上升而下降
示例4:高收益债券定价
7年期高收益债券,票面利率10%,半年付息
prices, accrued = bndprice(
Yield=[0.08, 0.10, 0.12],
Settle='01-Oct-2023',
Maturity='01-Oct-2030',
CouponRate=0.10, # 高票息
Period=2,
Basis=1 # 30/360基准
)
7年期高收益债券价格:
print(f"收益率8.0%: {prices[0]:.4f} (溢价)")
print(f"收益率10.0%: {prices[1]:.4f} (平价)")
print(f"收益率12.0%: {prices[2]:.4f} (折价)")
#收益率8.0%: 110.5631 (溢价)
#收益率10.0%: 100.0000 (平价)
#收益率12.0%: 90.7050 (折价)
#高票息债券对收益率变化更敏感
示例5:不同付息频率的影响
比较不同付息频率对债券价格的影响
yield_rate = 0.05
coupon_rate = 0.06
maturity = '15-Dec-2028'
settle = '15-Dec-2023'
年付息:
price_annual, _ = bndprice(
Yield=[yield_rate],
Settle=settle,
Maturity=maturity,
CouponRate=coupon_rate,
Period=1, # 年付息
Basis=1
)
半年付息:
price_semi, _ = bndprice(
Yield=[yield_rate],
Settle=settle,
Maturity=maturity,
CouponRate=coupon_rate,
Period=2, # 半年付息
Basis=1
)
季度付息:
price_quarterly, _ = bndprice(
Yield=[yield_rate],
Settle=settle,
Maturity=maturity,
CouponRate=coupon_rate,
Period=4, # 季度付息
Basis=1
)
不同付息频率对债券价格的影响(收益率5%,票面利率6%):
print(f"年付息价格: {price_annual[0]:.4f}")
print(f"半年付息价格: {price_semi[0]:.4f}")
print(f"季度付息价格: {price_quarterly[0]:.4f}")
#年付息价格: 104.3295
#半年付息价格: 104.3760
#季度付息价格: 104.3998
#付息频率越高,债券价格越高
示例6:应计利息计算验证
验证应计利息计算的准确性
选择一个付息日附近的日期,计算应计利息
prices, accrued = bndprice(
Yield=[0.05],
Settle='14-Mar-2024', # 付息日前一天
Maturity='15-Mar-2029',
CouponRate=0.06,
Period=2, # 半年付息
Basis=1 # 30/360基准
)
应计利息验证:
print(f"付息日前一天的价格: {prices[0]:.4f}")
print(f"应计利息: {accrued[0]:.4f} (应接近一个付息期的利息)")
#付息日前一天的价格: 104.3780
#应计利息: 2.9833 (应接近一个付息期的利息)
比较付息日后一天的情况
prices2, accrued2 = bndprice(
Yield=[0.05],
Settle='16-Mar-2024', # 付息日后一天
Maturity='15-Mar-2029',
CouponRate=0.06,
Period=2,
Basis=1
)
print(f"付息日后一天的价格: {prices2[0]:.4f}")
print(f"应计利息: {accrued2[0]:.4f} (应接近零)")
#付息日后一天的价格: 104.3737
#应计利息: 0.0167 (应接近零)
#付息日前应计利息高,付息日后应计利息低
示例7:不同日计数基准的比较
比较不同日计数基准对债券价格的影响:
yield_rate = 0.05
coupon_rate = 0.06
maturity = '15-Dec-2028'
settle = '15-Jun-2023'
30/360基准:
price_30360, accrued_30360 = bndprice(
Yield=[yield_rate],
Settle=settle,
Maturity=maturity,
CouponRate=coupon_rate,
Period=2,
Basis=1 # 30/360
)
实际/实际基准:
price_actact, accrued_actact = bndprice(
Yield=[yield_rate],
Settle=settle,
Maturity=maturity,
CouponRate=coupon_rate,
Period=2,
Basis=0 # 实际/实际
)
不同日计数基准对债券价格的影响:
print(f"30/360基准 - 价格: {price_30360[0]:.4f}, 应计利息: {accrued_30360[0]:.4f}")
print(f"实际/实际基准 - 价格: {price_actact[0]:.4f}, 应计利息: {accrued_actact[0]:.4f}")
#30/360基准 - 价格: 104.7571, 应计利息: 3.0000
#实际/实际基准 - 价格: 104.3826, 应计利息: 3.0000
#不同基准下价格和应计利息可能有细微差异
相对于即期利率曲线的静态利差
Spread = bndspread(ZeroRates,CurveDates, Price,Coupon,Settle,Maturity) 计算基准的静态点差(Z点差),以基点为单位。
Spread = bndspread(___,Name,Value) 添加可选的名称-值对参数。
ZeroRates —— 到期日定义的投资期限内每个点的隐含零利率, 小数向量
CurveDates —— 与零利率相对应的到期日, 日期时间|序列日期号
Price —— 计算利差的每100美元名义债券的结算价格, 数字
Coupon —— 计算息差的债券的年息票率, 小数
Settle —— 债券结算日期, 日期时间数组|字符串数组|日期字符向量
Maturity —— 债券到期日, 日期时间数组|字符串数组|日期字符向量
Period —— 年付息次数, 2(默认)|值为0、1、2、3、4、6或12的数字
Basis —— 日计数基准, 0(默认)|数值:0、1、2、3、4、6、7、8、9、10、11、12、13
示例1:公司债券与国债曲线对比
公司债券相对于国债曲线的Z-Spread
z_spread1 = bndspread(
CurveDates=['15-01-2023', '15-01-2025', '15-01-2030', '15-01-2040', '15-01-2050'],
ZeroRates=[0.015, 0.018, 0.022, 0.025, 0.026], # 国债即期利率曲线
Price=98.50, # 公司债券市场价格
Coupon=0.045, # 4.5%票息
Settle='20-01-2023',
Maturity='15-01-2043',
Period=2, # 半年付息
Basis=1 # 30/360计息规则
)
print(f"公司债券Z-Spread: {z_spread1}bps")
#公司债券Z-Spread: 2.1154bps
# 这反映了公司债券相对于无风险曲线的信用风险和流动性溢价
示例2:不同信用等级债券比较
投资级公司债券
z_spread_IG = bndspread(
CurveDates=['01-03-2023', '01-03-2028', '01-03-2033', '01-03-2043'],
ZeroRates=[0.025, 0.028, 0.030, 0.032], # 互换利率曲线
Price=101.25,
Coupon=0.0525, # 5.25%票息
Settle='15-03-2023',
Maturity='01-03-2033'
)
print(f"投资级债券Z-Spread: {z_spread_IG}bps")
#投资级债券Z-Spread: 2.0865bps
高收益债券
z_spread_HY = bndspread(
CurveDates=['01-03-2023', '01-03-2028', '01-03-2033', '01-03-2043'],
ZeroRates=[0.025, 0.028, 0.030, 0.032], # 同样的基准曲线
Price=92.80,
Coupon=0.085, # 8.5%票息
Settle='15-03-2023',
Maturity='01-03-2033'
)
print(f"高收益债券Z-Spread: {z_spread_HY}bps")
#高收益债券Z-Spread: 6.5285bps
# 高收益债券的Z-Spread通常更高,反映更高的信用风险
示例3:不同货币债券分析
欧元区公司债券(以EURIBOR为基准)
z_spread_eur = bndspread(
CurveDates=['15-06-2023', '15-06-2025', '15-06-2030', '15-06-2040'],
ZeroRates=[0.02, 0.022, 0.025, 0.027], # EURIBOR即期利率曲线
Price=99.75,
Coupon=0.0375, # 3.75%票息
Settle='20-06-2023',
Maturity='15-06-2035',
Basis=0 # ACT/ACT计息规则(欧洲常见)
)
print(f"欧元债券Z-Spread: {z_spread_eur}bps")
#欧元债券Z-Spread: 1.1691bps
英镑公司债券(以SONIA为基准)
z_spread_gbp = bndspread(
CurveDates=['15-06-2023', '15-06-2025', '15-06-2030', '15-06-2040'],
ZeroRates=[0.032, 0.034, 0.036, 0.038], # SONIA即期利率曲线
Price=101.20,
Coupon=0.055, # 5.5%票息
Settle='20-06-2023',
Maturity='15-06-2035',
Basis=1 # 30/360计息规则
)
print(f"英镑债券Z-Spread: {z_spread_gbp}bps")
#英镑债券Z-Spread: 1.6325bps
示例4:新兴市场美元债券
新兴市场发行的美元债券(以美国国债为基准)
z_spread_em = bndspread(
CurveDates=['15-07-2023', '15-07-2025', '15-07-2030', '15-07-2040'],
ZeroRates=[0.038, 0.039, 0.041, 0.043], # 美国国债即期利率曲线
Price=95.50,
Coupon=0.075, # 7.5%票息
Settle='20-07-2023',
Maturity='15-07-2032'
)
print(f"新兴市场美元债券Z-Spread: {z_spread_em}bps")
#新兴市场美元债券Z-Spread: 3.9603bps
# 这类债券的Z-Spread通常包含国家风险溢价
示例5:含期权的债券
可赎回债券的Z-Spread分析
z_spread_callable = bndspread(
CurveDates=['15-08-2023', '15-08-2025', '15-08-2030', '15-08-2040'],
ZeroRates=[0.035, 0.037, 0.040, 0.042],
Price=102.30,
Coupon=0.06, # 6%票息
Settle='20-08-2023',
Maturity='15-08-2035'
)
print(f"可赎回债券Z-Spread: {z_spread_callable}bps")
#可赎回债券Z-Spread: 1.6013bps
# 注意:对于含期权债券,Z-Spread可能不能完全反映风险特征
# 可能需要使用OAS(期权调整利差)进行更精确分析
固定息债券总收益
[BondEquiv,EffectiveRate] = bndtotalreturn(Price,CouponRate,Settle,Maturity,ReinvestRate)计算固定息票债券到期或特定投资期限的总回报。
[BondEquiv,EffectiveRate] = bndtotalreturn(___,Name,Value)添加可选的名称-值对参数。
Price —— 结算日的净价, 矩阵
CouponRate — 票面利率,小数的
Settle —— 固定息债券结算日, 日期时间数组|字符串数组|日期字符向量
Maturity —— 固定息债券到期日, 日期时间数组|字符串数组|日期字符向量
ReinvestRate —— 再投资率, 小数的
Period ——年付息次数, 2(默认)|值为0、1、2、3、4、6或12的数字
Basis —— 日计数基准, 0(实际/实际)(默认)|集合的整数[0…13]|集合的整数值向量[0…13m]
示例1:普通公司债券持有至到期
投资级公司债券持有至到期的总回报
result1 = bndtotalreturn(
ReinvestRate=0.035, # 再投资利率3.5%
Price=[98.50], # 购买价格98.50
CouponRate=0.045, # 票面利率4.5%
Settle='15-01-2023',
Maturity='15-01-2033', # 10年期债券
Period=2, # 半年付息
Basis=1 # 30/360计息规则
)
print(f"公司债券总回报 - BEY: {result1[0]}%, EAY: {result1[1]}%")
#公司债券总回报 - BEY: 4.4746%, EAY: 4.5246%
# 这显示了在3.5%再投资利率下,持有该债券10年的年化回报率
示例2:国债投资分析
美国国债总回报分析
result2 = bndtotalreturn(
ReinvestRate=0.025, # 国债再投资利率2.5%
Price=[100.25], # 略高于面值购买
CouponRate=0.03, # 3%票息
Settle='01-03-2023',
Maturity='01-03-2033', # 10年期国债
Period=2, # 半年付息
Basis=0 # ACT/ACT计息规则(国债常用)
)
print(f"国债总回报 - BEY: {result2[0]}%, EAY: {result2[1]}%")
#国债总回报 - BEY: 2.9111%, EAY: 2.9298%
# 这反映了国债投资的预期总回报,考虑了票息和再投资
示例3:高收益债券分析
高收益债券在不同再投资利率下的总回报
reinvestment_rates = [0.04, 0.05, 0.06] # 不同再投资利率假设
results = []
for rate in reinvestment_rates:
result = bndtotalreturn(
ReinvestRate=rate,
Price=[92.80], # 折价购买
CouponRate=0.085, # 8.5%高票息
Settle='15-03-2023',
Maturity='15-03-2028', # 5年期高收益债券
Period=2
)
results.append((rate, result))
for rate, result in results:
print(f"再投资利率{rate*100}% - BEY: {result[0]}%, EAY: {result[1]}%")
#再投资利率4.0% - BEY: 9.3484%, EAY: 9.5669%
#再投资利率5.0% - BEY: 9.5019%, EAY: 9.7277%
#再投资利率6.0% - BEY: 9.6585%, EAY: 9.8918%
# 这展示了再投资利率对高收益债券总回报的影响
示例4:不同持有期的债券比较
比较不同期限债券的总回报
bonds = [
{"name": "2年期债券", "maturity": "15-05-2025"},
{"name": "5年期债券", "maturity": "15-05-2028"},
{"name": "10年期债券", "maturity": "15-05-2033"}
]
for bond in bonds:
result = bndtotalreturn(
ReinvestRate=0.04,
Price=[99.50],
CouponRate=0.045,
Settle='15-05-2023',
Maturity=bond["maturity"],
Period=2
)
print(f"{bond['name']} - BEY: {result[0]}%, EAY: {result[1]}%")
#2年期债券 - BEY: 4.7402%, EAY: 4.7963%
#5年期债券 - BEY: 4.5561%, EAY: 4.608%
#10年期债券 - BEY: 4.4603%, EAY: 4.51%
# 这展示了债券期限对总回报的影响
示例5:不同购买价格的敏感性分析
分析不同购买价格对总回报的影响
prices = [95.00, 100.00, 105.00] # 折价、平价、溢价购买
results = []
for price in prices:
result = bndtotalreturn(
ReinvestRate=0.04,
Price=[price],
CouponRate=0.05,
Settle='01-06-2023',
Maturity='01-06-2033',
Period=2
)
results.append((price, result))
for price, result in results:
print(f"购买价格{price} - BEY: {result[0]}%, EAY: {result[1]}%")
#购买价格95.0 - BEY: 5.3291%, EAY: 5.4001%
#购买价格100.0 - BEY: 4.8032%, EAY: 4.8608%
#购买价格105.0 - BEY: 4.3042%, EAY: 4.3505%
# 这展示了购买价格对债券总回报的影响
示例6:机构债券投资分析
机构债券在不同计息基准下的总回报
for basis in [0, 1, 2, 3]:
result = bndtotalreturn(
ReinvestRate=0.042,
Price=[101.25],
CouponRate=0.0525,
Settle='20-06-2023',
Maturity='20-06-2033',
Period=2,
Basis=basis
)
basis_names = {0: "ACT/ACT", 1: "30/360", 2: "ACT/360", 3: "ACT/365"}
print(f"计息基准{basis_names[basis]} - BEY: {result[0]}%, EAY: {result[1]}%")
#计息基准ACT/ACT - BEY: 4.9075%, EAY: 4.9636%
#计息基准30/360 - BEY: 4.9075%, EAY: 4.9677%
#计息基准ACT/360 - BEY: 4.9075%, EAY: 4.8939%
#计息基准ACT/365 - BEY: 4.9075%, EAY: 4.9636%
# 这展示了不同计息规则对总回报计算的影响
示例7:零息债券总回报
零息债券总回报计算
result_zero = bndtotalreturn(
ReinvestRate=0.03, # 零息债券无票息再投资,此参数不影响结果
Price=[82.50], # 折价购买
CouponRate=0.00, # 零票息
Settle='01-07-2023',
Maturity='01-07-2033', # 10年期零息债券
Period=1 # 零息债券通常不付息,但设为1不影响计算
)
print(f"零息债券总回报 - BEY: {result_zero[0]}%, EAY: {result_zero[1]}%")
#零息债券总回报 - BEY: 3.8847%, EAY: 1.9423%
# 对于零息债券,总回报完全来自价格升值
实际应用说明
1, 投资决策:帮助投资者比较不同债券的预期总回报,考虑票息收入和再投资回报
2, 风险评估:通过不同再投资利率的敏感性分析,评估利率风险对债券投资的影响
3, 组合构建:帮助投资组合经理选择不同期限和特征的债券,优化整体回报
4, 绩效评估:与实际投资回报比较,评估投资策略的有效性
债券等值收益率
Yield = bndyield(Price,CouponRate,Settle,Maturity)返回到期时的债券等价收益率。
Price - 债券的净价格(不含应计利息的当前价格)
CouponRate - 用于确定债券应付息票的年百分比率
Settle - 债券结算日期
Maturity - 债券到期日
Period - 每年付息次数
Basis - 日计数基准
Yield - 债券等值收益率
示例1:平价债券收益率计算
平价债券(价格接近面值)的BEY计算
result1 = bndyield(
Price=[100.00], # 平价购买
Settle='2023-06-15',
Maturity='2033-06-15', # 10年期债券
CouponRate=0.05, # 5%票面利率
Period=2, # 半年付息
Basis=1 # 30/360计息规则
)
print(f"平价债券BEY: {result1}%")
#平价债券BEY: 0.05%
示例2:折价债券收益率计算
折价债券(价格低于面值)的BEY计算
result2 = bndyield(
Price=[92.50], # 折价购买
Settle='2023-07-01',
Maturity='2028-07-01', # 5年期债券
CouponRate=0.04, # 4%票面利率
Period=2
)
print(f"折价债券BEY: {result2}%")
#折价债券BEY: 0.0575%
示例3:溢价债券收益率计算
溢价债券(价格高于面值)的BEY计算
result3 = bndyield(
Price=[105.75], # 溢价购买
Settle='2023-08-10',
Maturity='2033-08-10', # 10年期债券
CouponRate=0.06, # 6%票面利率
Period=2
)
print(f"溢价债券BEY: {result3}%")
#溢价债券BEY: 0.0525%
示例4:不同计息基准的比较
比较不同计息基准对BEY计算的影响
bases = [0, 1, 2, 3] # 不同计息基准
basis_names = {
0: "ACT/ACT (ISMA)",
1: "30/360 (Bond)",
2: "ACT/360",
3: "ACT/365"
}
for basis in bases:
result = bndyield(
Price=[98.75],
Settle='2023-09-15',
Maturity='2030-09-15',
CouponRate=0.045,
Period=2,
Basis=basis
)
print(f"{basis_names[basis]}基准 - BEY: {result}%")
#ACT/ACT (ISMA)基准 - BEY: 0.0471%
#30/360 (Bond)基准 - BEY: 0.0471%
#ACT/360基准 - BEY: 0.0464%
#ACT/365基准 - BEY: 0.0471%
示例5:不同付息频率的影响
比较不同付息频率对BEY的影响
frequencies = [1, 2, 4] # 年付息、半年付息、季度付息
freq_names = {
1: "年付息",
2: "半年付息",
4: "季度付息"
}
for freq in frequencies:
result = bndyield(
Price=[99.50],
Settle='2023-10-01',
Maturity='2028-10-01',
CouponRate=0.05,
Period=freq
)
print(f"{freq_names[freq]} - BEY: {result}%")
#年付息 - BEY: 0.0512%
#半年付息 - BEY: 0.0511%
#季度付息 - BEY: 0.0511%
示例6:零息债券收益率计算
result_zero = bndyield(
Price=[82.30], # 大幅折价
Settle='2023-11-01',
Maturity='2033-11-01', # 10年期零息债券
CouponRate=0.00, # 零票息
Period=1 # 零息债券通常不付息
)
print(f"零息债券BEY: {result_zero}%")
#零息债券BEY: 0.0197%
示例7:不同期限债券的收益率比较
比较不同期限债券的BEY(收益率曲线分析)
maturities = [
('2024-06-15', '1年期'),
('2026-06-15', '3年期'),
('2033-06-15', '10年期'),
('2043-06-15', '20年期')
]
for maturity, label in maturities:
result = bndyield(
Price=[99.00],
Settle='2023-06-15',
Maturity=maturity,
CouponRate=0.05,
Period=2
)
print(f"{label}债券 - BEY: {result}%")
#1年期债券 - BEY: 0.0605%
#3年期债券 - BEY: 0.0537%
#10年期债券 - BEY: 0.0513%
#20年期债券 - BEY: 0.0508%
示例8:市场价格波动的敏感性分析
分析价格变动对BEY的影响
prices = [95.00, 97.50, 100.00, 102.50, 105.00] # 不同价格水平
for price in prices:
result = bndyield(
Price=[price],
Settle='2023-12-01',
Maturity='2030-12-01',
CouponRate=0.055,
Period=2
)
print(f"价格{price} - BEY: {result}%")
#价格95.0 - BEY: 0.064%
#价格97.5 - BEY: 0.0594%
#价格100.0 - BEY: 0.055%
#价格102.5 - BEY: 0.0507%
#价格105.0 - BEY: 0.0465%
示例9:实际市场债券分析
实际市场债券的BEY计算(以美国国债为例)
treasury_bonds = [
{
"name": "2年期国债",
"settle": "2023-07-15",
"maturity": "2025-07-15",
"coupon": 0.0475,
"price": 99.875
},
{
"name": "10年期国债",
"settle": "2023-07-15",
"maturity": "2033-07-15",
"coupon": 0.035,
"price": 98.250
},
{
"name": "30年期国债",
"settle": "2023-07-15",
"maturity": "2053-07-15",
"coupon": 0.04,
"price": 96.500
}
]
for bond in treasury_bonds:
result = bndyield(
Price=[bond["price"]],
Settle=bond["settle"],
Maturity=bond["maturity"],
CouponRate=bond["coupon"],
Period=2,
Basis=0 # 美国国债使用ACT/ACT
)
print(f"{bond['name']} - BEY: {result}%")
#2年期国债 - BEY: 0.0482%
#10年期国债 - BEY: 0.0371%
#30年期国债 - BEY: 0.0421%
bohman窗
Bohman窗是一种在信号处理中常用的窗函数,由两个半周期的余弦函数组成。它在频域具有良好的旁瓣衰减特性,适用于需要减少频谱泄漏的应用场景。
Bohman窗的主要优势在于它在主瓣宽度和旁瓣衰减之间提供了良好的平衡,使其成为许多信号处理应用的理想选择。
与矩形窗或汉宁窗等其他窗函数相比,Bohman窗具有更快的旁瓣衰减速率,这使其在需要高动态范围的应用中特别有用。
w = barthannwin(L,sym=1) 返回一个长度为L个点的修正的bohman窗 默认sym=1
当sym=1, 生成一个对称窗口,用于滤波器设计.
当sym=0, 生成一个周期性窗口,用于光谱分析.
示例1:频谱分析中的信号加窗
window = barthannwin(1024)
print(window[:5])
#结果:[0.0, 2.4583286260381615e-08, 1.966640643521686e-07, 6.637286981709539e-07, 1.573241295472691e-06]
意义: 生成长度为1024个样本的Bohman窗,用于对信号进行加窗处理,减少频谱分析中的频谱泄漏。在傅里叶变换前对信号加窗,可以改善频率分辨率并减少旁瓣效应。
应用场景: 在振动分析、声学测量或任何需要精确频率成分分析的场合,使用Bohman窗可以提高频谱分析的准确性。
示例2:滤波器设计
window = barthannwin(64,0)
print(window[:5])
#结果:[0.0, 0.00010030207385699694, 0.0008000981713110686, 0.0026873261028717566, 0.006326978236643285]
意义: 生成长度为64个样本的非对称Bohman窗(sym=0表示非对称),用于FIR滤波器设计。非对称窗函数更适合数字滤波器设计,可以确保滤波器的因果性。
应用场景: 设计低通、高通或带通FIR滤波器时,使用Bohman窗作为窗函数,可以在主瓣宽度和旁瓣衰减之间取得良好平衡。
示例3:短时傅里叶变换
window = barthannwin(256)
print(window[:5])
#结果:[0.0, 1.5871631400526248e-06, 1.2694992568305918e-05, 4.283259407041745e-05, 0.0001014859629542772]
意义: 生成长度为256个样本的Bohman窗,用于短时傅里叶变换(STFT)分析。STFT通过对信号分段并加窗来分析信号的时频特性。
应用场景: 在语音处理、音乐分析或非平稳信号分析中,使用Bohman窗可以减少时频分析中的交叉项干扰,提供更清晰的时频表示。
示例4:雷达信号处理
window = barthannwin(512,1)
print(window[:5])
#结果:[0.0, 1.9724191547328823e-07, 1.577863754296388e-06, 5.324887614129026e-06, 1.2620620020786094e-05]
意义: 生成长度为512个样本的对称Bohman窗(sym=1表示对称),用于雷达脉冲压缩处理。对称窗函数在雷达信号处理中常用于匹配滤波器设计。
应用场景: 在雷达系统中,使用Bohman窗对发射脉冲进行加权,可以改善距离分辨率同时保持较低的旁瓣水平,提高目标检测性能。
示例5:医学信号处理
window = barthannwin(128)
print(window[:5])
#结果:[0.0, 1.2845499905111274e-05, 0.00010268855414275607, 0.00034614978828281795, 0.000819097354074913]
意义: 生成长度为128个样本的Bohman窗,用于心电图(ECG)或脑电图(EEG)等生物医学信号的频谱分析。
应用场景: 在医学信号处理中,使用Bohman窗可以减少频谱泄漏,更准确地提取心率变异性、脑电节律等生理特征。
示例6:音频处理
window = barthannwin(2048,0)
print(window[:5])
#结果:[0.0, 3.063925576793358e-09, 2.451133550209622e-08, 8.272536771271669e-08, 1.9608846840712957e-07]
意义: 生成长度为2048个样本的非对称Bohman窗,用于音频信号分析和处理。较长的窗长度可以提供更好的频率分辨率。
应用场景: 在音频编码、音高检测或音频特效处理中,使用Bohman窗可以减少频谱泄漏,提高处理的精确度。
示例7:地震信号分析
window = barthannwin(1024)
print(window[:5])
#结果:[0.0, 2.4583286260381615e-08, 1.966640643521686e-07, 6.637286981709539e-07, 1.573241295472691e-06]
意义: 生成长度为1024个样本的Bohman窗,用于地震信号的时间-频率分析。
应用场景: 在地震勘探和地震学研究中,使用Bohman窗可以对地震波进行时频分析,识别不同地层反射特征,提高油气勘探的准确性。
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy import signal
def bohmanwin_window(input_str):
"""
根据输入字符串生成Bohman窗口函数。
参数:
input_str (str): 输入参数,可以是单个整数(如"5")或包含两个数字的元组(如"(5, 0)")。
返回:
list 或 str: 生成的窗口列表,或错误信息字符串。
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
# 情况1:输入是长度为2的元组(例如 "(M, sym)")
if isinstance(expr, tuple) and len(expr) == 2:
# 检查两个元素是否为数字
if expr[0].is_number and expr[1].is_number:
# 检查窗口长度M是否为整数且大于0
if not expr[0].is_integer:
return f"输入错误: 窗口长度必须为整数,但输入为{expr[0]}"
m = int(expr[0])
if m <= 0:
return f"输入错误: 窗口长度必须大于0,但输入为{m}"
# 确定sym参数(0为False,否则为True)
sym = False if expr[1] == 0 else True
window = signal.windows.bohman(m, sym)
result = list(window)
else:
error = True
# 情况2:输入是单个数字(例如 "M")
elif expr.is_number:
# 检查是否为整数且大于0
if not expr.is_integer:
return f"输入错误: 窗口长度必须为整数,但输入为{expr}"
m = int(expr)
if m <= 0:
return f"输入错误: 窗口长度必须大于0,但输入为{m}"
window = signal.windows.bohman(m)
result = list(window)
# 其他情况视为输入错误
else:
error = True
return result if not error else f"输入错误: {input_str}"
except sp.SympifyError:
return f"解析错误: 无法解析输入 '{input_str}'"
except Exception as e:
return f"运行时错误: {e}"
def main():
# 示例测试
test_cases = [
"5", # 正确输入,生成默认对称窗口
# 前3个值: [0.0, 0.31830988618379075, 1.0]...
"(10, 0)", # 正确输入,生成非对称窗口
#前3个值: [0.0, 0.02529445788273843, 0.1791238937062839]...
"(5, 1)", # 正确输入,sym=True
#前3个值: [0.0, 0.31830988618379075, 1.0]...
]
for case in test_cases:
print(f"输入: {case}")
result = bohmanwin_window(case)
if isinstance(result, list):
print(f"输出长度: {len(result)}")
print(f"前3个值: {result[:3]}...\n")
else:
print(f"输出: {result}\n")
if __name__ == "__main__":
main()
矩形窗
矩形窗(Boxcar Window)是最简单的窗函数,它在窗口范围内保持恒定的权重1,在窗口外为0。
它通常用于需要最小频谱泄漏但愿意接受较高旁瓣的应用,或者作为其他窗函数的比较基准。
尽管它的频域特性不如其他窗函数,但在某些特定应用中仍然非常有用。
w = boxcar(L,sym=1) 返回一个长度为L个点的修正的矩形窗 默认sym=1
当sym=1, 生成一个对称窗口,用于滤波器设计.
当sym=0, 生成一个周期性窗口,用于光谱分析.
示例1:信号截取与分段
window = boxcar(256)
print(window[:5])
#结果:[1.0, 1.0, 1.0, 1.0, 1.0]
意义: 生成长度为256个样本的矩形窗,用于截取信号的特定段进行分析。矩形窗相当于不对信号进行任何加权,直接截取一段信号。
应用场景: 在需要分析信号原始特性而不引入任何窗函数效应的场合,如检测信号的瞬态特性或分析信号的精确幅值。
示例2:FIR滤波器设计基础
window = boxcar(64,0)
print(window[:5])
#结果:[1.0, 1.0, 1.0, 1.0, 1.0]
意义: 生成长度为64个样本的非对称矩形窗(sym=0表示非对称),用于设计最简单的FIR滤波器。矩形窗对应的FIR滤波器就是理想滤波器的直接截断。
应用场景: 作为滤波器设计的起点,矩形窗滤波器具有最窄的主瓣宽度,但旁瓣衰减性能最差,常用于教学和理论分析。
示例3:频谱泄漏演示
window = boxcar(128)
print(window[:5])
#结果:[1.0, 1.0, 1.0, 1.0, 1.0]
意义: 生成长度为128个样本的矩形窗,用于演示频谱泄漏现象。矩形窗的频域特性具有较高的旁瓣,会导致严重的频谱泄漏。
应用场景: 在教学环境中,使用矩形窗可以清楚地展示频谱泄漏问题,帮助学生理解为什么需要其他类型的窗函数。
示例4:简单信号检测
window = boxcar(512,1)
print(window[:5])
#结果:[1.0, 1.0, 1.0, 1.0, 1.0]
意义: 生成长度为512个样本的对称矩形窗(sym=1表示对称),用于简单信号检测应用。
应用场景: 在需要检测信号是否存在而不关心频谱特性的简单应用中,矩形窗提供了一种快速简单的解决方案。
示例5:实时信号处理
window = boxcar(1024)
print(window[:5])
#结果:[1.0, 1.0, 1.0, 1.0, 1.0]
意义: 生成长度为1024个样本的矩形窗,用于实时信号处理应用。
应用场景: 在计算资源有限的实时系统中,矩形窗的计算复杂度最低,可以提供最快的处理速度,适合对性能要求极高的应用。
示例6:信号对齐与比较
window = boxcar(256)
print(window[:5])
#结果:[1.0, 1.0, 1.0, 1.0, 1.0]
意义: 生成长度为256个样本的矩形窗,用于信号对齐和比较。
应用场景: 在需要比较两段信号或对齐多个信号记录时,矩形窗可以确保信号段被完整截取而不引入任何加权效应。
示例7:数字通信系统
window = boxcar(32,0)
print(window[:5])
#结果:[1.0, 1.0, 1.0, 1.0, 1.0]
意义: 生成长度为32个样本的非对称矩形窗,用于数字通信系统中的符号检测。
应用场景: 在数字通信接收端,矩形窗可用于截取单个符号周期内的信号,进行符号判决和同步。
矩形窗的主要特点是它在时域上不引入任何失真,但在频域上具有较差的性能(高旁瓣电平)。
这使得它适用于那些对时域特性要求极高而对频域特性要求不高的应用,或者作为其他更复杂窗函数的比较基准。
在实际应用中,矩形窗通常被更复杂的窗函数(如汉宁窗、汉明窗等)所取代,除非有特定的需求需要使用矩形窗。
# Copyright 2025 小塔立软件有限公司及其旗下网站:www.qikjik.com
# Licensed under the MIT License.
import sympy as sp
from scipy import signal
def boxcar_window(input_str):
"""
根据输入字符串生成矩形(Boxcar)窗口函数
参数:
input_str (str): 输入参数,可以是:
- 单个整数(如"5")表示窗口长度
- 包含两个元素的元组(如"(5, 0)"),第二个参数表示对称性
返回:
list | str: 生成的窗口列表(成功时)或错误信息字符串(失败时)
注意:
- 窗口长度M必须为大于0的整数
- 对称参数sym:0表示False(生成非对称窗口),其他数值表示True(默认对称窗口)
"""
try:
expr = sp.sympify(input_str)
error = False
result = None
# 情况1:输入是包含两个元素的元组(如 "(M, sym)")
if isinstance(expr, tuple) and len(expr) == 2:
# 验证两个元素是否都是数字
if expr[0].is_number and expr[1].is_number:
# 检查窗口长度是否为有效整数
if not expr[0].is_integer:
return f"输入错误: 窗口长度必须为整数,但输入为{expr[0]}"
m = int(expr[0])
if m <= 0:
return f"输入错误: 窗口长度必须大于0,但输入为{m}"
# 确定对称性参数(0为False,其他为True)
sym = False if expr[1] == 0 else True
window = signal.windows.boxcar(m, sym)
result = list(window)
else:
error = True
# 情况2:输入是单个数字(如 "M")
elif expr.is_number:
# 验证窗口长度有效性
if not expr.is_integer:
return f"输入错误: 窗口长度必须为整数,但输入为{expr}"
m = int(expr)
if m <= 0:
return f"输入错误: 窗口长度必须大于0,但输入为{m}"
# 生成默认对称窗口
window = signal.windows.boxcar(m)
result = list(window)
# 情况3:无效输入格式
else:
error = True
return result if not error else f"输入错误: {input_str}"
except sp.SympifyError:
return f"解析错误: 无法解析输入 '{input_str}'"
except Exception as e:
return f"运行时错误: {e}"
def main():
"""测试函数的主入口"""
test_cases = [
"5", # 有效输入:对称窗口
#窗口值: [1.0, 1.0, 1.0, 1.0, 1.0]
"(10, 0)", # 有效输入:非对称窗口
#窗口值: [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
"(5, 1)", # 有效输入:显式对称窗口
#窗口值: [1.0, 1.0, 1.0, 1.0, 1.0]
]
for case in test_cases:
print(f"输入: {case}")
result = boxcar_window(case)
if isinstance(result, list):
print(f"输出长度: {len(result)}")
print(f"窗口值: {result}\n") # 全量输出方便观察矩形窗口特征
else:
print(f"输出: {result}\n")
if __name__ == "__main__":
main()
伯德图是系统频率响应的一种图示方法.
伯德图由幅值图和相角图组成,两者都按频率的对数分度绘制,故伯德图常也称为对数坐标图.
bodeplot(sys1,sys2)
sys1是控制系统的传递函数
var是符号变量
低通滤波器(一阶系统): RC电路噪声滤除。
bodeplot(1,0.1s+1)
直流电机速度控制: 电机调速系统
bodeplot(5,0.5*s^2+s)
质量-弹簧-阻尼系统: 机械振动分析
bodeplot(1,s^2+0.6s+1)
超前补偿器(PD控制器): 提高系统稳定裕度
bodeplot(2s+10,0.02s+1)
带通滤波器: 通信信号选频
bodeplot(0.1s,(s+1)(0.01s+1))
低通滤波器设计
一阶RC低通滤波器(电阻-电容电路)
去除音频信号中的高频噪声
bodeplot([1],[1,1])
质量-弹簧-阻尼系统
汽车悬架系统或机械振动系统
汽车悬架系统或机械振动系统
bodeplot([1],[1,0.6,1])
运算放大器电路
有源低通滤波器(增益带宽积=10 kHz)
传感器信号调理电路
bodeplot([100],[1,100])
电源稳压器稳定性
Buck变换器控制环路
确保开关电源不产生自激震荡
bodeplot([0.1,1],[0.01,0.11,1])
飞机俯仰控制
飞行器姿态控制系统
自动驾驶仪稳定性验证
bodeplot([1,0.5],[1,2,2,1])
音频均衡器
带阻滤波器(陷波器)
消除电源50/60 Hz工频干扰
bodeplot([1,100],[1,10,100])